Merge branch 'refactor'

This commit is contained in:
derv82
2018-03-17 17:30:11 -04:00
47 changed files with 539 additions and 426 deletions

View File

@@ -121,13 +121,13 @@ Not "/py":
* `tshark.py` <- process * `tshark.py` <- process
* `cowpatty.py` <- process * `cowpatty.py` <- process
* `pyrit.py` <- process * `pyrit.py` <- process
* `handshake.py` <- tshark, cowpatty, pyrit, aircrack
* `output.py` (color/printing) <- config * `output.py` (color/printing) <- config
* `process.py` <- config * `process.py` <- config
* `scan.py` (airodump output to target) <- config, target, airodump * `scan.py` (airodump output to target) <- config, target, airodump
* **target/** * **target/**
* `target.py` (ssid, pcap file) <- airodump, tshark * `target.py` (ssid, pcap file) <- airodump, tshark
* `result.py` (PIN/PSK/KEY) * `result.py` (PIN/PSK/KEY)
* `handshake.py` <- tshark, cowpatty, pyrit, aircrack
------------------------------------------------------ ------------------------------------------------------

240
Wifite.py
View File

@@ -1,239 +1,5 @@
#!/usr/bin/python2.7 #!/usr/bin/python
# -*- coding: utf-8 -*-
from py.Configuration import Configuration from wifite import wifite
from py.Scanner import Scanner
from py.Color import Color
from py.AttackWEP import AttackWEP
from py.AttackWPA import AttackWPA
from py.AttackWPS import AttackWPS
from py.CrackResult import CrackResult
from py.Handshake import Handshake
from py.CrackHandshake import CrackHandshake
from py.Process import Process
from json import loads wifite.run()
import os
from sys import exit
class Wifite(object):
def main(self):
''' Either performs action based on arguments, or starts attack scanning '''
if os.getuid() != 0:
Color.pl('{!} {R}error: {O}wifite{R} must be run as {O}root{W}')
Color.pl('{!} {O}re-run as: sudo ./Wifite.py{W}')
Configuration.exit_gracefully(0)
self.dependency_check()
Configuration.initialize(load_interface=False)
if Configuration.show_cracked:
self.display_cracked()
elif Configuration.check_handshake:
self.check_handshake(Configuration.check_handshake)
elif Configuration.crack_handshake:
CrackHandshake()
else:
Configuration.get_interface()
self.run()
def dependency_check(self):
''' Check that required programs are installed '''
required_apps = ['airmon-ng', 'iwconfig', 'ifconfig', 'aircrack-ng', 'aireplay-ng', 'airodump-ng', 'tshark']
optional_apps = ['packetforge-ng', 'reaver', 'bully', 'cowpatty', 'pyrit', 'stdbuf', 'macchanger']
missing_required = False
missing_optional = False
for app in required_apps:
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 not Process.exists(app):
missing_optional = True
Color.pl('{!} {O}warning: recommended app {R}%s{O} was not found' % app)
if missing_required:
Color.pl('{!} {R}required app(s) were not found, exiting.{W}')
exit(-1)
if missing_optional:
Color.pl('{!} {O}recommended app(s) were not found')
Color.pl('{!} {O}wifite may not work as expected{W}')
def display_cracked(self):
''' Show cracked targets from cracked.txt '''
Color.pl('{+} displaying {C}cracked target(s){W}')
name = CrackResult.cracked_file
if not os.path.exists(name):
Color.pl('{!} {O}file {C}%s{O} not found{W}' % name)
return
with open(name, 'r') as fid:
json = loads(fid.read())
for idx, item in enumerate(json, start=1):
Color.pl('\n{+} Cracked target #%d:' % (idx))
cr = CrackResult.load(item)
cr.dump()
def check_handshake(self, capfile):
''' Analyzes .cap file for handshake '''
if capfile == '<all>':
Color.pl('{+} checking all handshakes in {G}"./hs"{W} directory\n')
try:
capfiles = [os.path.join('hs', x) for x in os.listdir('hs') if x.endswith('.cap')]
except OSError, e:
capfiles = []
if len(capfiles) == 0:
Color.pl('{!} {R}no .cap files found in {O}"./hs"{W}\n')
else:
capfiles = [capfile]
for capfile in capfiles:
Color.pl('{+} checking for handshake in .cap file {C}%s{W}' % capfile)
if not os.path.exists(capfile):
Color.pl('{!} {O}.cap file {C}%s{O} not found{W}' % capfile)
return
hs = Handshake(capfile, bssid=Configuration.target_bssid, essid=Configuration.target_essid)
hs.analyze()
Color.pl('')
def run(self):
'''
Main program.
1) Scans for targets, asks user to select targets
2) Attacks each target
'''
s = Scanner()
if s.target:
# We found the target we want
targets = [s.target]
else:
targets = s.select_targets()
attacked_targets = 0
targets_remaining = len(targets)
for idx, t in enumerate(targets, start=1):
attacked_targets += 1
targets_remaining -= 1
Color.pl('\n{+} ({G}%d{W}/{G}%d{W})' % (idx, len(targets)) +
' starting attacks against {C}%s{W} ({C}%s{W})'
% (t.bssid, t.essid if t.essid_known else "{O}ESSID unknown"))
if 'WEP' in t.encryption:
attack = AttackWEP(t)
elif 'WPA' in t.encryption:
if t.wps:
attack = AttackWPS(t)
result = False
try:
result = attack.run()
except Exception as e:
Color.pl("\n{!} {R}Error: {O}%s" % str(e))
if Configuration.verbose > 0 or Configuration.print_stack_traces:
Color.pl('\n{!} {O}Full stack trace below')
from traceback import format_exc
Color.p('\n{!} ')
err = format_exc().strip()
err = err.replace('\n', '\n{!} {C} ')
err = err.replace(' File', '{W}File')
err = err.replace(' Exception: ', '{R}Exception: {O}')
Color.pl(err)
except KeyboardInterrupt:
Color.pl('\n{!} {O}interrupted{W}\n')
if not self.user_wants_to_continue(targets_remaining, 1):
break
if result and attack.success:
# We cracked it.
attack.crack_result.save()
continue
else:
# WPS failed, try WPA handshake.
attack = AttackWPA(t)
else:
# Not using WPS, try WPA handshake.
attack = AttackWPA(t)
else:
Color.pl("{!} {R}Error: {O}unable to attack: encryption not WEP or WPA")
continue
try:
attack.run()
except Exception, e:
Color.pl("\n{!} {R}Error: {O}%s" % str(e))
if Configuration.verbose > 0 or True:
Color.pl('\n{!} {O}Full stack trace below')
from traceback import format_exc
Color.p('\n{!} ')
err = format_exc().strip()
err = err.replace('\n', '\n{!} {C} ')
err = err.replace(' File', '{W}File')
err = err.replace(' Exception: ', '{R}Exception: {O}')
Color.pl(err)
except KeyboardInterrupt:
Color.pl('\n{!} {O}interrupted{W}\n')
if not self.user_wants_to_continue(targets_remaining):
break
if attack.success:
attack.crack_result.save()
Color.pl("{+} Finished attacking {C}%d{W} target(s), exiting" % attacked_targets)
def print_banner(self):
""" Displays ASCII art of the highest caliber. """
Color.pl(r'''
{G} . {GR}{D} {W}{G} . {W}
{G}.´ · .{GR}{D} {W}{G}. · `. {G}wifite {D}%s{W}
{G}: : : {GR}{D} (¯) {W}{G} : : : {W}{D}automated wireless auditor
{G}`. · `{GR}{D}\ {W}{G}´ · .´ {C}{D}https://github.com/derv82/wifite2
{G} ` {GR}{D}/¯¯¯\{W}{G} ´ {W}
''' % Configuration.version)
def user_wants_to_continue(self, targets_remaining, attacks_remaining=0):
''' Asks user if attacks should continue onto other targets '''
if attacks_remaining == 0 and targets_remaining == 0:
# No targets or attacksleft, drop out
return
prompt_list = []
if attacks_remaining > 0:
prompt_list.append(Color.s('{C}%d{W} attack(s)' % attacks_remaining))
if targets_remaining > 0:
prompt_list.append(Color.s('{C}%d{W} target(s)' % targets_remaining))
prompt = ' and '.join(prompt_list)
Color.pl('{+} %s remain, do you want to continue?' % prompt)
prompt = Color.s('{+} type {G}c{W} to {G}continue{W}' +
' or {R}s{W} to {R}stop{W}: ')
if raw_input(prompt).lower().startswith('s'):
return False
else:
return True
if __name__ == '__main__':
w = Wifite()
try:
w.print_banner()
w.main()
except Exception, e:
Color.pl('\n{!} {R}Error:{O} %s{W}' % str(e))
if Configuration.verbose > 0 or True:
Color.pl('\n{!} {O}Full stack trace below')
from traceback import format_exc
Color.p('\n{!} ')
err = format_exc().strip()
err = err.replace('\n', '\n{!} {C} ')
err = err.replace(' File', '{W}File')
err = err.replace(' Exception: ', '{R}Exception: {O}')
Color.pl(err)
Color.pl('\n{!} {R}Exiting{W}\n')
except KeyboardInterrupt:
Color.pl('\n{!} {O}interrupted, shutting down...{W}')
Configuration.exit_gracefully(0)

View File

@@ -1,2 +1,2 @@
#!/bin/sh #!/bin/sh
python2.7 -m unittest discover py/tests -v python2.7 -m unittest discover tests -v

View File

@@ -4,7 +4,7 @@
import sys import sys
sys.path.insert(0, '..') sys.path.insert(0, '..')
from py.Handshake import Handshake from wifite.model.handshake import Handshake
import unittest import unittest

View File

@@ -1,7 +1,7 @@
#!/usr/bin/python2.7 #!/usr/bin/python2.7
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from py.Airodump import Airodump from wifite.tools.airodump import Airodump
import unittest import unittest

200
py/Arguments.py → wifite/args.py Normal file → Executable file
View File

@@ -1,22 +1,55 @@
#!/usr/bin/python2.7 #!/usr/bin/python2.7
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import argparse from util.color import Color
from Color import Color
import argparse, sys
class Arguments(object): class Arguments(object):
''' Holds arguments used by the Wifite ''' ''' Holds arguments used by the Wifite '''
def __init__(self, Configuration):
self.args = self.get_arguments(Configuration)
def get_arguments(self, Configuration): def __init__(self, configuration):
self.verbose = any(['-v' in word for word in sys.argv])
self.config = configuration
self.args = self.get_arguments()
def _verbose(self, msg):
if self.verbose:
return Color.s(msg)
else:
return argparse.SUPPRESS
def get_arguments(self):
''' Returns parser.args() containing all program arguments ''' ''' Returns parser.args() containing all program arguments '''
parser = argparse.ArgumentParser(usage=argparse.SUPPRESS, parser = argparse.ArgumentParser(usage=argparse.SUPPRESS,
formatter_class=lambda prog: argparse.HelpFormatter(prog, max_help_position=80, width=130)) formatter_class=lambda prog: argparse.HelpFormatter(prog, max_help_position=80, width=130))
# Global variables
glob = parser.add_argument_group('SETTINGS') glob = parser.add_argument_group('SETTINGS')
self._add_global_args(glob)
wep_group = parser.add_argument_group('WEP')
self._add_wep_args(wep_group)
wpa_group = parser.add_argument_group('WPA')
self._add_wpa_args(wpa_group)
wps_group = parser.add_argument_group('WPS')
self._add_wps_args(wps_group)
commands_group = parser.add_argument_group('COMMANDS')
self._add_command_args(commands_group)
return parser.parse_args()
def _add_global_args(self, glob):
glob.add_argument('-v',
'--verbose',
action='count',
default=0,
dest='verbose',
help=Color.s('Shows more options ({C}-h -v{W}). Prints tool outputs. (default: {G}quiet{W})'))
glob.add_argument('-i', glob.add_argument('-i',
action='store', action='store',
@@ -25,18 +58,13 @@ class Arguments(object):
type=str, type=str,
help=Color.s('Wireless interface to use (default: {G}ask{W})')) help=Color.s('Wireless interface to use (default: {G}ask{W})'))
glob.add_argument('--kill',
action='store_true',
dest='kill_conflicting_processes',
help=Color.s('Kill processes that conflict with Airmon/Airodump (default: {G}off{W})'))
glob.add_argument('--channel', help=argparse.SUPPRESS, action='store', dest='channel', type=int)
glob.add_argument('-c', glob.add_argument('-c',
action='store', action='store',
dest='channel', dest='channel',
metavar='[channel]', metavar='[channel]',
type=int, type=int,
help=Color.s('Wireless channel to scan (default: {G}all channels{W})')) help=Color.s('Wireless channel to scan (default: {G}all channels{W})'))
glob.add_argument('--channel', help=argparse.SUPPRESS, action='store', dest='channel', type=int)
glob.add_argument('-mac', glob.add_argument('-mac',
'---random-mac', '---random-mac',
@@ -44,37 +72,61 @@ class Arguments(object):
dest='random_mac', dest='random_mac',
help=Color.s('Randomize wireless card MAC address (default: {G}off{W})')) help=Color.s('Randomize wireless card MAC address (default: {G}off{W})'))
glob.add_argument('-p',
action='store',
dest='scan_time',
nargs='?',
const=10,
metavar='scantime',
type=int,
help=Color.s('{G}Pillage{W}: Attack all targets after {C}scantime{W} seconds'))
glob.add_argument('--pillage', help=argparse.SUPPRESS, action='store', dest='scan_time', nargs='?', const=10, type=int)
glob.add_argument('--kill',
action='store_true',
dest='kill_conflicting_processes',
help=Color.s('Kill processes that conflict with Airmon/Airodump (default: {G}off{W})'))
glob.add_argument('-5', glob.add_argument('-5',
'--5ghz', '--5ghz',
action='store_true', action='store_true',
dest='five_ghz', dest='five_ghz',
help=Color.s('Include 5Ghz channels (default: {G}off{W})')) help=self._verbose('Include 5Ghz channels (default: {G}off{W})'))
glob.add_argument('--bssid', help=argparse.SUPPRESS, action='store', dest='target_bssid', type=str)
glob.add_argument('-b', glob.add_argument('-b',
action='store', action='store',
dest='target_bssid', dest='target_bssid',
metavar='[bssid]', metavar='[bssid]',
type=str, type=str,
help=Color.s('BSSID (e.g. {GR}AA:BB:CC:DD:EE:FF{W}) of access point to attack')) help=self._verbose('BSSID (e.g. {GR}AA:BB:CC:DD:EE:FF{W}) of access point to attack'))
glob.add_argument('--bssid', help=argparse.SUPPRESS, action='store', dest='target_bssid', type=str)
glob.add_argument('--essid', help=argparse.SUPPRESS, action='store', dest='target_essid', type=str)
glob.add_argument('-e', glob.add_argument('-e',
action='store', action='store',
dest='target_essid', dest='target_essid',
metavar='[essid]', metavar='[essid]',
type=str, type=str,
help=Color.s('ESSID (e.g. {GR}NETGEAR07{W}) of access point to attack')) help=self._verbose('ESSID (e.g. {GR}NETGEAR07{W}) of access point to attack'))
glob.add_argument('--essid', help=argparse.SUPPRESS, action='store', dest='target_essid', type=str)
glob.add_argument('-E',
action='store',
dest='ignore_essid',
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)
glob.add_argument('--showb', glob.add_argument('--showb',
action='store_true', action='store_true',
dest='show_bssids', dest='show_bssids',
help=Color.s('Show BSSIDs of targets while scanning')) help=self._verbose('Show BSSIDs of targets while scanning'))
glob.add_argument('--nodeauths', glob.add_argument('--nodeauths',
action='store_true', action='store_true',
dest='no_deauth', dest='no_deauth',
help=Color.s('Do not deauthenticate clients *EVER* (default: {G}off{W})')) help=Color.s('Passive mode: Never deauthenticates clients (default: {G}deauth targets{W})'))
glob.add_argument('--no-deauths', action='store_true', dest='no_deauth', help=argparse.SUPPRESS) glob.add_argument('--no-deauths', action='store_true', dest='no_deauth', help=argparse.SUPPRESS)
glob.add_argument('-nd', action='store_true', dest='no_deauth', help=argparse.SUPPRESS) glob.add_argument('-nd', action='store_true', dest='no_deauth', help=argparse.SUPPRESS)
@@ -84,151 +136,144 @@ class Arguments(object):
dest='num_deauths', dest='num_deauths',
metavar="[num]", metavar="[num]",
default=None, default=None,
help=Color.s('Number of deauth packets to send (default: {G}%d{W})' % Configuration.num_deauths)) help=self._verbose('Number of deauth packets to send (default: {G}%d{W})' % self.config.num_deauths))
glob.add_argument('--pillage', help=argparse.SUPPRESS, action='store', dest='scan_time', nargs='?', const=10, type=int)
glob.add_argument('-p',
action='store',
dest='scan_time',
nargs='?',
const=10,
metavar='scantime',
type=int,
help=Color.s('{G}Pillage{W}: Attack all targets after {C}scantime{W} seconds'))
glob.add_argument('-v',
'--verbose',
action='count',
default=0,
dest='verbose',
help=Color.s('Verbose mode, prints more lines (default: {G}quiet{W})'))
def _add_wep_args(self, wep):
# WEP # WEP
wep = parser.add_argument_group('WEP-RELATED')
wep.add_argument('--wep', wep.add_argument('--wep',
action='store_true', action='store_true',
dest='wep_filter', dest='wep_filter',
help=Color.s('Filter to display only WEP-encrypted networks (default: {G}off{W})')) help=Color.s('Filter to display only WEP-encrypted networks (default: {G}off{W})'))
wep.add_argument('-wep', help=argparse.SUPPRESS, action='store_true', dest='wep_filter') wep.add_argument('-wep', help=argparse.SUPPRESS, action='store_true', dest='wep_filter')
wep.add_argument('--require-fakeauth', wep.add_argument('--require-fakeauth',
action='store_true', action='store_true',
dest='require_fakeauth', dest='require_fakeauth',
help=Color.s('Fails attacks if fake-auth fails (default: {G}off{W})')) help=Color.s('Fails attacks if fake-auth fails (default: {G}off{W})'))
wep.add_argument('--nofakeauth', help=argparse.SUPPRESS, action='store_true', dest='require_fakeauth') wep.add_argument('--nofakeauth', help=argparse.SUPPRESS, action='store_true', dest='require_fakeauth')
wep.add_argument('-nofakeauth', help=argparse.SUPPRESS, action='store_true', dest='require_fakeauth') wep.add_argument('-nofakeauth', help=argparse.SUPPRESS, action='store_true', dest='require_fakeauth')
wep.add_argument('--pps', wep.add_argument('--pps',
action='store', action='store',
dest='wep_pps', dest='wep_pps',
metavar='[pps]', metavar='[pps]',
type=int, type=int,
help=Color.s('Packets Per Second to replay (default: {G}%d pps{W})') help=self._verbose('Packets Per Second to replay (default: {G}%d pps{W})' % self.config.wep_pps))
% Configuration.wep_pps)
wep.add_argument('-pps', help=argparse.SUPPRESS, action='store', dest='wep_pps', type=int) wep.add_argument('-pps', help=argparse.SUPPRESS, action='store', dest='wep_pps', type=int)
wep.add_argument('--wept', wep.add_argument('--wept',
action='store', action='store',
dest='wep_timeout', dest='wep_timeout',
metavar='[seconds]', metavar='[seconds]',
type=int, type=int,
help=Color.s('Seconds to wait before failing (default: {G}%d sec{W})') help=self._verbose('Seconds to wait before failing (default: {G}%d sec{W})' % self.config.wep_timeout))
% Configuration.wep_timeout)
wep.add_argument('-wept', help=argparse.SUPPRESS, action='store', dest='wep_timeout', type=int) wep.add_argument('-wept', help=argparse.SUPPRESS, action='store', dest='wep_timeout', type=int)
wep.add_argument('--wepca', wep.add_argument('--wepca',
action='store', action='store',
dest='wep_crack_at_ivs', dest='wep_crack_at_ivs',
metavar='[ivs]', metavar='[ivs]',
type=int, type=int,
help=Color.s('Start cracking at this many IVs (default: {G}%d ivs{W})') help=self._verbose('Start cracking at this many IVs (default: {G}%d ivs{W})' % self.config.wep_crack_at_ivs))
% Configuration.wep_crack_at_ivs)
wep.add_argument('-wepca', help=argparse.SUPPRESS, action='store', dest='wep_crack_at_ivs', type=int) wep.add_argument('-wepca', help=argparse.SUPPRESS, action='store', dest='wep_crack_at_ivs', type=int)
wep.add_argument('--weprs', wep.add_argument('--weprs',
action='store', action='store',
dest='wep_restart_stale_ivs', dest='wep_restart_stale_ivs',
metavar='[seconds]', metavar='[seconds]',
type=int, type=int,
help=Color.s('Restart aireplay if no new IVs appear (default: {G}%d sec{W})') help=self._verbose('Restart aireplay if no new IVs appear (default: {G}%d sec{W})' % self.config.wep_restart_stale_ivs))
% Configuration.wep_restart_stale_ivs)
wep.add_argument('-weprs', help=argparse.SUPPRESS, action='store', dest='wep_restart_stale_ivs', type=int) wep.add_argument('-weprs', help=argparse.SUPPRESS, action='store', dest='wep_restart_stale_ivs', type=int)
wep.add_argument('--weprc', wep.add_argument('--weprc',
action='store', action='store',
dest='wep_restart_aircrack', dest='wep_restart_aircrack',
metavar='[seconds]', metavar='[seconds]',
type=int, type=int,
help=Color.s('Restart aircrack after this delay (default: {G}%d sec{W})') help=self._verbose('Restart aircrack after this delay (default: {G}%d sec{W})' % self.config.wep_restart_aircrack))
% Configuration.wep_restart_aircrack)
wep.add_argument('-weprc', help=argparse.SUPPRESS, action='store', dest='wep_restart_aircrack', type=int) wep.add_argument('-weprc', help=argparse.SUPPRESS, action='store', dest='wep_restart_aircrack', type=int)
wep.add_argument('--arpreplay', wep.add_argument('--arpreplay',
action='store_true', action='store_true',
dest='wep_attack_replay', dest='wep_attack_replay',
help=Color.s('Use ARP-replay WEP attack (default: {G}on{W})')) help=self._verbose('Use ARP-replay WEP attack (default: {G}on{W})'))
wep.add_argument('-arpreplay', help=argparse.SUPPRESS, action='store_true', dest='wep_attack_replay') wep.add_argument('-arpreplay', help=argparse.SUPPRESS, action='store_true', dest='wep_attack_replay')
wep.add_argument('--fragment', wep.add_argument('--fragment',
action='store_true', action='store_true',
dest='wep_attack_fragment', dest='wep_attack_fragment',
help=Color.s('Use fragmentation WEP attack (default: {G}on{W})')) help=self._verbose('Use fragmentation WEP attack (default: {G}on{W})'))
wep.add_argument('-fragment', help=argparse.SUPPRESS, action='store_true', dest='wep_attack_fragment') wep.add_argument('-fragment', help=argparse.SUPPRESS, action='store_true', dest='wep_attack_fragment')
wep.add_argument('--chopchop', wep.add_argument('--chopchop',
action='store_true', action='store_true',
dest='wep_attack_chopchop', dest='wep_attack_chopchop',
help=Color.s('Use chop-chop WEP attack (default: {G}on{W})')) help=self._verbose('Use chop-chop WEP attack (default: {G}on{W})'))
wep.add_argument('-chopchop', help=argparse.SUPPRESS, action='store_true', dest='wep_attack_chopchop') wep.add_argument('-chopchop', help=argparse.SUPPRESS, action='store_true', dest='wep_attack_chopchop')
wep.add_argument('--caffelatte', wep.add_argument('--caffelatte',
action='store_true', action='store_true',
dest='wep_attack_caffe', dest='wep_attack_caffe',
help=Color.s('Use caffe-latte WEP attack (default: {G}on{W})')) help=self._verbose('Use caffe-latte WEP attack (default: {G}on{W})'))
wep.add_argument('-caffelatte', help=argparse.SUPPRESS, action='store_true', dest='wep_attack_caffelatte') wep.add_argument('-caffelatte', help=argparse.SUPPRESS, action='store_true', dest='wep_attack_caffelatte')
wep.add_argument('--p0841', wep.add_argument('--p0841',
action='store_true', action='store_true',
dest='wep_attack_p0841', dest='wep_attack_p0841',
help=Color.s('Use p0841 WEP attack (default: {G}on{W})')) help=self._verbose('Use p0841 WEP attack (default: {G}on{W})'))
wep.add_argument('-p0841', help=argparse.SUPPRESS, action='store_true', dest='wep_attack_p0841') wep.add_argument('-p0841', help=argparse.SUPPRESS, action='store_true', dest='wep_attack_p0841')
wep.add_argument('--hirte', wep.add_argument('--hirte',
action='store_true', action='store_true',
dest='wep_attack_hirte', dest='wep_attack_hirte',
help=Color.s('Use ARP-replay WEP attack (default: {G}on{W})')) help=self._verbose('Use ARP-replay WEP attack (default: {G}on{W})'))
wep.add_argument('-hirte', help=argparse.SUPPRESS, action='store_true', dest='wep_attack_hirte') wep.add_argument('-hirte', help=argparse.SUPPRESS, action='store_true', dest='wep_attack_hirte')
# WPA
wpa = parser.add_argument_group('WPA-RELATED') def _add_wpa_args(self, wpa):
wpa.add_argument('--wpa', wpa.add_argument('--wpa',
action='store_true', action='store_true',
dest='wpa_filter', dest='wpa_filter',
help=Color.s('Filter to display only WPA-encrypted networks (includes WPS)')) help=Color.s('Filter to display only WPA-encrypted networks (includes WPS)'))
wpa.add_argument('-wpa', help=argparse.SUPPRESS, action='store_true', dest='wpa_filter') wpa.add_argument('-wpa', help=argparse.SUPPRESS, action='store_true', dest='wpa_filter')
wpa.add_argument('--wpadt', wpa.add_argument('--wpadt',
action='store', action='store',
dest='wpa_deauth_timeout', dest='wpa_deauth_timeout',
metavar='[seconds]', metavar='[seconds]',
type=int, type=int,
help=Color.s('Time to wait between sending Deauths (default: {G}%d sec{W})') help=self._verbose('Time to wait between sending Deauths (default: {G}%d sec{W})' % self.config.wpa_deauth_timeout))
% Configuration.wpa_deauth_timeout)
wpa.add_argument('-wpadt', help=argparse.SUPPRESS, action='store', dest='wpa_deauth_timeout', type=int) wpa.add_argument('-wpadt', help=argparse.SUPPRESS, action='store', dest='wpa_deauth_timeout', type=int)
wpa.add_argument('--wpat', wpa.add_argument('--wpat',
action='store', action='store',
dest='wpa_attack_timeout', dest='wpa_attack_timeout',
metavar='[seconds]', metavar='[seconds]',
type=int, type=int,
help=Color.s('Time to wait before failing WPA attack (default: {G}%d sec{W})') help=self._verbose('Time to wait before failing WPA attack (default: {G}%d sec{W})' % self.config.wpa_attack_timeout))
% Configuration.wpa_attack_timeout)
wpa.add_argument('-wpat', help=argparse.SUPPRESS, action='store', dest='wpa_attack_timeout', type=int) wpa.add_argument('-wpat', help=argparse.SUPPRESS, action='store', dest='wpa_attack_timeout', type=int)
wpa.add_argument('--new-hs', wpa.add_argument('--new-hs',
action='store_true', action='store_true',
dest='ignore_old_handshakes', dest='ignore_old_handshakes',
help=Color.s('Captures new handshakes, ignores existing handshakes in ./hs (default: {G}off{W})')) help=Color.s('Captures new handshakes, ignores existing handshakes in ./hs (default: {G}off{W})'))
wpa.add_argument('--hs-dir', wpa.add_argument('--hs-dir',
action='store', action='store',
dest='wpa_handshake_dir', dest='wpa_handshake_dir',
metavar='[dir]', metavar='[dir]',
type=str, type=str,
help=Color.s('Directory to store handshake files (default: {G}%s{W})') help=self._verbose('Directory to store handshake files (default: {G}%s{W})' % self.config.wpa_handshake_dir))
% Configuration.wpa_handshake_dir)
wpa.add_argument('-hs-dir', help=argparse.SUPPRESS, action='store', dest='wpa_handshake_dir', type=str) wpa.add_argument('-hs-dir', help=argparse.SUPPRESS, action='store', dest='wpa_handshake_dir', type=str)
wpa.add_argument('--dict', wpa.add_argument('--dict',
action='store', action='store',
dest='wordlist', dest='wordlist',
metavar='[file]', metavar='[file]',
type=str, type=str,
help=Color.s('File containing passwords for cracking (default: {G}%s{W})') help=Color.s('File containing passwords for cracking (default: {G}%s{W})')
% Configuration.wordlist) % self.config.wordlist)
# TODO: Uncomment the --strip option once it works # TODO: Uncomment the --strip option once it works
''' '''
@@ -240,8 +285,8 @@ class Arguments(object):
''' '''
wpa.add_argument('-strip', help=argparse.SUPPRESS, action='store_true', dest='wpa_strip_handshake') wpa.add_argument('-strip', help=argparse.SUPPRESS, action='store_true', dest='wpa_strip_handshake')
# WPS
wps = parser.add_argument_group('WPS-RELATED') def _add_wps_args(self, wps):
wps.add_argument('--wps', wps.add_argument('--wps',
action='store_true', action='store_true',
dest='wps_filter', dest='wps_filter',
@@ -254,11 +299,11 @@ class Arguments(object):
wps.add_argument('--no-wps', wps.add_argument('--no-wps',
action='store_true', action='store_true',
dest='no_wps', dest='no_wps',
help=Color.s('{O}NEVER{W} use WPS attacks (Pixie-Dust) on WPA networks (default: {G}off{W})')) help=Color.s('{O}NEVER{W} use WPS attacks (Pixie-Dust) on non-WEP networks (default: {G}off{W})'))
wps.add_argument('--wps-only', wps.add_argument('--wps-only',
action='store_true', action='store_true',
dest='wps_only', dest='wps_only',
help=Color.s('{G}ALWAYS{W} use WPS attacks (Pixie-Dust) on WPA networks (default: {G}off{W})')) help=Color.s('{G}ALWAYS{W} use WPS attacks (Pixie-Dust) on non-WEP networks (default: {G}off{W})'))
# Same as --wps-only # Same as --wps-only
wps.add_argument('--pixie', wps.add_argument('--pixie',
@@ -271,30 +316,26 @@ class Arguments(object):
dest='wps_pixie_timeout', dest='wps_pixie_timeout',
metavar='[seconds]', metavar='[seconds]',
type=int, type=int,
help=Color.s('Time to wait before failing PixieDust attack (default: {G}%d sec{W})') help=self._verbose('Time to wait before failing PixieDust attack (default: {G}%d sec{W})' % self.config.wps_pixie_timeout))
% Configuration.wps_pixie_timeout)
wps.add_argument('--pixiest', wps.add_argument('--pixiest',
action='store', action='store',
dest='wps_pixie_step_timeout', dest='wps_pixie_step_timeout',
metavar='[seconds]', metavar='[seconds]',
type=int, type=int,
help=Color.s('Time to wait for a step to progress before failing PixieDust attack (default: {G}%d sec{W})') help=self._verbose('Time to wait for a step to progress before failing PixieDust attack (default: {G}%d sec{W})' % self.config.wps_pixie_step_timeout))
% Configuration.wps_pixie_step_timeout)
wps.add_argument('--wpsmf', wps.add_argument('--wpsmf',
action='store', action='store',
dest='wps_fail_threshold', dest='wps_fail_threshold',
metavar='[fails]', metavar='[fails]',
type=int, type=int,
help=Color.s('Maximum number of WPS Failures before failing attack (default: {G}%d{W})') help=self._verbose('Maximum number of WPS Failures before failing attack (default: {G}%d{W})' % self.config.wps_fail_threshold))
% Configuration.wps_fail_threshold)
wps.add_argument('-wpsmf', help=argparse.SUPPRESS, action='store', dest='wps_fail_threshold', type=int) wps.add_argument('-wpsmf', help=argparse.SUPPRESS, action='store', dest='wps_fail_threshold', type=int)
wps.add_argument('--wpsmt', wps.add_argument('--wpsmt',
action='store', action='store',
dest='wps_timeout_threshold', dest='wps_timeout_threshold',
metavar='[timeouts]', metavar='[timeouts]',
type=int, type=int,
help=Color.s('Maximum number of Timeouts before stopping (default: {G}%d{W})') help=self._verbose('Maximum number of Timeouts before stopping (default: {G}%d{W})' % self.config.wps_timeout_threshold))
% Configuration.wps_timeout_threshold)
wps.add_argument('-wpsmt', help=argparse.SUPPRESS, action='store', dest='wps_timeout_threshold', type=int) wps.add_argument('-wpsmt', help=argparse.SUPPRESS, action='store', dest='wps_timeout_threshold', type=int)
wps.add_argument('--ignore-ratelimit', wps.add_argument('--ignore-ratelimit',
action='store_false', action='store_false',
@@ -302,13 +343,14 @@ class Arguments(object):
help=Color.s('Ignores attack if WPS is rate-limited (default: {G}on{W})')) help=Color.s('Ignores attack if WPS is rate-limited (default: {G}on{W})'))
wps.add_argument('-ignore-ratelimit', help=argparse.SUPPRESS, action='store_false', dest='wps_skip_rate_limit') wps.add_argument('-ignore-ratelimit', help=argparse.SUPPRESS, action='store_false', dest='wps_skip_rate_limit')
# Commands
commands = parser.add_argument_group('COMMANDS') def _add_command_args(self, commands):
commands.add_argument('--cracked', commands.add_argument('--cracked',
action='store_true', action='store_true',
dest='cracked', dest='cracked',
help=Color.s('Display previously-cracked access points')) help=Color.s('Display previously-cracked access points'))
commands.add_argument('-cracked', help=argparse.SUPPRESS, action='store_true', dest='cracked') commands.add_argument('-cracked', help=argparse.SUPPRESS, action='store_true', dest='cracked')
commands.add_argument('--check', commands.add_argument('--check',
action='store', action='store',
metavar='file', metavar='file',
@@ -317,15 +359,15 @@ class Arguments(object):
dest='check_handshake', dest='check_handshake',
help=Color.s('Check a .cap file (or all hs/*.cap files) for WPA handshakes')) help=Color.s('Check a .cap file (or all hs/*.cap files) for WPA handshakes'))
commands.add_argument('-check', help=argparse.SUPPRESS, action='store', nargs='?', const='<all>', dest='check_handshake') commands.add_argument('-check', help=argparse.SUPPRESS, action='store', nargs='?', const='<all>', dest='check_handshake')
commands.add_argument('--crack', commands.add_argument('--crack',
action='store_true', action='store_true',
dest='crack_handshake', dest='crack_handshake',
help=Color.s('Show commands to crack a captured handshake')) help=Color.s('Show commands to crack a captured handshake'))
return parser.parse_args()
if __name__ == '__main__': if __name__ == '__main__':
from Color import Color from util.color import Color
from Configuration import Configuration from config import Configuration
Configuration.initialize(False) Configuration.initialize(False)
a = Arguments(Configuration) a = Arguments(Configuration)
args = a.args args = a.args

View File

24
py/AttackWEP.py → wifite/attack/wep.py Normal file → Executable file
View File

@@ -1,14 +1,14 @@
#!/usr/bin/python2.7 #!/usr/bin/python2.7
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from Attack import Attack from ..model.attack import Attack
from Airodump import Airodump from ..tools.airodump import Airodump
from Aireplay import Aireplay, WEPAttackType from ..tools.aireplay import Aireplay, WEPAttackType
from Aircrack import Aircrack from ..tools.aircrack import Aircrack
from Configuration import Configuration from ..config import Configuration
from Interface import Interface from ..model.interface import Interface
from Color import Color from ..util.color import Color
from CrackResultWEP import CrackResultWEP from ..model.wep_result import CrackResultWEP
import time import time
@@ -34,6 +34,7 @@ class AttackWEP(Attack):
aircrack = None # Aircrack process, not started yet aircrack = None # Aircrack process, not started yet
fakeauth_proc = None fakeauth_proc = None
replay_file = None replay_file = None
airodump_target = None
attacks_remaining = list(Configuration.wep_attacks) attacks_remaining = list(Configuration.wep_attacks)
while len(attacks_remaining) > 0: while len(attacks_remaining) > 0:
@@ -245,6 +246,9 @@ class AttackWEP(Attack):
Ask user what attack to perform next (re-orders attacks_remaining, returns False), Ask user what attack to perform next (re-orders attacks_remaining, returns False),
or if we should stop attacking this target (returns True). or if we should stop attacking this target (returns True).
''' '''
if target is None:
Color.pl("")
return True
target_name = target.essid if target.essid_known else target.bssid target_name = target.essid if target.essid_known else target.bssid
Color.pl("\n\n{!} {O}Interrupted") Color.pl("\n\n{!} {O}Interrupted")
@@ -322,9 +326,11 @@ class AttackWEP(Attack):
if __name__ == '__main__': if __name__ == '__main__':
from Target import Target Configuration.initialize(True)
from ..model.target import Target
fields = "A4:2B:8C:16:6B:3A, 2015-05-27 19:28:44, 2015-05-27 19:28:46, 6, 54e,WEP, WEP, , -58, 2, 0, 0. 0. 0. 0, 9, Test Router Please Ignore, ".split(',') fields = "A4:2B:8C:16:6B:3A, 2015-05-27 19:28:44, 2015-05-27 19:28:46, 6, 54e,WEP, WEP, , -58, 2, 0, 0. 0. 0. 0, 9, Test Router Please Ignore, ".split(',')
target = Target(fields) target = Target(fields)
wep = AttackWEP(target) wep = AttackWEP(target)
wep.run() wep.run()
Configuration.exit_gracefully(0)

26
py/AttackWPA.py → wifite/attack/wpa.py Normal file → Executable file
View File

@@ -1,15 +1,15 @@
#!/usr/bin/python2.7 #!/usr/bin/python2.7
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from Attack import Attack from ..model.attack import Attack
from Airodump import Airodump from ..tools.airodump import Airodump
from Aireplay import Aireplay from ..tools.aireplay import Aireplay
from Color import Color from ..config import Configuration
from Configuration import Configuration from ..util.color import Color
from Handshake import Handshake from ..util.process import Process
from Process import Process from ..util.timer import Timer
from CrackResultWPA import CrackResultWPA from ..model.handshake import Handshake
from Timer import Timer from ..model.wpa_result import CrackResultWPA
import time import time
import os import os
@@ -293,8 +293,14 @@ class AttackWPA(Attack):
Aireplay.deauth(target.bssid, client_mac=client, timeout=2) Aireplay.deauth(target.bssid, client_mac=client, timeout=2)
if __name__ == '__main__': if __name__ == '__main__':
from Target import Target Configuration.initialize(True)
from ..model.target import Target
fields = "A4:2B:8C:16:6B:3A, 2015-05-27 19:28:44, 2015-05-27 19:28:46, 11, 54e,WPA, WPA, , -58, 2, 0, 0. 0. 0. 0, 9, Test Router Please Ignore, ".split(',') fields = "A4:2B:8C:16:6B:3A, 2015-05-27 19:28:44, 2015-05-27 19:28:46, 11, 54e,WPA, WPA, , -58, 2, 0, 0. 0. 0. 0, 9, Test Router Please Ignore, ".split(',')
target = Target(fields) target = Target(fields)
wpa = AttackWPA(target) wpa = AttackWPA(target)
try:
wpa.run() wpa.run()
except KeyboardInterrupt:
Color.pl("")
pass
Configuration.exit_gracefully(0)

10
py/AttackWPS.py → wifite/attack/wps.py Normal file → Executable file
View File

@@ -1,11 +1,11 @@
#!/usr/bin/python2.7 #!/usr/bin/python2.7
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from Attack import Attack from ..model.attack import Attack
from Color import Color from ..util.color import Color
from Configuration import Configuration from ..config import Configuration
from Bully import Bully from ..tools.bully import Bully
from Reaver import Reaver from ..tools.reaver import Reaver
class AttackWPS(Attack): class AttackWPS(Attack):
def __init__(self, target): def __init__(self, target):

16
py/Configuration.py → wifite/config.py Normal file → Executable file
View File

@@ -1,8 +1,8 @@
#!/usr/bin/python2.7 #!/usr/bin/python2.7
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from Color import Color from util.color import Color
from Macchanger import Macchanger from tools.macchanger import Macchanger
import os import os
@@ -39,6 +39,7 @@ class Configuration(object):
Configuration.target_channel = None # User-defined channel to scan Configuration.target_channel = None # User-defined channel to scan
Configuration.target_essid = None # User-defined AP name Configuration.target_essid = None # User-defined AP name
Configuration.target_bssid = None # User-defined AP BSSID Configuration.target_bssid = None # User-defined AP BSSID
Configuration.ignore_essid = None # ESSIDs to ignore
Configuration.five_ghz = False # Scan 5Ghz channels Configuration.five_ghz = False # Scan 5Ghz channels
Configuration.show_bssids = False # Show BSSIDs in targets list Configuration.show_bssids = False # Show BSSIDs in targets list
Configuration.random_mac = False # Should generate a random Mac address at startup. Configuration.random_mac = False # Should generate a random Mac address at startup.
@@ -107,7 +108,7 @@ class Configuration(object):
def get_interface(): def get_interface():
if Configuration.interface is None: if Configuration.interface is None:
# Interface wasn't defined, select it! # Interface wasn't defined, select it!
from Airmon import Airmon from tools.airmon import Airmon
Configuration.interface = Airmon.ask() Configuration.interface = Airmon.ask()
if Configuration.random_mac: if Configuration.random_mac:
Macchanger.random() Macchanger.random()
@@ -116,7 +117,7 @@ class Configuration(object):
@staticmethod @staticmethod
def load_from_arguments(): def load_from_arguments():
''' Sets configuration values based on Argument.args object ''' ''' Sets configuration values based on Argument.args object '''
from Arguments import Arguments from args import Arguments
args = Arguments(Configuration).args args = Arguments(Configuration).args
if args.random_mac: if args.random_mac:
@@ -146,6 +147,9 @@ class Configuration(object):
if args.target_essid: if args.target_essid:
Configuration.target_essid = args.target_essid Configuration.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:
Configuration.ignore_essid = args.ignore_essid
Color.pl('{+} {C}option:{W} {O}ignoring ESSIDs that include {R}%s{W}' % args.ignore_essid)
if args.scan_time: if args.scan_time:
Configuration.scan_time = args.scan_time Configuration.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)
@@ -311,7 +315,7 @@ class Configuration(object):
''' Deletes temp and exist with the given code ''' ''' Deletes temp and exist with the given code '''
Configuration.delete_temp() Configuration.delete_temp()
Macchanger.reset_if_changed() Macchanger.reset_if_changed()
from Airmon import Airmon from tools.airmon import Airmon
if hasattr(Configuration, "interface") and Configuration.interface is not None and Airmon.base_interface is not None: if hasattr(Configuration, "interface") and Configuration.interface is not None and Airmon.base_interface is not None:
Airmon.stop(Configuration.interface) Airmon.stop(Configuration.interface)
Airmon.put_interface_up(Airmon.base_interface) Airmon.put_interface_up(Airmon.base_interface)
@@ -324,7 +328,7 @@ class Configuration(object):
@staticmethod @staticmethod
def dump(): def dump():
''' (Colorful) string representation of the configuration ''' ''' (Colorful) string representation of the configuration '''
from Color import Color from util.color import Color
max_len = 20 max_len = 20
for key in Configuration.__dict__.keys(): for key in Configuration.__dict__.keys():

0
wifite/model/__init__.py Normal file
View File

0
py/Attack.py → wifite/model/attack.py Normal file → Executable file
View File

0
py/Client.py → wifite/model/client.py Normal file → Executable file
View File

4
py/Handshake.py → wifite/model/handshake.py Normal file → Executable file
View File

@@ -1,8 +1,8 @@
#!/usr/bin/python2.7 #!/usr/bin/python2.7
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from Process import Process from ..util.process import Process
from Color import Color from ..util.color import Color
import re import re
import os import os

7
py/Interface.py → wifite/model/interface.py Normal file → Executable file
View File

@@ -1,7 +1,7 @@
#!/usr/bin/python2.7 #!/usr/bin/python2.7
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from Color import Color from ..util.color import Color
import re import re
@@ -78,9 +78,8 @@ class Interface(object):
@staticmethod @staticmethod
def get_mac(iface=None): def get_mac(iface=None):
from Configuration import Configuration from ..config import Configuration
from Process import Process from ..util.process import Process
import re
if iface is None: if iface is None:
Configuration.initialize() Configuration.initialize()

8
py/CrackResult.py → wifite/model/result.py Normal file → Executable file
View File

@@ -1,7 +1,7 @@
#!/usr/bin/python2.7 #!/usr/bin/python2.7
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from Color import Color from ..util.color import Color
import os import os
import time import time
@@ -50,20 +50,20 @@ class CrackResult(object):
def load(json): def load(json):
''' Returns an instance of the appropriate object given a json instance ''' ''' Returns an instance of the appropriate object given a json instance '''
if json['type'] == 'WPA': if json['type'] == 'WPA':
from CrackResultWPA import CrackResultWPA from .wpa_result import CrackResultWPA
result = CrackResultWPA(json['bssid'], result = CrackResultWPA(json['bssid'],
json['essid'], json['essid'],
json['handshake_file'], json['handshake_file'],
json['key']) json['key'])
elif json['type'] == 'WEP': elif json['type'] == 'WEP':
from CrackResultWEP import CrackResultWEP from .wep_result import CrackResultWEP
result = CrackResultWEP(json['bssid'], result = CrackResultWEP(json['bssid'],
json['essid'], json['essid'],
json['hex_key'], json['hex_key'],
json['ascii_key']) json['ascii_key'])
elif json['type'] == 'WPS': elif json['type'] == 'WPS':
from CrackResultWPS import CrackResultWPS from .wps_result import CrackResultWPS
result = CrackResultWPS(json['bssid'], result = CrackResultWPS(json['bssid'],
json['essid'], json['essid'],
json['pin'], json['pin'],

2
py/Target.py → wifite/model/target.py Normal file → Executable file
View File

@@ -1,7 +1,7 @@
#!/usr/bin/python2.7 #!/usr/bin/python2.7
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from Color import Color from ..util.color import Color
import re import re

4
py/CrackResultWEP.py → wifite/model/wep_result.py Normal file → Executable file
View File

@@ -1,8 +1,8 @@
#!/usr/bin/python2.7 #!/usr/bin/python2.7
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from Color import Color from ..util.color import Color
from CrackResult import CrackResult from .result import CrackResult
import time import time

4
py/CrackResultWPA.py → wifite/model/wpa_result.py Normal file → Executable file
View File

@@ -1,8 +1,8 @@
#!/usr/bin/python2.7 #!/usr/bin/python2.7
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from Color import Color from ..util.color import Color
from CrackResult import CrackResult from .result import CrackResult
class CrackResultWPA(CrackResult): class CrackResultWPA(CrackResult):
def __init__(self, bssid, essid, handshake_file, key): def __init__(self, bssid, essid, handshake_file, key):

4
py/CrackResultWPS.py → wifite/model/wps_result.py Normal file → Executable file
View File

@@ -1,8 +1,8 @@
#!/usr/bin/python2.7 #!/usr/bin/python2.7
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from Color import Color from ..util.color import Color
from CrackResult import CrackResult from ..model.result import CrackResult
import time import time

0
wifite/tools/__init__.py Normal file
View File

4
py/Aircrack.py → wifite/tools/aircrack.py Normal file → Executable file
View File

@@ -1,8 +1,8 @@
#!/usr/bin/python2.7 #!/usr/bin/python2.7
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from Process import Process from ..util.process import Process
from Configuration import Configuration from ..config import Configuration
import os import os

10
py/Aireplay.py → wifite/tools/aireplay.py Normal file → Executable file
View File

@@ -1,9 +1,9 @@
#!/usr/bin/python2.7 #!/usr/bin/python2.7
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from Configuration import Configuration from ..config import Configuration
from Process import Process from ..util.process import Process
from Timer import Timer from ..util.timer import Timer
import os, time, re import os, time, re
from threading import Thread from threading import Thread
@@ -314,7 +314,7 @@ class Aireplay(Thread):
if out.strip() == 'Wrote packet to: %s' % forged_file: if out.strip() == 'Wrote packet to: %s' % forged_file:
return forged_file return forged_file
else: else:
from Color import Color from ..util.color import Color
Color.pl('{!} {R}failed to forge packet from .xor file{W}') Color.pl('{!} {R}failed to forge packet from .xor file{W}')
Color.pl('output:\n"%s"' % out) Color.pl('output:\n"%s"' % out)
return None return None
@@ -385,7 +385,7 @@ if __name__ == '__main__':
t = WEPAttackType(t) t = WEPAttackType(t)
print t.name, type(t.name), t.value print t.name, type(t.name), t.value
from Target import Target from ..model.target import Target
fields = 'A4:2B:8C:16:6B:3A, 2015-05-27 19:28:44, 2015-05-27 19:28:46, 6, 54e, WEP, WEP, , -58, 2, 0, 0. 0. 0. 0, 9, Test Router Please Ignore, '.split(',') fields = 'A4:2B:8C:16:6B:3A, 2015-05-27 19:28:44, 2015-05-27 19:28:46, 6, 54e, WEP, WEP, , -58, 2, 0, 0. 0. 0. 0, 9, Test Router Please Ignore, '.split(',')
t = Target(fields) t = Target(fields)

35
py/Airmon.py → wifite/tools/airmon.py Normal file → Executable file
View File

@@ -1,10 +1,10 @@
#!/usr/bin/python2.7 #!/usr/bin/python2.7
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from Interface import Interface from ..model.interface import Interface
from Process import Process from ..util.process import Process
from Color import Color from ..util.color import Color
from Configuration import Configuration from ..config import Configuration
import re import re
import os import os
@@ -15,6 +15,10 @@ class Airmon(object):
base_interface = None base_interface = None
killed_network_manager = False killed_network_manager = False
#see if_arp.h
ARPHRD_ETHER = 1 #managed
ARPHRD_IEEE80211_RADIOTAP = 803 #monitor
def __init__(self): def __init__(self):
self.refresh() self.refresh()
@@ -56,6 +60,24 @@ class Airmon(object):
interfaces.append(Interface(fields)) interfaces.append(Interface(fields))
return interfaces return interfaces
@staticmethod
def start_baddriver(iface): #fix for bad drivers like the rtl8812AU
os.system("ifconfig %s down; iwconfig %s mode monitor; ifconfig %s up" % (iface, iface, iface))
with open("/sys/class/net/" + iface + "/type", "r") as f:
if (int(f.read()) == Airmon.ARPHRD_IEEE80211_RADIOTAP):
return iface
return None
@staticmethod
def stop_baddriver(iface):
os.system("ifconfig %s down; iwconfig %s mode managed; ifconfig %s up" % (iface, iface, iface))
with open("/sys/class/net/" + iface + "/type", "r") as f:
if (int(f.read()) == Airmon.ARPHRD_ETHER):
return iface
return None
@staticmethod @staticmethod
def start(iface): def start(iface):
''' '''
@@ -91,6 +113,8 @@ class Airmon(object):
if mon_iface is None: if mon_iface is None:
# Airmon did not enable monitor mode on an interface # Airmon did not enable monitor mode on an interface
mon_iface = Airmon.start_baddriver(iface)
if mon_iface is None:
Color.pl("{R}failed{W}") Color.pl("{R}failed{W}")
mon_ifaces = Airmon.get_interfaces_in_monitor_mode() mon_ifaces = Airmon.get_interfaces_in_monitor_mode()
@@ -134,6 +158,9 @@ class Airmon(object):
mon_iface = match.groups()[0] mon_iface = match.groups()[0]
break break
if not mon_iface:
mon_iface = Airmon.stop_baddriver(iface)
if mon_iface: if mon_iface:
Color.pl('{R}disabled %s{W}' % mon_iface) Color.pl('{R}disabled %s{W}' % mon_iface)
else: else:

18
py/Airodump.py → wifite/tools/airodump.py Normal file → Executable file
View File

@@ -1,11 +1,11 @@
#!/usr/bin/python2.7 #!/usr/bin/python2.7
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from Process import Process from .tshark import Tshark
from Configuration import Configuration from ..util.process import Process
from Target import Target from ..config import Configuration
from Client import Client from ..model.target import Target
from Tshark import Tshark from ..model.client import Client
import os, time import os, time
@@ -241,7 +241,9 @@ class Airodump(object):
essid = Configuration.target_essid essid = Configuration.target_essid
i = 0 i = 0
while i < len(result): while i < len(result):
if bssid and result[i].bssid.lower() != bssid.lower(): if result[i].essid is not None and Configuration.ignore_essid is not None and Configuration.ignore_essid.lower() in result[i].essid.lower():
result.pop(i)
elif bssid and result[i].bssid.lower() != bssid.lower():
result.pop(i) result.pop(i)
elif essid and result[i].essid and result[i].essid.lower() != essid.lower(): elif essid and result[i].essid and result[i].essid.lower() != essid.lower():
result.pop(i) result.pop(i)
@@ -278,7 +280,7 @@ class Airodump(object):
self.decloaking = True self.decloaking = True
self.decloaked_times[target.bssid] = now self.decloaked_times[target.bssid] = now
if Configuration.verbose > 1: if Configuration.verbose > 1:
from Color import Color from ..util.color import Color
verbout = " [?] Deauthing %s" % target.bssid verbout = " [?] Deauthing %s" % target.bssid
verbout += " (broadcast & %d clients)" % len(target.clients) verbout += " (broadcast & %d clients)" % len(target.clients)
Color.pe("\n{C}" + verbout + "{W}") Color.pe("\n{C}" + verbout + "{W}")
@@ -296,7 +298,7 @@ if __name__ == '__main__':
from time import sleep from time import sleep
sleep(7) sleep(7)
from Color import Color from ..util.color import Color
targets = airodump.get_targets() targets = airodump.get_targets()
for idx, target in enumerate(targets, start=1): for idx, target in enumerate(targets, start=1):

16
py/Bully.py → wifite/tools/bully.py Normal file → Executable file
View File

@@ -1,13 +1,13 @@
#!/usr/bin/python2.7 #!/usr/bin/python2.7
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from Attack import Attack from ..model.attack import Attack
from Airodump import Airodump from ..tools.airodump import Airodump
from Color import Color from ..util.color import Color
from Timer import Timer from ..util.timer import Timer
from Process import Process from ..util.process import Process
from Configuration import Configuration from ..config import Configuration
from CrackResultWPS import CrackResultWPS from ..model.wps_result import CrackResultWPS
import os, time, re import os, time, re
from threading import Thread from threading import Thread
@@ -217,7 +217,7 @@ class Bully(Attack):
if __name__ == '__main__': if __name__ == '__main__':
stdout = " [*] Pin is '11867722', key is '9a6f7997'" stdout = " [*] Pin is '11867722', key is '9a6f7997'"
Configuration.initialize(False) Configuration.initialize(False)
from Target import Target from ..model.target import Target
fields = 'AA:BB:CC:DD:EE:FF,2015-05-27 19:28:44,2015-05-27 19:28:46,1,54,WPA2,CCMP TKIP,PSK,-58,2,0,0.0.0.0,9,HOME-ABCD,'.split(',') fields = 'AA:BB:CC:DD:EE:FF,2015-05-27 19:28:44,2015-05-27 19:28:46,1,54,WPA2,CCMP TKIP,PSK,-58,2,0,0.0.0.0,9,HOME-ABCD,'.split(',')
target = Target(fields) target = Target(fields)
b = Bully(target) b = Bully(target)

14
py/Macchanger.py → wifite/tools/macchanger.py Normal file → Executable file
View File

@@ -1,8 +1,8 @@
#!/usr/bin/python2.7 #!/usr/bin/python2.7
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from Interface import Interface from ..model.interface import Interface
from Color import Color from ..util.color import Color
class Macchanger(object): class Macchanger(object):
is_init = False is_init = False
@@ -12,7 +12,7 @@ class Macchanger(object):
@classmethod @classmethod
def init(cls): def init(cls):
if cls.is_init: return if cls.is_init: return
from Configuration import Configuration from ..config import Configuration
iface = Configuration.interface iface = Configuration.interface
if type(iface) == Interface: if type(iface) == Interface:
iface = iface.name iface = iface.name
@@ -21,8 +21,8 @@ class Macchanger(object):
@classmethod @classmethod
def down_macch_up(cls, macch_option): def down_macch_up(cls, macch_option):
cls.init() cls.init()
from Process import Process from ..util.process import Process
from Configuration import Configuration from ..config import Configuration
iface = Configuration.interface iface = Configuration.interface
cmd = ["ifconfig", iface, "down"] cmd = ["ifconfig", iface, "down"]
@@ -61,7 +61,7 @@ class Macchanger(object):
# --permanent to reset to permanent MAC address # --permanent to reset to permanent MAC address
if not cls.down_macch_up("-p"): return if not cls.down_macch_up("-p"): return
Color.pl("\r{+} {C}macchanger{W}: Resetting MAC address...") Color.pl("\r{+} {C}macchanger{W}: Resetting MAC address...")
from Configuration import Configuration from ..config import Configuration
new_mac = Interface.get_mac(Configuration.interface) new_mac = Interface.get_mac(Configuration.interface)
Color.clear_entire_line() Color.clear_entire_line()
Color.pl("\r{+} {C}macchanger{W}: Reset MAC address back to {C}%s{W}" % new_mac) Color.pl("\r{+} {C}macchanger{W}: Reset MAC address back to {C}%s{W}" % new_mac)
@@ -71,7 +71,7 @@ class Macchanger(object):
# Use --permanent to use random MAC address # Use --permanent to use random MAC address
if not cls.down_macch_up("-r"): return if not cls.down_macch_up("-r"): return
cls.is_changed = True cls.is_changed = True
from Configuration import Configuration from ..config import Configuration
new_mac = Interface.get_mac(Configuration.interface) new_mac = Interface.get_mac(Configuration.interface)
Color.clear_entire_line() Color.clear_entire_line()
Color.pl("\r{+} {C}macchanger{W}: Changed MAC address to {C}%s{W}" % new_mac) Color.pl("\r{+} {C}macchanger{W}: Changed MAC address to {C}%s{W}" % new_mac)

12
py/Reaver.py → wifite/tools/reaver.py Normal file → Executable file
View File

@@ -1,12 +1,12 @@
#!/usr/bin/python2.7 #!/usr/bin/python2.7
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from Attack import Attack from ..model.attack import Attack
from Airodump import Airodump from ..config import Configuration
from Color import Color from ..util.color import Color
from Configuration import Configuration from ..util.process import Process
from CrackResultWPS import CrackResultWPS from ..tools.airodump import Airodump
from Process import Process from ..model.wps_result import CrackResultWPS
import os, time, re import os, time, re

4
py/Tshark.py → wifite/tools/tshark.py Normal file → Executable file
View File

@@ -1,7 +1,7 @@
#!/usr/bin/python2.7 #!/usr/bin/python2.7
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from Process import Process from ..util.process import Process
import re import re
class Tshark(object): class Tshark(object):
@@ -63,7 +63,7 @@ if __name__ == '__main__':
test_file = './tests/files/contains_wps_network.cap' test_file = './tests/files/contains_wps_network.cap'
target_bssid = 'A4:2B:8C:16:6B:3A' target_bssid = 'A4:2B:8C:16:6B:3A'
from Target import Target from ..model.target import Target
fields = [ fields = [
'A4:2B:8C:16:6B:3A', # BSSID 'A4:2B:8C:16:6B:3A', # BSSID
'2015-05-27 19:28:44', '2015-05-27 19:28:46', # Dates '2015-05-27 19:28:44', '2015-05-27 19:28:46', # Dates

0
wifite/util/__init__.py Normal file
View File

0
py/Color.py → wifite/util/color.py Normal file → Executable file
View File

9
py/CrackHandshake.py → wifite/util/crack.py Normal file → Executable file
View File

@@ -1,10 +1,11 @@
#!/usr/bin/python2.7 #!/usr/bin/python2.7
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from Process import Process from ..util.process import Process
from Color import Color from ..util.color import Color
from Configuration import Configuration from ..config import Configuration
from CrackResult import CrackResult from ..model.result import CrackResult
from datetime import datetime from datetime import datetime
import os import os

12
py/Process.py → wifite/util/process.py Normal file → Executable file
View File

@@ -4,8 +4,8 @@
import time import time
from subprocess import Popen, PIPE from subprocess import Popen, PIPE
from Color import Color from ..util.color import Color
from Configuration import Configuration from ..config import Configuration
class Process(object): class Process(object):
@@ -37,9 +37,9 @@ class Process(object):
(stdout, stderr) = pid.communicate() (stdout, stderr) = pid.communicate()
if Configuration.verbose > 1 and stdout.strip() != '': if Configuration.verbose > 1 and stdout.strip() != '':
Color.pe("{P} [stdout] %s{W}" % '\n [stdout] '.join(stdout.split('\n'))) Color.pe("{P} [stdout] %s{W}" % '\n [stdout] '.join(stdout.strip().split('\n')))
if Configuration.verbose > 1 and stderr.strip() != '': if Configuration.verbose > 1 and stderr.strip() != '':
Color.pe("{P} [stderr] %s{W}" % '\n [stderr] '.join(stderr.split('\n'))) Color.pe("{P} [stderr] %s{W}" % '\n [stderr] '.join(stderr.strip().split('\n')))
return (stdout, stderr) return (stdout, stderr)
@@ -92,14 +92,14 @@ class Process(object):
''' Waits for process to finish, returns stdout output ''' ''' Waits for process to finish, returns stdout output '''
self.get_output() self.get_output()
if Configuration.verbose > 1 and self.out.strip() != '': if Configuration.verbose > 1 and self.out.strip() != '':
Color.pe("{P} [stdout] %s{W}" % '\n [stdout] '.join(self.out.split('\n'))) Color.pe("{P} [stdout] %s{W}" % '\n [stdout] '.join(self.out.strip().split('\n')))
return self.out return self.out
def stderr(self): def stderr(self):
''' Waits for process to finish, returns stderr output ''' ''' Waits for process to finish, returns stderr output '''
self.get_output() self.get_output()
if Configuration.verbose > 1 and self.err.strip() != '': if Configuration.verbose > 1 and self.err.strip() != '':
Color.pe("{P} [stderr] %s{W}" % '\n [stderr] '.join(self.err.split('\n'))) Color.pe("{P} [stderr] %s{W}" % '\n [stderr] '.join(self.err.strip().split('\n')))
return self.err return self.err
def stdoutln(self): def stdoutln(self):

12
py/Scanner.py → wifite/util/scanner.py Normal file → Executable file
View File

@@ -1,10 +1,10 @@
#!/usr/bin/python2.7 #!/usr/bin/python2.7
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from Airodump import Airodump from ..tools.airodump import Airodump
from Color import Color from ..util.color import Color
from Target import Target from ..model.target import Target
from Configuration import Configuration from ..config import Configuration
from time import sleep, time from time import sleep, time
@@ -88,6 +88,8 @@ class Scanner(object):
return False return False
for target in self.targets: for target in self.targets:
if Configuration.wps_only and target.wps != True:
continue
if bssid and target.bssid and bssid.lower() == target.bssid.lower(): if bssid and target.bssid and bssid.lower() == target.bssid.lower():
self.target = target self.target = target
break break
@@ -120,7 +122,7 @@ class Scanner(object):
# 1) We have less targets than before, so we can't overwrite the previous list # 1) We have less targets than before, so we can't overwrite the previous list
# 2) The terminal can't display the targets without scrolling. # 2) The terminal can't display the targets without scrolling.
# Clear the screen. # Clear the screen.
from Process import Process from ..util.process import Process
Process.call('clear') Process.call('clear')
else: else:
# We can fit the targets in the terminal without scrolling # We can fit the targets in the terminal without scrolling

0
py/Timer.py → wifite/util/timer.py Normal file → Executable file
View File

258
wifite/wifite.py Executable file
View File

@@ -0,0 +1,258 @@
#!/usr/bin/python2.7
# -*- coding: utf-8 -*-
try:
from config import Configuration
except (ValueError, ImportError) as e:
raise Exception('You may need to run wifite from the root directory (which includes README.md)')
from util.scanner import Scanner
from util.process import Process
from util.color import Color
from util.crack import CrackHandshake
from attack.wep import AttackWEP
from attack.wpa import AttackWPA
from attack.wps import AttackWPS
from model.result import CrackResult
from model.handshake import Handshake
import json
import os
import sys
class Wifite(object):
def main(self):
''' Either performs action based on arguments, or starts attack scanning '''
if os.getuid() != 0:
Color.pl('{!} {R}error: {O}wifite{R} must be run as {O}root{W}')
Color.pl('{!} {O}re-run as: sudo ./Wifite.py{W}')
Configuration.exit_gracefully(0)
self.dependency_check()
Configuration.initialize(load_interface=False)
if Configuration.show_cracked:
self.display_cracked()
elif Configuration.check_handshake:
self.check_handshake(Configuration.check_handshake)
elif Configuration.crack_handshake:
CrackHandshake()
else:
Configuration.get_interface()
self.run()
def dependency_check(self):
''' Check that required programs are installed '''
required_apps = ['airmon-ng', 'iwconfig', 'ifconfig', 'aircrack-ng', 'aireplay-ng', 'airodump-ng', 'tshark']
optional_apps = ['packetforge-ng', 'reaver', 'bully', 'cowpatty', 'pyrit', 'stdbuf', 'macchanger']
missing_required = False
missing_optional = False
for app in required_apps:
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 not Process.exists(app):
missing_optional = True
Color.pl('{!} {O}warning: recommended app {R}%s{O} was not found' % app)
if missing_required:
Color.pl('{!} {R}required app(s) were not found, exiting.{W}')
sys.exit(-1)
if missing_optional:
Color.pl('{!} {O}recommended app(s) were not found')
Color.pl('{!} {O}wifite may not work as expected{W}')
def display_cracked(self):
''' Show cracked targets from cracked.txt '''
name = CrackResult.cracked_file
if not os.path.exists(name):
Color.pl('{!} {O}file {C}%s{O} not found{W}' % name)
return
with open(name, 'r') as fid:
cracked_targets = json.loads(fid.read())
if len(cracked_targets) == 0:
Color.pl('{!} {R}no results found in {O}%s{W}' % name)
else:
Color.pl('{+} displaying {G}%d {C}cracked target(s){W}\n' % len(cracked_targets))
for item in cracked_targets:
cr = CrackResult.load(item)
cr.dump()
Color.pl('')
def check_handshake(self, capfile):
''' Analyzes .cap file for handshake '''
if capfile == '<all>':
Color.pl('{+} checking all handshakes in {G}"./hs"{W} directory\n')
try:
capfiles = [os.path.join('hs', x) for x in os.listdir('hs') if x.endswith('.cap')]
except OSError, e:
capfiles = []
if len(capfiles) == 0:
Color.pl('{!} {R}no .cap files found in {O}"./hs"{W}\n')
else:
capfiles = [capfile]
for capfile in capfiles:
Color.pl('{+} checking for handshake in .cap file {C}%s{W}' % capfile)
if not os.path.exists(capfile):
Color.pl('{!} {O}.cap file {C}%s{O} not found{W}' % capfile)
return
hs = Handshake(capfile, bssid=Configuration.target_bssid, essid=Configuration.target_essid)
hs.analyze()
Color.pl('')
def run(self):
'''
Main program.
1) Scans for targets, asks user to select targets
2) Attacks each target
'''
s = Scanner()
if s.target:
# We found the target we want
targets = [s.target]
else:
targets = s.select_targets()
attacked_targets = 0
targets_remaining = len(targets)
for idx, t in enumerate(targets, start=1):
attacked_targets += 1
targets_remaining -= 1
Color.pl('\n{+} ({G}%d{W}/{G}%d{W})' % (idx, len(targets)) +
' starting attacks against {C}%s{W} ({C}%s{W})'
% (t.bssid, t.essid if t.essid_known else "{O}ESSID unknown"))
if 'WEP' in t.encryption:
attack = AttackWEP(t)
elif 'WPA' in t.encryption:
if t.wps:
attack = AttackWPS(t)
result = False
try:
result = attack.run()
except Exception as e:
Color.pl("\n{!} {R}Error: {O}%s" % str(e))
if Configuration.verbose > 0 or Configuration.print_stack_traces:
Color.pl('\n{!} {O}Full stack trace below')
from traceback import format_exc
Color.p('\n{!} ')
err = format_exc().strip()
err = err.replace('\n', '\n{!} {C} ')
err = err.replace(' File', '{W}File')
err = err.replace(' Exception: ', '{R}Exception: {O}')
Color.pl(err)
except KeyboardInterrupt:
Color.pl('\n{!} {O}interrupted{W}\n')
if not self.user_wants_to_continue(targets_remaining, 1):
break
if result and attack.success:
# We cracked it.
attack.crack_result.save()
continue
else:
# WPS failed, try WPA handshake.
attack = AttackWPA(t)
else:
# Not using WPS, try WPA handshake.
attack = AttackWPA(t)
else:
Color.pl("{!} {R}Error: {O}unable to attack: encryption not WEP or WPA")
continue
try:
attack.run()
except Exception, e:
Color.pl("\n{!} {R}Error: {O}%s" % str(e))
if Configuration.verbose > 0 or True:
Color.pl('\n{!} {O}Full stack trace below')
from traceback import format_exc
Color.p('\n{!} ')
err = format_exc().strip()
err = err.replace('\n', '\n{!} {C} ')
err = err.replace(' File', '{W}File')
err = err.replace(' Exception: ', '{R}Exception: {O}')
Color.pl(err)
except KeyboardInterrupt:
Color.pl('\n{!} {O}interrupted{W}\n')
if not self.user_wants_to_continue(targets_remaining):
break
if attack.success:
attack.crack_result.save()
Color.pl("{+} Finished attacking {C}%d{W} target(s), exiting" % attacked_targets)
def print_banner(self):
""" Displays ASCII art of the highest caliber. """
Color.pl('''\
{G} . {GR}{D} {W}{G} . {W}
{G}.´ · .{GR}{D} {W}{G}. · `. {G}wifite {D}%s{W}
{G}: : : {GR}{D} (¯) {W}{G} : : : {W}{D}automated wireless auditor
{G}`. · `{GR}{D}\ {W}{G}´ · .´ {C}{D}https://github.com/derv82/wifite2
{G} ` {GR}{D}/¯¯¯\{W}{G} ´ {W}
''' % Configuration.version)
def user_wants_to_continue(self, targets_remaining, attacks_remaining=0):
''' Asks user if attacks should continue onto other targets '''
if attacks_remaining == 0 and targets_remaining == 0:
# No targets or attacksleft, drop out
return
prompt_list = []
if attacks_remaining > 0:
prompt_list.append(Color.s('{C}%d{W} attack(s)' % attacks_remaining))
if targets_remaining > 0:
prompt_list.append(Color.s('{C}%d{W} target(s)' % targets_remaining))
prompt = ' and '.join(prompt_list)
Color.pl('{+} %s remain, do you want to continue?' % prompt)
prompt = Color.s('{+} type {G}c{W} to {G}continue{W}' +
' or {R}s{W} to {R}stop{W}: ')
if raw_input(prompt).lower().startswith('s'):
return False
else:
return True
def run():
w = Wifite()
w.print_banner()
try:
w.main()
except Exception, e:
Color.pl('\n{!} {R}Error:{O} %s{W}' % str(e))
if Configuration.verbose > 0 or True:
Color.pl('\n{!} {O}Full stack trace below')
from traceback import format_exc
Color.p('\n{!} ')
err = format_exc().strip()
err = err.replace('\n', '\n{!} {C} ')
err = err.replace(' File', '{W}File')
err = err.replace(' Exception: ', '{R}Exception: {O}')
Color.pl(err)
Color.pl('\n{!} {R}Exiting{W}\n')
except KeyboardInterrupt:
Color.pl('\n{!} {O}interrupted, shutting down...{W}')
Configuration.exit_gracefully(0)
if __name__ == '__main__':
run()