def check_for_wps_and_update_targets(capfile, targets): ''' Given a cap file and list of targets, use Wash to find which BSSIDs in the cap file use WPS. Then update the 'wps' flag for those BSSIDs in the targets. Args: capfile - .cap file from airodump containing packets targets - list of Targets from scan, to be updated ''' # Wash/Walsh is required to detect WPS wash_name = 'wash' if not Process.exists(wash_name): wash_name = 'walsh' if not Process.exists(wash_name): # Wash isn't found, drop out return command = [ 'wash', '-f', capfile # Path to cap file ] p = Process(command) p.wait() if p.poll() != 0: return bssids = [bssid.upper() for bssid in Wash.BSSID_REGEX.findall(p.stdout())] for t in targets: t.wps = t.bssid.upper() in bssids
def start_network_manager(): Color.p("{!} {O}restarting {R}NetworkManager{O}...") if Process.exists('service'): cmd = 'service network-manager start' proc = Process(cmd) (out, err) = proc.get_output() if proc.poll() != 0: Color.pl(" {R}Error executing {O}%s{W}" % cmd) if out is not None and out.strip() != "": Color.pl("{!} {O}STDOUT> %s{W}" % out) if err is not None and err.strip() != "": Color.pl("{!} {O}STDERR> %s{W}" % err) else: Color.pl(" {G}done{W} ({C}%s{W})" % cmd) return if Process.exists('systemctl'): cmd = 'systemctl start NetworkManager' proc = Process(cmd) (out, err) = proc.get_output() if proc.poll() != 0: Color.pl(" {R}Error executing {O}%s{W}" % cmd) if out is not None and out.strip() != "": Color.pl("{!} {O}STDOUT> %s{W}" % out) if err is not None and err.strip() != "": Color.pl("{!} {O}STDERR> %s{W}" % err) else: Color.pl(" {G}done{W} ({C}%s{W})" % cmd) return else: Color.pl( " {R}can't restart NetworkManager: {O}systemctl{R} or {O}service{R} not found{W}" )
def print_oclhashcat(self, cap_file): if not Process.exists("hashcat"): return Color.pl("\n {O}# OCLHASHCAT: GPU-based cracking. Fast.") hccapx_file = "generated.hccapx" if Process.exists("cap2hccapx"): Color.pl(" {G}cap2hccapx {C}%s %s{W}" % (cap_file, hccapx_file)) else: Color.pl(" {O}# Visit https://hashcat.net/cap2hccapx to generate a .hccapx file{W}") Color.pl(" {O}# Browse -> %s -> Convert" % cap_file) Color.pl(" {G}hashcat {W}-m 2500 {C}%s %s{W}" % (hccapx_file, self.wordlist))
def print_oclhashcat(self, cap_file): if not Process.exists("hashcat"): return Color.pl("\n {O}# OCLHASHCAT: GPU-based cracking. Fast.") hccapx_file = "generated.hccapx" if Process.exists("cap2hccapx"): Color.pl(" {G}cap2hccapx {C}%s %s{W}" % (cap_file, hccapx_file)) else: Color.pl( " {O}# Visit https://hashcat.net/cap2hccapx to generate a .hccapx file{W}" ) Color.pl(" {O}# Browse -> %s -> Convert" % cap_file) Color.pl(" {G}hashcat {W}-m 2500 {C}%s %s{W}" % (hccapx_file, self.wordlist))
def tshark_bssid_essid_pairs(self): ''' Scrapes capfile for beacon frames indicating the ESSID. Returns list of tuples: (bssid,essid) ''' if not Process.exists('tshark'): raise Exception('tshark is required to find ESSID') essids = set() # Extract beacon frames from cap file cmd = [ 'tshark', '-r', self.capfile, '-R', 'wlan.fc.type_subtype == 0x08', '-n' ] proc = Process(cmd, devnull=False) for line in proc.stdout().split('\n'): # Extract src, dst, and essid mac_regex = ('[a-zA-Z0-9]{2}:' * 6)[:-1] match = re.search( '(%s) -> (%s).*.*SSID=(.*)$' % (mac_regex, mac_regex), line) if match == None: # Line doesn't contain src, dst, ssid continue (src, dst, essid) = match.groups() if self.bssid: # We know the BSSID, only return the ESSID for this BSSID. if self.bssid.lower() == src.lower(): essids.add((src, essid)) else: # We do not know BSSID, add it. essids.add((src, essid)) # Return list of tuples return [x for x in essids]
def print_oclhashcat(self, cap_file): Color.pl("") if not Process.exists("hashcat"): Color.pl(" {R}hashcat {O}not found.") Color.pl( " {O}More info on installing {R}hashcat{O} here: {C}https://hashcat.net/hashcat/" ) return Color.pl(" {O}# HASHCAT: GPU-based cracking. Fast.") Color.pl( " {O}# See {C}https://hashcat.net/wiki/doku.php?id=cracking_wpawpa2 {O}for more info" ) hccapx_file = "/tmp/generated.hccapx" cap2hccapx = "/usr/lib/hashcat-utils/cap2hccapx.bin" if os.path.exists(cap2hccapx): Color.pl(" {G}%s {W}%s {C}%s{W}" % (cap2hccapx, cap_file, hccapx_file)) else: Color.pl( " {O}# Install hashcat-utils: {C}https://hashcat.net/wiki/doku.php?id=hashcat_utils" ) Color.pl(" {C}cap2hccapx.bin {W}%s {C}%s{W}" % (cap_file, hccapx_file)) Color.pl( " {O}# OR visit https://hashcat.net/cap2hccapx to generate a .hccapx file{W}" ) Color.pl( " {O}# Then click BROWSE -> %s -> CONVERT and save to %s" % (cap_file, hccapx_file)) Color.pl(" {G}hashcat {W}-m 2500 {C}%s %s{W}" % (hccapx_file, self.wordlist))
def print_john(self, cap_file): if not Process.exists("pyrit"): return Color.pl("\n {O}# JOHN: CPU or GPU-based cracking. Fast.") Color.pl(" {O}# Use --format=wpapsk-cuda (or wpapsk-opengl) to enable GPU acceleration") Color.pl(" {O}# See http://openwall.info/wiki/john/WPA-PSK for more info on this process") Color.pl(" {G}aircrack-ng {W}-J hccap {C}%s{W}" % cap_file) Color.pl(" {G}hccap2john {W}hccap.hccap > hccap.john{W}") Color.pl(" {G}john {W}--wordlist {C}\"%s\" {W}--format=wpapsk {C}\"hccap.john\"{W}" % (self.wordlist))
def print_aircrack(self, cap_file, bssid): Color.pl("") if not Process.exists("aircrack-ng"): Color.pl(" {R}aircrack-ng not found.") Color.pl( " {O}More info on installing {R}Aircrack{O} here: {C}https://www.aircrack-ng.org/downloads.html{W}" ) return Color.pl(" {O}# AIRCRACK: CPU-based cracking. Slow.") Color.pl(" {G}aircrack-ng {W}-a {C}2 {W}-b {C}%s {W}-w {C}%s %s{W}" % (bssid, self.wordlist, cap_file))
def print_pyrit(self, cap_file, bssid): Color.pl("") if not Process.exists("pyrit"): Color.pl(" {R}pyrit not found.") Color.pl( " {O}More info on installing {R}Pyrit{O} here: {C}https://github.com/JPaulMora/Pyrit{W}" ) return Color.pl(" {O}# PYRIT: GPU-based cracking. Fast.") Color.pl( " {G}pyrit {W}-b {C}%s {W}-i {C}%s {W}-r {C}%s {W}attack_passthrough{W}" % (bssid, self.wordlist, cap_file))
def cowpatty_handshakes(self): ''' Returns True if cowpatty identifies a handshake, False otherwise ''' if not Process.exists('cowpatty'): return [] if not self.essid: return [] # We need a essid for cowpatty :( proc = Process(self.cowpatty_command(), devnull=False) for line in proc.stdout().split('\n'): if 'Collected all necessary data to mount crack against WPA' in line: return [(None, self.essid)] return []
def check_for_wps_and_update_targets(capfile, targets): ''' Given a cap file and list of targets, use TShark to find which BSSIDs in the cap file use WPS. Then update the 'wps' flag for those BSSIDs in the targets. Args: capfile - .cap file from airodump containing packets targets - list of Targets from scan, to be updated ''' # Tshark is required to detect WPS networks if not Process.exists('tshark'): return command = [ 'tshark', '-r', capfile, # Path to cap file '-n', # Don't resolve addresses # Filter WPS broadcast packets '-Y', 'wps.wifi_protected_setup_state && wlan.da == ff:ff:ff:ff:ff:ff', '-T', 'fields', # Only output certain fields '-e', 'wlan.ta', # BSSID '-e', 'wps.ap_setup_locked', # Locked status '-E', 'separator=,' # CSV ] p = Process(command) try: p.wait() lines = p.stdout() except: # Failure is acceptable return bssids = set() for line in lines.split('\n'): if ',' not in line: continue bssid, locked = line.split(',') # TODO: Ignore if WPS is locked? bssids.add(bssid.upper()) for t in targets: t.wps = t.bssid.upper() in bssids
def print_john(self, cap_file): if not Process.exists("pyrit"): return Color.pl("\n {O}# JOHN: CPU or GPU-based cracking. Fast.") Color.pl( " {O}# Use --format=wpapsk-cuda (or wpapsk-opengl) to enable GPU acceleration" ) Color.pl( " {O}# See http://openwall.info/wiki/john/WPA-PSK for more info on this process" ) Color.pl(" {G}aircrack-ng {W}-J hccap {C}%s{W}" % cap_file) Color.pl(" {G}hccap2john {W}hccap.hccap > hccap.john{W}") Color.pl( " {G}john {W}--wordlist {C}\"%s\" {W}--format=wpapsk {C}\"hccap.john\"{W}" % (self.wordlist))
def pyrit_handshakes(self): ''' Returns True if pyrit identifies a handshake, False otherwise ''' if not Process.exists('pyrit'): return [] bssid_essid_pairs = set() hit_target = False current_bssid = self.bssid current_essid = self.essid proc = Process(self.pyrit_command(), devnull=False) for line in proc.stdout().split('\n'): mac_regex = ('[a-zA-Z0-9]{2}:' * 6)[:-1] match = re.search("^#\d+: AccessPoint (%s) \('(.*)'\):$" % (mac_regex), line) if match: # We found a BSSID and ESSID (bssid, essid) = match.groups() # Compare to what we're searching for if self.bssid and self.bssid.lower() == bssid.lower(): current_essid = essid hit_target = True continue elif self.essid and self.essid == essid: current_bssid = bssid hit_target = True continue elif not self.bssid and not self.essid: # We don't know either current_bssid = bssid current_essid = essid hit_target = True else: # This AccessPoint is not what we're looking for hit_Target = False else: # Line does not contain AccessPoint if hit_target and ', good,' in line: bssid_essid_pairs.add( (current_bssid, current_essid) ) return [x for x in bssid_essid_pairs]
def print_john(self, cap_file): Color.pl("") if not Process.exists("john"): Color.pl(" {R}john not found.") Color.pl( " {O}More info on installing {R}John The Ripper{O} here: {C}http://www.openwall.com/john/{W}" ) return Color.pl(" {O}# JOHN: CPU or GPU-based cracking. Fast.") Color.pl( " {O}# Use --format=wpapsk-cuda (or wpapsk-opengl) to enable GPU acceleration" ) Color.pl( " {O}# See http://openwall.info/wiki/john/WPA-PSK for more info on this process" ) Color.pl(" {G}aircrack-ng {W}-J hccap {C}%s{W}" % cap_file) Color.pl(" {G}hccap2john {C}hccap.hccap {W}> {C}hccap.john{W}") Color.pl( " {G}john {W}--wordlist {C}\"%s\" {W}--format=wpapsk {C}\"hccap.john\"{W}" % (self.wordlist))
def check_for_wps_and_update_targets(capfile, targets): ''' Given a cap file and list of targets, use Wash to find which BSSIDs in the cap file use WPS. Then update the 'wps' flag for those BSSIDs in the targets. Args: capfile - .cap file from airodump containing packets targets - list of Targets from scan, to be updated ''' # Wash/Walsh is required to detect WPS wash_name = 'wash' if not Process.exists(wash_name): wash_name = 'walsh' if not Proces.exists(wash_name): # Wash isn't found, drop out return command = [ 'wash', '-f', capfile, # Path to cap file '-C' # Ignore Frame Check Sum errors ] p = Process(command) for line in p.stdout().split('\n'): # Ignore irrelevant lines if line.strip() == '' or line.startswith('Scanning for'): continue bssid = line.split(' ')[0] for t in targets: if t.bssid.lower() == bssid.lower(): # Update the WPS flag t.wps = True # Mark other targets as "no" wps support for t in targets: if t.wps: continue t.wps = False
def tshark_bssid_essid_pairs(self): ''' Scrapes capfile for beacon frames indicating the ESSID. Returns list of tuples: (bssid,essid) ''' if not Process.exists('tshark'): raise Exception('tshark is required to find ESSID') essids = set() # Extract beacon frames from cap file cmd = [ 'tshark', '-r', self.capfile, '-R', 'wlan.fc.type_subtype == 0x08 || wlan.fc.type_subtype == 0x05', '-2', # tshark: -R without -2 is deprecated. '-n' ] proc = Process(cmd, devnull=False) for line in proc.stdout().split('\n'): # Extract src, dst, and essid mac_regex = ('[a-zA-Z0-9]{2}:' * 6)[:-1] match = re.search('(%s) [^ ]* (%s).*.*SSID=(.*)$' % (mac_regex, mac_regex), line) if match == None: # Line doesn't contain src, dst, ssid continue (src, dst, essid) = match.groups() if dst.lower() == "ff:ff:ff:ff:ff:ff": continue if self.bssid: # We know the BSSID, only return the ESSID for this BSSID. if self.bssid.lower() == src.lower() or self.bssid.lower() == dst.lower(): essids.add((src, essid)) else: # We do not know BSSID, add it. essids.add((src, essid)) # Return list of tuples return [x for x in essids]
def tshark_handshakes(self): ''' Returns True if tshark identifies a handshake, False otherwise ''' if not Process.exists('tshark'): return [] target_client_msg_nums = {} # Dump EAPOL packets proc = Process(self.tshark_command(), devnull=False) for line in proc.stdout().split('\n'): # Extract source mac, destination mac, and message numbers mac_regex = ('[a-zA-Z0-9]{2}:' * 6)[:-1] match = re.search('(%s) -> (%s).*Message.*(\d).*(\d)' % (mac_regex, mac_regex), line) if match == None: # Line doesn't contain src, dst, Message numbers continue (src, dst, index, ttl) = match.groups() # "Message (index) of (ttl)" index = int(index) ttl = int(ttl) if ttl != 4: # Must be a 4-way handshake continue # Identify the client and target MAC addresses if index % 2 == 1: # First and Third messages target = src client = dst else: # Second and Fourth messages client = src target = dst if self.bssid and self.bssid.lower() != target.lower(): # We know the BSSID and this msg was not for the target continue target_client_key = '%s,%s' % (target, client) # Ensure all 4 messages are: # Between the same client and target # In numeric & chronological order (1,2,3,4) if index == 1: # First message, add to dict target_client_msg_nums[target_client_key] = 1 elif target_client_key not in target_client_msg_nums: # Not first message, we haven't gotten the first message yet continue elif index - 1 != target_client_msg_nums[target_client_key]: # Message is not in sequence continue else: # Message is > 1 and is received in-order target_client_msg_nums[target_client_key] = index bssids = set() # Check if we have all 4 messages for the handshake between the same MACs for (client_target, num) in target_client_msg_nums.iteritems(): if num == 4: # We got a handshake! bssid = client_target.split(',')[0] bssids.add(bssid) return [(bssid, None) for bssid in bssids]
def print_pyrit(self, cap_file): if not Process.exists("pyrit"): return Color.pl("\n {O}# PYRIT: GPU-based cracking. Fast.") Color.pl( " {G}pyrit {W}-i {C}%s {W}-r {C}%s {W}attack_passthrough{W}" % (self.wordlist, cap_file))
def print_pyrit(self, cap_file): if not Process.exists("pyrit"): return Color.pl("\n {O}# PYRIT: GPU-based cracking. Fast.") Color.pl(" {G}pyrit {W}-i {C}%s {W}-r {C}%s {W}attack_passthrough{W}" % (self.wordlist, cap_file))
def print_aircrack(self, cap_file): if not Process.exists("aircrack-ng"): return Color.pl("\n {O}# AIRCRACK: CPU-based cracking. Slow.") Color.pl(" {G}aircrack-ng {W}-a 2 -w {C}%s %s{W}" % (self.wordlist, cap_file))