Path: blob/master/modules/post/windows/wlan/wlan_current_connection.rb
19500 views
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45class MetasploitModule < Msf::Post6include Msf::Auxiliary::Report78def initialize(info = {})9super(10update_info(11info,12'Name' => 'Windows Gather Wireless Current Connection Info',13'Description' => %q{14This module gathers information about the current connection on each15wireless lan interface on the target machine.16},17'License' => MSF_LICENSE,18'Author' => ['theLightCosine'],19'Platform' => [ 'win' ],20'SessionTypes' => [ 'meterpreter' ],21'Compat' => {22'Meterpreter' => {23'Commands' => %w[24stdapi_railgun_api25stdapi_sys_process_attach26stdapi_sys_process_getpid27]28}29},30'Notes' => {31'Stability' => [CRASH_SAFE],32'SideEffects' => [],33'Reliability' => []34}35)36)37end3839def run40# Opens memory access into the host process41mypid = client.sys.process.getpid42@host_process = client.sys.process.open(mypid, PROCESS_ALL_ACCESS)43@wlanapi = client.railgun.wlanapi4445wlan_connections = "Wireless LAN Active Connections: \n"46wlan_handle = open_handle47unless wlan_handle48print_error("Couldn't open WlanAPI Handle. WLAN API may not be installed on target")49print_error('On Windows XP this could also mean the Wireless Zero Configuration Service is turned off')50return51end52wlan_iflist = enum_interfaces(wlan_handle)5354wlan_iflist.each do |interface|55connect_info = query_current_connection(wlan_handle, interface['guid'])56guid = guid_to_string(interface['guid'])57wlan_connection = "GUID: #{guid} \nDescription: #{interface['description']} \nState: #{interface['state']}\n"58if connect_info59wlan_connection << "\tMode: #{connect_info['mode']} \n\tProfile: #{connect_info['profile']} \n"60wlan_connection << "\tSSID: #{connect_info['ssid']} \n\tAP MAC: #{connect_info['bssid']} \n"61wlan_connection << "\tBSS Type: #{connect_info['type']} \n\tPhysical Type: #{connect_info['physical']} \n"62wlan_connection << "\tSignal Strength: #{connect_info['signal']} \n\tRX Rate: #{connect_info['rxrate']} \n"63wlan_connection << "\tTX Rate: #{connect_info['txrate']} \n\tSecurity Enabled: #{connect_info['security']} \n"64wlan_connection << "\toneX Enabled: #{connect_info['oneX']} \n\tAuthentication Algorithm: #{connect_info['auth']} \n"65wlan_connection << "\tCipher Algorithm: #{connect_info['cipher']} \n"66else67wlan_connection << "\tThis interface is not currently connected to a network\n"68end69print_good(wlan_connection)70wlan_connections << wlan_connection71end7273wlan_connections.gsub!(/\x00/, '')74store_loot('host.windows.wlan.connections', 'text/plain', session, wlan_connections, 'wlan_connections.txt', 'Wireless LAN Connections')75# close the Wlan API Handle76closehandle = @wlanapi.WlanCloseHandle(wlan_handle, nil)77if closehandle['return'] == 078print_status('WlanAPI Handle Closed Successfully')79else80print_error('There was an error closing the Handle')81end82end8384def open_handle85begin86wlhandle = @wlanapi.WlanOpenHandle(2, nil, 4, 4)87rescue StandardError88return nil89end90return wlhandle['phClientHandle']91end9293def query_current_connection(wlan_handle, guid)94connection = {}95conn_info = @wlanapi.WlanQueryInterface(wlan_handle, guid, 7, nil, 4, 4, nil)96# Grab the pointer to our data structure. We skip voer the Interface State since we already have it97# We interpret the connection mode used first98pointer = conn_info['ppData']99pointer = (pointer + 4)100mode = @host_process.memory.read(pointer, 4)101mode = mode.unpack('V')[0]102case mode103when 0104connection['mode'] = 'A profile is used to make the connection.'105when 1106connection['mode'] = 'A temporary profile is used to make the connection.'107when 2108connection['mode'] = 'Secure discovery is used to make the connection.'109when 3110connection['mode'] = 'Unsecure discovery is used to make the connection.'111when 4112connection['mode'] = 'connection initiated by wireless service automatically using a persistent profile.'113when 5114connection['mode'] = 'Invalid connection mode.'115else116connection['state'] = 'Unknown connection Mode.'117end118119# Grab the wirelessprofile name used in the connection120pointer = (pointer + 4)121profile = @host_process.memory.read(pointer, 512)122connection['profile'] = profile.gsub(/\x00/, '')123124# Check the size of the SSID value. If we get nothing back, the interface is not currently connected125# We return nil and deal with the results back in the calling function126pointer = (pointer + 512)127len_ssid = @host_process.memory.read(pointer, 4)128unless len_ssid.unpack('V')[0]129return nil130end131132# Grabs the SSID of the BSS connected to133pointer = (pointer + 4)134ssid = @host_process.memory.read(pointer, 32)135connection['ssid'] = ssid.gsub(/\x00/, '')136137# Grabs what type of a BSS this is and itnerpretes it into human readable138pointer = (pointer + 32)139bsstype = @host_process.memory.read(pointer, 4)140bsstype = bsstype.unpack('V')[0]141case bsstype142when 1143connection['type'] = 'Infrastructure'144when 2145connection['type'] = 'Independent'146when 3147connection['type'] = 'Any'148else149connection['type'] = 'Unknown BSS Type'150end151152# Grabs the BSS MAC address153pointer = (pointer + 4)154bssid = @host_process.memory.read(pointer, 6)155bssid = bssid.unpack('H*')[0]156bssid.insert(2, ':')157bssid.insert(5, ':')158bssid.insert(8, ':')159bssid.insert(11, ':')160bssid.insert(14, ':')161connection['bssid'] = bssid162163# Grabs the physical association type and interprets it into human readable164pointer = (pointer + 8)165phy_type = @host_process.memory.read(pointer, 4)166phy_type = phy_type.unpack('V')[0]167case phy_type168when 1169connection['physical'] = 'Frequency-hopping spread-spectrum (FHSS)'170when 2171connection['physical'] = 'Direct sequence spread spectrum (DSSS)'172when 3173connection['physical'] = 'Infrared (IR) baseband'174when 4175connection['physical'] = 'Orthogonal frequency division multiplexing (OFDM)'176when 5177connection['physical'] = 'High-rate DSSS (HRDSSS)'178when 6179connection['physical'] = 'Extended rate PHY type'180when 7181connection['physical'] = '802.11n PHY type'182else183connection['physical'] = 'Unknown Association Type'184end185186# Grabs the signal strength value187pointer = (pointer + 8)188signal = @host_process.memory.read(pointer, 4)189connection['signal'] = signal.unpack('V')[0]190191# Grabs the receive rate value192pointer = (pointer + 4)193rxrate = @host_process.memory.read(pointer, 4)194connection['rxrate'] = rxrate.unpack('V')[0]195196# Grabs the transmit rate value197pointer = (pointer + 4)198txrate = @host_process.memory.read(pointer, 4)199connection['txrate'] = txrate.unpack('V')[0]200201# Checks if security is enabled on this BSS202pointer = (pointer + 4)203security_enabled = @host_process.memory.read(pointer, 4)204if security_enabled.unpack('V')[0] == 1205connection['security'] = 'Yes'206else207connection['security'] = 'No'208end209210# Checks of 802.1x Authentication is used211pointer = (pointer + 4)212onex = @host_process.memory.read(pointer, 4)213if onex.unpack('V')[0] == 1214connection['oneX'] = 'Yes'215else216connection['oneX'] = 'No'217end218219# Determines wat Authentication Algorithm is being used220pointer = (pointer + 4)221algo = @host_process.memory.read(pointer, 4)222algo = algo.unpack('V')[0]223case algo224when 1225connection['auth'] = '802.11 Open'226when 2227connection['auth'] = '802.11 Shared'228when 3229connection['auth'] = 'WPA'230when 4231connection['auth'] = 'WPA-PSK'232when 5233connection['auth'] = 'WPA-None'234when 6235connection['auth'] = 'RSNA'236when 7237connection['auth'] = 'RSNA with PSK'238else239connection['auth'] = 'Unknown Algorithm'240end241242# Determines what Cipher is being used243pointer = (pointer + 4)244cipher = @host_process.memory.read(pointer, 4)245cipher = cipher.unpack('V')[0]246case cipher247when 0248connection['cipher'] = 'None'249when 1250connection['cipher'] = 'WEP-40'251when 2252connection['cipher'] = 'TKIP'253when 4254connection['cipher'] = 'CCMP'255when 5256connection['cipher'] = 'WEP-104'257when 256258connection['cipher'] = 'Use Group Key'259when 257260connection['cipher'] = 'WEP'261else262connection['cipher'] = 'Unknown Cipher'263end264return connection265end266267def enum_interfaces(wlan_handle)268iflist = @wlanapi.WlanEnumInterfaces(wlan_handle, nil, 4)269pointer = iflist['ppInterfaceList']270271numifs = @host_process.memory.read(pointer, 4)272numifs = numifs.unpack('V')[0]273274interfaces = []275276# Set the pointer ahead to the first element in the array277pointer = (pointer + 8)278(1..numifs).each do |_i|279interface = {}280# Read the GUID (16 bytes)281interface['guid'] = @host_process.memory.read(pointer, 16)282pointer = (pointer + 16)283# Read the description(up to 512 bytes)284interface['description'] = @host_process.memory.read(pointer, 512)285pointer = (pointer + 512)286# Read the state of the interface (4 bytes)287state = @host_process.memory.read(pointer, 4)288pointer = (pointer + 4)289290# Turn the state into human readable form291state = state.unpack('V')[0]292case state293when 0294interface['state'] = 'The interface is not ready to operate.'295when 1296interface['state'] = 'The interface is connected to a network.'297when 2298interface['state'] = 'The interface is the first node in an ad hoc network. No peer has connected.'299when 3300interface['state'] = 'The interface is disconnecting from the current network.'301when 4302interface['state'] = 'The interface is not connected to any network.'303when 5304interface['state'] = 'The interface is attempting to associate with a network.'305when 6306interface['state'] = 'Auto configuration is discovering the settings for the network.'307when 7308interface['state'] = 'The interface is in the process of authenticating.'309else310interface['state'] = 'Unknown State'311end312interfaces << interface313end314return interfaces315end316317# Convert the GUID to human readable form318def guid_to_string(guid)319aguid = guid.unpack('H*')[0]320sguid = '{' + aguid[6, 2] + aguid[4, 2] + aguid[2, 2] + aguid[0, 2]321sguid << '-' + aguid[10, 2] + aguid[8, 2] + '-' + aguid[14, 2] + aguid[12, 2] + '-' + aguid[16, 4]322sguid << '-' + aguid[20, 12] + '}'323return sguid324end325end326327328