@@ -30,7 +30,7 @@ Support
|
|||||||
-------
|
-------
|
||||||
Wifite2 is designed entirely for the latest version of Kali Rolling release (tested on Kali 2016.2, updated May 2017).
|
Wifite2 is designed entirely for the latest version of Kali Rolling release (tested on Kali 2016.2, updated May 2017).
|
||||||
|
|
||||||
This means only the latest versions of these programs are supported: Aircrack-ng suite, wash, reaver, tshark, cowpatty.
|
This means only the latest versions of these programs are supported: Aircrack-ng suite, reaver, tshark, cowpatty.
|
||||||
|
|
||||||
Other pen-testing distributions (such as BackBox) have outdated versions of these suites; these distributions are not supported.
|
Other pen-testing distributions (such as BackBox) have outdated versions of these suites; these distributions are not supported.
|
||||||
|
|
||||||
|
|||||||
16
TODO.md
16
TODO.md
@@ -57,6 +57,22 @@ TSHARK
|
|||||||
* DIY: Extract Beacon frames from the .cap file with WPS flags...
|
* DIY: Extract Beacon frames from the .cap file with WPS flags...
|
||||||
* `tshark -r f.cap -R "wps.primary_device_type.category == 6" -n -2`
|
* `tshark -r f.cap -R "wps.primary_device_type.category == 6" -n -2`
|
||||||
|
|
||||||
|
We can extract WPS networks' BSSID and WPS lock status:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
% tshark -r withwps-01.cap -n -Y "wps.wifi_protected_setup_state && wlan.da == ff:ff:ff:ff:ff:ff" -T fields -e wlan.ta -e wps.ap_setup_locked -E separator=,
|
||||||
|
# Output:
|
||||||
|
88:ad:43:d2:77:c8,
|
||||||
|
18:d6:c7:6d:6b:18,
|
||||||
|
f4:f2:6d:9e:34:25,
|
||||||
|
fc:51:a4:1e:11:67,
|
||||||
|
98:e7:f4:90:f1:12,0x00000001
|
||||||
|
10:13:31:30:35:2c,
|
||||||
|
60:a4:4c:6a:46:b0,
|
||||||
|
c0:7c:d1:6f:a2:c8,
|
||||||
|
f8:cf:c5:fb:a3:e2,
|
||||||
|
```
|
||||||
|
|
||||||
------------------------------------------------------
|
------------------------------------------------------
|
||||||
|
|
||||||
### Backwards Compatibility
|
### Backwards Compatibility
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ from Process import Process
|
|||||||
from Configuration import Configuration
|
from Configuration import Configuration
|
||||||
from Target import Target
|
from Target import Target
|
||||||
from Client import Client
|
from Client import Client
|
||||||
from Wash import Wash
|
from Tshark import Tshark
|
||||||
|
|
||||||
import os, time
|
import os, time
|
||||||
|
|
||||||
@@ -14,7 +14,7 @@ class Airodump(object):
|
|||||||
|
|
||||||
def __init__(self, interface=None, channel=None, encryption=None,\
|
def __init__(self, interface=None, channel=None, encryption=None,\
|
||||||
wps=False, target_bssid=None, output_file_prefix='airodump',\
|
wps=False, target_bssid=None, output_file_prefix='airodump',\
|
||||||
ivs_only=False, skip_wash=False):
|
ivs_only=False, skip_wps=False):
|
||||||
'''
|
'''
|
||||||
Sets up airodump arguments, doesn't start process yet
|
Sets up airodump arguments, doesn't start process yet
|
||||||
'''
|
'''
|
||||||
@@ -40,7 +40,7 @@ class Airodump(object):
|
|||||||
self.target_bssid = target_bssid
|
self.target_bssid = target_bssid
|
||||||
self.output_file_prefix = output_file_prefix
|
self.output_file_prefix = output_file_prefix
|
||||||
self.ivs_only = ivs_only
|
self.ivs_only = ivs_only
|
||||||
self.skip_wash = skip_wash
|
self.skip_wps = skip_wps
|
||||||
|
|
||||||
# For tracking decloaked APs (previously were hidden)
|
# For tracking decloaked APs (previously were hidden)
|
||||||
self.decloaking = False
|
self.decloaking = False
|
||||||
@@ -139,13 +139,13 @@ class Airodump(object):
|
|||||||
targets = Airodump.get_targets_from_csv(csv_filename)
|
targets = Airodump.get_targets_from_csv(csv_filename)
|
||||||
|
|
||||||
# Check targets for WPS
|
# Check targets for WPS
|
||||||
if not self.skip_wash:
|
if not self.skip_wps:
|
||||||
capfile = csv_filename[:-3] + 'cap'
|
capfile = csv_filename[:-3] + 'cap'
|
||||||
Wash.check_for_wps_and_update_targets(capfile, targets)
|
Tshark.check_for_wps_and_update_targets(capfile, targets)
|
||||||
|
|
||||||
if apply_filter:
|
if apply_filter:
|
||||||
# Filter targets based on encryption & WPS capability
|
# Filter targets based on encryption & WPS capability
|
||||||
targets = Airodump.filter_targets(targets, skip_wash=self.skip_wash)
|
targets = Airodump.filter_targets(targets, skip_wps=self.skip_wps)
|
||||||
|
|
||||||
# Sort by power
|
# Sort by power
|
||||||
targets.sort(key=lambda x: x.power, reverse=True)
|
targets.sort(key=lambda x: x.power, reverse=True)
|
||||||
@@ -218,7 +218,7 @@ class Airodump(object):
|
|||||||
return targets
|
return targets
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def filter_targets(targets, skip_wash=False):
|
def filter_targets(targets, skip_wps=False):
|
||||||
''' Filters targets based on Configuration '''
|
''' Filters targets based on Configuration '''
|
||||||
result = []
|
result = []
|
||||||
# Filter based on Encryption
|
# Filter based on Encryption
|
||||||
@@ -229,7 +229,7 @@ class Airodump(object):
|
|||||||
result.append(target)
|
result.append(target)
|
||||||
elif 'WPS' in Configuration.encryption_filter and target.wps:
|
elif 'WPS' in Configuration.encryption_filter and target.wps:
|
||||||
result.append(target)
|
result.append(target)
|
||||||
elif skip_wash:
|
elif skip_wps:
|
||||||
result.append(target)
|
result.append(target)
|
||||||
|
|
||||||
# Filter based on BSSID/ESSID
|
# Filter based on BSSID/ESSID
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ class AttackWEP(Attack):
|
|||||||
with Airodump(channel=self.target.channel,
|
with Airodump(channel=self.target.channel,
|
||||||
target_bssid=self.target.bssid,
|
target_bssid=self.target.bssid,
|
||||||
ivs_only=True, # Only capture IVs packets
|
ivs_only=True, # Only capture IVs packets
|
||||||
skip_wash=True, # Don't check for WPS-compatibility
|
skip_wps=True, # Don't check for WPS-compatibility
|
||||||
output_file_prefix='wep') as airodump:
|
output_file_prefix='wep') as airodump:
|
||||||
|
|
||||||
Color.clear_line()
|
Color.clear_line()
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ class AttackWPA(Attack):
|
|||||||
# First, start Airodump process
|
# First, start Airodump process
|
||||||
with Airodump(channel=self.target.channel,
|
with Airodump(channel=self.target.channel,
|
||||||
target_bssid=self.target.bssid,
|
target_bssid=self.target.bssid,
|
||||||
skip_wash=True,
|
skip_wps=True,
|
||||||
output_file_prefix='wpa') as airodump:
|
output_file_prefix='wpa') as airodump:
|
||||||
|
|
||||||
Color.clear_entire_line()
|
Color.clear_entire_line()
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ class Bully(Attack):
|
|||||||
def run(self):
|
def run(self):
|
||||||
with Airodump(channel=self.target.channel,
|
with Airodump(channel=self.target.channel,
|
||||||
target_bssid=self.target.bssid,
|
target_bssid=self.target.bssid,
|
||||||
skip_wash=True,
|
skip_wps=True,
|
||||||
output_file_prefix='wps_pin') as airodump:
|
output_file_prefix='wps_pin') as airodump:
|
||||||
# Wait for target
|
# Wait for target
|
||||||
Color.clear_entire_line()
|
Color.clear_entire_line()
|
||||||
|
|||||||
13
py/Client.py
13
py/Client.py
@@ -21,10 +21,15 @@ class Client(object):
|
|||||||
5 BSSID, (Access Point's MAC address)
|
5 BSSID, (Access Point's MAC address)
|
||||||
6 Probed ESSIDs
|
6 Probed ESSIDs
|
||||||
'''
|
'''
|
||||||
self.station = fields[0].strip()
|
try:
|
||||||
self.power = int(fields[3].strip())
|
self.station = fields[0].strip()
|
||||||
self.packets = int(fields[4].strip())
|
self.power = int(fields[3].strip())
|
||||||
self.bssid = fields[5].strip()
|
self.packets = int(fields[4].strip())
|
||||||
|
self.bssid = fields[5].strip()
|
||||||
|
except ValueError, e:
|
||||||
|
print "\nValueError ({})".format(e)
|
||||||
|
print "\twhile parsing {}".format(fields)
|
||||||
|
raise e
|
||||||
|
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ class Reaver(Attack):
|
|||||||
|
|
||||||
with Airodump(channel=self.target.channel,
|
with Airodump(channel=self.target.channel,
|
||||||
target_bssid=self.target.bssid,
|
target_bssid=self.target.bssid,
|
||||||
skip_wash=True,
|
skip_wps=True,
|
||||||
output_file_prefix='pixie') as airodump:
|
output_file_prefix='pixie') as airodump:
|
||||||
|
|
||||||
Color.clear_line()
|
Color.clear_line()
|
||||||
@@ -210,7 +210,7 @@ class Reaver(Attack):
|
|||||||
|
|
||||||
with Airodump(channel=self.target.channel,
|
with Airodump(channel=self.target.channel,
|
||||||
target_bssid=self.target.bssid,
|
target_bssid=self.target.bssid,
|
||||||
skip_wash=True,
|
skip_wps=True,
|
||||||
output_file_prefix='wps') as airodump:
|
output_file_prefix='wps') as airodump:
|
||||||
|
|
||||||
Color.clear_line()
|
Color.clear_line()
|
||||||
|
|||||||
83
py/Tshark.py
Normal file
83
py/Tshark.py
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
#!/usr/bin/python2.7
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
from Process import Process
|
||||||
|
import re
|
||||||
|
|
||||||
|
class Tshark(object):
|
||||||
|
''' Wrapper for Tshark program. '''
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def check_for_wps_and_update_targets(capfile, targets):
|
||||||
|
'''
|
||||||
|
Given a cap file and list of targets, use TShark to
|
||||||
|
find which BSSIDs in the cap file use WPS.
|
||||||
|
Then update the 'wps' flag for those BSSIDs in the targets.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
capfile - .cap file from airodump containing packets
|
||||||
|
targets - list of Targets from scan, to be updated
|
||||||
|
'''
|
||||||
|
# Tshark is required to detect WPS networks
|
||||||
|
if not Process.exists('tshark'):
|
||||||
|
return
|
||||||
|
|
||||||
|
command = [
|
||||||
|
'tshark',
|
||||||
|
'-r', capfile, # Path to cap file
|
||||||
|
'-n', # Don't resolve addresses
|
||||||
|
# Filter WPS broadcast packets
|
||||||
|
'-Y', 'wps.wifi_protected_setup_state && wlan.da == ff:ff:ff:ff:ff:ff',
|
||||||
|
'-T', 'fields', # Only output certain fields
|
||||||
|
'-e', 'wlan.ta', # BSSID
|
||||||
|
'-e', 'wps.ap_setup_locked', # Locked status
|
||||||
|
'-E', 'separator=,' # CSV
|
||||||
|
]
|
||||||
|
p = Process(command)
|
||||||
|
|
||||||
|
|
||||||
|
try:
|
||||||
|
p.wait()
|
||||||
|
lines = p.stdout()
|
||||||
|
except:
|
||||||
|
# Failure is acceptable
|
||||||
|
return
|
||||||
|
|
||||||
|
bssids = set()
|
||||||
|
for line in lines.split('\n'):
|
||||||
|
if ',' not in line:
|
||||||
|
continue
|
||||||
|
bssid, locked = line.split(',')
|
||||||
|
# TODO: Ignore if WPS is locked?
|
||||||
|
bssids.add(bssid.upper())
|
||||||
|
|
||||||
|
for t in targets:
|
||||||
|
t.wps = t.bssid.upper() in bssids
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
test_file = './tests/files/contains_wps_network.cap'
|
||||||
|
|
||||||
|
target_bssid = 'A4:2B:8C:16:6B:3A'
|
||||||
|
from Target import Target
|
||||||
|
fields = [
|
||||||
|
'A4:2B:8C:16:6B:3A', # BSSID
|
||||||
|
'2015-05-27 19:28:44', '2015-05-27 19:28:46', # Dates
|
||||||
|
'11', # Channel
|
||||||
|
'54', # throughput
|
||||||
|
'WPA2', 'CCMP TKIP', 'PSK', # AUTH
|
||||||
|
'-58', '2', '0', '0.0.0.0', '9', # ???
|
||||||
|
'Test Router Please Ignore', # SSID
|
||||||
|
]
|
||||||
|
t = Target(fields)
|
||||||
|
targets = [t]
|
||||||
|
|
||||||
|
# Should update 'wps' field of a target
|
||||||
|
Tshark.check_for_wps_and_update_targets(test_file, targets)
|
||||||
|
|
||||||
|
print 'Target(BSSID={}).wps = {} (Expected: True)'.format(targets[0].bssid, targets[0].wps)
|
||||||
|
assert targets[0].wps == True
|
||||||
|
|
||||||
56
py/Wash.py
56
py/Wash.py
@@ -1,56 +0,0 @@
|
|||||||
#!/usr/bin/python2.7
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
from Process import Process
|
|
||||||
import re
|
|
||||||
|
|
||||||
class Wash(object):
|
|
||||||
''' Wrapper for Wash program. '''
|
|
||||||
BSSID_REGEX = re.compile("([A-F0-9\:]{17})", re.IGNORECASE)
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def check_for_wps_and_update_targets(capfile, targets):
|
|
||||||
'''
|
|
||||||
Given a cap file and list of targets, use Wash to
|
|
||||||
find which BSSIDs in the cap file use WPS.
|
|
||||||
Then update the 'wps' flag for those BSSIDs in the targets.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
capfile - .cap file from airodump containing packets
|
|
||||||
targets - list of Targets from scan, to be updated
|
|
||||||
'''
|
|
||||||
# Wash/Walsh is required to detect WPS
|
|
||||||
wash_name = 'wash'
|
|
||||||
if not Process.exists(wash_name):
|
|
||||||
wash_name = 'walsh'
|
|
||||||
if not Process.exists(wash_name):
|
|
||||||
# Wash isn't found, drop out
|
|
||||||
return
|
|
||||||
|
|
||||||
command = [
|
|
||||||
'wash',
|
|
||||||
'-f', capfile # Path to cap file
|
|
||||||
]
|
|
||||||
p = Process(command)
|
|
||||||
|
|
||||||
p.wait()
|
|
||||||
if p.poll() != 0:
|
|
||||||
return
|
|
||||||
|
|
||||||
bssids = [bssid.upper() for bssid in Wash.BSSID_REGEX.findall(p.stdout())]
|
|
||||||
for t in targets:
|
|
||||||
t.wps = t.bssid.upper() in bssids
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
from Target import Target
|
|
||||||
# Test target within range
|
|
||||||
fields = 'A4:2B:8C:16:6B:3A,2015-05-27 19:28:44,2015-05-27 19:28:46,11,54,WPA2,CCMP TKIP,PSK,-58,2,0,0.0.0.0,9,Test Router Please Ignore,'.split(',')
|
|
||||||
t = Target(fields)
|
|
||||||
targets = [t]
|
|
||||||
Wash.check_for_wps_and_update_targets('./tests/files/handshake_exists.cap', targets)
|
|
||||||
print targets[0].bssid, 'WPS =', targets[0].wps
|
|
||||||
|
|
||||||
BIN
py/tests/files/contains_wps_network.cap
Normal file
BIN
py/tests/files/contains_wps_network.cap
Normal file
Binary file not shown.
Reference in New Issue
Block a user