Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged tested pull requests and added manufacturer/oui functionality #186

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
23,478 changes: 23,478 additions & 0 deletions ieee-oui.txt

Large diffs are not rendered by default.

37 changes: 29 additions & 8 deletions wifite/args.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,10 @@ def _add_global_args(self, glob):
action='store',
dest='channel',
metavar='[channel]',
type=int,
help=Color.s('Wireless channel to scan (default: {G}all 2Ghz channels{W})'))
help=Color.s('Wireless channel to scan e.g. {C}1,3-6{W} ' +
'(default: {G}all 2Ghz channels{W})'))
glob.add_argument('--channel', help=argparse.SUPPRESS, action='store',
dest='channel', type=int)
dest='channel')

glob.add_argument('-5',
'--5ghz',
Expand Down Expand Up @@ -105,6 +105,16 @@ def _add_global_args(self, glob):
glob.add_argument('--bssid', help=argparse.SUPPRESS, action='store',
dest='target_bssid', type=str)

glob.add_argument('-m',
action='store',
dest='target_manufacturer',
metavar='[manufacturer]',
type=str,
help=self._verbose('Manufacturer (e.g. {GR}D-Link{W}) of access ' +
'point to match'))
glob.add_argument('--manufacturer', help=argparse.SUPPRESS, action='store',
dest='target_manufacturer', type=str)

glob.add_argument('-e',
action='store',
dest='target_essid',
Expand All @@ -115,14 +125,15 @@ def _add_global_args(self, glob):
dest='target_essid', type=str)

glob.add_argument('-E',
action='store',
dest='ignore_essid',
action='append',
dest='ignore_essids',
metavar='[text]',
type=str,
default=None,
help=self._verbose('Hides targets with ESSIDs that match the given text'))
glob.add_argument('--ignore-essid', help=argparse.SUPPRESS, action='store',
dest='ignore_essid', type=str)
help=self._verbose('Hides targets with ESSIDs that match the given text. '
'Can be used more than once.'))
glob.add_argument('--ignore-essid', help=argparse.SUPPRESS, action='append',
dest='ignore_essids', type=str)

glob.add_argument('--clients-only',
action='store_true',
Expand All @@ -135,6 +146,11 @@ def _add_global_args(self, glob):
dest='show_bssids',
help=self._verbose('Show BSSIDs of targets while scanning'))

glob.add_argument('--showm',
action='store_true',
dest='show_manufacturers',
help=self._verbose('Show manufacturers of targets while scanning'))

glob.add_argument('--nodeauths',
action='store_true',
dest='no_deauth',
Expand Down Expand Up @@ -433,6 +449,11 @@ def _add_pmkid_args(self, pmkid):
dest='use_pmkid_only',
help=Color.s('{O}Only{W} use {C}PMKID capture{W}, avoids other WPS & ' +
'WPA attacks (default: {G}off{W})'))
pmkid.add_argument('--no-pmkid',
action='store_true',
dest='dont_use_pmkid',
help=Color.s('{O}Don\'t{W} use {C}PMKID capture{W} ' +
'(default: {G}off{W})'))
# Alias
pmkid.add_argument('-pmkid', help=argparse.SUPPRESS, action='store_true', dest='use_pmkid_only')

Expand Down
15 changes: 12 additions & 3 deletions wifite/attack/all.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ def attack_single(cls, target, targets_remaining):
Attacks a single `target` (wifite.model.target).
Returns: True if attacks should continue, False otherwise.
'''
if 'MGT' in target.authentication:
Color.pl("\n{!}{O}Skipping. Target is using {C}WPA-Enterprise {O}and can not be cracked.")
return True

attacks = []

Expand All @@ -64,6 +67,10 @@ def attack_single(cls, target, targets_remaining):
if Configuration.wps_pixie:
attacks.append(AttackWPS(target, pixie_dust=True))

# Null PIN zero-day attack
if Configuration.wps_pin:
attacks.append(AttackWPS(target, pixie_dust=False, null_pin=True))

# PIN attack
if Configuration.wps_pin:
attacks.append(AttackWPS(target, pixie_dust=False))
Expand Down Expand Up @@ -110,7 +117,9 @@ def user_wants_to_continue(cls, targets_remaining, attacks_remaining=0):
'''
Asks user if attacks should continue onto other targets
Returns:
True if user wants to continue, False otherwise.
None if the user wants to skip the current target
True if the user wants to continue to the next attack on the current target
False if the user wants to stop the remaining attacks
'''
if attacks_remaining == 0 and targets_remaining == 0:
return # No targets or attacksleft, drop out
Expand Down Expand Up @@ -138,12 +147,12 @@ def user_wants_to_continue(cls, targets_remaining, attacks_remaining=0):
prompt += ' or {R}exit{W} %s? {C}' % options

from ..util.input import raw_input
answer = raw_input(Color.s(prompt)).lower()
Color.p(prompt)
answer = raw_input().lower()

if answer.startswith('s'):
return None # Skip
elif answer.startswith('e'):
return False # Exit
else:
return True # Continue

23 changes: 16 additions & 7 deletions wifite/attack/pmkid.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,15 @@ def run(self):
Returns:
True if handshake is captured. False otherwise.
'''

