Do not show handshake files that are in cracked.txt with a key (match on filename) (#133)

Make cracked.txt a configurable variable
* Do not show handshake files that are in cracked.txt with a key (match on filename).
* Don't ask user for a crack-tool when attacking PMKIDs only
* Few minor cleanups

Fixed any_pmkid -> all_pmkid (to decide that we are strictly using hashcat)
* Added a safe-check to make sure we are indeed using hashcat for the PMKID hashes
* Changed the ugly split() to basename()

Making an FR from the TODO
This commit is contained in:
WhiteOnBlackCode
2018-09-03 20:53:59 +03:00
committed by derv
parent 5e204686fa
commit 6d492aca44
3 changed files with 47 additions and 22 deletions

View File

@@ -82,6 +82,7 @@ class Configuration(object):
cls.pmkid_timeout = 30 # Time to wait for PMKID capture cls.pmkid_timeout = 30 # Time to wait for PMKID capture
# Default dictionary for cracking # Default dictionary for cracking
cls.cracked_file = 'cracked.txt'
cls.wordlist = None cls.wordlist = None
wordlists = [ wordlists = [
'./wordlist-top4800-probable.txt', # Local file (ran from cloned repo) './wordlist-top4800-probable.txt', # Local file (ran from cloned repo)

View File

@@ -2,6 +2,7 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from ..util.color import Color from ..util.color import Color
from ..config import Configuration
import os import os
import time import time
@@ -11,7 +12,7 @@ class CrackResult(object):
''' Abstract class containing results from a crack session ''' ''' Abstract class containing results from a crack session '''
# File to save cracks to, in PWD # File to save cracks to, in PWD
cracked_file = 'cracked.txt' cracked_file = Configuration.cracked_file
def __init__(self): def __init__(self):
self.date = int(time.time()) self.date = int(time.time())
@@ -55,8 +56,8 @@ class CrackResult(object):
this_dict['date'] = entry.get('date') this_dict['date'] = entry.get('date')
if entry == this_dict: if entry == this_dict:
# Skip if we already saved this BSSID+ESSID+TYPE+KEY # Skip if we already saved this BSSID+ESSID+TYPE+KEY
Color.pl('{+} {C}%s{O} already exists in {G}cracked.txt{O}, skipping.' % ( Color.pl('{+} {C}%s{O} already exists in {G}%s{O}, skipping.' % (
self.essid)) self.essid, Configuration.cracked_file))
return return
saved_results.append(self.to_dict()) saved_results.append(self.to_dict())
@@ -67,7 +68,7 @@ class CrackResult(object):
@classmethod @classmethod
def display(cls): def display(cls):
''' Show cracked targets from cracked.txt ''' ''' Show cracked targets from cracked file '''
name = cls.cracked_file name = cls.cracked_file
if not os.path.exists(name): if not os.path.exists(name):
Color.pl('{!} {O}file {C}%s{O} not found{W}' % name) Color.pl('{!} {O}file {C}%s{O} not found{W}' % name)

View File

@@ -13,15 +13,13 @@ from ..tools.cowpatty import Cowpatty
from ..tools.hashcat import Hashcat, HcxPcapTool from ..tools.hashcat import Hashcat, HcxPcapTool
from ..tools.john import John from ..tools.john import John
from datetime import datetime from json import loads
import os import os
# TODO: Bring back the 'print' option, for easy copy/pasting. Just one-liners people can paste into terminal. # TODO: Bring back the 'print' option, for easy copy/pasting. Just one-liners people can paste into terminal.
# 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) # TODO: --no-crack option while attacking targets (implies user will run --crack later)
class CrackHelper: class CrackHelper:
@@ -32,7 +30,6 @@ class CrackHelper:
'PMKID': 'PMKID Hash' 'PMKID': 'PMKID Hash'
} }
@classmethod @classmethod
def run(cls): def run(cls):
Configuration.initialize(False) Configuration.initialize(False)
@@ -53,7 +50,7 @@ class CrackHelper:
return return
hs_to_crack = cls.get_user_selection(handshakes) hs_to_crack = cls.get_user_selection(handshakes)
any_pmkid = any([hs['type'] == 'PMKID' for hs in hs_to_crack]) all_pmkid = all([hs['type'] == 'PMKID' for hs in hs_to_crack])
# Tools for cracking & their dependencies. # Tools for cracking & their dependencies.
available_tools = { available_tools = {
@@ -79,26 +76,48 @@ class CrackHelper:
dep_list = ', '.join([dep.dependency_name for dep in deps]) dep_list = ', '.join([dep.dependency_name for dep in deps])
Color.pl(' {R}* {R}%s {W}({O}%s{W})' % (tool, dep_list)) 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}' % ( if all_pmkid:
'{W}, {C}'.join(available_tools.keys())))
tool_name = raw_input()
if tool_name not in available_tools:
Color.pl('{!} {R}"%s"{O} tool not found, defaulting to {C}aircrack{W}' % tool_name)
tool_name = 'aircrack'
elif any_pmkid and tool_name != 'hashcat':
Color.pl('{!} {O}Note: PMKID hashes will be cracked using {C}hashcat{W}') Color.pl('{!} {O}Note: PMKID hashes will be cracked using {C}hashcat{W}')
tool_name = 'hashcat'
else:
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('{!} {R}"%s"{O} tool not found, defaulting to {C}aircrack{W}' % tool_name)
tool_name = 'aircrack'
try: try:
for hs in hs_to_crack: for hs in hs_to_crack:
if tool_name != 'hashcat' and hs['type'] == 'PMKID':
if 'hashcat' in missing_tools:
Color.pl('{!} {O}Hashcat is missing, therefore we cannot crack PMKID hash{W}')
else:
cls.crack(hs, 'hashcat')
cls.crack(hs, tool_name) cls.crack(hs, tool_name)
except KeyboardInterrupt: except KeyboardInterrupt:
Color.pl('\n{!} {O}Interrupted{W}') Color.pl('\n{!} {O}Interrupted{W}')
@classmethod
def is_cracked(cls, file):
if not os.path.exists(Configuration.cracked_file):
return False
with open(Configuration.cracked_file) as f:
json = loads(f.read())
if json is None:
return False
for result in json:
for k in result.keys():
v = result[k]
if 'file' in k and os.path.basename(v) == file:
return True
return False
@classmethod @classmethod
def get_handshakes(cls): def get_handshakes(cls):
handshakes = [] handshakes = []
skipped_pmkid_files = 0 skipped_pmkid_files = skipped_cracked_files = 0
hs_dir = Configuration.wpa_handshake_dir hs_dir = Configuration.wpa_handshake_dir
if not os.path.exists(hs_dir) or not os.path.isdir(hs_dir): if not os.path.exists(hs_dir) or not os.path.isdir(hs_dir):
@@ -110,6 +129,10 @@ class CrackHelper:
if hs_file.count('_') != 3: if hs_file.count('_') != 3:
continue continue
if cls.is_cracked(hs_file):
skipped_cracked_files += 1
continue
if hs_file.endswith('.cap'): if hs_file.endswith('.cap'):
# WPA Handshake # WPA Handshake
hs_type = '4-WAY' hs_type = '4-WAY'
@@ -148,7 +171,9 @@ class CrackHelper:
handshakes.append(handshake) handshakes.append(handshake)
if skipped_pmkid_files > 0: if skipped_pmkid_files > 0:
Color.pl('{!} {O}Skipping %d {R}*.16800{O} files because {R}hashcat{O} is missing.' % skipped_pmkid_files) Color.pl('{!} {O}Skipping %d {R}*.16800{O} files because {R}hashcat{O} is missing.\n' % skipped_pmkid_files)
if skipped_cracked_files > 0:
Color.pl('{!} {O}Skipping %d already cracked files.\n' % skipped_cracked_files)
# Sort by Date (Descending) # Sort by Date (Descending)
return sorted(handshakes, key=lambda x: x.get('date'), reverse=True) return sorted(handshakes, key=lambda x: x.get('date'), reverse=True)
@@ -170,8 +195,6 @@ class CrackHelper:
Color.p(' ' + ('-' * 19) + '{W}\n') Color.p(' ' + ('-' * 19) + '{W}\n')
# Handshakes # Handshakes
for index, handshake in enumerate(handshakes, start=1): for index, handshake in enumerate(handshakes, start=1):
bssid = handshake['bssid']
date = handshake['date']
Color.p(' {G}%s{W}' % str(index).rjust(3)) Color.p(' {G}%s{W}' % str(index).rjust(3))
Color.p(' {C}%s{W}' % handshake['essid'].ljust(max_essid_len)) Color.p(' {C}%s{W}' % handshake['essid'].ljust(max_essid_len))
Color.p(' {O}%s{W}' % handshake['bssid'].ljust(17)) Color.p(' {O}%s{W}' % handshake['bssid'].ljust(17))
@@ -208,7 +231,7 @@ class CrackHelper:
cls.TYPES[hs['type']], hs['essid'], hs['bssid'])) cls.TYPES[hs['type']], hs['essid'], hs['bssid']))
if hs['type'] == 'PMKID': if hs['type'] == 'PMKID':
crack_result = cls.crack_pmkid(hs, tool) crack_result = cls.crack_pmkid(hs)
elif hs['type'] == '4-WAY': elif hs['type'] == '4-WAY':
crack_result = cls.crack_4way(hs, tool) crack_result = cls.crack_4way(hs, tool)
else: else:
@@ -253,7 +276,7 @@ class CrackHelper:
@classmethod @classmethod
def crack_pmkid(cls, hs, tool_name): def crack_pmkid(cls, hs):
key = Hashcat.crack_pmkid(hs['filename'], verbose=True) key = Hashcat.crack_pmkid(hs['filename'], verbose=True)
if key is not None: if key is not None: