From 622ec064a50fb085c13a045f1bbe543d4cbc71f0 Mon Sep 17 00:00:00 2001 From: derv82 Date: Sat, 17 Mar 2018 04:04:05 -0400 Subject: [PATCH 01/12] Massive refactor/renaming. No more upper-case filenames. --- Wifite.py | 240 +----------------- {py => tests}/__init__.py | 0 {py/tests => tests}/files/airmon.output | 0 {py/tests => tests}/files/airodump.csv | 0 .../files/contains_wps_network.cap | Bin .../files/handshake_exists.cap | Bin .../handshake_exists.cap.stripped.tshark | Bin .../files/handshake_not_exists.cap | Bin {py/tests => tests}/files/wep-crackable.ivs | Bin {py/tests => tests}/files/wep-uncrackable.ivs | Bin {py/tests => tests}/test_Handshake.py | 0 {py/tests => tests}/test_Target.py | 0 {py/tests => wifite}/__init__.py | 0 py/Arguments.py => wifite/args.py | 3 +- wifite/attack/__init__.py | 0 py/AttackWEP.py => wifite/attack/wep.py | 16 +- py/AttackWPA.py => wifite/attack/wpa.py | 18 +- py/AttackWPS.py => wifite/attack/wps.py | 10 +- py/Configuration.py => wifite/config.py | 12 +- py/CrackHandshake.py => wifite/crack.py | 9 +- wifite/model/__init__.py | 0 py/Attack.py => wifite/model/attack.py | 0 py/Client.py => wifite/model/client.py | 0 py/Handshake.py => wifite/model/handshake.py | 4 +- py/Interface.py => wifite/model/interface.py | 2 +- py/CrackResult.py => wifite/model/result.py | 2 +- py/Target.py => wifite/model/target.py | 2 +- .../model/wep_result.py | 4 +- .../model/wpa_result.py | 4 +- .../model/wps_result.py | 4 +- wifite/tools/__init__.py | 0 py/Aircrack.py => wifite/tools/aircrack.py | 4 +- py/Aireplay.py => wifite/tools/aireplay.py | 6 +- py/Airmon.py => wifite/tools/airmon.py | 8 +- py/Airodump.py => wifite/tools/airodump.py | 10 +- py/Bully.py => wifite/tools/bully.py | 14 +- .../tools/macchanger.py | 4 +- py/Reaver.py => wifite/tools/reaver.py | 12 +- py/Tshark.py => wifite/tools/tshark.py | 2 +- wifite/util/__init__.py | 0 py/Color.py => wifite/util/color.py | 0 py/Process.py => wifite/util/process.py | 4 +- py/Scanner.py => wifite/util/scanner.py | 8 +- py/Timer.py => wifite/util/timer.py | 0 wifite/wifite.py | 239 +++++++++++++++++ 45 files changed, 322 insertions(+), 319 deletions(-) rename {py => tests}/__init__.py (100%) rename {py/tests => tests}/files/airmon.output (100%) rename {py/tests => tests}/files/airodump.csv (100%) rename {py/tests => tests}/files/contains_wps_network.cap (100%) rename {py/tests => tests}/files/handshake_exists.cap (100%) rename {py/tests => tests}/files/handshake_exists.cap.stripped.tshark (100%) rename {py/tests => tests}/files/handshake_not_exists.cap (100%) rename {py/tests => tests}/files/wep-crackable.ivs (100%) rename {py/tests => tests}/files/wep-uncrackable.ivs (100%) rename {py/tests => tests}/test_Handshake.py (100%) rename {py/tests => tests}/test_Target.py (100%) rename {py/tests => wifite}/__init__.py (100%) rename py/Arguments.py => wifite/args.py (99%) mode change 100644 => 100755 create mode 100644 wifite/attack/__init__.py rename py/AttackWEP.py => wifite/attack/wep.py (98%) mode change 100644 => 100755 rename py/AttackWPA.py => wifite/attack/wpa.py (97%) mode change 100644 => 100755 rename py/AttackWPS.py => wifite/attack/wps.py (89%) mode change 100644 => 100755 rename py/Configuration.py => wifite/config.py (98%) mode change 100644 => 100755 rename py/CrackHandshake.py => wifite/crack.py (97%) mode change 100644 => 100755 create mode 100644 wifite/model/__init__.py rename py/Attack.py => wifite/model/attack.py (100%) mode change 100644 => 100755 rename py/Client.py => wifite/model/client.py (100%) mode change 100644 => 100755 rename py/Handshake.py => wifite/model/handshake.py (99%) mode change 100644 => 100755 rename py/Interface.py => wifite/model/interface.py (98%) mode change 100644 => 100755 rename py/CrackResult.py => wifite/model/result.py (99%) mode change 100644 => 100755 rename py/Target.py => wifite/model/target.py (99%) mode change 100644 => 100755 rename py/CrackResultWEP.py => wifite/model/wep_result.py (94%) mode change 100644 => 100755 rename py/CrackResultWPA.py => wifite/model/wpa_result.py (96%) mode change 100644 => 100755 rename py/CrackResultWPS.py => wifite/model/wps_result.py (94%) mode change 100644 => 100755 create mode 100644 wifite/tools/__init__.py rename py/Aircrack.py => wifite/tools/aircrack.py (96%) mode change 100644 => 100755 rename py/Aireplay.py => wifite/tools/aireplay.py (99%) mode change 100644 => 100755 rename py/Airmon.py => wifite/tools/airmon.py (98%) mode change 100644 => 100755 rename py/Airodump.py => wifite/tools/airodump.py (98%) mode change 100644 => 100755 rename py/Bully.py => wifite/tools/bully.py (97%) mode change 100644 => 100755 rename py/Macchanger.py => wifite/tools/macchanger.py (97%) mode change 100644 => 100755 rename py/Reaver.py => wifite/tools/reaver.py (98%) mode change 100644 => 100755 rename py/Tshark.py => wifite/tools/tshark.py (98%) mode change 100644 => 100755 create mode 100644 wifite/util/__init__.py rename py/Color.py => wifite/util/color.py (100%) mode change 100644 => 100755 rename py/Process.py => wifite/util/process.py (98%) mode change 100644 => 100755 rename py/Scanner.py => wifite/util/scanner.py (98%) mode change 100644 => 100755 rename py/Timer.py => wifite/util/timer.py (100%) mode change 100644 => 100755 create mode 100755 wifite/wifite.py 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) From f4a11f9acb350babd0e9ace630c0f4f70cec7fe9 Mon Sep 17 00:00:00 2001 From: derv82 Date: Sat, 17 Mar 2018 04:15:19 -0400 Subject: [PATCH 02/12] Refactor arguments --- Wifite.py | 2 +- wifite/args.py | 92 +++++++++++++++++++++++++++++++++++--------------- 2 files changed, 66 insertions(+), 28 deletions(-) diff --git a/Wifite.py b/Wifite.py index cc74bec..de3e6e5 100755 --- a/Wifite.py +++ b/Wifite.py @@ -1 +1 @@ -python -m wifite.wifite +python2 -m wifite.wifite $@ diff --git a/wifite/args.py b/wifite/args.py index aea1682..f3c3a35 100755 --- a/wifite/args.py +++ b/wifite/args.py @@ -7,10 +7,12 @@ import argparse class Arguments(object): ''' Holds arguments used by the Wifite ''' - def __init__(self, Configuration): - self.args = self.get_arguments(Configuration) - def get_arguments(self, Configuration): + def __init__(self, config): + self.args = self.get_arguments(config) + + + def get_arguments(self, config): ''' Returns parser.args() containing all program arguments ''' parser = argparse.ArgumentParser(usage=argparse.SUPPRESS, @@ -18,7 +20,24 @@ class Arguments(object): # Global variables glob = parser.add_argument_group('SETTINGS') + self._add_global_args(glob, config) + wep_group = parser.add_argument_group('WEP-RELATED') + self._add_wep_args(wep_group, config) + + wpa_group = parser.add_argument_group('WPA-RELATED') + self._add_wpa_args(wpa_group, config) + + wps_group = parser.add_argument_group('WPS-RELATED') + self._add_wps_args(wps_group, config) + + commands_group = parser.add_argument_group('COMMANDS') + self._add_command_args(commands_group, config) + + return parser.parse_args() + + + def _add_global_args(self, glob, config): glob.add_argument('-i', action='store', dest='interface', @@ -85,7 +104,7 @@ class Arguments(object): dest='num_deauths', metavar="[num]", default=None, - help=Color.s('Number of deauth packets to send (default: {G}%d{W})' % Configuration.num_deauths)) + help=Color.s('Number of deauth packets to send (default: {G}%d{W})' % config.num_deauths)) glob.add_argument('--pillage', help=argparse.SUPPRESS, action='store', dest='scan_time', nargs='?', const=10, type=int) glob.add_argument('-p', @@ -104,132 +123,150 @@ class Arguments(object): dest='verbose', help=Color.s('Verbose mode, prints more lines (default: {G}quiet{W})')) + + def _add_wep_args(self, wep, config): # WEP - wep = parser.add_argument_group('WEP-RELATED') wep.add_argument('--wep', action='store_true', dest='wep_filter', 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('--require-fakeauth', action='store_true', dest='require_fakeauth', 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('--pps', action='store', dest='wep_pps', metavar='[pps]', type=int, help=Color.s('Packets Per Second to replay (default: {G}%d pps{W})') - % Configuration.wep_pps) + % config.wep_pps) wep.add_argument('-pps', help=argparse.SUPPRESS, action='store', dest='wep_pps', type=int) + wep.add_argument('--wept', action='store', dest='wep_timeout', metavar='[seconds]', type=int, help=Color.s('Seconds to wait before failing (default: {G}%d sec{W})') - % Configuration.wep_timeout) + % config.wep_timeout) wep.add_argument('-wept', help=argparse.SUPPRESS, action='store', dest='wep_timeout', type=int) + wep.add_argument('--wepca', action='store', dest='wep_crack_at_ivs', metavar='[ivs]', type=int, help=Color.s('Start cracking at this many IVs (default: {G}%d ivs{W})') - % Configuration.wep_crack_at_ivs) + % config.wep_crack_at_ivs) wep.add_argument('-wepca', help=argparse.SUPPRESS, action='store', dest='wep_crack_at_ivs', type=int) + wep.add_argument('--weprs', action='store', dest='wep_restart_stale_ivs', metavar='[seconds]', type=int, help=Color.s('Restart aireplay if no new IVs appear (default: {G}%d sec{W})') - % Configuration.wep_restart_stale_ivs) + % config.wep_restart_stale_ivs) wep.add_argument('-weprs', help=argparse.SUPPRESS, action='store', dest='wep_restart_stale_ivs', type=int) + wep.add_argument('--weprc', action='store', dest='wep_restart_aircrack', metavar='[seconds]', type=int, help=Color.s('Restart aircrack after this delay (default: {G}%d sec{W})') - % Configuration.wep_restart_aircrack) + % config.wep_restart_aircrack) wep.add_argument('-weprc', help=argparse.SUPPRESS, action='store', dest='wep_restart_aircrack', type=int) + wep.add_argument('--arpreplay', action='store_true', dest='wep_attack_replay', help=Color.s('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('--fragment', action='store_true', dest='wep_attack_fragment', help=Color.s('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('--chopchop', action='store_true', dest='wep_attack_chopchop', help=Color.s('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('--caffelatte', action='store_true', dest='wep_attack_caffe', help=Color.s('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('--p0841', action='store_true', dest='wep_attack_p0841', help=Color.s('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('--hirte', action='store_true', dest='wep_attack_hirte', help=Color.s('Use ARP-replay WEP attack (default: {G}on{W})')) 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, config): wpa.add_argument('--wpa', action='store_true', dest='wpa_filter', 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('--wpadt', action='store', dest='wpa_deauth_timeout', metavar='[seconds]', type=int, help=Color.s('Time to wait between sending Deauths (default: {G}%d sec{W})') - % Configuration.wpa_deauth_timeout) + % config.wpa_deauth_timeout) wpa.add_argument('-wpadt', help=argparse.SUPPRESS, action='store', dest='wpa_deauth_timeout', type=int) + wpa.add_argument('--wpat', action='store', dest='wpa_attack_timeout', metavar='[seconds]', type=int, help=Color.s('Time to wait before failing WPA attack (default: {G}%d sec{W})') - % Configuration.wpa_attack_timeout) + % config.wpa_attack_timeout) wpa.add_argument('-wpat', help=argparse.SUPPRESS, action='store', dest='wpa_attack_timeout', type=int) + wpa.add_argument('--new-hs', action='store_true', dest='ignore_old_handshakes', help=Color.s('Captures new handshakes, ignores existing handshakes in ./hs (default: {G}off{W})')) + wpa.add_argument('--hs-dir', action='store', dest='wpa_handshake_dir', metavar='[dir]', type=str, help=Color.s('Directory to store handshake files (default: {G}%s{W})') - % Configuration.wpa_handshake_dir) + % config.wpa_handshake_dir) wpa.add_argument('-hs-dir', help=argparse.SUPPRESS, action='store', dest='wpa_handshake_dir', type=str) + wpa.add_argument('--dict', action='store', dest='wordlist', metavar='[file]', type=str, help=Color.s('File containing passwords for cracking (default: {G}%s{W})') - % Configuration.wordlist) + % config.wordlist) # TODO: Uncomment the --strip option once it works ''' @@ -241,8 +278,8 @@ class Arguments(object): ''' 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, config): wps.add_argument('--wps', action='store_true', dest='wps_filter', @@ -273,21 +310,21 @@ class Arguments(object): metavar='[seconds]', type=int, help=Color.s('Time to wait before failing PixieDust attack (default: {G}%d sec{W})') - % Configuration.wps_pixie_timeout) + % config.wps_pixie_timeout) wps.add_argument('--pixiest', action='store', dest='wps_pixie_step_timeout', metavar='[seconds]', type=int, help=Color.s('Time to wait for a step to progress before failing PixieDust attack (default: {G}%d sec{W})') - % Configuration.wps_pixie_step_timeout) + % config.wps_pixie_step_timeout) wps.add_argument('--wpsmf', action='store', dest='wps_fail_threshold', metavar='[fails]', type=int, help=Color.s('Maximum number of WPS Failures before failing attack (default: {G}%d{W})') - % Configuration.wps_fail_threshold) + % config.wps_fail_threshold) wps.add_argument('-wpsmf', help=argparse.SUPPRESS, action='store', dest='wps_fail_threshold', type=int) wps.add_argument('--wpsmt', action='store', @@ -295,7 +332,7 @@ class Arguments(object): metavar='[timeouts]', type=int, help=Color.s('Maximum number of Timeouts before stopping (default: {G}%d{W})') - % Configuration.wps_timeout_threshold) + % config.wps_timeout_threshold) wps.add_argument('-wpsmt', help=argparse.SUPPRESS, action='store', dest='wps_timeout_threshold', type=int) wps.add_argument('--ignore-ratelimit', action='store_false', @@ -303,13 +340,14 @@ class Arguments(object): 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') - # Commands - commands = parser.add_argument_group('COMMANDS') + + def _add_command_args(self, commands, config): commands.add_argument('--cracked', action='store_true', dest='cracked', help=Color.s('Display previously-cracked access points')) commands.add_argument('-cracked', help=argparse.SUPPRESS, action='store_true', dest='cracked') + commands.add_argument('--check', action='store', metavar='file', @@ -318,15 +356,15 @@ class Arguments(object): dest='check_handshake', 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='', dest='check_handshake') + commands.add_argument('--crack', action='store_true', dest='crack_handshake', help=Color.s('Show commands to crack a captured handshake')) - return parser.parse_args() if __name__ == '__main__': - from Color import Color - from Configuration import Configuration + from util.color import Color + from config import Configuration Configuration.initialize(False) a = Arguments(Configuration) args = a.args From 7b9a023bd6c1b89738e746247a5fd5b45eff3ba4 Mon Sep 17 00:00:00 2001 From: derv82 Date: Sat, 17 Mar 2018 04:32:00 -0400 Subject: [PATCH 03/12] Cleaning up imports, fixing a few bugs. --- wifite/attack/wep.py | 8 +++++++- wifite/attack/wpa.py | 10 ++++++++-- wifite/model/interface.py | 7 +++---- wifite/model/result.py | 6 +++--- wifite/model/target.py | 2 +- wifite/tools/aireplay.py | 4 ++-- wifite/tools/airodump.py | 14 +++++++------- wifite/tools/bully.py | 2 +- wifite/tools/macchanger.py | 14 +++++++------- wifite/tools/tshark.py | 4 ++-- wifite/util/process.py | 4 ++-- wifite/util/scanner.py | 10 +++++----- 12 files changed, 48 insertions(+), 37 deletions(-) diff --git a/wifite/attack/wep.py b/wifite/attack/wep.py index 07cb724..bf74f29 100755 --- a/wifite/attack/wep.py +++ b/wifite/attack/wep.py @@ -34,6 +34,7 @@ class AttackWEP(Attack): aircrack = None # Aircrack process, not started yet fakeauth_proc = None replay_file = None + airodump_target = None attacks_remaining = list(Configuration.wep_attacks) 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), 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 Color.pl("\n\n{!} {O}Interrupted") @@ -322,9 +326,11 @@ class AttackWEP(Attack): 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(',') target = Target(fields) wep = AttackWEP(target) wep.run() + Configuration.exit_gracefully(0) diff --git a/wifite/attack/wpa.py b/wifite/attack/wpa.py index 316fa57..5403c4f 100755 --- a/wifite/attack/wpa.py +++ b/wifite/attack/wpa.py @@ -293,8 +293,14 @@ class AttackWPA(Attack): Aireplay.deauth(target.bssid, client_mac=client, timeout=2) 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(',') target = Target(fields) wpa = AttackWPA(target) - wpa.run() + try: + wpa.run() + except KeyboardInterrupt: + Color.pl("") + pass + Configuration.exit_gracefully(0) diff --git a/wifite/model/interface.py b/wifite/model/interface.py index f11b745..9fd8595 100755 --- a/wifite/model/interface.py +++ b/wifite/model/interface.py @@ -1,7 +1,7 @@ #!/usr/bin/python2.7 # -*- coding: utf-8 -*- -from wifite.util.color import Color +from ..util.color import Color import re @@ -78,9 +78,8 @@ class Interface(object): @staticmethod def get_mac(iface=None): - from Configuration import Configuration - from Process import Process - import re + from ..config import Configuration + from ..util.process import Process if iface is None: Configuration.initialize() diff --git a/wifite/model/result.py b/wifite/model/result.py index 4bf81f8..10d7677 100755 --- a/wifite/model/result.py +++ b/wifite/model/result.py @@ -50,20 +50,20 @@ class CrackResult(object): def load(json): ''' Returns an instance of the appropriate object given a json instance ''' if json['type'] == 'WPA': - from CrackResultWPA import CrackResultWPA + from .wpa_result import CrackResultWPA result = CrackResultWPA(json['bssid'], json['essid'], json['handshake_file'], json['key']) elif json['type'] == 'WEP': - from CrackResultWEP import CrackResultWEP + from .wep_result import CrackResultWEP result = CrackResultWEP(json['bssid'], json['essid'], json['hex_key'], json['ascii_key']) elif json['type'] == 'WPS': - from CrackResultWPS import CrackResultWPS + from .wps_result import CrackResultWPS result = CrackResultWPS(json['bssid'], json['essid'], json['pin'], diff --git a/wifite/model/target.py b/wifite/model/target.py index c35f878..39c3f97 100755 --- a/wifite/model/target.py +++ b/wifite/model/target.py @@ -1,7 +1,7 @@ #!/usr/bin/python2.7 # -*- coding: utf-8 -*- -from wifite.util.color import Color +from ..util.color import Color import re diff --git a/wifite/tools/aireplay.py b/wifite/tools/aireplay.py index 557062e..c0c71d2 100755 --- a/wifite/tools/aireplay.py +++ b/wifite/tools/aireplay.py @@ -314,7 +314,7 @@ class Aireplay(Thread): if out.strip() == 'Wrote packet to: %s' % forged_file: return forged_file else: - from Color import Color + from ..util.color import Color Color.pl('{!} {R}failed to forge packet from .xor file{W}') Color.pl('output:\n"%s"' % out) return None @@ -385,7 +385,7 @@ if __name__ == '__main__': t = WEPAttackType(t) 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(',') t = Target(fields) diff --git a/wifite/tools/airodump.py b/wifite/tools/airodump.py index cf1a522..8ff39b4 100755 --- a/wifite/tools/airodump.py +++ b/wifite/tools/airodump.py @@ -1,11 +1,11 @@ #!/usr/bin/python2.7 # -*- coding: utf-8 -*- -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 +from .tshark import Tshark +from ..util.process import Process +from ..config import Configuration +from ..model.target import Target +from ..model.client import Client import os, time @@ -278,7 +278,7 @@ class Airodump(object): self.decloaking = True self.decloaked_times[target.bssid] = now if Configuration.verbose > 1: - from Color import Color + from ..util.color import Color verbout = " [?] Deauthing %s" % target.bssid verbout += " (broadcast & %d clients)" % len(target.clients) Color.pe("\n{C}" + verbout + "{W}") @@ -296,7 +296,7 @@ if __name__ == '__main__': from time import sleep sleep(7) - from Color import Color + from ..util.color import Color targets = airodump.get_targets() for idx, target in enumerate(targets, start=1): diff --git a/wifite/tools/bully.py b/wifite/tools/bully.py index e6f7b5d..c083e02 100755 --- a/wifite/tools/bully.py +++ b/wifite/tools/bully.py @@ -217,7 +217,7 @@ class Bully(Attack): if __name__ == '__main__': stdout = " [*] Pin is '11867722', key is '9a6f7997'" 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(',') target = Target(fields) b = Bully(target) diff --git a/wifite/tools/macchanger.py b/wifite/tools/macchanger.py index c87153a..46cd81d 100755 --- a/wifite/tools/macchanger.py +++ b/wifite/tools/macchanger.py @@ -1,8 +1,8 @@ #!/usr/bin/python2.7 # -*- coding: utf-8 -*- -from wifite.model.interface import Interface -from wifite.util.color import Color +from ..model.interface import Interface +from ..util.color import Color class Macchanger(object): is_init = False @@ -12,7 +12,7 @@ class Macchanger(object): @classmethod def init(cls): if cls.is_init: return - from Configuration import Configuration + from ..config import Configuration iface = Configuration.interface if type(iface) == Interface: iface = iface.name @@ -21,8 +21,8 @@ class Macchanger(object): @classmethod def down_macch_up(cls, macch_option): cls.init() - from Process import Process - from Configuration import Configuration + from ..util.process import Process + from ..config import Configuration iface = Configuration.interface cmd = ["ifconfig", iface, "down"] @@ -61,7 +61,7 @@ class Macchanger(object): # --permanent to reset to permanent MAC address if not cls.down_macch_up("-p"): return Color.pl("\r{+} {C}macchanger{W}: Resetting MAC address...") - from Configuration import Configuration + from ..config import Configuration new_mac = Interface.get_mac(Configuration.interface) Color.clear_entire_line() 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 if not cls.down_macch_up("-r"): return cls.is_changed = True - from Configuration import Configuration + from ..config import Configuration new_mac = Interface.get_mac(Configuration.interface) Color.clear_entire_line() Color.pl("\r{+} {C}macchanger{W}: Changed MAC address to {C}%s{W}" % new_mac) diff --git a/wifite/tools/tshark.py b/wifite/tools/tshark.py index f622ab1..36a0d0f 100755 --- a/wifite/tools/tshark.py +++ b/wifite/tools/tshark.py @@ -1,7 +1,7 @@ #!/usr/bin/python2.7 # -*- coding: utf-8 -*- -from wifite.util.process import Process +from ..util.process import Process import re class Tshark(object): @@ -63,7 +63,7 @@ if __name__ == '__main__': test_file = './tests/files/contains_wps_network.cap' target_bssid = 'A4:2B:8C:16:6B:3A' - from Target import Target + from ..model.target import Target fields = [ 'A4:2B:8C:16:6B:3A', # BSSID '2015-05-27 19:28:44', '2015-05-27 19:28:46', # Dates diff --git a/wifite/util/process.py b/wifite/util/process.py index d0769e4..0b1af74 100755 --- a/wifite/util/process.py +++ b/wifite/util/process.py @@ -4,8 +4,8 @@ import time from subprocess import Popen, PIPE -from wifite.util.color import Color -from wifite.config import Configuration +from ..util.color import Color +from ..config import Configuration class Process(object): diff --git a/wifite/util/scanner.py b/wifite/util/scanner.py index 17b5c62..a28e405 100755 --- a/wifite/util/scanner.py +++ b/wifite/util/scanner.py @@ -1,10 +1,10 @@ #!/usr/bin/python2.7 # -*- coding: utf-8 -*- -from wifite.tools.airodump import Airodump -from wifite.util.color import Color -from wifite.model.target import Target -from wifite.config import Configuration +from ..tools.airodump import Airodump +from ..util.color import Color +from ..model.target import Target +from ..config import Configuration from time import sleep, time @@ -120,7 +120,7 @@ class Scanner(object): # 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. # Clear the screen. - from Process import Process + from ..util.process import Process Process.call('clear') else: # We can fit the targets in the terminal without scrolling From d63f43016d62041e5425061a34dec84b0d7fc0ce Mon Sep 17 00:00:00 2001 From: derv82 Date: Sat, 17 Mar 2018 04:33:42 -0400 Subject: [PATCH 04/12] Fixing tests --- runtests.sh | 2 +- tests/test_Handshake.py | 2 +- tests/test_Target.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/runtests.sh b/runtests.sh index da9b3ed..8844f45 100755 --- a/runtests.sh +++ b/runtests.sh @@ -1,2 +1,2 @@ #!/bin/sh -python2.7 -m unittest discover py/tests -v +python2.7 -m unittest discover tests -v diff --git a/tests/test_Handshake.py b/tests/test_Handshake.py index b0ac1c9..3ed0566 100644 --- a/tests/test_Handshake.py +++ b/tests/test_Handshake.py @@ -4,7 +4,7 @@ import sys sys.path.insert(0, '..') -from py.Handshake import Handshake +from wifite.model.handshake import Handshake import unittest diff --git a/tests/test_Target.py b/tests/test_Target.py index d16f1d9..6d2f05f 100644 --- a/tests/test_Target.py +++ b/tests/test_Target.py @@ -1,7 +1,7 @@ #!/usr/bin/python2.7 # -*- coding: utf-8 -*- -from py.Airodump import Airodump +from wifite.tools.airodump import Airodump import unittest From 9ff7404d535cc20ab3284428fd13d7f5a1c17568 Mon Sep 17 00:00:00 2001 From: derv82 Date: Sat, 17 Mar 2018 04:41:44 -0400 Subject: [PATCH 05/12] Small refactoring --- TODO.md | 2 +- Wifite.py | 2 +- wifite/{ => util}/crack.py | 8 ++++---- wifite/wifite.py | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) rename wifite/{ => util}/crack.py (97%) diff --git a/TODO.md b/TODO.md index 07cd3e8..ac10678 100644 --- a/TODO.md +++ b/TODO.md @@ -121,13 +121,13 @@ Not "/py": * `tshark.py` <- process * `cowpatty.py` <- process * `pyrit.py` <- process + * `handshake.py` <- tshark, cowpatty, pyrit, aircrack * `output.py` (color/printing) <- config * `process.py` <- config * `scan.py` (airodump output to target) <- config, target, airodump * **target/** * `target.py` (ssid, pcap file) <- airodump, tshark * `result.py` (PIN/PSK/KEY) - * `handshake.py` <- tshark, cowpatty, pyrit, aircrack ------------------------------------------------------ diff --git a/Wifite.py b/Wifite.py index de3e6e5..4bffa51 100755 --- a/Wifite.py +++ b/Wifite.py @@ -1 +1 @@ -python2 -m wifite.wifite $@ +python2.7 -m wifite.wifite $@ diff --git a/wifite/crack.py b/wifite/util/crack.py similarity index 97% rename from wifite/crack.py rename to wifite/util/crack.py index b1a3393..b0c1d6f 100755 --- a/wifite/crack.py +++ b/wifite/util/crack.py @@ -1,10 +1,10 @@ #!/usr/bin/python2.7 # -*- coding: utf-8 -*- -from util.process import Process -from util.color import Color -from config import Configuration -from model.result 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 diff --git a/wifite/wifite.py b/wifite/wifite.py index f03dbca..0240f59 100755 --- a/wifite/wifite.py +++ b/wifite/wifite.py @@ -3,14 +3,14 @@ from config import Configuration 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 -from crack import CrackHandshake -from util.process import Process from json import loads import os From 0a089c8aab49274eadfd28cdd1337dd1312c6d76 Mon Sep 17 00:00:00 2001 From: derv82 Date: Sat, 17 Mar 2018 05:14:41 -0400 Subject: [PATCH 06/12] Verbose mode for --help --- wifite/args.py | 152 +++++++++++++++++++++++------------------------ wifite/wifite.py | 5 +- 2 files changed, 77 insertions(+), 80 deletions(-) diff --git a/wifite/args.py b/wifite/args.py index f3c3a35..deba0bb 100755 --- a/wifite/args.py +++ b/wifite/args.py @@ -3,41 +3,54 @@ from util.color import Color -import argparse +import argparse, sys class Arguments(object): ''' Holds arguments used by the Wifite ''' - def __init__(self, config): - self.args = self.get_arguments(config) + 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, config): + def get_arguments(self): ''' Returns parser.args() containing all program arguments ''' parser = argparse.ArgumentParser(usage=argparse.SUPPRESS, formatter_class=lambda prog: argparse.HelpFormatter(prog, max_help_position=80, width=130)) - # Global variables glob = parser.add_argument_group('SETTINGS') - self._add_global_args(glob, config) + self._add_global_args(glob) wep_group = parser.add_argument_group('WEP-RELATED') - self._add_wep_args(wep_group, config) + self._add_wep_args(wep_group) wpa_group = parser.add_argument_group('WPA-RELATED') - self._add_wpa_args(wpa_group, config) + self._add_wpa_args(wpa_group) wps_group = parser.add_argument_group('WPS-RELATED') - self._add_wps_args(wps_group, config) + self._add_wps_args(wps_group) commands_group = parser.add_argument_group('COMMANDS') - self._add_command_args(commands_group, config) + self._add_command_args(commands_group) return parser.parse_args() - def _add_global_args(self, glob, config): + def _add_global_args(self, glob): + glob.add_argument('-v', + '--verbose', + action='count', + default=0, + dest='verbose', + help=Color.s('Shows more options (-h) and the executed commands (default: {G}quiet{W})')) + glob.add_argument('-i', action='store', dest='interface', @@ -45,18 +58,13 @@ class Arguments(object): type=str, 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', action='store', dest='channel', metavar='[channel]', type=int, 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', '---random-mac', @@ -64,37 +72,52 @@ class Arguments(object): dest='random_mac', 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', '--5ghz', action='store_true', 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', action='store', dest='target_bssid', metavar='[bssid]', 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', action='store', dest='target_essid', metavar='[essid]', 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('--showb', action='store_true', 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', action='store_true', 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('-nd', action='store_true', dest='no_deauth', help=argparse.SUPPRESS) @@ -104,27 +127,10 @@ class Arguments(object): dest='num_deauths', metavar="[num]", default=None, - help=Color.s('Number of deauth packets to send (default: {G}%d{W})' % 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})')) + help=self._verbose('Number of deauth packets to send (default: {G}%d{W})' % self.config.num_deauths)) - def _add_wep_args(self, wep, config): + def _add_wep_args(self, wep): # WEP wep.add_argument('--wep', action='store_true', @@ -144,8 +150,7 @@ class Arguments(object): dest='wep_pps', metavar='[pps]', type=int, - help=Color.s('Packets Per Second to replay (default: {G}%d pps{W})') - % config.wep_pps) + help=self._verbose('Packets Per Second to replay (default: {G}%d pps{W})' % self.config.wep_pps)) wep.add_argument('-pps', help=argparse.SUPPRESS, action='store', dest='wep_pps', type=int) wep.add_argument('--wept', @@ -153,8 +158,7 @@ class Arguments(object): dest='wep_timeout', metavar='[seconds]', type=int, - help=Color.s('Seconds to wait before failing (default: {G}%d sec{W})') - % config.wep_timeout) + help=self._verbose('Seconds to wait before failing (default: {G}%d sec{W})' % self.config.wep_timeout)) wep.add_argument('-wept', help=argparse.SUPPRESS, action='store', dest='wep_timeout', type=int) wep.add_argument('--wepca', @@ -162,8 +166,7 @@ class Arguments(object): dest='wep_crack_at_ivs', metavar='[ivs]', type=int, - help=Color.s('Start cracking at this many IVs (default: {G}%d ivs{W})') - % config.wep_crack_at_ivs) + help=self._verbose('Start cracking at this many IVs (default: {G}%d ivs{W})' % self.config.wep_crack_at_ivs)) wep.add_argument('-wepca', help=argparse.SUPPRESS, action='store', dest='wep_crack_at_ivs', type=int) wep.add_argument('--weprs', @@ -171,8 +174,7 @@ class Arguments(object): dest='wep_restart_stale_ivs', metavar='[seconds]', type=int, - help=Color.s('Restart aireplay if no new IVs appear (default: {G}%d sec{W})') - % config.wep_restart_stale_ivs) + help=self._verbose('Restart aireplay if no new IVs appear (default: {G}%d sec{W})' % self.config.wep_restart_stale_ivs)) wep.add_argument('-weprs', help=argparse.SUPPRESS, action='store', dest='wep_restart_stale_ivs', type=int) wep.add_argument('--weprc', @@ -180,48 +182,47 @@ class Arguments(object): dest='wep_restart_aircrack', metavar='[seconds]', type=int, - help=Color.s('Restart aircrack after this delay (default: {G}%d sec{W})') - % config.wep_restart_aircrack) + help=self._verbose('Restart aircrack after this delay (default: {G}%d sec{W})' % self.config.wep_restart_aircrack)) wep.add_argument('-weprc', help=argparse.SUPPRESS, action='store', dest='wep_restart_aircrack', type=int) wep.add_argument('--arpreplay', action='store_true', 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('--fragment', action='store_true', 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('--chopchop', action='store_true', 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('--caffelatte', action='store_true', 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('--p0841', action='store_true', 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('--hirte', action='store_true', 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') - def _add_wpa_args(self, wpa, config): + def _add_wpa_args(self, wpa): wpa.add_argument('--wpa', action='store_true', dest='wpa_filter', @@ -233,8 +234,7 @@ class Arguments(object): dest='wpa_deauth_timeout', metavar='[seconds]', type=int, - help=Color.s('Time to wait between sending Deauths (default: {G}%d sec{W})') - % config.wpa_deauth_timeout) + help=self._verbose('Time to wait between sending Deauths (default: {G}%d sec{W})' % self.config.wpa_deauth_timeout)) wpa.add_argument('-wpadt', help=argparse.SUPPRESS, action='store', dest='wpa_deauth_timeout', type=int) wpa.add_argument('--wpat', @@ -242,8 +242,7 @@ class Arguments(object): dest='wpa_attack_timeout', metavar='[seconds]', type=int, - help=Color.s('Time to wait before failing WPA attack (default: {G}%d sec{W})') - % config.wpa_attack_timeout) + help=self._verbose('Time to wait before failing WPA attack (default: {G}%d sec{W})' % self.config.wpa_attack_timeout)) wpa.add_argument('-wpat', help=argparse.SUPPRESS, action='store', dest='wpa_attack_timeout', type=int) wpa.add_argument('--new-hs', @@ -256,8 +255,7 @@ class Arguments(object): dest='wpa_handshake_dir', metavar='[dir]', type=str, - help=Color.s('Directory to store handshake files (default: {G}%s{W})') - % config.wpa_handshake_dir) + help=self._verbose('Directory to store handshake files (default: {G}%s{W})' % self.config.wpa_handshake_dir)) wpa.add_argument('-hs-dir', help=argparse.SUPPRESS, action='store', dest='wpa_handshake_dir', type=str) wpa.add_argument('--dict', @@ -266,7 +264,7 @@ class Arguments(object): metavar='[file]', type=str, help=Color.s('File containing passwords for cracking (default: {G}%s{W})') - % config.wordlist) + % self.config.wordlist) # TODO: Uncomment the --strip option once it works ''' @@ -279,7 +277,7 @@ class Arguments(object): wpa.add_argument('-strip', help=argparse.SUPPRESS, action='store_true', dest='wpa_strip_handshake') - def _add_wps_args(self, wps, config): + def _add_wps_args(self, wps): wps.add_argument('--wps', action='store_true', dest='wps_filter', @@ -292,11 +290,11 @@ class Arguments(object): wps.add_argument('--no-wps', action='store_true', 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', action='store_true', 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 wps.add_argument('--pixie', @@ -309,30 +307,26 @@ class Arguments(object): dest='wps_pixie_timeout', metavar='[seconds]', type=int, - help=Color.s('Time to wait before failing PixieDust attack (default: {G}%d sec{W})') - % config.wps_pixie_timeout) + help=self._verbose('Time to wait before failing PixieDust attack (default: {G}%d sec{W})' % self.config.wps_pixie_timeout)) wps.add_argument('--pixiest', action='store', dest='wps_pixie_step_timeout', metavar='[seconds]', type=int, - help=Color.s('Time to wait for a step to progress before failing PixieDust attack (default: {G}%d sec{W})') - % config.wps_pixie_step_timeout) + 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)) wps.add_argument('--wpsmf', action='store', dest='wps_fail_threshold', metavar='[fails]', type=int, - help=Color.s('Maximum number of WPS Failures before failing attack (default: {G}%d{W})') - % config.wps_fail_threshold) + help=self._verbose('Maximum number of WPS Failures before failing attack (default: {G}%d{W})' % self.config.wps_fail_threshold)) wps.add_argument('-wpsmf', help=argparse.SUPPRESS, action='store', dest='wps_fail_threshold', type=int) wps.add_argument('--wpsmt', action='store', dest='wps_timeout_threshold', metavar='[timeouts]', type=int, - help=Color.s('Maximum number of Timeouts before stopping (default: {G}%d{W})') - % config.wps_timeout_threshold) + help=self._verbose('Maximum number of Timeouts before stopping (default: {G}%d{W})' % self.config.wps_timeout_threshold)) wps.add_argument('-wpsmt', help=argparse.SUPPRESS, action='store', dest='wps_timeout_threshold', type=int) wps.add_argument('--ignore-ratelimit', action='store_false', @@ -341,7 +335,7 @@ class Arguments(object): wps.add_argument('-ignore-ratelimit', help=argparse.SUPPRESS, action='store_false', dest='wps_skip_rate_limit') - def _add_command_args(self, commands, config): + def _add_command_args(self, commands): commands.add_argument('--cracked', action='store_true', dest='cracked', diff --git a/wifite/wifite.py b/wifite/wifite.py index 0240f59..f88ff69 100755 --- a/wifite/wifite.py +++ b/wifite/wifite.py @@ -1,7 +1,10 @@ #!/usr/bin/python2.7 # -*- coding: utf-8 -*- -from config import Configuration +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 a100d5330058905e6d7e1cb52e745a695d36d58d Mon Sep 17 00:00:00 2001 From: derv82 Date: Sat, 17 Mar 2018 05:30:12 -0400 Subject: [PATCH 07/12] Cleaning up --help, banner, small fixes --- wifite/args.py | 6 +++--- wifite/wifite.py | 35 ++++++++++++++++++++++++----------- 2 files changed, 27 insertions(+), 14 deletions(-) diff --git a/wifite/args.py b/wifite/args.py index deba0bb..eda6060 100755 --- a/wifite/args.py +++ b/wifite/args.py @@ -28,13 +28,13 @@ class Arguments(object): glob = parser.add_argument_group('SETTINGS') self._add_global_args(glob) - wep_group = parser.add_argument_group('WEP-RELATED') + wep_group = parser.add_argument_group('WEP') self._add_wep_args(wep_group) - wpa_group = parser.add_argument_group('WPA-RELATED') + wpa_group = parser.add_argument_group('WPA') self._add_wpa_args(wpa_group) - wps_group = parser.add_argument_group('WPS-RELATED') + wps_group = parser.add_argument_group('WPS') self._add_wps_args(wps_group) commands_group = parser.add_argument_group('COMMANDS') diff --git a/wifite/wifite.py b/wifite/wifite.py index f88ff69..b3185ed 100755 --- a/wifite/wifite.py +++ b/wifite/wifite.py @@ -5,6 +5,7 @@ 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 @@ -15,9 +16,9 @@ from attack.wps import AttackWPS from model.result import CrackResult from model.handshake import Handshake -from json import loads +import json import os -from sys import exit +import sys class Wifite(object): @@ -63,7 +64,7 @@ class Wifite(object): if missing_required: Color.pl('{!} {R}required app(s) were not found, exiting.{W}') - exit(-1) + sys.exit(-1) if missing_optional: Color.pl('{!} {O}recommended app(s) were not found') @@ -71,17 +72,22 @@ class Wifite(object): 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() + 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 ''' @@ -95,6 +101,7 @@ class Wifite(object): 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): @@ -189,7 +196,7 @@ class Wifite(object): def print_banner(self): """ Displays ASCII art of the highest caliber. """ - Color.pl(r''' + 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 @@ -222,11 +229,14 @@ class Wifite(object): if __name__ == '__main__': w = Wifite() + w.print_banner() + 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 @@ -236,7 +246,10 @@ if __name__ == '__main__': 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) From b5cb8b69f139db0d4849b94e14fdec3c54d800c9 Mon Sep 17 00:00:00 2001 From: derv82 Date: Sat, 17 Mar 2018 05:47:02 -0400 Subject: [PATCH 08/12] Filter *out* by ESSID using -E (--ignore-essid) More refactoring! --- Wifite.py | 4 +++- wifite/args.py | 11 ++++++++++- wifite/config.py | 4 ++++ wifite/tools/airodump.py | 4 +++- wifite/wifite.py | 5 ++++- 5 files changed, 24 insertions(+), 4 deletions(-) diff --git a/Wifite.py b/Wifite.py index 4bffa51..39bacea 100755 --- a/Wifite.py +++ b/Wifite.py @@ -1 +1,3 @@ -python2.7 -m wifite.wifite $@ +#!/usr/bin/python +from wifite import wifite +wifite.run() diff --git a/wifite/args.py b/wifite/args.py index eda6060..c78c507 100755 --- a/wifite/args.py +++ b/wifite/args.py @@ -49,7 +49,7 @@ class Arguments(object): action='count', default=0, dest='verbose', - help=Color.s('Shows more options (-h) and the executed commands (default: {G}quiet{W})')) + help=Color.s('Shows more options ({C}-h -v{W}). Prints tool outputs. (default: {G}quiet{W})')) glob.add_argument('-i', action='store', @@ -109,6 +109,15 @@ class Arguments(object): 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', action='store_true', dest='show_bssids', diff --git a/wifite/config.py b/wifite/config.py index 57fe12c..e3bad55 100755 --- a/wifite/config.py +++ b/wifite/config.py @@ -39,6 +39,7 @@ class Configuration(object): Configuration.target_channel = None # User-defined channel to scan Configuration.target_essid = None # User-defined AP name Configuration.target_bssid = None # User-defined AP BSSID + Configuration.ignore_essid = None # ESSIDs to ignore Configuration.five_ghz = False # Scan 5Ghz channels Configuration.show_bssids = False # Show BSSIDs in targets list Configuration.random_mac = False # Should generate a random Mac address at startup. @@ -146,6 +147,9 @@ class Configuration(object): if args.target_essid: Configuration.target_essid = args.target_essid Color.pl('{+} {C}option:{W} targeting ESSID {G}%s{W}' % args.target_essid) + if args.ignore_essid is not None: + 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: 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) diff --git a/wifite/tools/airodump.py b/wifite/tools/airodump.py index 8ff39b4..7e52d7d 100755 --- a/wifite/tools/airodump.py +++ b/wifite/tools/airodump.py @@ -241,7 +241,9 @@ class Airodump(object): essid = Configuration.target_essid i = 0 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) elif essid and result[i].essid and result[i].essid.lower() != essid.lower(): result.pop(i) diff --git a/wifite/wifite.py b/wifite/wifite.py index b3185ed..196ef8f 100755 --- a/wifite/wifite.py +++ b/wifite/wifite.py @@ -227,7 +227,7 @@ class Wifite(object): return True -if __name__ == '__main__': +def run(): w = Wifite() w.print_banner() @@ -253,3 +253,6 @@ if __name__ == '__main__': Color.pl('\n{!} {O}interrupted, shutting down...{W}') Configuration.exit_gracefully(0) + +if __name__ == '__main__': + run() From c7a952b3dfc49150760a521388c1634ccc1ac88b Mon Sep 17 00:00:00 2001 From: Niller303 <2797716+Niller303@users.noreply.github.com> Date: Tue, 20 Mar 2018 15:24:45 +0100 Subject: [PATCH 09/12] Added fix for bad drivers --- wifite/tools/airmon.py | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/wifite/tools/airmon.py b/wifite/tools/airmon.py index 8853033..53283da 100755 --- a/wifite/tools/airmon.py +++ b/wifite/tools/airmon.py @@ -15,6 +15,10 @@ class Airmon(object): base_interface = None killed_network_manager = False + #see if_arp.h + ARPHRD_ETHER = 1 #managed + ARPHRD_IEEE80211_RADIOTAP = 803 #monitor + def __init__(self): self.refresh() @@ -56,6 +60,28 @@ class Airmon(object): interfaces.append(Interface(fields)) 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)) + #You cannot trust the output of the rtl8812AU + #it says that interface 10 is the monitor interface, it isn't. + #its actually just the same name, but lets not trust it anyway + for x in os.listdir("/sys/class/net/."): + with open("/sys/class/net/" + x + "/type", "r") as f: + if (int(f.read()) == Airmon.ARPHRD_IEEE80211_RADIOTAP): + return x + + 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 def start(iface): ''' @@ -91,7 +117,9 @@ class Airmon(object): if mon_iface is None: # Airmon did not enable monitor mode on an interface - Color.pl("{R}failed{W}") + mon_iface = Airmon.start_baddriver(iface) + if mon_iface is None: + Color.pl("{R}failed{W}") mon_ifaces = Airmon.get_interfaces_in_monitor_mode() @@ -134,6 +162,9 @@ class Airmon(object): mon_iface = match.groups()[0] break + if not mon_iface: + mon_iface = Airmon.stop_baddriver(iface) + if mon_iface: Color.pl('{R}disabled %s{W}' % mon_iface) else: From 0de54db1ec8fa6bb846d243dde7b797034fad325 Mon Sep 17 00:00:00 2001 From: Niller303 <2797716+Niller303@users.noreply.github.com> Date: Tue, 20 Mar 2018 15:43:07 +0100 Subject: [PATCH 10/12] Fix brainfart --- wifite/tools/airmon.py | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/wifite/tools/airmon.py b/wifite/tools/airmon.py index 53283da..352bd0b 100755 --- a/wifite/tools/airmon.py +++ b/wifite/tools/airmon.py @@ -63,22 +63,18 @@ class Airmon(object): @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)) - #You cannot trust the output of the rtl8812AU - #it says that interface 10 is the monitor interface, it isn't. - #its actually just the same name, but lets not trust it anyway - for x in os.listdir("/sys/class/net/."): - with open("/sys/class/net/" + x + "/type", "r") as f: - if (int(f.read()) == Airmon.ARPHRD_IEEE80211_RADIOTAP): - return x + 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 + with open("/sys/class/net/" + iface + "/type", "r") as f: + if (int(f.read()) == Airmon.ARPHRD_ETHER): + return iface return None From 964bf2376321abd64dd2fa2cdece08e72f43c4f6 Mon Sep 17 00:00:00 2001 From: derv82 Date: Sat, 17 Mar 2018 15:07:58 -0400 Subject: [PATCH 11/12] Small fixes to verbose output --- Wifite.py | 2 ++ wifite/util/process.py | 8 ++++---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/Wifite.py b/Wifite.py index 39bacea..246013a 100755 --- a/Wifite.py +++ b/Wifite.py @@ -1,3 +1,5 @@ #!/usr/bin/python + from wifite import wifite + wifite.run() diff --git a/wifite/util/process.py b/wifite/util/process.py index 0b1af74..76c22cc 100755 --- a/wifite/util/process.py +++ b/wifite/util/process.py @@ -37,9 +37,9 @@ class Process(object): (stdout, stderr) = pid.communicate() 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() != '': - 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) @@ -92,14 +92,14 @@ class Process(object): ''' Waits for process to finish, returns stdout output ''' self.get_output() 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 def stderr(self): ''' Waits for process to finish, returns stderr output ''' self.get_output() 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 def stdoutln(self): From 7d4219808df97a5f74a3c1abb95697a0b3f34b70 Mon Sep 17 00:00:00 2001 From: derv82 Date: Sat, 17 Mar 2018 17:17:17 -0400 Subject: [PATCH 12/12] Wait for WPS results if target is specified in switches and --wps-only as well --- wifite/util/scanner.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/wifite/util/scanner.py b/wifite/util/scanner.py index a28e405..7942a4c 100755 --- a/wifite/util/scanner.py +++ b/wifite/util/scanner.py @@ -88,6 +88,8 @@ class Scanner(object): return False 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(): self.target = target break