# Skip if user doesn't want to run PMKID attack
if Configuration.dont_use_pmkid:
self.success = False
return False

from ..util.process import Process
# Check that we have all hashcat programs
dependencies = [
Hashcat.dependency_name,
HcxDumpTool.dependency_name,
HcxPcapTool.dependency_name
]
Expand All @@ -91,12 +96,17 @@ def run(self):
return False # No hash found.

# Crack it.
try:
self.success = self.crack_pmkid_file(pmkid_file)
except KeyboardInterrupt:
Color.pl('\n{!} {R}Failed to crack PMKID: {O}Cracking interrupted by user{W}')
if Process.exists(Hashcat.dependency_name):
try:
self.success = self.crack_pmkid_file(pmkid_file)
except KeyboardInterrupt:
Color.pl('\n{!} {R}Failed to crack PMKID: {O}Cracking interrupted by user{W}')
self.success = False
return True
else:
self.success = False
return False
Color.pl('\n {O}[{R}!{O}] Note: PMKID attacks are not possible because you do not have {C}%s{O}.{W}'
% Hashcat.dependency_name)

return True # Even if we don't crack it, capturing a PMKID is 'successful'

Expand Down Expand Up @@ -210,4 +220,3 @@ def save_pmkid(self, pmkid_hash):
pmkid_handle.write('\n')

return pmkid_file

3 changes: 2 additions & 1 deletion wifite/attack/wep.py
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,8 @@ def user_wants_to_stop(self, current_attack, attacks_remaining, target):
attack_index += 1
Color.pl(' {G}%d{W}: {R}Stop attacking, {O}Move onto next target{W}' % attack_index)
while True:
answer = raw_input(Color.s('{?} Select an option ({G}1-%d{W}): ' % attack_index))
Color.p('{?} Select an option ({G}1-%d{W}): ' % attack_index)
answer = raw_input()
if not answer.isdigit() or int(answer) < 1 or int(answer) > attack_index:
Color.pl('{!} {R}Invalid input: {O}Must enter a number between {G}1-%d{W}' % attack_index)
continue
Expand Down
13 changes: 7 additions & 6 deletions wifite/attack/wps.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,12 @@ class AttackWPS(Attack):
def can_attack_wps():
return Reaver.exists() or Bully.exists()

def __init__(self, target, pixie_dust=False):
def __init__(self, target, pixie_dust=False, null_pin=False):
super(AttackWPS, self).__init__(target)
self.success = False
self.crack_result = None
self.pixie_dust = pixie_dust
self.null_pin = null_pin

def run(self):
''' Run all WPS-related attacks '''
Expand All @@ -33,14 +34,14 @@ def run(self):
return False

if not Configuration.wps_pixie and self.pixie_dust:
Color.pl('\r{!} {O}--no-pixie{R} was given, ignoring WPS PIN Attack on ' +
'{O}%s{W}' % self.target.essid)
Color.pl('\r{!} {O}--no-pixie{R} was given, ignoring WPS Pixie-Dust Attack ' +
'on {O}%s{W}' % self.target.essid)
self.success = False
return False

if not Configuration.wps_pin and not self.pixie_dust:
Color.pl('\r{!} {O}--no-pin{R} was given, ignoring WPS Pixie-Dust Attack ' +
'on {O}%s{W}' % self.target.essid)
Color.pl('\r{!} {O}--pixie{R} was given, ignoring WPS PIN Attack on ' +
'{O}%s{W}' % self.target.essid)
self.success = False
return False

Expand Down Expand Up @@ -78,7 +79,7 @@ def run_bully(self):


def run_reaver(self):
reaver = Reaver(self.target, pixie_dust=self.pixie_dust)
reaver = Reaver(self.target, pixie_dust=self.pixie_dust, null_pin=self.null_pin)
reaver.run()
self.crack_result = reaver.crack_result
self.success = self.crack_result is not None
Expand Down
44 changes: 39 additions & 5 deletions wifite/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
# -*- coding: utf-8 -*-

import os
import re

from .util.color import Color
from .tools.macchanger import Macchanger
Expand Down Expand Up @@ -41,10 +42,12 @@ def initialize(cls, load_interface=True):
cls.target_channel = None # User-defined channel to scan
cls.target_essid = None # User-defined AP name
cls.target_bssid = None # User-defined AP BSSID
cls.ignore_essid = None # ESSIDs to ignore
cls.ignore_essids = None # ESSIDs to ignore
cls.clients_only = False # Only show targets that have associated clients
cls.five_ghz = False # Scan 5Ghz channels
cls.show_bssids = False # Show BSSIDs in targets list
cls.show_manufacturers = False # Show manufacturers in targets list
cls.target_manufacturer = False # User-defined AP manufacturer
cls.random_mac = False # Should generate a random Mac address at startup.
cls.no_deauth = False # Deauth hidden networks & WPA handshake targets
cls.num_deauths = 1 # Number of deauth packets to send to each target.
Expand Down Expand Up @@ -82,6 +85,7 @@ def initialize(cls, load_interface=True):
# PMKID variables
cls.use_pmkid_only = False # Only use PMKID Capture+Crack attack
cls.pmkid_timeout = 30 # Time to wait for PMKID capture
cls.dont_use_pmkid = False # Don't use PMKID attack

