Merge branch 'master' of https://github.com/kimocoder/wifite2 into kimocoder-master

This commit is contained in:
derv82
2018-02-27 04:24:39 -05:00
4 changed files with 141 additions and 90 deletions

View File

@@ -17,6 +17,12 @@ class Arguments(object):
# Global variables # Global variables
glob = parser.add_argument_group('SETTINGS') glob = parser.add_argument_group('SETTINGS')
glob.add_argument('-s',
action='store',
dest='scan_time',
metavar='[scantime]',
type=int,
help=Color.s('Seconds to scan before attacking (default: {G}ask{W})'))
glob.add_argument('-i', glob.add_argument('-i',
action='store', action='store',
dest='interface', dest='interface',
@@ -71,6 +77,11 @@ class Arguments(object):
metavar="[num]", metavar="[num]",
default=None, 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})' % Configuration.num_deauths))
glob.add_argument('-p',
action='store',
dest='pillage',
type=bool,
help=Color.s('Pillage "All" mode to attack everything (default: {G}ask{W})'))
# WEP # WEP
wep = parser.add_argument_group('WEP-RELATED') wep = parser.add_argument_group('WEP-RELATED')

View File

@@ -46,75 +46,81 @@ class AttackWPA(Attack):
self.clients = [] self.clients = []
handshake = None bssid = airodump_target.bssid
essid = airodump_target.essid if airodump_target.essid_known else None
handshake = self.load_handshake(bssid=bssid, essid=essid)
timeout_timer = Timer(Configuration.wpa_attack_timeout) if handshake:
deauth_timer = Timer(Configuration.wpa_deauth_timeout) Color.pl('\n\n{+} {G}using existing handshake found at %s{W}' % handshake.capfile)
Color.pl('\n\n{+} {G}successfully loaded handshake{W}')
else:
timeout_timer = Timer(Configuration.wpa_attack_timeout)
deauth_timer = Timer(Configuration.wpa_deauth_timeout)
while handshake is None and not timeout_timer.ended(): while handshake is None and not timeout_timer.ended():
step_timer = Timer(1) step_timer = Timer(1)
Color.clear_entire_line() Color.clear_entire_line()
Color.pattack("WPA", Color.pattack("WPA",
airodump_target, airodump_target,
"Handshake capture", "Handshake capture",
"Listening. (clients:{G}%d{W}, deauth:{O}%s{W}, timeout:{R}%s{W})" % (len(self.clients), deauth_timer, timeout_timer)) "Listening. (clients:{G}%d{W}, deauth:{O}%s{W}, timeout:{R}%s{W})" % (len(self.clients), deauth_timer, timeout_timer))
# Find .cap file # Find .cap file
cap_files = airodump.find_files(endswith='.cap') cap_files = airodump.find_files(endswith='.cap')
if len(cap_files) == 0: if len(cap_files) == 0:
# No cap files yet # No cap files yet
time.sleep(step_timer.remaining())
continue
cap_file = cap_files[0]
# Copy .cap file to temp for consistency
temp_file = Configuration.temp('handshake.cap.bak')
copy(cap_file, temp_file)
# Check cap file in temp for Handshake
bssid = airodump_target.bssid
essid = airodump_target.essid if airodump_target.essid_known else None
handshake = Handshake(temp_file, bssid=bssid, essid=essid)
if handshake.has_handshake():
# We got a handshake
Color.pl('\n\n{+} {G}successfully captured handshake{W}')
break
# There is no handshake
handshake = None
# Delete copied .cap file in temp to save space
os.remove(temp_file)
# Look for new clients
airodump_target = self.wait_for_target(airodump)
for client in airodump_target.clients:
if client.station not in self.clients:
Color.clear_entire_line()
Color.pattack("WPA",
airodump_target,
"Handshake capture",
"Discovered new client: {G}%s{W}" % client.station)
Color.pl("")
self.clients.append(client.station)
# Send deauth to a client or broadcast
if deauth_timer.ended():
self.deauth(airodump_target)
# Restart timer
deauth_timer = Timer(Configuration.wpa_deauth_timeout)
# Sleep for at-most 1 second
time.sleep(step_timer.remaining()) time.sleep(step_timer.remaining())
continue continue # Handshake listen+deauth loop
cap_file = cap_files[0]
# Copy .cap file to temp for consistency if not handshake:
temp_file = Configuration.temp('handshake.cap.bak') # No handshake, attack failed.
copy(cap_file, temp_file) Color.pl("\n{!} {O}WPA handshake capture {R}FAILED:{O} Timed out after %d seconds" % (Configuration.wpa_attack_timeout))
self.success = False
return self.success
# Check cap file in temp for Handshake # Save copy of handshake to ./hs/
bssid = airodump_target.bssid self.save_handshake(handshake)
essid = airodump_target.essid if airodump_target.essid_known else None
handshake = Handshake(temp_file, bssid=bssid, essid=essid)
if handshake.has_handshake():
# We got a handshake
Color.pl('\n\n{+} {G}successfully captured handshake{W}')
break
# There is no handshake
handshake = None
# Delete copied .cap file in temp to save space
os.remove(temp_file)
# Look for new clients
airodump_target = self.wait_for_target(airodump)
for client in airodump_target.clients:
if client.station not in self.clients:
Color.clear_entire_line()
Color.pattack("WPA",
airodump_target,
"Handshake capture",
"Discovered new client: {G}%s{W}" % client.station)
Color.pl("")
self.clients.append(client.station)
# Send deauth to a client or broadcast
if deauth_timer.ended():
self.deauth(airodump_target)
# Restart timer
deauth_timer = Timer(Configuration.wpa_deauth_timeout)
# Sleep for at-most 1 second
time.sleep(step_timer.remaining())
continue # Handshake listen+deauth loop
if not handshake:
# No handshake, attack failed.
Color.pl("\n{!} {O}WPA handshake capture {R}FAILED:{O} Timed out after %d seconds" % (Configuration.wpa_attack_timeout))
self.success = False
return self.success
# Save copy of handshake to ./hs/
self.save_handshake(handshake)
# Print analysis of handshake file # Print analysis of handshake file
Color.pl('\n{+} analysis of captured handshake file:') Color.pl('\n{+} analysis of captured handshake file:')
@@ -200,6 +206,24 @@ class AttackWPA(Attack):
" {O}%s{R} did not contain password{W}" % wordlist.split(os.sep)[-1]) " {O}%s{R} did not contain password{W}" % wordlist.split(os.sep)[-1])
return None return None
def load_handshake(self, bssid, essid):
if not os.path.exists(Configuration.wpa_handshake_dir):
return None
if essid:
essid_safe = re.escape(re.sub('[^a-zA-Z0-9]', '', essid))
else:
essid_safe = '[a-zA-Z0-9]+'
bssid_safe = re.escape(bssid.replace(':', '-'))
date = '\d{4}-\d{2}-\d{2}T\d{2}-\d{2}-\d{2}'
get_filename = re.compile('handshake_%s_%s_%s\.cap' % (essid_safe, bssid_safe, date))
for filename in os.listdir(Configuration.wpa_handshake_dir):
cap_filename = os.path.join(Configuration.wpa_handshake_dir, filename)
if os.path.isfile(cap_filename) and re.match(get_filename, filename):
return Handshake(capfile=cap_filename, bssid=bssid, essid=essid)
return None
def save_handshake(self, handshake): def save_handshake(self, handshake):
''' '''

