Files
metasploit-gs/modules/post/windows/wlan/wlan_probe_request.rb
T

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

156 lines
5.0 KiB
Ruby
Raw Normal View History

##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Post
2021-09-10 12:53:39 +01:00
def initialize(info = {})
super(
update_info(
info,
'Name' => 'Windows Send Probe Request Packets',
'Description' => %q{
This module send probe requests through the wlan interface.
The ESSID field will be use to set a custom message.
},
2021-09-10 12:53:39 +01:00
'License' => MSF_LICENSE,
'Author' => [ 'Borja Merino <bmerinofe[at]gmail.com>' ],
'Platform' => [ 'win' ],
2021-10-06 13:43:31 +01:00
'SessionTypes' => [ 'meterpreter' ],
'Compat' => {
'Meterpreter' => {
'Commands' => %w[
stdapi_railgun_api
stdapi_sys_process_attach
stdapi_sys_process_getpid
]
}
}
2021-09-10 12:53:39 +01:00
)
)
register_options(
2021-09-10 12:53:39 +01:00
[
OptString.new('SSID', [true, 'Message to be embedded in the SSID field', '']),
OptInt.new('TIMEOUT', [false, 'Timeout in seconds running probes', '30'])
]
)
end
def run
ssid = datastore['SSID']
time = datastore['TIMEOUT']
if ssid.length > 32
2023-02-08 13:47:34 +00:00
print_error('The SSID must be equal to or less than 32 bytes')
return
end
mypid = client.sys.process.getpid
@host_process = client.sys.process.open(mypid, PROCESS_ALL_ACCESS)
@wlanapi = client.railgun.wlanapi
2023-02-08 13:47:34 +00:00
wlan_handle = open_handle
unless wlan_handle
print_error("Couldn't open WlanAPI Handle. WLAN API may not be installed on target")
2023-02-08 13:47:34 +00:00
print_error('On Windows XP this could also mean the Wireless Zero Configuration Service is turned off')
return
end
# typedef struct _DOT11_SSID {
# ULONG uSSIDLength;
# UCHAR ucSSID[DOT11_SSID_MAX_LENGTH];
# } DOT11_SSID, *PDOT11_SSID;
2023-02-08 13:47:34 +00:00
pDot11Ssid = [ssid.length].pack('L<') << ssid
wlan_iflist = enum_interfaces(wlan_handle)
2023-02-08 13:47:34 +00:00
if wlan_iflist.empty?
print_status('Wlan interfaces not found')
return
end
print_status("Wlan interfaces found: #{wlan_iflist.length}")
print_status("Sending probe requests for #{time} seconds")
begin
::Timeout.timeout(time) do
2023-02-08 13:47:34 +00:00
loop do
wlan_iflist.each do |interface|
vprint_status("Interface Guid: #{interface['guid'].unpack('H*')[0]}")
vprint_status("Interface State: #{interface['state']}")
2021-09-10 12:53:39 +01:00
vprint_status("DOT11_SSID payload: #{pDot11Ssid.chars.map { |c| c.ord.to_s(16) }.join(':')}")
@wlanapi.WlanScan(wlan_handle, interface['guid'], pDot11Ssid, nil, nil)
sleep(10)
end
end
end
rescue ::Timeout::Error
2021-09-10 12:53:39 +01:00
closehandle = @wlanapi.WlanCloseHandle(wlan_handle, nil)
if closehandle['return'] == 0
2023-02-08 13:47:34 +00:00
print_status('WlanAPI Handle closed successfully')
else
2023-02-08 13:47:34 +00:00
print_error('There was an error closing the Handle')
end
end
end
# Function borrowed from @theLightCosine wlan_* modules
def open_handle
begin
2021-09-10 12:53:39 +01:00
wlhandle = @wlanapi.WlanOpenHandle(2, nil, 4, 4)
2023-02-08 13:47:34 +00:00
rescue StandardError
return nil
end
return wlhandle['phClientHandle']
end
# Function borrowed from @theLightCosine wlan_* modules
def enum_interfaces(wlan_handle)
2021-09-10 12:53:39 +01:00
iflist = @wlanapi.WlanEnumInterfaces(wlan_handle, nil, 4)
pointer = iflist['ppInterfaceList']
2021-09-10 12:53:39 +01:00
numifs = @host_process.memory.read(pointer, 4)
2023-02-08 13:47:34 +00:00
numifs = numifs.unpack('V')[0]
interfaces = []
2021-09-10 12:53:39 +01:00
# Set the pointer ahead to the first element in the array
pointer = (pointer + 8)
2023-02-08 13:47:34 +00:00
(1..numifs).each do |_i|
interface = {}
2021-09-10 12:53:39 +01:00
# Read the GUID (16 bytes)
interface['guid'] = @host_process.memory.read(pointer, 16)
pointer = (pointer + 16)
2021-09-10 12:53:39 +01:00
# Read the description(up to 512 bytes)
interface['description'] = @host_process.memory.read(pointer, 512)
pointer = (pointer + 512)
2021-09-10 12:53:39 +01:00
# Read the state of the interface (4 bytes)
state = @host_process.memory.read(pointer, 4)
pointer = (pointer + 4)
2021-09-10 12:53:39 +01:00
# Turn the state into human readable form
2023-02-08 13:47:34 +00:00
state = state.unpack('V')[0]
case state
2021-09-10 12:53:39 +01:00
when 0
2023-02-08 13:47:34 +00:00
interface['state'] = 'The interface is not ready to operate.'
2021-09-10 12:53:39 +01:00
when 1
2023-02-08 13:47:34 +00:00
interface['state'] = 'The interface is connected to a network.'
2021-09-10 12:53:39 +01:00
when 2
2023-02-08 13:47:34 +00:00
interface['state'] = 'The interface is the first node in an ad hoc network. No peer has connected.'
2021-09-10 12:53:39 +01:00
when 3
2023-02-08 13:47:34 +00:00
interface['state'] = 'The interface is disconnecting from the current network.'
2021-09-10 12:53:39 +01:00
when 4
2023-02-08 13:47:34 +00:00
interface['state'] = 'The interface is not connected to any network.'
2021-09-10 12:53:39 +01:00
when 5
2023-02-08 13:47:34 +00:00
interface['state'] = 'The interface is attempting to associate with a network.'
2021-09-10 12:53:39 +01:00
when 6
2023-02-08 13:47:34 +00:00
interface['state'] = 'Auto configuration is discovering the settings for the network.'
2021-09-10 12:53:39 +01:00
when 7
2023-02-08 13:47:34 +00:00
interface['state'] = 'The interface is in the process of authenticating.'
2021-09-10 12:53:39 +01:00
else
2023-02-08 13:47:34 +00:00
interface['state'] = 'Unknown State'
end
interfaces << interface
end
return interfaces
end
end