# Default dictionary for cracking
cls.cracked_file = 'cracked.txt'
Expand All @@ -100,6 +104,16 @@ def initialize(cls, load_interface=True):
cls.wordlist = wlist
break

manufacturers = './ieee-oui.txt'

if os.path.exists(manufacturers):
with open(manufacturers, "r") as f:
# Parse txt format into dict
lines = f.read().splitlines()
k = lambda line: line.split()[0]
v = lambda line: ' '.join(line.split()[1:3]).rstrip('.')
cls.manufacturers = {k(line):v(line) for line in lines}

# WPS variables
cls.wps_filter = False # Only attack WPS networks
cls.no_wps = False # Do not use WPS attacks (Pixie-Dust & PIN attacks)
Expand Down Expand Up @@ -168,6 +182,9 @@ def validate(cls):
if cls.use_pmkid_only and cls.wps_only:
Color.pl('{!} {R}Bad Configuration:{O} --pmkid and --wps-only are not compatible')
raise RuntimeError('Unable to attack networks: --pmkid and --wps-only are not compatible together')
if cls.use_pmkid_only and cls.dont_use_pmkid:
Color.pl('{!} {R}Bad Configuration:{O} --pmkid and --no-pmkid are not compatible')
raise RuntimeError('Unable to attack networks: --pmkid and --no-pmkid are not compatible together')


@classmethod
Expand All @@ -179,6 +196,10 @@ def parse_settings_args(cls, args):
'when scanning & attacking')

if args.channel:
chn_arg_re = re.compile("^[0-9]+((,[0-9]+)|(-[0-9]+,[0-9]+))*(-[0-9]+)?$")
if not chn_arg_re.match(args.channel):
raise ValueError("Invalid channel! The format must be 1,3-6,9")

cls.target_channel = args.channel
Color.pl('{+} {C}option:{W} scanning for targets on channel ' +
'{G}%s{W}' % args.channel)
Expand All @@ -193,6 +214,11 @@ def parse_settings_args(cls, args):
Color.pl('{+} {C}option:{W} targeting BSSID ' +
'{G}%s{W}' % args.target_bssid)

if args.target_manufacturer:
cls.target_manufacturer = args.target_manufacturer
Color.pl('{+} {C}option:{W} targeting manufacturer ' +
'{G}%s{W}' % args.target_manufacturer)

if args.five_ghz == True:
cls.five_ghz = True
Color.pl('{+} {C}option:{W} including {G}5Ghz networks{W} in scans')
Expand All @@ -201,6 +227,10 @@ def parse_settings_args(cls, args):
cls.show_bssids = True
Color.pl('{+} {C}option:{W} showing {G}bssids{W} of targets during scan')

if args.show_manufacturers == True:
cls.show_manufacturers = True
Color.pl('{+} {C}option:{W} showing {G}manufacturers{W} of targets during scan')

if args.no_deauth == True:
cls.no_deauth = True
Color.pl('{+} {C}option:{W} will {R}not{W} {O}deauth{W} clients ' +
Expand All @@ -215,10 +245,10 @@ def parse_settings_args(cls, args):
cls.target_essid = args.target_essid
Color.pl('{+} {C}option:{W} targeting ESSID {G}%s{W}' % args.target_essid)

if args.ignore_essid is not None:
cls.ignore_essid = args.ignore_essid
Color.pl('{+} {C}option:{W} {O}ignoring ESSIDs that include {R}%s{W}' % (
args.ignore_essid))
if args.ignore_essids is not None:
cls.ignore_essids = args.ignore_essids
Color.pl('{+} {C}option: {O}ignoring ESSID(s): {R}%s{W}' %
', '.join(args.ignore_essids))

if args.clients_only == True:
cls.clients_only = True
Expand Down Expand Up @@ -393,6 +423,10 @@ def parse_pmkid_args(cls, args):
cls.pmkid_timeout = args.pmkid_timeout
Color.pl('{+} {C}option:{W} will wait {G}%d seconds{W} during {C}PMKID{W} capture' % args.pmkid_timeout)

if args.dont_use_pmkid:
cls.dont_use_pmkid = True
Color.pl('{+} {C}option:{W} will NOT use {C}PMKID{W} attack on WPA networks')

@classmethod
def parse_encryption(cls):
'''Adjusts encryption filter (WEP and/or WPA and/or WPS)'''
Expand Down
Loading