From af33c1d9e429e9471bdb04445a21ef643e92b384 Mon Sep 17 00:00:00 2001 From: David Durvaux Date: Thu, 26 Oct 2023 07:42:32 +0200 Subject: [PATCH 1/4] Add authors to README --- README.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index f675629..e2446df 100644 --- a/README.md +++ b/README.md @@ -61,7 +61,7 @@ Tested On: - iOS13 - iOS14 - iOS16 -- iOS17.0 (ongoing) +- iOS17 # Timesketch @@ -75,6 +75,12 @@ Note that for a reasonable sysdiagnose log output, we recommend the following ba - Minimum 64 GB of HDD space just for timesketch data (add some more GBs for the OS and OS upgrades, etc.) - SSDs (NVMEs) for the data. +# Contributors + +- David DURVAUX (European Commission - EC DIGIT Cybersecurity Operation Centre) +- Aaron KAPLAN (European Commission - EC DIGIT Cybersecurity Operation Centre) +- Emilien Le Jamtel (CERT-EU) + # License This project is released under the European Public Licence https://commission.europa.eu/content/european-union-public-licence_en From 32569be1595aee786575d34c7284805f1e02b7b6 Mon Sep 17 00:00:00 2001 From: aaronkaplan Date: Wed, 22 Nov 2023 22:14:01 +0100 Subject: [PATCH 2/4] finally add the kml analyzer otherwise it gets embarassing. --- analyzers/sysdiagnose-wifi-gelocation-kml.py | 130 +++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 analyzers/sysdiagnose-wifi-gelocation-kml.py diff --git a/analyzers/sysdiagnose-wifi-gelocation-kml.py b/analyzers/sysdiagnose-wifi-gelocation-kml.py new file mode 100644 index 0000000..157e9fa --- /dev/null +++ b/analyzers/sysdiagnose-wifi-gelocation-kml.py @@ -0,0 +1,130 @@ +#! /usr/bin/env python3 + +# For Python3 +# Author: Aaron Kaplan + +import sys +import json +# import dateutil.parser +from optparse import OptionParser + +import xml.etree.ElementTree as ET + + +sys.path.append('..') # noqa: E402 +# from sysdiagnose import config # noqa: E402 + + +version_string = "sysdiagnose-wifi-geolocation-kml.py v2023-08-09 Version 0.2" + +# ----- definition for analyse.py script -----# +# ----- DO NOT DELETE ----# + +analyser_description = "Generate KML file for wifi geolocations" +analyser_call = "generate_kml" +analyser_format = "json" + + +def generate_kml(jsonfile: str, outfile: str = "wifi-geolocations.kml"): + """ + Modify the function to generate a KML file from Wi-Fi geolocation data and include a tour between the locations. + Reads as input and extracts all known Wi-Fi networks and their locations. + """ + try: + with open(jsonfile, 'r') as fp: + json_data = json.load(fp) + except Exception as e: + print(f"Error while parsing inputfile JSON. Reason: {str(e)}") + sys.exit(-1) + + json_entry = json_data.get('com.apple.wifi.known-networks.plist') + if not json_entry: + print("Could not find the 'com.apple.wifi.known-networks.plist' section. Bailing out.", file=sys.stderr) + sys.exit(-2) + json_data = json_entry + + # Create new KML root + kml = ET.Element('kml', xmlns='http://www.opengis.net/kml/2.2') + document = ET.SubElement(kml, 'Document') + + # Add tour elements + tour = ET.SubElement(document, 'gx:Tour') + ET.SubElement(tour, 'name').text = 'WiFi Tour' + playlist = ET.SubElement(tour, 'gx:Playlist') + + for network_name, network_data in json_data.items(): + ssid = network_name + lat = network_data.get('Latitude') + lon = network_data.get('Longitude') + + if lat and lon: + placemark = ET.SubElement(document, 'Placemark') + ET.SubElement(placemark, 'name').text = ssid + point = ET.SubElement(placemark, 'Point') + ET.SubElement(point, 'coordinates').text = f"{lon},{lat},0" + + # Add to tour playlist + flyto = ET.SubElement(playlist, 'gx:FlyTo') + ET.SubElement(flyto, 'gx:duration').text = '5.0' # Duration of each flyto + ET.SubElement(flyto, 'gx:flyToMode').text = 'smooth' + camera = ET.SubElement(flyto, 'Camera') + ET.SubElement(camera, 'longitude').text = str(lon) + ET.SubElement(camera, 'latitude').text = str(lat) + ET.SubElement(camera, 'altitude').text = '500' # Camera altitude + ET.SubElement(camera, 'heading').text = '0' + ET.SubElement(camera, 'tilt').text = '45' + ET.SubElement(camera, 'roll').text = '0' + + # Convert the ElementTree to a string and save it to a file + tree = ET.ElementTree(kml) + tree.write(outfile) + + # Example usage: + # generate_kml_with_tour('input_json_file.json', 'output_kml_file.kml') + + return + + +# --------------------------------------------------------------------------- # +""" + Main function +""" + + +def main(): + + print(f"Running {version_string}\n") + + usage = "\n%prog -d JSON directory\n" + + parser = OptionParser(usage=usage) + parser.add_option("-i", dest="inputfile", + action="store", type="string", + help="JSON file from parsers") + parser.add_option("-o", dest="outputfile", + action="store", type="string", + help="KML file to save output") + (options, args) = parser.parse_args() + + # no arguments given by user, print help and exit + if len(sys.argv) == 1: + parser.print_help() + sys.exit(-1) + + if not options.inputfile and not options.outputfile: + parser.error("Need to specify inputfile and outputfile") + else: + generate_kml(options.inputfile, outfile=options.outputfile) + + +# --------------------------------------------------------------------------- # + +""" + Call main function +""" +if __name__ == "__main__": + + # Create an instance of the Analysis class (called "base") and run main + main() + +# That's all folks ;) From 474371ce0f25bf0b46fd88c4c90ae5dea3c07d70 Mon Sep 17 00:00:00 2001 From: aaronkaplan Date: Wed, 22 Nov 2023 23:05:26 +0100 Subject: [PATCH 3/4] fix pycodestyle error --- parsers/sysdiagnose-networkextension.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/parsers/sysdiagnose-networkextension.py b/parsers/sysdiagnose-networkextension.py index b22ee38..c437a3b 100644 --- a/parsers/sysdiagnose-networkextension.py +++ b/parsers/sysdiagnose-networkextension.py @@ -45,7 +45,7 @@ def parseplist(file): output = {'objects': []} for object in objects: - if type(object) == str: + if isinstance(object,str): output['objects'].append(object) return output From fabab825f94e23aa81904d06474c889c618e934e Mon Sep 17 00:00:00 2001 From: aaronkaplan Date: Wed, 22 Nov 2023 23:12:19 +0100 Subject: [PATCH 4/4] more pycodestyle fixes --- .github/workflows/pycodestyle.yml | 2 +- analyzers/apps.py | 7 +++++-- parsers/sysdiagnose-networkextension.py | 10 +++++----- parsing.py | 2 +- 4 files changed, 12 insertions(+), 9 deletions(-) diff --git a/.github/workflows/pycodestyle.yml b/.github/workflows/pycodestyle.yml index 323314c..5158d21 100644 --- a/.github/workflows/pycodestyle.yml +++ b/.github/workflows/pycodestyle.yml @@ -28,4 +28,4 @@ jobs: - name: Analysing the code with pycodestyle run: | - pycodestyle --exclude=venv --ignore=errors=E221,E225,E251,E501,E266,E302 --max-line-length=128 $(git ls-files '*.py') + pycodestyle --exclude=venv --ignore=errors=E302,E221,E225,E251,E501,E266,E302 --max-line-length=128 $(git ls-files '*.py') diff --git a/analyzers/apps.py b/analyzers/apps.py index 3ba78f6..fe8acf7 100644 --- a/analyzers/apps.py +++ b/analyzers/apps.py @@ -15,11 +15,11 @@ -v --version Show version. """ import os -from optparse import OptionParser +# from optparse import OptionParser import json import ijson from docopt import docopt -import glob +# import glob version_string = "sysdiagnose-demo-analyser.py v2023-04-28 Version 0.1" @@ -32,6 +32,7 @@ # --------------------------------------------------------------------------- # + def apps_analysis(jsondir, filename): """ Go through all json files in the folder and generate the markdown file @@ -94,6 +95,8 @@ def apps_analysis(jsondir, filename): """ Main function """ + + def main(): """ Main function, to be called when used as CLI tool diff --git a/parsers/sysdiagnose-networkextension.py b/parsers/sysdiagnose-networkextension.py index c437a3b..50c81fa 100644 --- a/parsers/sysdiagnose-networkextension.py +++ b/parsers/sysdiagnose-networkextension.py @@ -16,11 +16,11 @@ -v --version Show version. """ -import sys -from optparse import OptionParser -import plistlib +# import sys +# from optparse import OptionParser +# import plistlib import biplist -import json +# import json from docopt import docopt from tabulate import tabulate @@ -45,7 +45,7 @@ def parseplist(file): output = {'objects': []} for object in objects: - if isinstance(object,str): + if isinstance(object, str): output['objects'].append(object) return output diff --git a/parsing.py b/parsing.py index 0c93df3..31baa1e 100644 --- a/parsing.py +++ b/parsing.py @@ -116,7 +116,7 @@ def parse(parser, case_id): spec.loader.exec_module(module) # building command - if type(case[module.parser_input]) == str: + if isinstance(case[module.parser_input], str): command = 'module.' + module.parser_call + '(\'' + case[module.parser_input] + '\')' else: command = 'module.' + module.parser_call + '(' + str(case[module.parser_input]) + ')'