Remove dependency on Wash; detect WPS via Tshark.

Should resolve #62
This commit is contained in:
derv82
2018-02-27 04:09:46 -05:00
parent a6c0a58013
commit 080e674aa6
11 changed files with 122 additions and 74 deletions

View File

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

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

Binary file not shown.