diff --git a/Wifite.py b/Wifite.py index 0a15cd7..cc74bec 100755 --- a/Wifite.py +++ b/Wifite.py @@ -1,239 +1 @@ -#!/usr/bin/python2.7 -# -*- coding: utf-8 -*- - -from py.Configuration import Configuration -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 -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 == '': - 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) +python -m wifite.wifite diff --git a/py/__init__.py b/tests/__init__.py similarity index 100% rename from py/__init__.py rename to tests/__init__.py diff --git a/py/tests/files/airmon.output b/tests/files/airmon.output similarity index 100% rename from py/tests/files/airmon.output rename to tests/files/airmon.output diff --git a/py/tests/files/airodump.csv b/tests/files/airodump.csv similarity index 100% rename from py/tests/files/airodump.csv rename to tests/files/airodump.csv diff --git a/py/tests/files/contains_wps_network.cap b/tests/files/contains_wps_network.cap similarity index 100% rename from py/tests/files/contains_wps_network.cap rename to tests/files/contains_wps_network.cap diff --git a/py/tests/files/handshake_exists.cap b/tests/files/handshake_exists.cap similarity index 100% rename from py/tests/files/handshake_exists.cap rename to tests/files/handshake_exists.cap diff --git a/py/tests/files/handshake_exists.cap.stripped.tshark b/tests/files/handshake_exists.cap.stripped.tshark similarity index 100% rename from py/tests/files/handshake_exists.cap.stripped.tshark rename to tests/files/handshake_exists.cap.stripped.tshark diff --git a/py/tests/files/handshake_not_exists.cap b/tests/files/handshake_not_exists.cap similarity index 100% rename from py/tests/files/handshake_not_exists.cap rename to tests/files/handshake_not_exists.cap diff --git a/py/tests/files/wep-crackable.ivs b/tests/files/wep-crackable.ivs similarity index 100% rename from py/tests/files/wep-crackable.ivs rename to tests/files/wep-crackable.ivs diff --git a/py/tests/files/wep-uncrackable.ivs b/tests/files/wep-uncrackable.ivs similarity index 100% rename from py/tests/files/wep-uncrackable.ivs rename to tests/files/wep-uncrackable.ivs diff --git a/py/tests/test_Handshake.py b/tests/test_Handshake.py similarity index 100% rename from py/tests/test_Handshake.py rename to tests/test_Handshake.py diff --git a/py/tests/test_Target.py b/tests/test_Target.py similarity index 100% rename from py/tests/test_Target.py rename to tests/test_Target.py diff --git a/py/tests/__init__.py b/wifite/__init__.py similarity index 100% rename from py/tests/__init__.py rename to wifite/__init__.py diff --git a/py/Arguments.py b/wifite/args.py old mode 100644 new mode 100755 similarity index 99% rename from py/Arguments.py rename to wifite/args.py index 3fb6b2e..aea1682 --- a/py/Arguments.py +++ b/wifite/args.py @@ -1,8 +1,9 @@ #!/usr/bin/python2.7 # -*- coding: utf-8 -*- +from util.color import Color + import argparse -from Color import Color class Arguments(object): ''' Holds arguments used by the Wifite ''' diff --git a/wifite/attack/__init__.py b/wifite/attack/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/py/AttackWEP.py b/wifite/attack/wep.py old mode 100644 new mode 100755 similarity index 98% rename from py/AttackWEP.py rename to wifite/attack/wep.py index 1f94dee..07cb724 --- a/py/AttackWEP.py +++ b/wifite/attack/wep.py @@ -1,14 +1,14 @@ #!/usr/bin/python2.7 # -*- coding: utf-8 -*- -from Attack import Attack -from Airodump import Airodump -from Aireplay import Aireplay, WEPAttackType -from Aircrack import Aircrack -from Configuration import Configuration -from Interface import Interface -from Color import Color -from CrackResultWEP import CrackResultWEP +from ..model.attack import Attack +from ..tools.airodump import Airodump +from ..tools.aireplay import Aireplay, WEPAttackType +from ..tools.aircrack import Aircrack +from ..config import Configuration +from ..model.interface import Interface +from ..util.color import Color +from ..model.wep_result import CrackResultWEP import time diff --git a/py/AttackWPA.py b/wifite/attack/wpa.py old mode 100644 new mode 100755 similarity index 97% rename from py/AttackWPA.py rename to wifite/attack/wpa.py index d2e273c..316fa57 --- a/py/AttackWPA.py +++ b/wifite/attack/wpa.py @@ -1,15 +1,15 @@ #!/usr/bin/python2.7 # -*- coding: utf-8 -*- -from Attack import Attack -from Airodump import Airodump -from Aireplay import Aireplay -from Color import Color -from Configuration import Configuration -from Handshake import Handshake -from Process import Process -from CrackResultWPA import CrackResultWPA -from Timer import Timer +from ..model.attack import Attack +from ..tools.airodump import Airodump +from ..tools.aireplay import Aireplay +from ..config import Configuration +from ..util.color import Color +from ..util.process import Process +from ..util.timer import Timer +from ..model.handshake import Handshake +from ..model.wpa_result import CrackResultWPA import time import os diff --git a/py/AttackWPS.py b/wifite/attack/wps.py old mode 100644 new mode 100755 similarity index 89% rename from py/AttackWPS.py rename to wifite/attack/wps.py index 073b102..906a25f --- a/py/AttackWPS.py +++ b/wifite/attack/wps.py @@ -1,11 +1,11 @@ #!/usr/bin/python2.7 # -*- coding: utf-8 -*- -from Attack import Attack -from Color import Color -from Configuration import Configuration -from Bully import Bully -from Reaver import Reaver +from ..model.attack import Attack +from ..util.color import Color +from ..config import Configuration +from ..tools.bully import Bully +from ..tools.reaver import Reaver class AttackWPS(Attack): def __init__(self, target): diff --git a/py/Configuration.py b/wifite/config.py old mode 100644 new mode 100755 similarity index 98% rename from py/Configuration.py rename to wifite/config.py index f5e36c3..57fe12c --- a/py/Configuration.py +++ b/wifite/config.py @@ -1,8 +1,8 @@ #!/usr/bin/python2.7 # -*- coding: utf-8 -*- -from Color import Color -from Macchanger import Macchanger +from util.color import Color +from tools.macchanger import Macchanger import os @@ -107,7 +107,7 @@ class Configuration(object): def get_interface(): if Configuration.interface is None: # Interface wasn't defined, select it! - from Airmon import Airmon + from tools.airmon import Airmon Configuration.interface = Airmon.ask() if Configuration.random_mac: Macchanger.random() @@ -116,7 +116,7 @@ class Configuration(object): @staticmethod def load_from_arguments(): ''' Sets configuration values based on Argument.args object ''' - from Arguments import Arguments + from args import Arguments args = Arguments(Configuration).args if args.random_mac: @@ -311,7 +311,7 @@ class Configuration(object): ''' Deletes temp and exist with the given code ''' Configuration.delete_temp() 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: Airmon.stop(Configuration.interface) Airmon.put_interface_up(Airmon.base_interface) @@ -324,7 +324,7 @@ class Configuration(object): @staticmethod def dump(): ''' (Colorful) string representation of the configuration ''' - from Color import Color + from util.color import Color max_len = 20 for key in Configuration.__dict__.keys(): diff --git a/py/CrackHandshake.py b/wifite/crack.py old mode 100644 new mode 100755 similarity index 97% rename from py/CrackHandshake.py rename to wifite/crack.py index c8eb261..b1a3393 --- a/py/CrackHandshake.py +++ b/wifite/crack.py @@ -1,10 +1,11 @@ #!/usr/bin/python2.7 # -*- coding: utf-8 -*- -from Process import Process -from Color import Color -from Configuration import Configuration -from CrackResult import CrackResult +from util.process import Process +from util.color import Color +from config import Configuration +from model.result import CrackResult + from datetime import datetime import os diff --git a/wifite/model/__init__.py b/wifite/model/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/py/Attack.py b/wifite/model/attack.py old mode 100644 new mode 100755 similarity index 100% rename from py/Attack.py rename to wifite/model/attack.py diff --git a/py/Client.py b/wifite/model/client.py old mode 100644 new mode 100755 similarity index 100% rename from py/Client.py rename to wifite/model/client.py diff --git a/py/Handshake.py b/wifite/model/handshake.py old mode 100644 new mode 100755 similarity index 99% rename from py/Handshake.py rename to wifite/model/handshake.py index 78ce6a6..a93df72 --- a/py/Handshake.py +++ b/wifite/model/handshake.py @@ -1,8 +1,8 @@ #!/usr/bin/python2.7 # -*- coding: utf-8 -*- -from Process import Process -from Color import Color +from ..util.process import Process +from ..util.color import Color import re import os diff --git a/py/Interface.py b/wifite/model/interface.py old mode 100644 new mode 100755 similarity index 98% rename from py/Interface.py rename to wifite/model/interface.py index b08b89a..f11b745 --- a/py/Interface.py +++ b/wifite/model/interface.py @@ -1,7 +1,7 @@ #!/usr/bin/python2.7 # -*- coding: utf-8 -*- -from Color import Color +from wifite.util.color import Color import re diff --git a/py/CrackResult.py b/wifite/model/result.py old mode 100644 new mode 100755 similarity index 99% rename from py/CrackResult.py rename to wifite/model/result.py index 0e8768c..4bf81f8 --- a/py/CrackResult.py +++ b/wifite/model/result.py @@ -1,7 +1,7 @@ #!/usr/bin/python2.7 # -*- coding: utf-8 -*- -from Color import Color +from ..util.color import Color import os import time diff --git a/py/Target.py b/wifite/model/target.py old mode 100644 new mode 100755 similarity index 99% rename from py/Target.py rename to wifite/model/target.py index bd68a99..c35f878 --- a/py/Target.py +++ b/wifite/model/target.py @@ -1,7 +1,7 @@ #!/usr/bin/python2.7 # -*- coding: utf-8 -*- -from Color import Color +from wifite.util.color import Color import re diff --git a/py/CrackResultWEP.py b/wifite/model/wep_result.py old mode 100644 new mode 100755 similarity index 94% rename from py/CrackResultWEP.py rename to wifite/model/wep_result.py index 31f73d9..4bbdf98 --- a/py/CrackResultWEP.py +++ b/wifite/model/wep_result.py @@ -1,8 +1,8 @@ #!/usr/bin/python2.7 # -*- coding: utf-8 -*- -from Color import Color -from CrackResult import CrackResult +from ..util.color import Color +from .result import CrackResult import time diff --git a/py/CrackResultWPA.py b/wifite/model/wpa_result.py old mode 100644 new mode 100755 similarity index 96% rename from py/CrackResultWPA.py rename to wifite/model/wpa_result.py index f7b348e..dbdea78 --- a/py/CrackResultWPA.py +++ b/wifite/model/wpa_result.py @@ -1,8 +1,8 @@ #!/usr/bin/python2.7 # -*- coding: utf-8 -*- -from Color import Color -from CrackResult import CrackResult +from ..util.color import Color +from .result import CrackResult class CrackResultWPA(CrackResult): def __init__(self, bssid, essid, handshake_file, key): diff --git a/py/CrackResultWPS.py b/wifite/model/wps_result.py old mode 100644 new mode 100755 similarity index 94% rename from py/CrackResultWPS.py rename to wifite/model/wps_result.py index 87b543c..5673101 --- a/py/CrackResultWPS.py +++ b/wifite/model/wps_result.py @@ -1,8 +1,8 @@ #!/usr/bin/python2.7 # -*- coding: utf-8 -*- -from Color import Color -from CrackResult import CrackResult +from ..util.color import Color +from ..model.result import CrackResult import time diff --git a/wifite/tools/__init__.py b/wifite/tools/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/py/Aircrack.py b/wifite/tools/aircrack.py old mode 100644 new mode 100755 similarity index 96% rename from py/Aircrack.py rename to wifite/tools/aircrack.py index 751b128..d0c73f0 --- a/py/Aircrack.py +++ b/wifite/tools/aircrack.py @@ -1,8 +1,8 @@ #!/usr/bin/python2.7 # -*- coding: utf-8 -*- -from Process import Process -from Configuration import Configuration +from ..util.process import Process +from ..config import Configuration import os diff --git a/py/Aireplay.py b/wifite/tools/aireplay.py old mode 100644 new mode 100755 similarity index 99% rename from py/Aireplay.py rename to wifite/tools/aireplay.py index 6d5b799..557062e --- a/py/Aireplay.py +++ b/wifite/tools/aireplay.py @@ -1,9 +1,9 @@ #!/usr/bin/python2.7 # -*- coding: utf-8 -*- -from Configuration import Configuration -from Process import Process -from Timer import Timer +from ..config import Configuration +from ..util.process import Process +from ..util.timer import Timer import os, time, re from threading import Thread diff --git a/py/Airmon.py b/wifite/tools/airmon.py old mode 100644 new mode 100755 similarity index 98% rename from py/Airmon.py rename to wifite/tools/airmon.py index f12706c..8853033 --- a/py/Airmon.py +++ b/wifite/tools/airmon.py @@ -1,10 +1,10 @@ #!/usr/bin/python2.7 # -*- coding: utf-8 -*- -from Interface import Interface -from Process import Process -from Color import Color -from Configuration import Configuration +from ..model.interface import Interface +from ..util.process import Process +from ..util.color import Color +from ..config import Configuration import re import os diff --git a/py/Airodump.py b/wifite/tools/airodump.py old mode 100644 new mode 100755 similarity index 98% rename from py/Airodump.py rename to wifite/tools/airodump.py index 3a5fb46..cf1a522 --- a/py/Airodump.py +++ b/wifite/tools/airodump.py @@ -1,11 +1,11 @@ #!/usr/bin/python2.7 # -*- coding: utf-8 -*- -from Process import Process -from Configuration import Configuration -from Target import Target -from Client import Client -from Tshark import Tshark +from wifite.util.process import Process +from wifite.config import Configuration +from wifite.model.target import Target +from wifite.model.client import Client +from wifite.tools.tshark import Tshark import os, time diff --git a/py/Bully.py b/wifite/tools/bully.py old mode 100644 new mode 100755 similarity index 97% rename from py/Bully.py rename to wifite/tools/bully.py index 2cd72fc..e6f7b5d --- a/py/Bully.py +++ b/wifite/tools/bully.py @@ -1,13 +1,13 @@ #!/usr/bin/python2.7 # -*- coding: utf-8 -*- -from Attack import Attack -from Airodump import Airodump -from Color import Color -from Timer import Timer -from Process import Process -from Configuration import Configuration -from CrackResultWPS import CrackResultWPS +from ..model.attack import Attack +from ..tools.airodump import Airodump +from ..util.color import Color +from ..util.timer import Timer +from ..util.process import Process +from ..config import Configuration +from ..model.wps_result import CrackResultWPS import os, time, re from threading import Thread diff --git a/py/Macchanger.py b/wifite/tools/macchanger.py old mode 100644 new mode 100755 similarity index 97% rename from py/Macchanger.py rename to wifite/tools/macchanger.py index 5876bdc..c87153a --- a/py/Macchanger.py +++ b/wifite/tools/macchanger.py @@ -1,8 +1,8 @@ #!/usr/bin/python2.7 # -*- coding: utf-8 -*- -from Interface import Interface -from Color import Color +from wifite.model.interface import Interface +from wifite.util.color import Color class Macchanger(object): is_init = False diff --git a/py/Reaver.py b/wifite/tools/reaver.py old mode 100644 new mode 100755 similarity index 98% rename from py/Reaver.py rename to wifite/tools/reaver.py index 4d84373..5a3fe48 --- a/py/Reaver.py +++ b/wifite/tools/reaver.py @@ -1,12 +1,12 @@ #!/usr/bin/python2.7 # -*- coding: utf-8 -*- -from Attack import Attack -from Airodump import Airodump -from Color import Color -from Configuration import Configuration -from CrackResultWPS import CrackResultWPS -from Process import Process +from ..model.attack import Attack +from ..config import Configuration +from ..util.color import Color +from ..util.process import Process +from ..tools.airodump import Airodump +from ..model.wps_result import CrackResultWPS import os, time, re diff --git a/py/Tshark.py b/wifite/tools/tshark.py old mode 100644 new mode 100755 similarity index 98% rename from py/Tshark.py rename to wifite/tools/tshark.py index b55ac73..f622ab1 --- a/py/Tshark.py +++ b/wifite/tools/tshark.py @@ -1,7 +1,7 @@ #!/usr/bin/python2.7 # -*- coding: utf-8 -*- -from Process import Process +from wifite.util.process import Process import re class Tshark(object): diff --git a/wifite/util/__init__.py b/wifite/util/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/py/Color.py b/wifite/util/color.py old mode 100644 new mode 100755 similarity index 100% rename from py/Color.py rename to wifite/util/color.py diff --git a/py/Process.py b/wifite/util/process.py old mode 100644 new mode 100755 similarity index 98% rename from py/Process.py rename to wifite/util/process.py index ef78de1..d0769e4 --- a/py/Process.py +++ b/wifite/util/process.py @@ -4,8 +4,8 @@ import time from subprocess import Popen, PIPE -from Color import Color -from Configuration import Configuration +from wifite.util.color import Color +from wifite.config import Configuration class Process(object): diff --git a/py/Scanner.py b/wifite/util/scanner.py old mode 100644 new mode 100755 similarity index 98% rename from py/Scanner.py rename to wifite/util/scanner.py index 3af1f4c..17b5c62 --- a/py/Scanner.py +++ b/wifite/util/scanner.py @@ -1,10 +1,10 @@ #!/usr/bin/python2.7 # -*- coding: utf-8 -*- -from Airodump import Airodump -from Color import Color -from Target import Target -from Configuration import Configuration +from wifite.tools.airodump import Airodump +from wifite.util.color import Color +from wifite.model.target import Target +from wifite.config import Configuration from time import sleep, time diff --git a/py/Timer.py b/wifite/util/timer.py old mode 100644 new mode 100755 similarity index 100% rename from py/Timer.py rename to wifite/util/timer.py diff --git a/wifite/wifite.py b/wifite/wifite.py new file mode 100755 index 0000000..f03dbca --- /dev/null +++ b/wifite/wifite.py @@ -0,0 +1,239 @@ +#!/usr/bin/python2.7 +# -*- coding: utf-8 -*- + +from config import Configuration +from util.scanner import Scanner +from util.color import Color +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 +from crack import CrackHandshake +from util.process import Process + +from json import loads +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 == '': + 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)