Prettier output on WPS/WPA attacks

This commit is contained in:
derv82
2015-06-02 07:59:22 -07:00
parent ff66d08308
commit 7148040199
3 changed files with 50 additions and 28 deletions

View File

@@ -29,7 +29,8 @@ class AttackWPA(Attack):
output_file_prefix='wpa') as airodump: output_file_prefix='wpa') as airodump:
Color.clear_line() Color.clear_line()
Color.p('\r{+} {O}waiting{W} for target to appear...') Color.p('\r{+} {C}WPA-handshake attack{W}: ')
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
@@ -45,8 +46,9 @@ class AttackWPA(Attack):
while True: while True:
if not deauth_proc or deauth_proc.poll() != None: if not deauth_proc or deauth_proc.poll() != None:
# Clear line only if we're not deauthing right now # Clear line only if we're not deauthing right now
Color.p('\r%s\r' % (' ' * 70)) Color.p('\r%s\r' % (' ' * 90))
Color.p('\r{+} waiting for {C}handshake{W}...') Color.p('\r{+} {C}WPA-handshake attack{W}: ')
Color.p('waiting for {C}handshake{W}...')
time.sleep(1) time.sleep(1)
@@ -81,8 +83,7 @@ class AttackWPA(Attack):
for client in airodump_target.clients: for client in airodump_target.clients:
if client.station not in clients: if client.station not in clients:
Color.pl('\r{+} discovered {G}client{W}:' + Color.pl('\r{+} discovered {G}client{W}:' +
' {C}%s{W}' % client.station) ' {C}%s{W}%s' % (client.station, ' ' * 10))
Color.p(' ' * len(' [+] waiting for handshake... '))
clients.append(client.station) clients.append(client.station)
# Send deauth to a client or broadcast # Send deauth to a client or broadcast
@@ -182,7 +183,7 @@ class AttackWPA(Attack):
Color.p('{+} saving copy of {C}handshake{W} to {C}%s{W} ' % cap_filename) Color.p('{+} saving copy of {C}handshake{W} to {C}%s{W} ' % cap_filename)
copy(handshake.capfile, cap_filename) copy(handshake.capfile, cap_filename)
Color.pl(' {G}saved{W}') Color.pl('{G}saved{W}')
# Update handshake to use the stored handshake file for future operations # Update handshake to use the stored handshake file for future operations
handshake.capfile = cap_filename handshake.capfile = cap_filename

View File

@@ -74,7 +74,7 @@ class AttackWPS(Attack):
while True: while True:
time.sleep(1) time.sleep(1)
Color.clear_line() Color.clear_line()
Color.p('\r{+} {C}WPS pixiedust attack{W}: ') Color.p('\r{+} {C}WPS pixie-dust attack{W} ')
stdout_write.flush() stdout_write.flush()
@@ -96,51 +96,69 @@ class AttackWPS(Attack):
if pin and psk and ssid: if pin and psk and ssid:
# We cracked it. # We cracked it.
bssid = self.target.bssid bssid = self.target.bssid
Color.pl('{G}success{W}\n') Color.pl('\n\n{+} {G}successfully cracked WPS PIN and PSK{W}\n')
self.crack_result = CrackResultWPS(bssid, ssid, pin, psk) self.crack_result = CrackResultWPS(bssid, ssid, pin, psk)
self.crack_result.dump() self.crack_result.dump()
self.success = True return True
else: else:
# Failed to crack, reaver proces ended. # Failed to crack, reaver proces ended.
Color.pl('{R}failed: {O}WPS pin not found{W}') Color.pl('{R}failed: {O}WPS pin not found{W}')
self.success = False return False
break
# 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 = '(step 1/8) initialized, waiting for beacon to associate' step = '({C}step 1/8{W}) waiting for beacon'
elif 'Associated with' in stdout_last_line: elif 'Associated with' in stdout_last_line:
step = '(step 2/8) associated, waiting to start session' step = '({C}step 2/8{W}) waiting to start session'
elif 'Starting Cracking Session.' in stdout_last_line: elif 'Starting Cracking Session.' in stdout_last_line:
step = '(step 3/8) started session, waiting to try pin' step = '({C}step 3/8{W}) waiting to try pin'
elif 'Trying pin' in stdout_last_line: elif 'Trying pin' in stdout_last_line:
step = '(step 4/8) trying pin' step = '({C}step 4/8{W}) trying pin'
elif 'Sending EAPOL START request' in stdout_last_line: elif 'Sending EAPOL START request' in stdout_last_line:
step = '(step 5/8) sending eapol start request' step = '({C}step 5/8{W}) sending eapol start request'
elif 'Sending identity response' in stdout_last_line: elif 'Sending identity response' in stdout_last_line:
step = '(step 6/8) sending identity response' step = '({C}step 6/8{W}) sending identity response'
elif 'Sending M2 message' in stdout_last_line: elif 'Sending M2 message' in stdout_last_line:
step = '(step 7/8) sending m2 message (may take a while)' step = '({C}step 7/8{W}) sending m2 message (may take a while)'
elif 'Detected AP rate limiting,' in stdout_last_line: elif 'Detected AP rate limiting,' in stdout_last_line:
step = '(step 0/8) waiting for AP rate limit' if Configuration.wps_skip_rate_limit:
Color.pl('{R}failed: {O}hit WPS rate-limit{W}')
# TODO: Argument for --ignore-rate-limit
'''
Color.pl('{!} {O}use {R}--ignore-rate-limit{O} to ignore' +
' this kind of failure in the future')
'''
break
step = '({C}step -/8{W}) waiting for AP rate limit'
if 'WPS pin not found' in stdout: if 'WPS pin not found' in stdout:
# Attack failed; PIN not found.
Color.pl('{R}failed: {O}WPS pin not found{W}') Color.pl('{R}failed: {O}WPS pin not found{W}')
reaver.interrupt() break
return False
# TODO: Timeout check
if reaver.running_time() > Configuration.wps_timeout:
Color.pl('{R}failed: {O}timeout after %d seconds{W}' % Configuration.wps_timeout)
break
# Reaver Failure/Timeout check
fail_count = stdout.count('WPS transaction failed') fail_count = stdout.count('WPS transaction failed')
if fail_count > Configuration.wps_fail_threshold:
Color.pl('{R}failed: {O}too many failures (%d){W}' % fail_count)
break
timeout_count = stdout.count('Receive timeout occurred') timeout_count = stdout.count('Receive timeout occurred')
if timeout_count > Configuration.wps_timeout_threshold:
Color.pl('{R}failed: {O}too many timeouts (%d){W}' % timeout_count)
break
# Display status of Pixie-Dust attack # Display status of Pixie-Dust attack
Color.p('{W}%s{W}' % step) Color.p('{W}%s{W}' % step)
continue continue
# Attack failed, already printed reason why
reaver.interrupt() reaver.interrupt()
stdout_write.close() stdout_write.close()
return self.success return False
@staticmethod @staticmethod

