144 lines
4.7 KiB
Python
Executable File
144 lines
4.7 KiB
Python
Executable File
#!/usr/bin/env python
|
|
# -*- coding: utf-8 -*-
|
|
|
|
from .wep import AttackWEP
|
|
from .wpa import AttackWPA
|
|
from .wps import AttackWPS
|
|
from .pmkid import AttackPMKID
|
|
from ..config import Configuration
|
|
from ..util.color import Color
|
|
|
|
class AttackAll(object):
|
|
|
|
@classmethod
|
|
def attack_multiple(cls, targets):
|
|
'''
|
|
Attacks all given `targets` (list[wifite.model.target]) until user interruption.
|
|
Returns: Number of targets that were attacked (int)
|
|
'''
|
|
if any(t.wps for t in targets) and not AttackWPS.can_attack_wps():
|
|
# Warn that WPS attacks are not available.
|
|
Color.pl('{!} {O}Note: WPS attacks are not possible because you do not have {C}reaver{O} nor {C}bully{W}')
|
|
|
|
attacked_targets = 0
|
|
targets_remaining = len(targets)
|
|
for index, target in enumerate(targets, start=1):
|
|
attacked_targets += 1
|
|
targets_remaining -= 1
|
|
|
|
bssid = target.bssid
|
|
essid = target.essid if target.essid_known else '{O}ESSID unknown{W}'
|
|
|
|
Color.pl('\n{+} ({G}%d{W}/{G}%d{W})' % (index, len(targets)) +
|
|
' Starting attacks against {C}%s{W} ({C}%s{W})' % (bssid, essid))
|
|
|
|
should_continue = cls.attack_single(target, targets_remaining)
|
|
if not should_continue:
|
|
break
|
|
|
|
return attacked_targets
|
|
|
|
@classmethod
|
|
def attack_single(cls, target, targets_remaining):
|
|
'''
|
|
Attacks a single `target` (wifite.model.target).
|
|
Returns: True if attacks should continue, False otherwise.
|
|
'''
|
|
|
|
attacks = []
|
|
|
|
if Configuration.use_eviltwin:
|
|
# TODO: EvilTwin attack
|
|
pass
|
|
|
|
elif 'WEP' in target.encryption:
|
|
attacks.append(AttackWEP(target))
|
|
|
|
elif 'WPA' in target.encryption:
|
|
# WPA can have multiple attack vectors:
|
|
|
|
# WPS
|
|
if target.wps != False and AttackWPS.can_attack_wps():
|
|
if Configuration.wps_pixie:
|
|
attacks.append(AttackWPS(target, pixie_dust=True))
|
|
if Configuration.wps_pin:
|
|
attacks.append(AttackWPS(target, pixie_dust=False))
|
|
|
|
# PMKID
|
|
attacks.append(AttackPMKID(target))
|
|
|
|
# Handshake capture
|
|
attacks.append(AttackWPA(target))
|
|
|
|
if len(attacks) == 0:
|
|
Color.pl('{!} {R}Error: {O}Unable to attack: encryption not WEP or WPA')
|
|
return
|
|
|
|
while len(attacks) > 0:
|
|
attack = attacks.pop(0)
|
|
try:
|
|
result = attack.run()
|
|
if result:
|
|
break # Attack was successful, stop other attacks.
|
|
except Exception as e:
|
|
Color.pexception(e)
|
|
continue
|
|
except KeyboardInterrupt:
|
|
Color.pl('\n{!} {O}Interrupted{W}\n')
|
|
answer = cls.user_wants_to_continue(targets_remaining, len(attacks))
|
|
if answer is True:
|
|
continue # Keep attacking the same target (continue)
|
|
elif answer is None:
|
|
return True # Keep attacking other targets (skip)
|
|
else:
|
|
return False # Stop all attacks (exit)
|
|
|
|
if attack.success:
|
|
attack.crack_result.save()
|
|
|
|
return True # Keep attacking other targets
|
|
|
|
|
|
@classmethod
|
|
def user_wants_to_continue(cls, targets_remaining, attacks_remaining=0):
|
|
'''
|
|
Asks user if attacks should continue onto other targets
|
|
Returns:
|
|
True if user wants to continue, False otherwise.
|
|
'''
|
|
if attacks_remaining == 0 and targets_remaining == 0:
|
|
return # No targets or attacksleft, drop out
|
|
|
|
prompt_list = []
|
|
if attacks_remaining > 0:
|
|
prompt_list.append(Color.s('{C}%d{W} attack(s)' % attacks_remaining))
|
|
if targets_remaining > 0:
|
|
prompt_list.append(Color.s('{C}%d{W} target(s)' % targets_remaining))
|
|
prompt = ' and '.join(prompt_list) + ' remain'
|
|
Color.pl('{+} %s' % prompt)
|
|
|
|
prompt = '{+} Do you want to'
|
|
options = '('
|
|
|
|
if attacks_remaining > 0:
|
|
prompt += ' {G}continue{W} attacking,'
|
|
options += '{G}C{W}{D}, {W}'
|
|
|
|
if targets_remaining > 0:
|
|
prompt += ' {O}skip{W} to the next target,'
|
|
options += '{O}s{W}{D}, {W}'
|
|
|
|
options += '{R}e{W})'
|
|
prompt += ' or {R}exit{W} %s? {C}' % options
|
|
|
|
from ..util.input import raw_input
|
|
answer = raw_input(Color.s(prompt)).lower()
|
|
|
|
if answer.startswith('s'):
|
|
return None # Skip
|
|
elif answer.startswith('e'):
|
|
return False # Exit
|
|
else:
|
|
return True # Continue
|
|
|