View File

@@ -28,6 +28,9 @@ class Configuration(object):
Configuration.verbose = 0 # Verbosity level. Configuration.verbose = 0 # Verbosity level.
Configuration.scan_time = 0 # Scan time
Configuration.all_targets = False # Run attacks against all targets automatically
Configuration.tx_power = 0 # Wifi transmit power (0 is default) Configuration.tx_power = 0 # Wifi transmit power (0 is default)
Configuration.interface = None Configuration.interface = None
Configuration.target_channel = None # User-defined channel to scan Configuration.target_channel = None # User-defined channel to scan
@@ -66,7 +69,7 @@ class Configuration(object):
wordlists = [ wordlists = [
'/usr/share/wfuzz/wordlist/fuzzdb/wordlists-user-passwd/passwds/phpbb.txt', '/usr/share/wfuzz/wordlist/fuzzdb/wordlists-user-passwd/passwds/phpbb.txt',
'/usr/share/fuzzdb/wordlists-user-passwd/passwds/phpbb.txt', '/usr/share/fuzzdb/wordlists-user-passwd/passwds/phpbb.txt',
'/usr/share/wordlists/fern-wifi/common.txt' '/usr/share/fern-wifi-cracker/extras/wordlists/common.txt'
] ]
for wlist in wordlists: for wlist in wordlists:
if os.path.exists(wlist): if os.path.exists(wlist):
@@ -138,6 +141,12 @@ class Configuration(object):
if args.target_essid: if args.target_essid:
Configuration.target_essid = args.target_essid Configuration.target_essid = args.target_essid
Color.pl('{+} {C}option:{W} targeting ESSID {G}%s{W}' % args.target_essid) Color.pl('{+} {C}option:{W} targeting ESSID {G}%s{W}' % args.target_essid)
if args.scan_time:
Configuration.scan_time = args.scan_time
Color.pl('{+} {C}option:{W} scan time {G}%d{W}' % args.scan_time)
if args.pillage:
Configuration.verbose = args.pillage
Color.pl('{+} {C}option:{W} pillage {G}%d{W}' % args.verbose)
if args.verbose: if args.verbose:
Configuration.verbose = args.verbose Configuration.verbose = args.verbose
Color.pl('{+} {C}option:{W} verbosity level {G}%d{W}' % args.verbose) Color.pl('{+} {C}option:{W} verbosity level {G}%d{W}' % args.verbose)

