WPA handshake capture and cracking almost setup

This commit is contained in:
derv82
2015-06-01 00:30:02 -07:00
parent 50538168e2
commit 625642fee7
8 changed files with 189 additions and 19 deletions

View File

@@ -85,10 +85,8 @@ class AttackWEP(Attack):
essid = airodump_target.essid
else:
essid = None
print '\n'
Color.pl('{+} {C}%s{W} WEP attack {G}successful{W}'
Color.pl('\n{+} {C}%s{W} WEP attack {G}successful{W}\n'
% attack_name)
print ''
if aireplay:
aireplay.stop()
self.crack_result = CrackResultWEP(bssid, \
@@ -138,8 +136,8 @@ class AttackWEP(Attack):
# TODO: Check for .xor file.
# If .xor is not there, the process failed. Check stdout.
# XXX: For debugging
print '\n%s stopped, output:' % attack_name
print aireplay.get_output()
Color.pl('\n%s stopped, output:' % attack_name)
Color.pl(aireplay.get_output())
break
# If .xor exists, run packetforge-ng to create .cap
@@ -148,8 +146,8 @@ class AttackWEP(Attack):
# 2. Start Aireplay to replay the .cap file
else:
Color.pl('\n{!} {O}aireplay-ng exited unexpectedly{W}')
print '\naireplay.get_output():'
print aireplay.get_output()
Color.pl('\naireplay.get_output():')
Color.pl(aireplay.get_output())
break
# Check if IVs stopped flowing (same for > N seconds)

View File

@@ -1,10 +1,19 @@
#!/usr/bin/python
from Attack import Attack
from Airodump import Airodump
from Color import Color
from Configuration import Configuration
from Handshake import Handshake
from Process import Process
from WPAResult import WPAResult
import time
class AttackWPA(Attack):
def __init__(self, target):
super(AttackWPA, self).__init__(target)
self.crack_result = None
def run(self):
'''
@@ -15,8 +24,117 @@ class AttackWPA(Attack):
target_bssid=self.target.bssid,
output_file_prefix='wpa') as airodump:
Color.p('\r{+} {O}waiting{W} for target to appear...')
airodump_target = self.wait_for_target(airodump)
for attack_num in xrange(1, 6):
attack_type = WEPAttackType(attack_num)
clients = airodump_target.clients
client_index = 0
handshake = None
time_since_deauth = time.time()
while True:
Color.p('\r %s' % (' ' * 45))
Color.p('\r{+} waiting for {C}handshake{W}...')
time.sleep(1)
# Find .cap file
cap_files = airodump.find_files(endswith='.cap')
if len(cap_files) == 0:
# No cap files yet
continue
cap_file = cap_files[0]
# Check for Handshake
bssid = airodump_target.bssid
essid = None
if airodump_target.essid_known:
essid = airodump_target.essid
handshake = Handshake(cap_file, bssid=bssid, essid=essid)
if handshake.has_handshake():
# We got a handshake
Color.pl(' {G}captured handshake!{W}')
break
# TODO: Send deauth to a client or broadcast
if time.time()-time_since_deauth > Configuration.wpa_deauth_timeout:
if len(clients) == 0 or client_index >= len(clients):
# Send deauth for broadcoast
client_index = 0
else:
# Send deauth for client
client = clients[client_index]
client_index += 1
time_since_deauth = time.time()
continue
if not handshake:
# No handshake, attack failed.
raise Exception('Handshake not captured')
return False
key = None
# TODO: Save copy of handshake to ./hs/
import os
if not os.path.exists('hs'):
os.mkdir('hs')
import re
essid_safe = re.sub('[^a-zA-Z0-9]', '', handshake.essid)
bssid_safe = handshake.bssid.replace(':', '-')
date = time.strftime('%Y-%m-%dT%H-%M-%S')
cap_filename = 'handshake_%s_%s_%s.cap' % (essid_safe, bssid_safe, date)
cap_filename = os.path.join('hs', cap_filename)
from shutil import copy
Color.p('{+} saving copy of {C}handshake{W} to {C}%s{W} ' % cap_filename)
copy(handshake.capfile, cap_filename)
Color.pl(' {G}saved{W}')
handshake.capfile = cap_filename
# TODO: Crack handshake
wordlist = Configuration.wordlist
if wordlist != None:
if not os.path.exists(wordlist):
Color.pl('{!} {R}unable to crack:' +
' wordlist {O}%s{R} does not exist{W}' % wordlist)
else:
# We have a wordlist we can use
Color.p('{+} {G}cracking{W} handshake using {C}%s{W} wordlist'
% wordlist.split(os.sep)[-1])
# TODO: More-verbose cracking status
# 1. Read number of lines in 'wordlist'
# 2. Pipe aircrack stdout to file
# 3. Read from file every second, get keys tried so far
# 4. Display # of keys tried / total keys, and ETA
key_file = Configuration.temp('wpakey.txt')
command = [
'aircrack-ng',
'-a', '2',
'-w', wordlist,
'-l', key_file,
handshake.capfile
]
aircrack = Process(command, devnull=True)
aircrack.wait()
if os.path.exists(key_file):
# We cracked it.
Color.pl('{G}cracked{W}')
f = open(key_file, 'r')
key = f.read()
f.close()
else:
Color.pl('{R}failed{W}')
self.crack_result = WPAResult(bssid, essid, handshake.capfile, key)
self.crack_result.dump()
return True
if __name__ == '__main__':
from 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()

View File

@@ -23,6 +23,8 @@ class Color(object):
'{!}': ' {W}[{R}!{W}]'
}
last_sameline_length = 0
@staticmethod
def p(text):
'''
@@ -32,6 +34,7 @@ class Color(object):
'''
sys.stdout.write(Color.s(text))
sys.stdout.flush()
Color.last_sameline_length += len(text)
@staticmethod
def pl(text):
@@ -39,6 +42,7 @@ class Color(object):
Prints text using colored format with trailing new line.
'''
Color.p('%s\n' % text)
Color.last_sameline_length = 0
@staticmethod
def s(text):
@@ -50,6 +54,12 @@ class Color(object):
output = output.replace("{%s}" % key, value)
return output
@staticmethod
def clear_line():
spaces = ' ' * Color.last_sameline_length
sys.stdout.write('\r%s\r' % spaces)
sys.stdout.flush()
if __name__ == '__main__':
Color.pl("{R}Testing{G}One{C}Two{P}Three{W}Done")
print Color.s("{C}Testing{P}String{W}")

View File

@@ -95,11 +95,11 @@ class Configuration(object):
@staticmethod
def temp():
def temp(subfile=''):
''' Creates and/or returns the temporary directory '''
if Configuration.temp_dir == None:
Configuration.temp_dir = Configuration.create_temp()
return Configuration.temp_dir
return Configuration.temp_dir + subfile
@staticmethod
def create_temp():

View File

@@ -59,15 +59,22 @@ class Handshake(object):
if not self.bssid or not self.essid:
self.divine_essid_and_bssid()
if self.tshark_handshakes():
if len(self.tshark_handshakes()) > 0:
return True
if self.cowpatty_handshakes():
if len(self.cowpatty_handshakes()) > 0:
return True
if self.pyrit_handshakes():
if len(self.pyrit_handshakes()) > 0:
return True
# XXX: Disabling aircrack check since I don't think it's reliable.
'''
if len(self.aircrack_handshakes()) > 0:
return True
'''
return False
def tshark_bssid_essid_pairs(self):
'''

View File

@@ -86,6 +86,9 @@ class Process(object):
''' Returns exit code if process is dead, otherwise "None" '''
return self.pid.poll()
def wait(self):
self.pid.wait()
def running_time(self):
''' Returns number of seconds since process was started '''
return int(time.time() - self.start_time)

View File

@@ -39,7 +39,7 @@ class Scanner(object):
[len(t.clients)
for t in self.targets])
Color.p(
"\r {+} Scanning, " +
"\r{+} Scanning, " +
"found {G}%d{W} target(s)," % target_count +
" {G}%d{W} clients" % client_count +
". {O}Ctrl+C{W} when ready")
@@ -71,7 +71,7 @@ class Scanner(object):
else:
# We can fit the targets in the terminal without scrolling
# "Move" cursor up so we will print over the previous list
print Scanner.UP_CHAR * (3 + self.previous_target_count)
Color.pl(Scanner.UP_CHAR * (3 + self.previous_target_count))
self.previous_target_count = len(self.targets)
@@ -109,6 +109,9 @@ class Scanner(object):
chosen_targets = []
for choice in raw_input(Color.s(input_str)).split(','):
if choice == 'all':
chosen_targets = self.targets
break
if '-' in choice:
# User selected a range
(lower,upper) = [int(x) - 1 for x in choice.split('-')]
@@ -130,7 +133,6 @@ if __name__ == '__main__':
Color.pl('\r {!} {R}Error{W}: %s' % str(e))
Configuration.exit_gracefully(0)
for t in targets:
Color.p("{W}Selected: ")
print t
Color.pl(" {W}Selected: %s" % t)
Configuration.exit_gracefully(0)

32
py/WPAResult.py Normal file
View File

@@ -0,0 +1,32 @@
#!/usr/bin/python
from Color import Color
class WPAResult(object):
def __init__(self, bssid, essid, handshake_file, key):
self.bssid = bssid
self.essid = essid
self.handshake_file = handshake_file
self.key = key
def dump(self):
if self.essid:
Color.pl('{+} %s: {C}%s{W}' %
('Access Point Name'.rjust(19), self.essid))
if self.bssid:
Color.pl('{+} %s: {C}%s{W}' %
('Access Point BSSID'.rjust(19), self.bssid))
if self.handshake_file:
Color.pl('{+} %s: {C}%s{W}' %
('Handshake File'.rjust(19), self.handshake_file))
if self.key:
Color.pl('{+} %s: {G}%s{W}' % ('PSK (password)'.rjust(19), self.key))
else:
Color.pl('{!} %s {O}key unknown{W}' % ''.rjust(19))
if __name__ == '__main__':
w = WPAResult('AA:BB:CC:DD:EE:FF', 'Test Router', 'hs/capfile.cap', 'abcd1234')
w.dump()
print '\n'
w = WPAResult('AA:BB:CC:DD:EE:FF', 'Test Router', 'hs/capfile.cap', None)
w.dump()