From 0e274af5a08be24e88ab0a8165b5938c52f70799 Mon Sep 17 00:00:00 2001 From: Jeroen Oudshoorn Date: Thu, 8 Feb 2024 20:06:33 +0100 Subject: [PATCH] Revert "Testing pcapng fileformat" This reverts commit 7040be2d3079ce5d3496c858a07632da1dfda69b. --- pwnagotchi/plugins/default/gps.py | 2 +- pwnagotchi/plugins/default/grid.py | 17 +++---- pwnagotchi/plugins/default/hashie.py | 6 +-- pwnagotchi/plugins/default/net-pos.py | 2 +- pwnagotchi/plugins/default/onlinehashcrack.py | 4 +- pwnagotchi/plugins/default/webgpsmap.py | 44 +++++++++++-------- pwnagotchi/plugins/default/wigle.py | 10 ++--- pwnagotchi/plugins/default/wpa-sec.py | 2 +- pwnagotchi/utils.py | 10 ++--- 9 files changed, 53 insertions(+), 44 deletions(-) diff --git a/pwnagotchi/plugins/default/gps.py b/pwnagotchi/plugins/default/gps.py index 0e5f958d..a351406b 100644 --- a/pwnagotchi/plugins/default/gps.py +++ b/pwnagotchi/plugins/default/gps.py @@ -48,7 +48,7 @@ class GPS(plugins.Plugin): if self.running: info = agent.session() self.coordinates = info["gps"] - gps_filename = filename.replace(".pcapng", ".gps.json") + gps_filename = filename.replace(".pcap", ".gps.json") if self.coordinates and all([ # avoid 0.000... measurements diff --git a/pwnagotchi/plugins/default/grid.py b/pwnagotchi/plugins/default/grid.py index fbc3374e..cdca794e 100644 --- a/pwnagotchi/plugins/default/grid.py +++ b/pwnagotchi/plugins/default/grid.py @@ -5,21 +5,22 @@ import glob import re import pwnagotchi.grid as grid +import pwnagotchi.plugins import pwnagotchi.plugins as plugins -from pwnagotchi.utils import StatusFile, WifiInfo, extract_from_pcapng +from pwnagotchi.utils import StatusFile, WifiInfo, extract_from_pcap from threading import Lock def parse_pcap(filename): logging.info("grid: parsing %s ..." % filename) - net_id = os.path.basename(filename).replace('.pcapng', '') + net_id = os.path.basename(filename).replace('.pcap', '') if '_' in net_id: - # /root/handshakes/ESSID_BSSID.pcapng + # /root/handshakes/ESSID_BSSID.pcap essid, bssid = net_id.split('_') else: - # /root/handshakes/BSSID.pcapng + # /root/handshakes/BSSID.pcap essid, bssid = '', net_id mac_re = re.compile('[0-9a-fA-F]{12}') @@ -35,7 +36,7 @@ def parse_pcap(filename): } try: - info = extract_from_pcapng(filename, [WifiInfo.BSSID, WifiInfo.ESSID]) + info = extract_from_pcap(filename, [WifiInfo.BSSID, WifiInfo.ESSID]) except Exception as e: logging.error("grid: %s" % e) @@ -86,10 +87,10 @@ class Grid(plugins.Plugin): agent.view().on_unread_messages(self.unread_messages, self.total_messages) def check_handshakes(self, agent): - logging.debug("checking pcapng's") + logging.debug("checking pcaps") config = agent.config() - pcap_files = glob.glob(os.path.join(agent.config()['bettercap']['handshakes'], "*.pcapng")) + pcap_files = glob.glob(os.path.join(agent.config()['bettercap']['handshakes'], "*.pcap")) num_networks = len(pcap_files) reported = self.report.data_field_or('reported', default=[]) num_reported = len(reported) @@ -102,7 +103,7 @@ class Grid(plugins.Plugin): logging.debug(" exclude: %s" % config['main']['whitelist']) for pcap_file in pcap_files: - net_id = os.path.basename(pcap_file).replace('.pcapng', '') + net_id = os.path.basename(pcap_file).replace('.pcap', '') if net_id not in reported: if self.is_excluded(net_id, agent): logging.debug("skipping %s due to exclusion filter" % pcap_file) diff --git a/pwnagotchi/plugins/default/hashie.py b/pwnagotchi/plugins/default/hashie.py index b5c8e18a..cd41122b 100644 --- a/pwnagotchi/plugins/default/hashie.py +++ b/pwnagotchi/plugins/default/hashie.py @@ -82,12 +82,12 @@ class Hashie(plugins.Plugin): if os.path.isfile(fullpathNoExt + '.22000'): handshake_status.append('Already have {}.22000 (EAPOL)'.format(name)) elif self._writeEAPOL(filename): - handshake_status.append('Created {}.22000 (EAPOL) from pcapng'.format(name)) + handshake_status.append('Created {}.22000 (EAPOL) from pcap'.format(name)) if os.path.isfile(fullpathNoExt + '.16800'): handshake_status.append('Already have {}.16800 (PMKID)'.format(name)) elif self._writePMKID(filename): - handshake_status.append('Created {}.16800 (PMKID) from pcapng'.format(name)) + handshake_status.append('Created {}.16800 (PMKID) from pcap'.format(name)) if handshake_status: logging.info('[Hashie] Good news:\n\t' + '\n\t'.join(handshake_status)) @@ -111,7 +111,7 @@ class Hashie(plugins.Plugin): return False def _process_stale_pcaps(self, handshake_dir): - handshakes_list = [os.path.join(handshake_dir, filename) for filename in os.listdir(handshake_dir) if filename.endswith('.pcapng')] + handshakes_list = [os.path.join(handshake_dir, filename) for filename in os.listdir(handshake_dir) if filename.endswith('.pcap')] failed_jobs = [] successful_jobs = [] lonely_pcaps = [] diff --git a/pwnagotchi/plugins/default/net-pos.py b/pwnagotchi/plugins/default/net-pos.py index ef5f0c59..3f226204 100644 --- a/pwnagotchi/plugins/default/net-pos.py +++ b/pwnagotchi/plugins/default/net-pos.py @@ -108,7 +108,7 @@ class NetPos(plugins.Plugin): return netpos["ts"] = int("%.0f" % time.time()) - netpos_filename = filename.replace('.pcapng', '.net-pos.json') + netpos_filename = filename.replace('.pcap', '.net-pos.json') logging.debug("NET-POS: Saving net-location to %s", netpos_filename) try: diff --git a/pwnagotchi/plugins/default/onlinehashcrack.py b/pwnagotchi/plugins/default/onlinehashcrack.py index 1eafb9fa..aeb01dda 100644 --- a/pwnagotchi/plugins/default/onlinehashcrack.py +++ b/pwnagotchi/plugins/default/onlinehashcrack.py @@ -142,6 +142,6 @@ class OnlineHashCrack(plugins.Plugin): for row in csv.DictReader(cracked_list): if row['password']: filename = re.sub(r'[^a-zA-Z0-9]', '', row['ESSID']) + '_' + row['BSSID'].replace(':','') - if os.path.exists( os.path.join(handshake_dir, filename+'.pcapng')): - with open(os.path.join(handshake_dir, filename+'.pcapng.cracked'), 'w') as f: + if os.path.exists( os.path.join(handshake_dir, filename+'.pcap') ): + with open(os.path.join(handshake_dir, filename+'.pcap.cracked'), 'w') as f: f.write(row['password']) diff --git a/pwnagotchi/plugins/default/webgpsmap.py b/pwnagotchi/plugins/default/webgpsmap.py index b03fef50..f9f513d9 100644 --- a/pwnagotchi/plugins/default/webgpsmap.py +++ b/pwnagotchi/plugins/default/webgpsmap.py @@ -13,8 +13,8 @@ from dateutil.parser import parse webgpsmap shows existing position data stored in your /handshakes/ directory the plugin does the following: - - search for *.pcapng files in your /handshakes/ dir - - for every found .pcapng file it looks for a .geo.json or .gps.json or file with + - search for *.pcap files in your /handshakes/ dir + - for every found .pcap file it looks for a .geo.json or .gps.json or .paw-gps.json file with latitude+longitude data inside and shows this position on the map - if also an .cracked file with a plaintext password inside exist, it reads the content and shows the position as green instead of red and the password inside the infopox of the position @@ -87,8 +87,7 @@ class Webgpsmap(plugins.Plugin): # returns all positions try: self.ALREADY_SENT = list() - response_data = bytes( - json.dumps(self.load_gps_from_dir(self.config['bettercap']['handshakes'])), "utf-8") + response_data = bytes(json.dumps(self.load_gps_from_dir(self.config['bettercap']['handshakes'])), "utf-8") response_status = 200 response_mimetype = "application/json" response_header_contenttype = 'application/json' @@ -101,8 +100,7 @@ class Webgpsmap(plugins.Plugin): self.ALREADY_SENT = list() json_data = json.dumps(self.load_gps_from_dir(self.config['bettercap']['handshakes'])) html_data = self.get_html() - html_data = html_data.replace('var positions = [];', - 'var positions = ' + json_data + ';positionsLoaded=true;drawPositions();') + html_data = html_data.replace('var positions = [];', 'var positions = ' + json_data + ';positionsLoaded=true;drawPositions();') response_data = bytes(html_data, "utf-8") response_status = 200 response_mimetype = "application/xhtml+xml" @@ -165,8 +163,7 @@ class Webgpsmap(plugins.Plugin): all_files = os.listdir(handshake_dir) # print(all_files) - all_pcap_files = [os.path.join(handshake_dir, filename) for filename in all_files if - filename.endswith('.pcapng')] + all_pcap_files = [os.path.join(handshake_dir, filename) for filename in all_files if filename.endswith('.pcap')] all_geo_or_gps_files = [] for filename_pcap in all_pcap_files: filename_base = filename_pcap[:-5] # remove ".pcap" @@ -183,18 +180,22 @@ class Webgpsmap(plugins.Plugin): if check_for in all_files: filename_position = str(os.path.join(handshake_dir, check_for)) + logging.debug("[webgpsmap] search for .paw-gps.json") + check_for = os.path.basename(filename_base) + ".paw-gps.json" + if check_for in all_files: + filename_position = str(os.path.join(handshake_dir, check_for)) + logging.debug(f"[webgpsmap] end search for position data files and use {filename_position}") if filename_position is not None: all_geo_or_gps_files.append(filename_position) - # all_geo_or_gps_files = set(all_geo_or_gps_files) - set(SKIP) # remove skipped networks? No! + # all_geo_or_gps_files = set(all_geo_or_gps_files) - set(SKIP) # remove skipped networks? No! if newest_only: all_geo_or_gps_files = set(all_geo_or_gps_files) - set(self.ALREADY_SENT) - logging.info( - f"[webgpsmap] Found {len(all_geo_or_gps_files)} position-data files from {len(all_pcap_files)} handshakes. Fetching positions ...") + logging.info(f"[webgpsmap] Found {len(all_geo_or_gps_files)} position-data files from {len(all_pcap_files)} handshakes. Fetching positions ...") for pos_file in all_geo_or_gps_files: try: @@ -212,7 +213,9 @@ class Webgpsmap(plugins.Plugin): pos_type = 'gps' elif pos.type() == PositionFile.GEO: pos_type = 'geo' - gps_data[ssid + "_" + mac] = { + elif pos.type() == PositionFile.PAWGPS: + pos_type = 'paw' + gps_data[ssid+"_"+mac] = { 'ssid': ssid, 'mac': mac, 'type': pos_type, @@ -221,10 +224,10 @@ class Webgpsmap(plugins.Plugin): 'acc': pos.accuracy(), 'ts_first': pos.timestamp_first(), 'ts_last': pos.timestamp_last(), - } + } # get ap password if exist - check_for = os.path.basename(pos_file).split(".")[0] + ".pcapng.cracked" + check_for = os.path.basename(pos_file).split(".")[0] + ".pcap.cracked" if check_for in all_files: gps_data[ssid + "_" + mac]["pass"] = pos.password() @@ -262,6 +265,7 @@ class PositionFile: """ GPS = 1 GEO = 2 + PAWGPS = 3 def __init__(self, path): self._file = path @@ -278,7 +282,7 @@ class PositionFile: """ Returns the mac from filename """ - parsed_mac = re.search(r'.*_?([a-zA-Z0-9]{12})\.(?:gps|geo)\.json', self._filename) + parsed_mac = re.search(r'.*_?([a-zA-Z0-9]{12})\.(?:gps|geo|paw-gps)\.json', self._filename) if parsed_mac: mac = parsed_mac.groups()[0] return mac @@ -288,7 +292,7 @@ class PositionFile: """ Returns the ssid from filename """ - parsed_ssid = re.search(r'(.+)_[a-zA-Z0-9]{12}\.(?:gps|geo)\.json', self._filename) + parsed_ssid = re.search(r'(.+)_[a-zA-Z0-9]{12}\.(?:gps|geo|paw-gps)\.json', self._filename) if parsed_ssid: return parsed_ssid.groups()[0] return None @@ -329,7 +333,7 @@ class PositionFile: return_pass = None # 2do: make better filename split/remove extension because this one has problems with "." in path base_filename, ext1, ext2 = re.split('\.', self._file) - password_file_path = base_filename + ".pcapng.cracked" + password_file_path = base_filename + ".pcap.cracked" if os.path.isfile(password_file_path): try: password_file = open(password_file_path, 'r') @@ -350,6 +354,8 @@ class PositionFile: return PositionFile.GPS if self._file.endswith('.geo.json'): return PositionFile.GEO + if self._file.endswith('.paw-gps.json'): + return PositionFile.PAWGPS return None def lat(self): @@ -396,7 +402,9 @@ class PositionFile: def accuracy(self): if self.type() == PositionFile.GPS: - return 50.0 # a default + return 50.0 # a default + if self.type() == PositionFile.PAWGPS: + return 50.0 # a default if self.type() == PositionFile.GEO: try: return self._json['accuracy'] diff --git a/pwnagotchi/plugins/default/wigle.py b/pwnagotchi/plugins/default/wigle.py index 11805c3b..353660ea 100644 --- a/pwnagotchi/plugins/default/wigle.py +++ b/pwnagotchi/plugins/default/wigle.py @@ -7,7 +7,7 @@ import pwnagotchi from io import StringIO from datetime import datetime -from pwnagotchi.utils import WifiInfo, FieldNotFoundError, extract_from_pcapng, StatusFile, remove_whitelisted +from pwnagotchi.utils import WifiInfo, FieldNotFoundError, extract_from_pcap, StatusFile, remove_whitelisted from threading import Lock from pwnagotchi import plugins from pwnagotchi._version import __version__ as __pwnagotchi_version__ @@ -153,11 +153,11 @@ class Wigle(plugins.Plugin): no_err_entries = list() for gps_file in new_gps_files: if gps_file.endswith('.gps.json'): - pcap_filename = gps_file.replace('.gps.json', '.pcapng') + pcap_filename = gps_file.replace('.gps.json', '.pcap') if gps_file.endswith('.geo.json'): - pcap_filename = gps_file.replace('.geo.json', '.pcapng') + pcap_filename = gps_file.replace('.geo.json', '.pcap') if not os.path.exists(pcap_filename): - logging.debug("WIGLE: Can't find pcapng for %s", gps_file) + logging.debug("WIGLE: Can't find pcap for %s", gps_file) self.skip.append(gps_file) continue try: @@ -175,7 +175,7 @@ class Wigle(plugins.Plugin): self.skip.append(gps_file) continue try: - pcap_data = extract_from_pcapng(pcap_filename, [WifiInfo.BSSID, + pcap_data = extract_from_pcap(pcap_filename, [WifiInfo.BSSID, WifiInfo.ESSID, WifiInfo.ENCRYPTION, WifiInfo.CHANNEL, diff --git a/pwnagotchi/plugins/default/wpa-sec.py b/pwnagotchi/plugins/default/wpa-sec.py index 42f1c29f..696b53b4 100644 --- a/pwnagotchi/plugins/default/wpa-sec.py +++ b/pwnagotchi/plugins/default/wpa-sec.py @@ -98,7 +98,7 @@ class WpaSec(plugins.Plugin): reported = self.report.data_field_or('reported', default=list()) handshake_dir = config['bettercap']['handshakes'] handshake_filenames = os.listdir(handshake_dir) - handshake_paths = [os.path.join(handshake_dir, filename) for filename in handshake_filenames if filename.endswith('.pcapng')] + handshake_paths = [os.path.join(handshake_dir, filename) for filename in handshake_filenames if filename.endswith('.pcap')] handshake_paths = remove_whitelisted(handshake_paths, config['main']['whitelist']) handshake_new = set(handshake_paths) - set(reported) - set(self.skip) diff --git a/pwnagotchi/utils.py b/pwnagotchi/utils.py index eacf8899..4158f94b 100644 --- a/pwnagotchi/utils.py +++ b/pwnagotchi/utils.py @@ -82,7 +82,7 @@ def remove_whitelisted(list_of_handshakes, list_of_whitelisted_strings, valid_on for handshake in list_of_handshakes: try: - normalized_handshake = normalize(os.path.basename(handshake).rstrip('.pcapng')) + normalized_handshake = normalize(os.path.basename(handshake).rstrip('.pcap')) for whitelist in list_of_whitelisted_strings: normalized_whitelist = normalize(whitelist) if normalized_whitelist in normalized_handshake: @@ -440,7 +440,7 @@ def secs_to_hhmmss(secs): def total_unique_handshakes(path): - expr = os.path.join(path, "*.pcapng") + expr = os.path.join(path, "*.pcap") return len(glob.glob(expr)) @@ -498,11 +498,11 @@ def md5(fname): return hash_md5.hexdigest() -def extract_from_pcapng(path, fields): +def extract_from_pcap(path, fields): """ - Search in pcapng-file for specified information + Search in pcap-file for specified information - path: Path to pcapng file + path: Path to pcap file fields: Array of fields that should be extracted If a field is not found, FieldNotFoundError is raised