Add eviltwin args. Add "Dependency" subclass

This commit is contained in:
derv82
2018-04-21 04:25:46 -04:00
parent 28b2d8312c
commit 1083db6f88
8 changed files with 245 additions and 167 deletions

View File

@@ -37,6 +37,9 @@ class Arguments(object):
wps_group = parser.add_argument_group('WPS') wps_group = parser.add_argument_group('WPS')
self._add_wps_args(wps_group) self._add_wps_args(wps_group)
eviltwin_group = parser.add_argument_group('EVIL TWIN')
self._add_eviltwin_args(eviltwin_group)
commands_group = parser.add_argument_group('COMMANDS') commands_group = parser.add_argument_group('COMMANDS')
self._add_command_args(commands_group) self._add_command_args(commands_group)
@@ -144,6 +147,15 @@ class Arguments(object):
help=self._verbose('Number of deauth packets to send (default: {G}%d{W})' % self.config.num_deauths)) help=self._verbose('Number of deauth packets to send (default: {G}%d{W})' % self.config.num_deauths))
def _add_eviltwin_args(self, group):
group.add_argument('-ev',
'--eviltwin',
action='store_true',
dest='use_eviltwin',
help=Color.s('Use the "Evil Twin" attack against all targets (default: {G}off{W})'))
# TODO: Args to specify deauth interface, server port, etc.
def _add_wep_args(self, wep): def _add_wep_args(self, wep):
# WEP # WEP
wep.add_argument('--wep', wep.add_argument('--wep',

View File

@@ -15,65 +15,73 @@ class Configuration(object):
interface = None interface = None
verbose = 0 verbose = 0
@staticmethod @classmethod
def initialize(load_interface=True): def initialize(cls, load_interface=True):
''' '''
Sets up default initial configuration values. Sets up default initial configuration values.
Also sets config values based on command-line arguments. Also sets config values based on command-line arguments.
''' '''
# TODO: categorize configuration into separate classes (under config/*.py)
# E.g. Configuration.wps.enabled, Configuration.wps.timeout, etc
# Only initialize this class once # Only initialize this class once
if Configuration.initialized: if cls.initialized:
return return
Configuration.initialized = True cls.initialized = True
Configuration.verbose = 0 # Verbosity level. cls.verbose = 0 # Verbosity of output. Higher number means more debug info about running processes.
Configuration.print_stack_traces = True cls.print_stack_traces = True
Configuration.kill_conflicting_processes = False cls.kill_conflicting_processes = False
Configuration.scan_time = 0 # Time to wait before attacking all targets cls.scan_time = 0 # Time to wait before attacking all targets
Configuration.all_targets = False # Run attacks against all targets automatically cls.all_targets = False # Run attacks against all targets automatically
Configuration.tx_power = 0 # Wifi transmit power (0 is default) cls.tx_power = 0 # Wifi transmit power (0 is default)
Configuration.interface = None cls.interface = None
Configuration.target_channel = None # User-defined channel to scan cls.target_channel = None # User-defined channel to scan
Configuration.target_essid = None # User-defined AP name cls.target_essid = None # User-defined AP name
Configuration.target_bssid = None # User-defined AP BSSID cls.target_bssid = None # User-defined AP BSSID
Configuration.ignore_essid = None # ESSIDs to ignore cls.ignore_essid = None # ESSIDs to ignore
Configuration.clients_only = False # Only show targets that have associated clients cls.clients_only = False # Only show targets that have associated clients
Configuration.five_ghz = False # Scan 5Ghz channels cls.five_ghz = False # Scan 5Ghz channels
Configuration.show_bssids = False # Show BSSIDs in targets list cls.show_bssids = False # Show BSSIDs in targets list
Configuration.random_mac = False # Should generate a random Mac address at startup. cls.random_mac = False # Should generate a random Mac address at startup.
Configuration.no_deauth = False # Deauth hidden networks & WPA handshake targets cls.no_deauth = False # Deauth hidden networks & WPA handshake targets
Configuration.num_deauths = 1 # Number of deauth packets to send to each target. cls.num_deauths = 1 # Number of deauth packets to send to each target.
Configuration.encryption_filter = ['WEP', 'WPA', 'WPS'] cls.encryption_filter = ['WEP', 'WPA', 'WPS']
# EvilTwin variables
cls.use_eviltwin = False
cls.eviltwin_port = 80
cls.eviltwin_deauth_iface = None
cls.eviltwin_fakeap_iface = None
# WEP variables # WEP variables
Configuration.wep_filter = False # Only attack WEP networks cls.wep_filter = False # Only attack WEP networks
Configuration.wep_pps = 600 # Packets per second cls.wep_pps = 600 # Packets per second
Configuration.wep_timeout = 600 # Seconds to wait before failing cls.wep_timeout = 600 # Seconds to wait before failing
Configuration.wep_crack_at_ivs = 10000 # Minimum IVs to start cracking cls.wep_crack_at_ivs = 10000 # Minimum IVs to start cracking
Configuration.require_fakeauth = False cls.require_fakeauth = False
Configuration.wep_restart_stale_ivs = 11 # Seconds to wait before restarting cls.wep_restart_stale_ivs = 11 # Seconds to wait before restarting
# Aireplay if IVs don't increaes. # Aireplay if IVs don't increaes.
# "0" means never restart. # "0" means never restart.
Configuration.wep_restart_aircrack = 30 # Seconds to give aircrack to crack cls.wep_restart_aircrack = 30 # Seconds to give aircrack to crack
# before restarting the process. # before restarting the process.
Configuration.wep_crack_at_ivs = 10000 # Number of IVS to start cracking cls.wep_crack_at_ivs = 10000 # Number of IVS to start cracking
Configuration.wep_keep_ivs = False # Retain .ivs files across multiple attacks. cls.wep_keep_ivs = False # Retain .ivs files across multiple attacks.
# WPA variables # WPA variables
Configuration.wpa_filter = False # Only attack WPA networks cls.wpa_filter = False # Only attack WPA networks
Configuration.wpa_deauth_timeout = 15 # Wait time between deauths cls.wpa_deauth_timeout = 15 # Wait time between deauths
Configuration.wpa_attack_timeout = 500 # Wait time before failing cls.wpa_attack_timeout = 500 # Wait time before failing
Configuration.wpa_handshake_dir = "hs" # Dir to store handshakes cls.wpa_handshake_dir = "hs" # Dir to store handshakes
Configuration.wpa_strip_handshake = False # Strip non-handshake packets cls.wpa_strip_handshake = False # Strip non-handshake packets
Configuration.ignore_old_handshakes = False # Always fetch a new handshake cls.ignore_old_handshakes = False # Always fetch a new handshake
# Default dictionary for cracking # Default dictionary for cracking
Configuration.wordlist = None cls.wordlist = None
wordlists = [ wordlists = [
'/usr/share/wfuzz/wordlist/fuzzdb/wordlists-user-passwd/passwds/phpbb.txt', '/usr/share/wfuzz/wordlist/fuzzdb/wordlists-user-passwd/passwds/phpbb.txt',
'/usr/share/fuzzdb/wordlists-user-passwd/passwds/phpbb.txt', '/usr/share/fuzzdb/wordlists-user-passwd/passwds/phpbb.txt',
@@ -81,219 +89,224 @@ class Configuration(object):
] ]
for wlist in wordlists: for wlist in wordlists:
if os.path.exists(wlist): if os.path.exists(wlist):
Configuration.wordlist = wlist cls.wordlist = wlist
break break
# WPS variables # WPS variables
Configuration.wps_filter = False # Only attack WPS networks cls.wps_filter = False # Only attack WPS networks
Configuration.no_wps = False # Do not use WPS attacks (Pixie-Dust & PIN attacks) cls.no_wps = False # Do not use WPS attacks (Pixie-Dust & PIN attacks)
Configuration.wps_only = False # ONLY use WPS attacks on non-WEP networks cls.wps_only = False # ONLY use WPS attacks on non-WEP networks
Configuration.use_bully = False # Use bully instead of reaver cls.use_bully = False # Use bully instead of reaver
Configuration.wps_pixie_timeout = 300 # Seconds to wait for PIN before WPS Pixie attack fails cls.wps_pixie_timeout = 300 # Seconds to wait for PIN before WPS Pixie attack fails
Configuration.wps_fail_threshold = 100 # Max number of failures cls.wps_fail_threshold = 100 # Max number of failures
Configuration.wps_timeout_threshold = 100 # Max number of timeouts cls.wps_timeout_threshold = 100 # Max number of timeouts
# Commands # Commands
Configuration.show_cracked = False cls.show_cracked = False
Configuration.check_handshake = None cls.check_handshake = None
Configuration.crack_handshake = False cls.crack_handshake = False
# Overwrite config values with arguments (if defined) # Overwrite config values with arguments (if defined)
Configuration.load_from_arguments() cls.load_from_arguments()
if load_interface: if load_interface:
Configuration.get_monitor_mode_interface() cls.get_monitor_mode_interface()
@staticmethod @classmethod
def get_monitor_mode_interface(): def get_monitor_mode_interface(cls):
if Configuration.interface is None: if cls.interface is None:
# Interface wasn't defined, select it! # Interface wasn't defined, select it!
from .tools.airmon import Airmon from .tools.airmon import Airmon
Configuration.interface = Airmon.ask() cls.interface = Airmon.ask()
if Configuration.random_mac: if cls.random_mac:
Macchanger.random() Macchanger.random()
@staticmethod @staticmethod
def get_wireless_interface(): def get_wireless_interface():
pass pass
@staticmethod @classmethod
def load_from_arguments(): def load_from_arguments(cls):
''' Sets configuration values based on Argument.args object ''' ''' Sets configuration values based on Argument.args object '''
from .args import Arguments from .args import Arguments
args = Arguments(Configuration).args args = Arguments(cls).args
if args.random_mac: if args.random_mac:
Configuration.random_mac = True cls.random_mac = True
Color.pl('{+} {C}option:{W} using {G}random mac address{W} when scanning & attacking') Color.pl('{+} {C}option:{W} using {G}random mac address{W} when scanning & attacking')
if args.channel: if args.channel:
Configuration.target_channel = args.channel cls.target_channel = args.channel
Color.pl('{+} {C}option:{W} scanning for targets on channel {G}%s{W}' % args.channel) Color.pl('{+} {C}option:{W} scanning for targets on channel {G}%s{W}' % args.channel)
if args.interface: if args.interface:
Configuration.interface = args.interface cls.interface = args.interface
Color.pl('{+} {C}option:{W} using wireless interface {G}%s{W}' % args.interface) Color.pl('{+} {C}option:{W} using wireless interface {G}%s{W}' % args.interface)
if args.target_bssid: if args.target_bssid:
Configuration.target_bssid = args.target_bssid cls.target_bssid = args.target_bssid
Color.pl('{+} {C}option:{W} targeting BSSID {G}%s{W}' % args.target_bssid) Color.pl('{+} {C}option:{W} targeting BSSID {G}%s{W}' % args.target_bssid)
if args.five_ghz == True: if args.five_ghz == True:
Configuration.five_ghz = True cls.five_ghz = True
Color.pl('{+} {C}option:{W} including {G}5Ghz networks{W} in scans') Color.pl('{+} {C}option:{W} including {G}5Ghz networks{W} in scans')
if args.show_bssids == True: if args.show_bssids == True:
Configuration.show_bssids = True cls.show_bssids = True
Color.pl('{+} {C}option:{W} showing {G}bssids{W} of targets during scan') Color.pl('{+} {C}option:{W} showing {G}bssids{W} of targets during scan')
if args.no_deauth == True: if args.no_deauth == True:
Configuration.no_deauth = True cls.no_deauth = True
Color.pl('{+} {C}option:{W} will {R}not{W} {O}deauth{W} clients during scans or captures') Color.pl('{+} {C}option:{W} will {R}not{W} {O}deauth{W} clients during scans or captures')
if args.num_deauths and args.num_deauths > 0: if args.num_deauths and args.num_deauths > 0:
Configuration.num_deauths = args.num_deauths cls.num_deauths = args.num_deauths
Color.pl('{+} {C}option:{W} will send {G}%d{W} deauth packets when deauthing' % Configuration.num_deauths) Color.pl('{+} {C}option:{W} will send {G}%d{W} deauth packets when deauthing' % cls.num_deauths)
if args.target_essid: if args.target_essid:
Configuration.target_essid = args.target_essid cls.target_essid = args.target_essid
Color.pl('{+} {C}option:{W} targeting ESSID {G}%s{W}' % args.target_essid) Color.pl('{+} {C}option:{W} targeting ESSID {G}%s{W}' % args.target_essid)
if args.ignore_essid is not None: if args.ignore_essid is not None:
Configuration.ignore_essid = args.ignore_essid cls.ignore_essid = args.ignore_essid
Color.pl('{+} {C}option:{W} {O}ignoring ESSIDs that include {R}%s{W}' % args.ignore_essid) Color.pl('{+} {C}option:{W} {O}ignoring ESSIDs that include {R}%s{W}' % args.ignore_essid)
if args.clients_only == True: if args.clients_only == True:
Configuration.clients_only = True cls.clients_only = True
Color.pl('{+} {C}option:{W} {O}ignoring targets that do not have associated clients') Color.pl('{+} {C}option:{W} {O}ignoring targets that do not have associated clients')
if args.scan_time: if args.scan_time:
Configuration.scan_time = args.scan_time cls.scan_time = args.scan_time
Color.pl('{+} {C}option:{W} ({G}pillage{W}) attack all targets after {G}%d{W}s' % args.scan_time) Color.pl('{+} {C}option:{W} ({G}pillage{W}) attack all targets after {G}%d{W}s' % args.scan_time)
if args.verbose: if args.verbose:
Configuration.verbose = args.verbose cls.verbose = args.verbose
Color.pl('{+} {C}option:{W} verbosity level {G}%d{W}' % args.verbose) Color.pl('{+} {C}option:{W} verbosity level {G}%d{W}' % args.verbose)
if args.kill_conflicting_processes: if args.kill_conflicting_processes:
Configuration.kill_conflicting_processes = True cls.kill_conflicting_processes = True
Color.pl('{+} {C}option:{W} kill conflicting processes {G}enabled{W}') Color.pl('{+} {C}option:{W} kill conflicting processes {G}enabled{W}')
# EvilTwin
if args.use_eviltwin:
cls.use_eviltwin = True
Color.pl('{+} {C}option:{W} using {G}eviltwin attacks{W} against all targets')
# WEP # WEP
if args.wep_filter: if args.wep_filter:
Configuration.wep_filter = args.wep_filter cls.wep_filter = args.wep_filter
if args.wep_pps: if args.wep_pps:
Configuration.wep_pps = args.wep_pps cls.wep_pps = args.wep_pps
Color.pl('{+} {C}option:{W} using {G}%d{W} packets-per-second on WEP attacks' % args.wep_pps) Color.pl('{+} {C}option:{W} using {G}%d{W} packets-per-second on WEP attacks' % args.wep_pps)
if args.wep_timeout: if args.wep_timeout:
Configuration.wep_timeout = args.wep_timeout cls.wep_timeout = args.wep_timeout
Color.pl('{+} {C}option:{W} WEP attack timeout set to {G}%d seconds{W}' % args.wep_timeout) Color.pl('{+} {C}option:{W} WEP attack timeout set to {G}%d seconds{W}' % args.wep_timeout)
if args.require_fakeauth: if args.require_fakeauth:
Configuration.require_fakeauth = True cls.require_fakeauth = True
Color.pl('{+} {C}option:{W} fake-authentication is {G}required{W} for WEP attacks') Color.pl('{+} {C}option:{W} fake-authentication is {G}required{W} for WEP attacks')
if args.wep_crack_at_ivs: if args.wep_crack_at_ivs:
Configuration.wep_crack_at_ivs = args.wep_crack_at_ivs cls.wep_crack_at_ivs = args.wep_crack_at_ivs
Color.pl('{+} {C}option:{W} will start cracking WEP keys at {G}%d IVs{W}' % args.wep_crack_at_ivs) Color.pl('{+} {C}option:{W} will start cracking WEP keys at {G}%d IVs{W}' % args.wep_crack_at_ivs)
if args.wep_restart_stale_ivs: if args.wep_restart_stale_ivs:
Configuration.wep_restart_stale_ivs = args.wep_restart_stale_ivs cls.wep_restart_stale_ivs = args.wep_restart_stale_ivs
Color.pl('{+} {C}option:{W} will restart aireplay after {G}%d seconds{W} of no new IVs' % args.wep_restart_stale_ivs) Color.pl('{+} {C}option:{W} will restart aireplay after {G}%d seconds{W} of no new IVs' % args.wep_restart_stale_ivs)
if args.wep_restart_aircrack: if args.wep_restart_aircrack:
Configuration.wep_restart_aircrack = args.wep_restart_aircrack cls.wep_restart_aircrack = args.wep_restart_aircrack
Color.pl('{+} {C}option:{W} will restart aircrack every {G}%d seconds{W}' % args.wep_restart_aircrack) Color.pl('{+} {C}option:{W} will restart aircrack every {G}%d seconds{W}' % args.wep_restart_aircrack)
if args.wep_keep_ivs: if args.wep_keep_ivs:
Configuration.wep_keep_ivs = args.wep_keep_ivs cls.wep_keep_ivs = args.wep_keep_ivs
Color.pl('{+} {C}option:{W} keep .ivs files across multiple WEP attacks') Color.pl('{+} {C}option:{W} keep .ivs files across multiple WEP attacks')
# WPA # WPA
if args.wpa_filter: if args.wpa_filter:
Configuration.wpa_filter = args.wpa_filter cls.wpa_filter = args.wpa_filter
if args.wordlist: if args.wordlist:
if os.path.exists(args.wordlist): if os.path.exists(args.wordlist):
Configuration.wordlist = args.wordlist cls.wordlist = args.wordlist
Color.pl('{+} {C}option:{W} using wordlist {G}%s{W} to crack WPA handshakes' % args.wordlist) Color.pl('{+} {C}option:{W} using wordlist {G}%s{W} to crack WPA handshakes' % args.wordlist)
else: else:
Configuration.wordlist = None cls.wordlist = None
Color.pl('{+} {C}option:{O} wordlist {R}%s{O} was not found, wifite will NOT attempt to crack handshakes' % args.wordlist) Color.pl('{+} {C}option:{O} wordlist {R}%s{O} was not found, wifite will NOT attempt to crack handshakes' % args.wordlist)
if args.wpa_deauth_timeout: if args.wpa_deauth_timeout:
Configuration.wpa_deauth_timeout = args.wpa_deauth_timeout cls.wpa_deauth_timeout = args.wpa_deauth_timeout
Color.pl('{+} {C}option:{W} will deauth WPA clients every {G}%d seconds{W}' % args.wpa_deauth_timeout) Color.pl('{+} {C}option:{W} will deauth WPA clients every {G}%d seconds{W}' % args.wpa_deauth_timeout)
if args.wpa_attack_timeout: if args.wpa_attack_timeout:
Configuration.wpa_attack_timeout = args.wpa_attack_timeout cls.wpa_attack_timeout = args.wpa_attack_timeout
Color.pl('{+} {C}option:{W} will stop WPA handshake capture after {G}%d seconds{W}' % args.wpa_attack_timeout) Color.pl('{+} {C}option:{W} will stop WPA handshake capture after {G}%d seconds{W}' % args.wpa_attack_timeout)
if args.ignore_old_handshakes: if args.ignore_old_handshakes:
Configuration.ignore_old_handshakes = True cls.ignore_old_handshakes = True
Color.pl("{+} {C}option:{W} will {O}ignore{W} existing handshakes (force capture)") Color.pl("{+} {C}option:{W} will {O}ignore{W} existing handshakes (force capture)")
if args.wpa_handshake_dir: if args.wpa_handshake_dir:
Configuration.wpa_handshake_dir = args.wpa_handshake_dir cls.wpa_handshake_dir = args.wpa_handshake_dir
Color.pl('{+} {C}option:{W} will store handshakes to {G}%s{W}' % args.wpa_handshake_dir) Color.pl('{+} {C}option:{W} will store handshakes to {G}%s{W}' % args.wpa_handshake_dir)
if args.wpa_strip_handshake: if args.wpa_strip_handshake:
Configuration.wpa_strip_handshake = True cls.wpa_strip_handshake = True
Color.pl("{+} {C}option:{W} will {G}strip{W} non-handshake packets") Color.pl("{+} {C}option:{W} will {G}strip{W} non-handshake packets")
# WPS # WPS
if args.wps_filter: if args.wps_filter:
Configuration.wps_filter = args.wps_filter cls.wps_filter = args.wps_filter
if args.wps_only: if args.wps_only:
Configuration.wps_only = True cls.wps_only = True
Color.pl('{+} {C}option:{W} will *only* attack non-WEP networks with {G}WPS attacks{W} (no handshake capture)') Color.pl('{+} {C}option:{W} will *only* attack non-WEP networks with {G}WPS attacks{W} (no handshake capture)')
if args.no_wps: if args.no_wps:
Configuration.no_wps = args.no_wps cls.no_wps = args.no_wps
Color.pl('{+} {C}option:{W} will {O}never{W} use {C}WPS attacks{W} (Pixie-Dust/PIN) on targets') Color.pl('{+} {C}option:{W} will {O}never{W} use {C}WPS attacks{W} (Pixie-Dust/PIN) on targets')
if args.use_bully: if args.use_bully:
Configuration.use_bully = args.use_bully cls.use_bully = args.use_bully
Color.pl('{+} {C}option:{W} use {C}bully{W} instead of {C}reaver{W} for WPS Attacks') Color.pl('{+} {C}option:{W} use {C}bully{W} instead of {C}reaver{W} for WPS Attacks')
if args.wps_pixie_timeout: if args.wps_pixie_timeout:
Configuration.wps_pixie_timeout = args.wps_pixie_timeout cls.wps_pixie_timeout = args.wps_pixie_timeout
Color.pl('{+} {C}option:{W} WPS pixie-dust attack will fail after {O}%d seconds{W}' % args.wps_pixie_timeout) Color.pl('{+} {C}option:{W} WPS pixie-dust attack will fail after {O}%d seconds{W}' % args.wps_pixie_timeout)
if args.wps_fail_threshold: if args.wps_fail_threshold:
Configuration.wps_fail_threshold = args.wps_fail_threshold cls.wps_fail_threshold = args.wps_fail_threshold
Color.pl('{+} {C}option:{W} will stop WPS attack after {O}%d failures{W}' % args.wps_fail_threshold) Color.pl('{+} {C}option:{W} will stop WPS attack after {O}%d failures{W}' % args.wps_fail_threshold)
if args.wps_timeout_threshold: if args.wps_timeout_threshold:
Configuration.wps_timeout_threshold = args.wps_timeout_threshold cls.wps_timeout_threshold = args.wps_timeout_threshold
Color.pl('{+} {C}option:{W} will stop WPS attack after {O}%d timeouts{W}' % args.wps_timeout_threshold) Color.pl('{+} {C}option:{W} will stop WPS attack after {O}%d timeouts{W}' % args.wps_timeout_threshold)
# Adjust encryption filter # Adjust encryption filter
Configuration.encryption_filter = [] cls.encryption_filter = []
if Configuration.wep_filter: Configuration.encryption_filter.append('WEP') if cls.wep_filter: cls.encryption_filter.append('WEP')
if Configuration.wpa_filter: Configuration.encryption_filter.append('WPA') if cls.wpa_filter: cls.encryption_filter.append('WPA')
if Configuration.wps_filter: Configuration.encryption_filter.append('WPS') if cls.wps_filter: cls.encryption_filter.append('WPS')
if len(Configuration.encryption_filter) == 3: if len(cls.encryption_filter) == 3:
Color.pl('{+} {C}option:{W} targeting {G}all encrypted networks{W}') Color.pl('{+} {C}option:{W} targeting {G}all encrypted networks{W}')
elif len(Configuration.encryption_filter) == 0: elif len(cls.encryption_filter) == 0:
# Default to scan all types # Default to scan all types
Configuration.encryption_filter = ['WEP', 'WPA', 'WPS'] cls.encryption_filter = ['WEP', 'WPA', 'WPS']
else: else:
Color.pl('{+} {C}option:{W} ' + Color.pl('{+} {C}option:{W} ' +
'targeting {G}%s-encrypted{W} networks' 'targeting {G}%s-encrypted{W} networks'
% '/'.join(Configuration.encryption_filter)) % '/'.join(cls.encryption_filter))
# Adjust WEP attack list # Adjust WEP attack list
Configuration.wep_attacks = [] cls.wep_attacks = []
import sys import sys
seen = set() seen = set()
for arg in sys.argv: for arg in sys.argv:
if arg in seen: continue if arg in seen: continue
seen.add(arg) seen.add(arg)
if arg == '-arpreplay': Configuration.wep_attacks.append('replay') if arg == '-arpreplay': cls.wep_attacks.append('replay')
if arg == '-fragment': Configuration.wep_attacks.append('fragment') if arg == '-fragment': cls.wep_attacks.append('fragment')
if arg == '-chopchop': Configuration.wep_attacks.append('chopchop') if arg == '-chopchop': cls.wep_attacks.append('chopchop')
if arg == '-caffelatte': Configuration.wep_attacks.append('caffelatte') if arg == '-caffelatte': cls.wep_attacks.append('caffelatte')
if arg == '-p0841': Configuration.wep_attacks.append('p0841') if arg == '-p0841': cls.wep_attacks.append('p0841')
if arg == '-hirte': Configuration.wep_attacks.append('hirte') if arg == '-hirte': cls.wep_attacks.append('hirte')
if len(Configuration.wep_attacks) == 0: if len(cls.wep_attacks) == 0:
# Use all attacks # Use all attacks
Configuration.wep_attacks = ['replay', cls.wep_attacks = ['replay',
'fragment', 'fragment',
'chopchop', 'chopchop',
'caffelatte', 'caffelatte',
'p0841', 'p0841',
'hirte'] 'hirte']
elif len(Configuration.wep_attacks) > 0: elif len(cls.wep_attacks) > 0:
Color.pl('{+} {C}option:{W} using {G}%s{W} WEP attacks' Color.pl('{+} {C}option:{W} using {G}%s{W} WEP attacks'
% '{W}, {G}'.join(Configuration.wep_attacks)) % '{W}, {G}'.join(cls.wep_attacks))
# Commands # Commands
if args.cracked: Configuration.show_cracked = True if args.cracked: cls.show_cracked = True
if args.check_handshake: Configuration.check_handshake = args.check_handshake if args.check_handshake: cls.check_handshake = args.check_handshake
if args.crack_handshake: Configuration.crack_handshake = True if args.crack_handshake: cls.crack_handshake = True
@staticmethod @classmethod
def temp(subfile=''): def temp(cls, subfile=''):
''' Creates and/or returns the temporary directory ''' ''' Creates and/or returns the temporary directory '''
if Configuration.temp_dir is None: if cls.temp_dir is None:
Configuration.temp_dir = Configuration.create_temp() cls.temp_dir = cls.create_temp()
return Configuration.temp_dir + subfile return cls.temp_dir + subfile
@staticmethod @staticmethod
def create_temp(): def create_temp():
@@ -304,28 +317,28 @@ class Configuration(object):
tmp += os.sep tmp += os.sep
return tmp return tmp
@staticmethod @classmethod
def delete_temp(): def delete_temp(cls):
''' Remove temp files and folder ''' ''' Remove temp files and folder '''
if Configuration.temp_dir is None: return if cls.temp_dir is None: return
if os.path.exists(Configuration.temp_dir): if os.path.exists(cls.temp_dir):
for f in os.listdir(Configuration.temp_dir): for f in os.listdir(cls.temp_dir):
os.remove(Configuration.temp_dir + f) os.remove(cls.temp_dir + f)
os.rmdir(Configuration.temp_dir) os.rmdir(cls.temp_dir)
@staticmethod @classmethod
def exit_gracefully(code=0): def exit_gracefully(cls, code=0):
''' Deletes temp and exist with the given code ''' ''' Deletes temp and exist with the given code '''
Configuration.delete_temp() cls.delete_temp()
Macchanger.reset_if_changed() Macchanger.reset_if_changed()
from .tools.airmon import Airmon from .tools.airmon import Airmon
if Configuration.interface is not None and Airmon.base_interface is not None: if cls.interface is not None and Airmon.base_interface is not None:
Color.pl('{!} Leaving interface {C}%s{W} in Monitor Mode.' % Configuration.interface) Color.pl('{!} Leaving interface {C}%s{W} in Monitor Mode.' % cls.interface)
Color.pl('{!} You can disable Monitor Mode when finished ({C}airmon-ng stop %s{W})' % Configuration.interface) Color.pl('{!} You can disable Monitor Mode when finished ({C}airmon-ng stop %s{W})' % cls.interface)
# Stop monitor mode # Stop monitor mode
#Airmon.stop(Configuration.interface) #Airmon.stop(cls.interface)
# Bring original interface back up # Bring original interface back up
#Airmon.put_interface_up(Airmon.base_interface) #Airmon.put_interface_up(Airmon.base_interface)
@@ -335,19 +348,19 @@ class Configuration(object):
exit(code) exit(code)
@staticmethod @classmethod
def dump(): def dump(cls):
''' (Colorful) string representation of the configuration ''' ''' (Colorful) string representation of the configuration '''
from .util.color import Color from .util.color import Color
max_len = 20 max_len = 20
for key in Configuration.__dict__.keys(): for key in cls.__dict__.keys():
max_len = max(max_len, len(key)) max_len = max(max_len, len(key))
result = Color.s('{W}%s Value{W}\n' % 'Configuration Key'.ljust(max_len)) result = Color.s('{W}%s Value{W}\n' % 'cls Key'.ljust(max_len))
result += Color.s('{W}%s------------------{W}\n' % ('-' * max_len)) result += Color.s('{W}%s------------------{W}\n' % ('-' * max_len))
for (key,val) in sorted(Configuration.__dict__.items()): for (key,val) in sorted(cls.__dict__.items()):
if key.startswith('__') or type(val) == staticmethod or val is None: if key.startswith('__') or type(val) == staticmethod or val is None:
continue continue
result += Color.s("{G}%s {W} {C}%s{W}\n" % (key.ljust(max_len),val)) result += Color.s("{G}%s {W} {C}%s{W}\n" % (key.ljust(max_len),val))

View File

@@ -1,13 +1,18 @@
#!/usr/bin/python2.7 #!/usr/bin/python2.7
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from .dependency import Dependency
from ..util.process import Process from ..util.process import Process
from ..util.input import xrange from ..util.input import xrange
from ..config import Configuration from ..config import Configuration
import os import os
class Aircrack(object): class Aircrack(Dependency):
dependency_required = True
dependency_name = 'aircrack-ng'
dependency_url = 'https://www.aircrack-ng.org/install.html'
def __init__(self, ivs_file=None): def __init__(self, ivs_file=None):
self.cracked_file = os.path.abspath( self.cracked_file = os.path.abspath(

View File

@@ -1,6 +1,7 @@
#!/usr/bin/python2.7 #!/usr/bin/python2.7
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from .dependency import Dependency
from ..config import Configuration from ..config import Configuration
from ..util.process import Process from ..util.process import Process
from ..util.timer import Timer from ..util.timer import Timer
@@ -54,7 +55,11 @@ class WEPAttackType(object):
return self.name return self.name
class Aireplay(Thread): class Aireplay(Thread, Dependency):
dependency_required = True
dependency_name = 'aircrack-ng'
dependency_url = 'https://www.aircrack-ng.org/install.html'
def __init__(self, target, attack_type, client_mac=None, replay_file=None): def __init__(self, target, attack_type, client_mac=None, replay_file=None):
''' '''
Starts aireplay process. Starts aireplay process.

View File

@@ -1,8 +1,9 @@
#!/usr/bin/python2.7 #!/usr/bin/python2.7
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from ..tools.ifconfig import Ifconfig from .dependency import Dependency
from ..tools.iwconfig import Iwconfig from .ifconfig import Ifconfig
from .iwconfig import Iwconfig
from ..util.process import Process from ..util.process import Process
from ..util.color import Color from ..util.color import Color
from ..util.input import raw_input from ..util.input import raw_input
@@ -49,8 +50,12 @@ class AirmonIface(object):
return s return s
class Airmon(object): class Airmon(Dependency):
''' Wrapper around the 'airmon-ng' program ''' ''' Wrapper around the 'airmon-ng' program '''
dependency_required = True
dependency_name = 'airmon-ng'
dependency_url = 'https://www.aircrack-ng.org/install.html'
base_interface = None base_interface = None
killed_network_manager = False killed_network_manager = False

View File

@@ -1,6 +1,7 @@
#!/usr/bin/python2.7 #!/usr/bin/python2.7
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from .dependency import Dependency
from .tshark import Tshark from .tshark import Tshark
from .wash import Wash from .wash import Wash
from ..util.process import Process from ..util.process import Process
@@ -10,8 +11,11 @@ from ..model.client import Client
import os, time import os, time
class Airodump(object): class Airodump(Dependency):
''' Wrapper around airodump-ng program ''' ''' Wrapper around airodump-ng program '''
dependency_required = True
dependency_name = 'airodump-ng'
dependency_url = 'https://www.aircrack-ng.org/install.html'
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',\

View File

@@ -0,0 +1,30 @@
from ..util.process import Process
from ..util.color import Color
class Dependency(object):
required_attr_names = ['dependency_name', 'dependency_url', 'dependency_required']
# https://stackoverflow.com/a/49024227
def __init_subclass__(cls):
for attr_name in cls.required_attr_names:
if not attr_name in cls.__dict__:
raise NotImplementedError(
"Attribute '{}' has not been overriden in class '{}'" \
.format(attr_name, cls.__name__)
)
@classmethod
def fails_dependency_check(cls):
if Process.exists(cls.dependency_name):
return False
if cls.dependency_required:
Color.pl('{!} {R}error: required app {O}%s{R} was not found' % cls.dependency_name)
Color.pl(' {W}install @ {C}%s{W}' % cls.dependency_url)
return True
else:
Color.pl('{!} {O}warning: recommended app {R}%s{O} was not found' % cls.dependency_name)
Color.pl(' {W}install @ {C}%s{W}' % cls.dependency_url)
return False

View File

@@ -16,6 +16,8 @@ from .attack.wpa import AttackWPA
from .attack.wps import AttackWPS from .attack.wps import AttackWPS
from .model.result import CrackResult from .model.result import CrackResult
from .model.handshake import Handshake from .model.handshake import Handshake
from .tools.airmon import Airmon
from .tools.airodump import Airodump
import json import json
import os import os
@@ -31,10 +33,10 @@ class Wifite(object):
Color.pl('{!} {O}re-run as: sudo ./Wifite.py{W}') Color.pl('{!} {O}re-run as: sudo ./Wifite.py{W}')
Configuration.exit_gracefully(0) Configuration.exit_gracefully(0)
self.dependency_check()
Configuration.initialize(load_interface=False) Configuration.initialize(load_interface=False)
self.dependency_check()
if Configuration.show_cracked: if Configuration.show_cracked:
self.display_cracked() self.display_cracked()
@@ -46,30 +48,24 @@ class Wifite(object):
Configuration.get_monitor_mode_interface() Configuration.get_monitor_mode_interface()
self.run() self.run()
def dependency_check(self): def dependency_check(self):
''' Check that required programs are installed ''' ''' Check that required programs are installed '''
required_apps = ['airmon-ng', 'iwconfig', 'ifconfig', 'aircrack-ng', 'aireplay-ng', 'airodump-ng']
optional_apps = ['packetforge-ng', 'reaver', 'bully', 'cowpatty', 'pyrit', 'stdbuf', 'macchanger', 'tshark']
missing_required = False
missing_optional = False
for app in required_apps: apps = [Airmon, Airodump] #, Iwconfig, Ifconfig, Aircrack, Aireplay, Airodump]
if not Process.exists(app):
missing_required = True
Color.pl('{!} {R}error: required app {O}%s{R} was not found' % app)
for app in optional_apps: if Configuration.use_eviltwin:
if not Process.exists(app): apps.extend([Hostapd, Dnsmasq, Iptables])
missing_optional = True
Color.pl('{!} {O}warning: recommended app {R}%s{O} was not found' % app) missing_required = any([app.fails_dependency_check() for app in apps])
if missing_required: if missing_required:
Color.pl('{!} {R}required app(s) were not found, exiting.{W}') Color.pl('{!} {R}required app(s) were not found, exiting.{W}')
sys.exit(-1) sys.exit(-1)
if missing_optional: #if missing_optional:
Color.pl('{!} {O}recommended app(s) were not found') # Color.pl('{!} {O}recommended app(s) were not found')
Color.pl('{!} {O}wifite may not work as expected{W}') # Color.pl('{!} {O}wifite may not work as expected{W}')
def display_cracked(self): def display_cracked(self):
''' Show cracked targets from cracked.txt ''' ''' Show cracked targets from cracked.txt '''
@@ -134,9 +130,17 @@ class Wifite(object):
Color.pl('\n{+} ({G}%d{W}/{G}%d{W})' % (idx, len(targets)) + Color.pl('\n{+} ({G}%d{W}/{G}%d{W})' % (idx, len(targets)) +
' starting attacks against {C}%s{W} ({C}%s{W})' ' starting attacks against {C}%s{W} ({C}%s{W})'
% (t.bssid, t.essid if t.essid_known else "{O}ESSID unknown")) % (t.bssid, t.essid if t.essid_known else "{O}ESSID unknown"))
if 'WEP' in t.encryption:
# TODO: Check if Eviltwin attack is selected.
if Configuration.use_eviltwin:
pass
elif 'WEP' in t.encryption:
attack = AttackWEP(t) attack = AttackWEP(t)
elif 'WPA' in t.encryption: elif 'WPA' in t.encryption:
# TODO: Move WPS+WPA decision to a combined attack
if t.wps: if t.wps:
attack = AttackWPS(t) attack = AttackWPS(t)
result = False result = False