Fix deauth, Pixie step timeout, better handshake options.
Deauth now deauths clients (whoops). Checks all handshakes if no filename is given to --check-hs Times out a --pixie attack if the step does not change in 30 seconds.
This commit is contained in:
28
Wifite.py
28
Wifite.py
@@ -13,7 +13,7 @@ from json import loads
|
|||||||
import os
|
import os
|
||||||
|
|
||||||
class Wifite(object):
|
class Wifite(object):
|
||||||
|
|
||||||
def main(self):
|
def main(self):
|
||||||
''' Either performs action based on arguments, or starts attack scanning '''
|
''' Either performs action based on arguments, or starts attack scanning '''
|
||||||
|
|
||||||
@@ -60,15 +60,27 @@ class Wifite(object):
|
|||||||
Color.pl('\n{+} Cracked target #%d:' % (index + 1))
|
Color.pl('\n{+} Cracked target #%d:' % (index + 1))
|
||||||
cr = CrackResult.load(item)
|
cr = CrackResult.load(item)
|
||||||
cr.dump()
|
cr.dump()
|
||||||
|
|
||||||
def check_handshake(self, capfile):
|
def check_handshake(self, capfile):
|
||||||
''' Analyzes .cap file for handshake '''
|
''' Analyzes .cap file for handshake '''
|
||||||
Color.pl('{+} checking for handshake in .cap file {C}%s{W}' % capfile)
|
if capfile == '<all>':
|
||||||
if not os.path.exists(capfile):
|
Color.pl('{+} checking all handshakes in {G}"./hs"{W} directory\n')
|
||||||
Color.pl('{!} {O}.cap file {C}%s{O} not found{W}' % capfile)
|
try:
|
||||||
return
|
capfiles = [os.path.join('hs', x) for x in os.listdir('hs') if x.endswith('.cap')]
|
||||||
hs = Handshake(capfile, bssid=Configuration.target_bssid, essid=Configuration.target_essid)
|
except OSError, e:
|
||||||
hs.analyze()
|
capfiles = []
|
||||||
|
if len(capfiles) == 0:
|
||||||
|
Color.pl('{!} {R}no .cap files found in {O}"./hs"{W}\n')
|
||||||
|
else:
|
||||||
|
capfiles = [capfile]
|
||||||
|
for capfile in capfiles:
|
||||||
|
Color.pl('{+} checking for handshake in .cap file {C}%s{W}' % capfile)
|
||||||
|
if not os.path.exists(capfile):
|
||||||
|
Color.pl('{!} {O}.cap file {C}%s{O} not found{W}' % capfile)
|
||||||
|
return
|
||||||
|
hs = Handshake(capfile, bssid=Configuration.target_bssid, essid=Configuration.target_essid)
|
||||||
|
hs.analyze()
|
||||||
|
Color.pl('')
|
||||||
|
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
|
|||||||
@@ -203,13 +203,13 @@ class Airmon(object):
|
|||||||
choice = raw_input(question)
|
choice = raw_input(question)
|
||||||
|
|
||||||
iface = a.get(choice)
|
iface = a.get(choice)
|
||||||
|
|
||||||
if a.get(choice).name in mon_ifaces:
|
if a.get(choice).name in mon_ifaces:
|
||||||
Color.pl('{+} {G}%s{W} is already in monitor mode' % iface.name)
|
Color.pl('{+} {G}%s{W} is already in monitor mode' % iface.name)
|
||||||
else:
|
else:
|
||||||
iface.name = Airmon.start(iface)
|
iface.name = Airmon.start(iface)
|
||||||
return iface.name
|
return iface.name
|
||||||
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def terminate_conflicting_processes():
|
def terminate_conflicting_processes():
|
||||||
@@ -221,7 +221,7 @@ class Airmon(object):
|
|||||||
Found 3 processes that could cause trouble.
|
Found 3 processes that could cause trouble.
|
||||||
If airodump-ng, aireplay-ng or airtun-ng stops working after
|
If airodump-ng, aireplay-ng or airtun-ng stops working after
|
||||||
a short period of time, you may want to kill (some of) them!
|
a short period of time, you may want to kill (some of) them!
|
||||||
-e
|
-e
|
||||||
PID Name
|
PID Name
|
||||||
2272 dhclient
|
2272 dhclient
|
||||||
2293 NetworkManager
|
2293 NetworkManager
|
||||||
@@ -246,7 +246,7 @@ class Airmon(object):
|
|||||||
pid = match.groups()[0]
|
pid = match.groups()[0]
|
||||||
pname = match.groups()[1]
|
pname = match.groups()[1]
|
||||||
Color.pl('{!} {R}terminating {O}conflicting process' +
|
Color.pl('{!} {R}terminating {O}conflicting process' +
|
||||||
' {R}%s{O} ({R}%s{O})' % (pname, pid))
|
' {R}%s{O} (PID {R}%s{O})' % (pname, pid))
|
||||||
os.kill(int(pid), signal.SIGTERM)
|
os.kill(int(pid), signal.SIGTERM)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -182,6 +182,13 @@ class Arguments(object):
|
|||||||
type=int,
|
type=int,
|
||||||
help=Color.s('Time to wait before stopping PixieDust (default: {G}%d sec{W})')
|
help=Color.s('Time to wait before stopping PixieDust (default: {G}%d sec{W})')
|
||||||
% Configuration.wps_pixie_timeout)
|
% Configuration.wps_pixie_timeout)
|
||||||
|
wps.add_argument('--pixiest',
|
||||||
|
action='store',
|
||||||
|
dest='wps_pixie_step_timeout',
|
||||||
|
metavar='[seconds]',
|
||||||
|
type=int,
|
||||||
|
help=Color.s('Time to wait for a step to change before stopping PixieDust (default: {G}%d sec{W})')
|
||||||
|
% Configuration.wps_pixie_step_timeout)
|
||||||
wps.add_argument('-wpst',
|
wps.add_argument('-wpst',
|
||||||
action='store',
|
action='store',
|
||||||
dest='wps_pin_timeout',
|
dest='wps_pin_timeout',
|
||||||
@@ -223,26 +230,28 @@ class Arguments(object):
|
|||||||
help=Color.s('Display previously-cracked access points'))
|
help=Color.s('Display previously-cracked access points'))
|
||||||
commands.add_argument('--check-hs',
|
commands.add_argument('--check-hs',
|
||||||
action='store',
|
action='store',
|
||||||
metavar='[file]',
|
metavar='file',
|
||||||
|
nargs='?',
|
||||||
|
const='<all>',
|
||||||
dest='check_handshake',
|
dest='check_handshake',
|
||||||
help=Color.s('Check a .cap file for WPA handshakes'))
|
help=Color.s('Check a .cap file (or all hs/*.cap files) for WPA handshakes'))
|
||||||
commands.add_argument('--crack-wpa',
|
commands.add_argument('--crack-wpa',
|
||||||
action='store',
|
action='store',
|
||||||
type=str,
|
type=str,
|
||||||
dest='crack_wpa',
|
dest='crack_wpa',
|
||||||
metavar='[file]',
|
metavar='file',
|
||||||
help=Color.s('Crack a .cap file containing a WPA handshake'))
|
help=Color.s('Crack a .cap file containing a WPA handshake'))
|
||||||
commands.add_argument('--crack-wep',
|
commands.add_argument('--crack-wep',
|
||||||
action='store',
|
action='store',
|
||||||
type=str,
|
type=str,
|
||||||
dest='crack_wep',
|
dest='crack_wep',
|
||||||
metavar='[file]',
|
metavar='file',
|
||||||
help=Color.s('Crack a .cap file containing WEP IVS'))
|
help=Color.s('Crack a .cap file containing WEP IVS'))
|
||||||
commands.add_argument('--update',
|
commands.add_argument('--update',
|
||||||
action='store_true',
|
action='store_true',
|
||||||
dest='update',
|
dest='update',
|
||||||
help=Color.s('Update to latest version of Wifite (on github)'))
|
help=Color.s('Update to latest version of Wifite (on github)'))
|
||||||
|
|
||||||
return parser.parse_args()
|
return parser.parse_args()
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ class AttackWPA(Attack):
|
|||||||
Color.p('\r{+} {C}WPA-handshake attack{W}: ')
|
Color.p('\r{+} {C}WPA-handshake attack{W}: ')
|
||||||
Color.p('{O}waiting{W} for target to appear...')
|
Color.p('{O}waiting{W} for target to appear...')
|
||||||
airodump_target = self.wait_for_target(airodump)
|
airodump_target = self.wait_for_target(airodump)
|
||||||
|
|
||||||
# Get client station MAC addresses
|
# Get client station MAC addresses
|
||||||
clients = [c.station for c in airodump_target.clients]
|
clients = [c.station for c in airodump_target.clients]
|
||||||
client_index = 0
|
client_index = 0
|
||||||
@@ -137,7 +137,7 @@ class AttackWPA(Attack):
|
|||||||
if wordlist != None:
|
if wordlist != None:
|
||||||
wordlist_name = wordlist.split(os.sep)[-1]
|
wordlist_name = wordlist.split(os.sep)[-1]
|
||||||
if not os.path.exists(wordlist):
|
if not os.path.exists(wordlist):
|
||||||
Color.pl('{!} {R}unable to crack:' +
|
Color.pl('{!} {R}unable to crack:' +
|
||||||
' wordlist {O}%s{R} does not exist{W}' % wordlist)
|
' wordlist {O}%s{R} does not exist{W}' % wordlist)
|
||||||
else:
|
else:
|
||||||
# We have a wordlist we can use
|
# We have a wordlist we can use
|
||||||
@@ -217,13 +217,14 @@ class AttackWPA(Attack):
|
|||||||
target_name = 'broadcast'
|
target_name = 'broadcast'
|
||||||
command = [
|
command = [
|
||||||
'aireplay-ng',
|
'aireplay-ng',
|
||||||
'--ignore-negative-one',
|
|
||||||
'-0', # Deauthentication
|
'-0', # Deauthentication
|
||||||
|
'1', # Number of deauths to perform.
|
||||||
'-a', self.target.bssid
|
'-a', self.target.bssid
|
||||||
]
|
]
|
||||||
|
command.append('--ignore-negative-one')
|
||||||
if station_bssid:
|
if station_bssid:
|
||||||
# Deauthing a specific client
|
# Deauthing a specific client
|
||||||
command.extend(['-h', station_bssid])
|
command.extend(['-c', station_bssid])
|
||||||
command.append(Configuration.interface)
|
command.append(Configuration.interface)
|
||||||
Color.p(' {C}sending deauth{W} to {C}%s{W}' % target_name)
|
Color.p(' {C}sending deauth{W} to {C}%s{W}' % target_name)
|
||||||
return Process(command)
|
return Process(command)
|
||||||
|
|||||||
@@ -71,6 +71,7 @@ class AttackWPS(Attack):
|
|||||||
|
|
||||||
pin = None
|
pin = None
|
||||||
step = '0) initializing'
|
step = '0) initializing'
|
||||||
|
time_since_last_step = 0
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
@@ -106,6 +107,7 @@ class AttackWPS(Attack):
|
|||||||
Color.pl('{R}failed: {O}WPS pin not found{W}')
|
Color.pl('{R}failed: {O}WPS pin not found{W}')
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
last_step = step
|
||||||
# Status updates, depending on last line of stdout
|
# Status updates, depending on last line of stdout
|
||||||
if 'Waiting for beacon from' in stdout_last_line:
|
if 'Waiting for beacon from' in stdout_last_line:
|
||||||
step = '({C}step 1/8{W}) waiting for beacon'
|
step = '({C}step 1/8{W}) waiting for beacon'
|
||||||
@@ -133,9 +135,19 @@ class AttackWPS(Attack):
|
|||||||
Color.pl('{R}failed: {O}WPS pin not found{W}')
|
Color.pl('{R}failed: {O}WPS pin not found{W}')
|
||||||
break
|
break
|
||||||
|
|
||||||
|
if step != last_step:
|
||||||
|
# Step changed, reset step timer
|
||||||
|
time_since_last_step = 0
|
||||||
|
else:
|
||||||
|
time_since_last_step += 1
|
||||||
|
|
||||||
|
if time_since_last_step > Configuration.wps_pixie_step_timeout:
|
||||||
|
Color.pl('{R}failed: {O}step-timeout after %d seconds{W}' % Configuration.wps_pixie_step_timeout)
|
||||||
|
break
|
||||||
|
|
||||||
# TODO: Timeout check
|
# TODO: Timeout check
|
||||||
if reaver.running_time() > Configuration.wps_pixie_timeout:
|
if reaver.running_time() > Configuration.wps_pixie_timeout:
|
||||||
Color.pl('{R}failed: {O}timeout after %d seconds{W}' % Configuration.wps_timeout)
|
Color.pl('{R}failed: {O}timeout after %d seconds{W}' % Configuration.wps_pixie_timeout)
|
||||||
break
|
break
|
||||||
|
|
||||||
# Reaver Failure/Timeout check
|
# Reaver Failure/Timeout check
|
||||||
@@ -197,7 +209,7 @@ class AttackWPS(Attack):
|
|||||||
if failures >= Configuration.wps_fail_threshold:
|
if failures >= Configuration.wps_fail_threshold:
|
||||||
Color.pl('{R}failed: {O}too many failures{W}')
|
Color.pl('{R}failed: {O}too many failures{W}')
|
||||||
break
|
break
|
||||||
|
|
||||||
# Get output
|
# Get output
|
||||||
out = self.get_stdout()
|
out = self.get_stdout()
|
||||||
|
|
||||||
@@ -364,15 +376,15 @@ class AttackWPS(Attack):
|
|||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
stdout = '''
|
stdout = '''
|
||||||
[Pixie-Dust]
|
[Pixie-Dust]
|
||||||
[Pixie-Dust] Pixiewps 1.1
|
[Pixie-Dust] Pixiewps 1.1
|
||||||
[Pixie-Dust]
|
[Pixie-Dust]
|
||||||
[Pixie-Dust] [*] E-S1: 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
|
[Pixie-Dust] [*] E-S1: 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
|
||||||
[Pixie-Dust] [*] E-S2: 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
|
[Pixie-Dust] [*] E-S2: 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
|
||||||
[Pixie-Dust] [+] WPS pin: 12345678
|
[Pixie-Dust] [+] WPS pin: 12345678
|
||||||
[Pixie-Dust]
|
[Pixie-Dust]
|
||||||
[Pixie-Dust] [*] Time taken: 0 s
|
[Pixie-Dust] [*] Time taken: 0 s
|
||||||
[Pixie-Dust]
|
[Pixie-Dust]
|
||||||
Running reaver with the correct pin, wait ...
|
Running reaver with the correct pin, wait ...
|
||||||
Cmd : reaver -i wlan0mon -b 08:86:3B:8C:FD:9C -c 11 -s y -vv -p 28097402
|
Cmd : reaver -i wlan0mon -b 08:86:3B:8C:FD:9C -c 11 -s y -vv -p 28097402
|
||||||
|
|
||||||
|
|||||||
@@ -70,8 +70,9 @@ class Configuration(object):
|
|||||||
Configuration.no_reaver = False # Do not use Reaver on WPS networks
|
Configuration.no_reaver = False # Do not use Reaver on WPS networks
|
||||||
Configuration.reaver = False # ONLY use Reaver on WPS networks
|
Configuration.reaver = False # ONLY use Reaver on WPS networks
|
||||||
Configuration.pixie_only = False # ONLY use Pixie-Dust attack on WPS
|
Configuration.pixie_only = False # ONLY use Pixie-Dust attack on WPS
|
||||||
Configuration.wps_pin_timeout = 600 # Seconds to wait before reaver fails
|
Configuration.wps_pin_timeout = 600 # Seconds to wait for PIN before reaver fails
|
||||||
Configuration.wps_pixie_timeout = 600 # Seconds to wait before pixie fails
|
Configuration.wps_pixie_timeout = 300 # Seconds to wait for PIN before pixie fails
|
||||||
|
Configuration.wps_pixie_step_timeout = 30 # Seconds to wait for a step to change before pixie fails
|
||||||
Configuration.wps_max_retries = 20 # Retries before failing
|
Configuration.wps_max_retries = 20 # Retries before failing
|
||||||
Configuration.wps_fail_threshold = 30 # Max number of failures
|
Configuration.wps_fail_threshold = 30 # Max number of failures
|
||||||
Configuration.wps_timeout_threshold = 30 # Max number of timeouts
|
Configuration.wps_timeout_threshold = 30 # Max number of timeouts
|
||||||
@@ -181,6 +182,9 @@ class Configuration(object):
|
|||||||
if args.wps_pixie_timeout:
|
if args.wps_pixie_timeout:
|
||||||
Configuration.wps_pixie_timeout = args.wps_pixie_timeout
|
Configuration.wps_pixie_timeout = args.wps_pixie_timeout
|
||||||
Color.pl('{+} {C}option:{W} WPS pixie-dust attack will timeout after {G}%d seconds{W}' % args.wps_pixie_timeout)
|
Color.pl('{+} {C}option:{W} WPS pixie-dust attack will timeout after {G}%d seconds{W}' % args.wps_pixie_timeout)
|
||||||
|
if args.wps_pixie_step_timeout:
|
||||||
|
Configuration.wps_pixie_step_timeout = args.wps_pixie_step_timeout
|
||||||
|
Color.pl('{+} {C}option:{W} Any step in the pixie-dust attack will timeout after {G}%d seconds{W}' % args.wps_pixie_step_timeout)
|
||||||
if args.wps_pin_timeout:
|
if args.wps_pin_timeout:
|
||||||
Configuration.wps_pin_timeout = args.wps_pin_timeout
|
Configuration.wps_pin_timeout = args.wps_pin_timeout
|
||||||
Color.pl('{+} {C}option:{W} WPS PIN attack will timeout after {G}%d seconds{W}' % args.wps_pin_timeout)
|
Color.pl('{+} {C}option:{W} WPS PIN attack will timeout after {G}%d seconds{W}' % args.wps_pin_timeout)
|
||||||
@@ -245,7 +249,7 @@ class Configuration(object):
|
|||||||
if args.crack_wep: Configuration.crack_wep = args.crack_wep
|
if args.crack_wep: Configuration.crack_wep = args.crack_wep
|
||||||
if args.update: Configuration.update = True
|
if args.update: Configuration.update = True
|
||||||
if args.check_handshake: Configuration.check_handshake = args.check_handshake
|
if args.check_handshake: Configuration.check_handshake = args.check_handshake
|
||||||
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def temp(subfile=''):
|
def temp(subfile=''):
|
||||||
|
|||||||
@@ -29,8 +29,6 @@ class Handshake(object):
|
|||||||
|
|
||||||
if not self.essid and not self.bssid:
|
if not self.essid and not self.bssid:
|
||||||
# We do not know the bssid nor the essid
|
# We do not know the bssid nor the essid
|
||||||
Color.pl('{!} {O}Warning{W}:' +
|
|
||||||
' {R}bssid{O} and {R}essid{O} were not specified{W}')
|
|
||||||
# TODO: Display menu for user to select from list
|
# TODO: Display menu for user to select from list
|
||||||
# HACK: Just use the first one we see
|
# HACK: Just use the first one we see
|
||||||
self.bssid = pairs[0][0]
|
self.bssid = pairs[0][0]
|
||||||
|
|||||||
Reference in New Issue
Block a user