View File

@@ -6,7 +6,7 @@ from Color import Color
from Target import Target from Target import Target
from Configuration import Configuration from Configuration import Configuration
from time import sleep from time import sleep, time
class Scanner(object): class Scanner(object):
''' Scans wifi networks & provides menu for selecting targets ''' ''' Scans wifi networks & provides menu for selecting targets '''
@@ -23,13 +23,15 @@ class Scanner(object):
self.targets = [] self.targets = []
self.target = None # Specific target (based on ESSID/BSSID) self.target = None # Specific target (based on ESSID/BSSID)
scan_time = Configuration.scan_time # currently in seconds
Color.pl("") Color.pl("")
# Loads airodump with interface/channel/etc from Configuration # Loads airodump with interface/channel/etc from Configuration
with Airodump() as airodump: with Airodump() as airodump:
try: try:
# Loop until interrupted (Ctrl+C) # Loop until interrupted (Ctrl+C) or until scan_time is reached (if scan_time was defined)
start_time = time()
while True: while True:
if airodump.pid.poll() is not None: if airodump.pid.poll() is not None:
# Airodump process died! # Airodump process died!
raise Exception( raise Exception(
@@ -63,6 +65,8 @@ class Scanner(object):
outline += " {G}%s{W}) " % ", ".join([x.essid for x in decloaked]) outline += " {G}%s{W}) " % ", ".join([x.essid for x in decloaked])
Color.clear_entire_line() Color.clear_entire_line()
Color.p(outline) Color.p(outline)
if scan_time > 0 and time() > (start_time + scan_time):
return
sleep(1) sleep(1)
except KeyboardInterrupt: except KeyboardInterrupt:
pass pass
@@ -153,30 +157,33 @@ class Scanner(object):
+ " You may need to wait longer," + " You may need to wait longer,"
+ " or you may have issues with your wifi card") + " or you may have issues with your wifi card")
self.print_targets() if not (Configuration.pillage is True):
Color.clear_entire_line() self.print_targets()
input_str = '{+} select target(s)' Color.clear_entire_line()
input_str += ' ({G}1-%d{W})' % len(self.targets) input_str = '{+} select target(s)'
input_str += ' separated by commas, dashes' input_str += ' ({G}1-%d{W})' % len(self.targets)
input_str += ' or {G}all{W}: ' input_str += ' separated by commas, dashes'
input_str += ' or {G}all{W}: '
chosen_targets = [] 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('-')]
for i in xrange(lower, min(len(self.targets), upper)):
chosen_targets.append(self.targets[i])
elif choice.isdigit():
choice = int(choice) - 1
chosen_targets.append(self.targets[choice])
else:
pass
return 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('-')]
for i in xrange(lower, min(len(self.targets), upper)):
chosen_targets.append(self.targets[i])
elif choice.isdigit():
choice = int(choice) - 1
chosen_targets.append(self.targets[choice])
else:
pass
return chosen_targets
else:
return self.targets
if __name__ == '__main__': if __name__ == '__main__':
# Example displays targets and selects the appropriate one # Example displays targets and selects the appropriate one