--crack: Dependency management, avoid dupes in cracked.txt
* Dupes are skipped if everything *except* date matches (same bssid/ssid/type/key) * John: Detect and use OpenCL or CUDA using `john --list=formats` * Removed `wifite.py` as it's no longer used & is confusing.
This commit is contained in:
@@ -39,19 +39,31 @@ class CrackResult(object):
|
||||
def save(self):
|
||||
''' Adds this crack result to the cracked file and saves it. '''
|
||||
name = CrackResult.cracked_file
|
||||
json = []
|
||||
saved_results = []
|
||||
if os.path.exists(name):
|
||||
with open(name, 'r') as fid:
|
||||
text = fid.read()
|
||||
try:
|
||||
json = loads(text)
|
||||
saved_results = loads(text)
|
||||
except Exception as e:
|
||||
Color.pl('{!} error while loading %s: %s' % (name, str(e)))
|
||||
json.append(self.to_dict())
|
||||
|
||||
# Check for duplicates
|
||||
this_dict = self.to_dict()
|
||||
this_dict.pop('date')
|
||||
for entry in saved_results:
|
||||
this_dict['date'] = entry.get('date')
|
||||
if entry == this_dict:
|
||||
# Skip if we already saved this BSSID+ESSID+TYPE+KEY
|
||||
Color.pl('{+} {C}%s{O} already exists in {G}cracked.txt{O}, skipping.' % (
|
||||
self.essid))
|
||||
return
|
||||
|
||||
saved_results.append(self.to_dict())
|
||||
with open(name, 'w') as fid:
|
||||
fid.write(dumps(json, indent=2))
|
||||
fid.write(dumps(saved_results, indent=2))
|
||||
Color.pl('{+} saved crack result to {C}%s{W} ({G}%d total{W})'
|
||||
% (name, len(json)))
|
||||
% (name, len(saved_results)))
|
||||
|
||||
@classmethod
|
||||
def display(cls):
|
||||
|
||||
@@ -21,27 +21,39 @@ class John(Dependency):
|
||||
def crack_handshake(handshake, show_command=False):
|
||||
john_file = HcxPcapTool.generate_john_file(handshake, show_command=show_command)
|
||||
|
||||
# Use `john --list=formats` to find if OpenCL or CUDA is supported.
|
||||
formats_stdout = Process(['john', '--list=formats']).stdout()
|
||||
if 'wpapsk-opencl' in formats_stdout:
|
||||
john_format = 'wpapsk-opencl'
|
||||
elif 'wpapsk-cuda' in formats_stdout:
|
||||
john_format = 'wpapsk-cuda'
|
||||
else:
|
||||
john_format = 'wpapsk'
|
||||
|
||||
# Crack john file
|
||||
command = [
|
||||
'john',
|
||||
'--format=wpapsk', # wpapsk-cuda or wpapsk-opencl
|
||||
'--format', john_format,
|
||||
'--wordlist', Configuration.wordlist,
|
||||
john_file
|
||||
]
|
||||
|
||||
if show_command:
|
||||
Color.pl('{+} {D}{C}Running %s{W}' % ' '.join(command))
|
||||
process = Process(command)
|
||||
process.wait()
|
||||
|
||||
# Show the password (if found)
|
||||
# Run again with --show to consistently get the password
|
||||
command = ['john', '--show', john_file]
|
||||
if show_command:
|
||||
Color.pl('{+} {D}{C}Running %s{W}' % ' '.join(command))
|
||||
process = Process(command)
|
||||
stdout, stderr = process.get_output()
|
||||
|
||||
# Parse password (regex doesn't work for some reason)
|
||||
if '0 password hashes cracked' in stdout:
|
||||
key = None
|
||||
if not '0 password hashes cracked' in stdout:
|
||||
else:
|
||||
for line in stdout.split('\n'):
|
||||
if handshake.capfile in line:
|
||||
key = line.split(':')[1]
|
||||
|
||||
@@ -22,6 +22,8 @@ import os
|
||||
|
||||
# TODO: Do not show handshake files that are in cracked.txt with a key (match on filename).
|
||||
|
||||
# TODO: --no-crack option while attacking targets (implies user will run --crack later)
|
||||
|
||||
class CrackHelper:
|
||||
'''Manages handshake retrieval, selection, and running the cracking commands.'''
|
||||
|
||||
@@ -52,20 +54,35 @@ class CrackHelper:
|
||||
|
||||
hs_to_crack = cls.get_user_selection(handshakes)
|
||||
|
||||
# Get tool
|
||||
available_tools = ['aircrack', 'hashcat', 'john', 'cowpatty']
|
||||
if not Process.exists(HcxPcapTool.dependency_name):
|
||||
Color.pl('{!} {R}Unable to use hashcat: {O}missing required hcxpcaptool{W}')
|
||||
available_tools.remove('hashcat')
|
||||
if not Process.exists(John.dependency_name):
|
||||
Color.pl('{!} {R}Unable to use john: {O}missing required "john" program{W}')
|
||||
available_tools.remove('john')
|
||||
# Tools for cracking & their dependencies.
|
||||
available_tools = {
|
||||
'aircrack': [Aircrack],
|
||||
'hashcat': [Hashcat, HcxPcapTool],
|
||||
'john': [John, HcxPcapTool],
|
||||
'cowpatty': [Cowpatty]
|
||||
}
|
||||
# Identify missing tools
|
||||
missing_tools = []
|
||||
for tool, dependencies in available_tools.items():
|
||||
missing = [
|
||||
dep for dep in dependencies
|
||||
if not Process.exists(dep.dependency_name)
|
||||
]
|
||||
if len(missing) > 0:
|
||||
available_tools.pop(tool)
|
||||
missing_tools.append( (tool, missing) )
|
||||
|
||||
Color.p('{+} Enter the {C}cracking tool{W} to use ({C}%s{W}): {G}' % (
|
||||
'{W}, {C}'.join(available_tools)))
|
||||
if len(missing_tools) > 0:
|
||||
Color.pl('\n{!} {O}Unavailable tools (install to enable):{W}')
|
||||
for tool, deps in missing_tools:
|
||||
dep_list = ', '.join([dep.dependency_name for dep in deps])
|
||||
Color.pl(' {R}* {R}%s {W}({O}%s{W})' % (tool, dep_list))
|
||||
|
||||
Color.p('\n{+} Enter the {C}cracking tool{W} to use ({C}%s{W}): {G}' % (
|
||||
'{W}, {C}'.join(available_tools.keys())))
|
||||
tool_name = raw_input()
|
||||
if tool_name not in available_tools:
|
||||
Color.pl('{!} {O}%s not found, defaulting to aircrack' % tool_name)
|
||||
Color.pl('{!} {R}"%s"{O} tool not found, defaulting to {C}aircrack{W}' % tool_name)
|
||||
tool_name = 'aircrack'
|
||||
|
||||
try:
|
||||
@@ -85,7 +102,7 @@ class CrackHelper:
|
||||
Color.pl('\n{!} {O}directory not found: {R}%s{W}' % hs_dir)
|
||||
return []
|
||||
|
||||
Color.pl('\n{+} Listing captured handshakes from {C}%s{W} ...\n' % os.path.abspath(hs_dir))
|
||||
Color.pl('\n{+} Listing captured handshakes from {C}%s{W}:\n' % os.path.abspath(hs_dir))
|
||||
for hs_file in os.listdir(hs_dir):
|
||||
if hs_file.count('_') != 3:
|
||||
continue
|
||||
@@ -146,7 +163,7 @@ class CrackHelper:
|
||||
Color.p(' ---')
|
||||
Color.p(' ' + ('-' * max_essid_len))
|
||||
Color.p(' ' + ('-' * 17))
|
||||
Color.p(' ' + ('-' * 6))
|
||||
Color.p(' ' + ('-' * 5))
|
||||
Color.p(' ' + ('-' * 19) + '{W}\n')
|
||||
# Handshakes
|
||||
for index, handshake in enumerate(handshakes, start=1):
|
||||
|
||||
105
wifite/wifite.py
105
wifite/wifite.py
@@ -1,105 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
try:
|
||||
from .config import Configuration
|
||||
except (ValueError, ImportError) as e:
|
||||
raise Exception('You may need to run wifite from the root directory (which includes README.md)', e)
|
||||
|
||||
from .util.color import Color
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
|
||||
class Wifite(object):
|
||||
|
||||
def __init__(self):
|
||||
'''
|
||||
Initializes Wifite. Checks for root permissions and ensures dependencies are installed.
|
||||
'''
|
||||
|
||||
self.print_banner()
|
||||
|
||||
Configuration.initialize(load_interface=False)
|
||||
|
||||
if os.getuid() != 0:
|
||||
Color.pl('{!} {R}error: {O}wifite{R} must be run as {O}root{W}')
|
||||
Color.pl('{!} {R}re-run with {O}sudo{W}')
|
||||
Configuration.exit_gracefully(0)
|
||||
|
||||
from .tools.dependency import Dependency
|
||||
Dependency.run_dependency_check()
|
||||
|
||||
|
||||
def start(self):
|
||||
'''
|
||||
Starts target-scan + attack loop, or launches utilities dpeending on user input.
|
||||
'''
|
||||
from .model.result import CrackResult
|
||||
from .model.handshake import Handshake
|
||||
from .util.crack import CrackHelper
|
||||
|
||||
if Configuration.show_cracked:
|
||||
CrackResult.display()
|
||||
|
||||
elif Configuration.check_handshake:
|
||||
Handshake.check()
|
||||
|
||||
elif Configuration.crack_handshake:
|
||||
CrackHelper.run()
|
||||
|
||||
else:
|
||||
Configuration.get_monitor_mode_interface()
|
||||
self.scan_and_attack()
|
||||
|
||||
|
||||
def print_banner(self):
|
||||
'''Displays ASCII art of the highest caliber.'''
|
||||
Color.pl(r'{G} . {GR}{D} {W}{G} . {W}')
|
||||
Color.pl(r'{G}.´ · .{GR}{D} {W}{G}. · `. {G}wifite {D}%s{W}' % Configuration.version)
|
||||
Color.pl(r'{G}: : : {GR}{D} (¯) {W}{G} : : : {W}{D}automated wireless auditor{W}')
|
||||
Color.pl(r'{G}`. · `{GR}{D} /¯\ {W}{G}´ · .´ {C}{D}https://github.com/derv82/wifite2{W}')
|
||||
Color.pl(r'{G} ` {GR}{D}/¯¯¯\{W}{G} ´ {W}')
|
||||
Color.pl('')
|
||||
|
||||
|
||||
def scan_and_attack(self):
|
||||
'''
|
||||
1) Scans for targets, asks user to select targets
|
||||
2) Attacks each target
|
||||
'''
|
||||
from .util.scanner import Scanner
|
||||
from .attack.all import AttackAll
|
||||
|
||||
Color.pl('')
|
||||
|
||||
# Scan
|
||||
s = Scanner()
|
||||
targets = s.select_targets()
|
||||
|
||||
# Attack
|
||||
attacked_targets = AttackAll.attack_multiple(targets)
|
||||
|
||||
Color.pl('\n{+} Finished attacking {C}%d{W} target(s), exiting' % attacked_targets)
|
||||
|
||||
|
||||
##############################################################
|
||||
|
||||
|
||||
def entry_point():
|
||||
try:
|
||||
wifite = Wifite()
|
||||
wifite.start()
|
||||
except Exception as e:
|
||||
Color.pexception(e)
|
||||
Color.pl('\n{!} {R}Exiting{W}\n')
|
||||
|
||||
except KeyboardInterrupt:
|
||||
Color.pl('\n{!} {O}interrupted, shutting down...{W}')
|
||||
|
||||
Configuration.exit_gracefully(0)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
entry_point()
|
||||
Reference in New Issue
Block a user