View File

@@ -82,8 +82,9 @@ class Configuration(object):
Configuration.pixie_only = False # ONLY use Pixie-Dust attack on WPS Configuration.pixie_only = False # ONLY use Pixie-Dust attack on WPS
Configuration.wps_timeout = 600 # Seconds to wait before failing Configuration.wps_timeout = 600 # Seconds to wait before failing
Configuration.wps_max_retries = 20 # Retries before failing Configuration.wps_max_retries = 20 # Retries before failing
Configuration.fail_threshold = 30 # Max number of failures Configuration.wps_fail_threshold = 30 # Max number of failures
Configuration.timeout_threshold = 30 # Max number of timeouts Configuration.wps_timeout_threshold = 30 # Max number of timeouts
Configuration.wps_skip_rate_limit = True # Skip rate-limited WPS APs
# Overwrite config values with arguments (if defined) # Overwrite config values with arguments (if defined)
Configuration.load_from_arguments() Configuration.load_from_arguments()
@@ -96,14 +97,17 @@ class Configuration(object):
''' Sets configuration values based on Argument.args object ''' ''' Sets configuration values based on Argument.args object '''
if args.channel: Configuration.target_channel = args.channel if args.channel: Configuration.target_channel = args.channel
if args.interface: Configuration.interface = args.interface if args.interface: Configuration.interface = args.interface
if args.wep_filter: Configuration.wep_filter = args.wep_filter if args.wep_filter: Configuration.wep_filter = args.wep_filter
if args.require_fakeauth: Configuration.require_fakeauth = False
if args.wpa_filter: Configuration.wpa_filter = args.wpa_filter if args.wpa_filter: Configuration.wpa_filter = args.wpa_filter
if args.wordlist: Configuration.wordlist = args.wordlist
if args.wps_filter: Configuration.wps_filter = args.wps_filter if args.wps_filter: Configuration.wps_filter = args.wps_filter
if args.no_reaver: Configuration.no_reaver = args.no_reaver if args.no_reaver: Configuration.no_reaver = args.no_reaver
if args.reaver_only: Configuration.reaver_only = args.reaver_only if args.reaver_only: Configuration.reaver_only = args.reaver_only
if args.pixie_only: Configuration.pixie_only = args.pixie_only if args.pixie_only: Configuration.pixie_only = args.pixie_only
if args.wordlist: Configuration.wordlist = args.wordlist
if args.require_fakeauth: Configuration.require_fakeauth = False
# Adjust encryption filter # Adjust encryption filter
if Configuration.wep_filter or \ if Configuration.wep_filter or \
@@ -111,7 +115,6 @@ class Configuration(object):
Configuration.wps_filter: Configuration.wps_filter:
# Reset filter # Reset filter
Configuration.encryption_filter = [] Configuration.encryption_filter = []
if Configuration.wep_filter: Configuration.encryption_filter.append('WEP') if Configuration.wep_filter: Configuration.encryption_filter.append('WEP')
if Configuration.wpa_filter: Configuration.encryption_filter.append('WPA') if Configuration.wpa_filter: Configuration.encryption_filter.append('WPA')
if Configuration.wps_filter: Configuration.encryption_filter.append('WPS') if Configuration.wps_filter: Configuration.encryption_filter.append('WPS')