From 512f40dcb458036f4ff4b89d5ab99b171803ff73 Mon Sep 17 00:00:00 2001 From: Nex Date: Fri, 19 Nov 2021 15:27:51 +0100 Subject: [PATCH] Standardized code with flake8 --- mvt/android/cli.py | 7 +++++-- mvt/android/download_apks.py | 3 ++- mvt/android/lookups/koodous.py | 1 + mvt/android/lookups/virustotal.py | 3 +++ mvt/android/modules/adb/base.py | 3 ++- mvt/android/modules/adb/chrome_history.py | 1 + mvt/android/modules/adb/dumpsys_batterystats.py | 3 ++- mvt/android/modules/adb/dumpsys_full.py | 3 ++- mvt/android/modules/adb/dumpsys_procstats.py | 1 + mvt/android/modules/adb/dumpsys_receivers.py | 9 +++++---- mvt/android/modules/adb/files.py | 1 + mvt/android/modules/adb/packages.py | 4 ++-- mvt/android/modules/adb/processes.py | 1 + mvt/android/modules/adb/rootbinaries.py | 1 + mvt/android/modules/adb/sms.py | 15 ++++++++------- mvt/android/modules/adb/whatsapp.py | 3 ++- mvt/android/modules/backup/__init__.py | 2 +- mvt/android/modules/backup/sms.py | 2 +- mvt/common/indicators.py | 3 ++- mvt/common/logo.py | 2 +- mvt/common/module.py | 3 +++ mvt/common/url.py | 5 +++-- mvt/common/utils.py | 5 ++++- mvt/common/version.py | 1 + mvt/ios/cli.py | 5 ++++- mvt/ios/decrypt.py | 1 + mvt/ios/modules/backup/configuration_profiles.py | 1 + mvt/ios/modules/backup/manifest.py | 10 +++++----- mvt/ios/modules/backup/profile_events.py | 1 + mvt/ios/modules/fs/__init__.py | 2 +- mvt/ios/modules/fs/analytics.py | 6 +++--- mvt/ios/modules/fs/cache_files.py | 4 ++-- mvt/ios/modules/fs/filesystem.py | 4 ++-- mvt/ios/modules/fs/net_netusage.py | 1 + mvt/ios/modules/fs/safari_favicon.py | 1 + mvt/ios/modules/fs/shutdownlog.py | 5 +++-- mvt/ios/modules/fs/version_history.py | 1 + mvt/ios/modules/fs/webkit_indexeddb.py | 1 + mvt/ios/modules/fs/webkit_localstorage.py | 1 + mvt/ios/modules/fs/webkit_safariviewservice.py | 1 + mvt/ios/modules/mixed/__init__.py | 2 +- mvt/ios/modules/mixed/calls.py | 3 ++- mvt/ios/modules/mixed/chrome_favicon.py | 1 + mvt/ios/modules/mixed/chrome_history.py | 2 +- mvt/ios/modules/mixed/contacts.py | 1 + mvt/ios/modules/mixed/firefox_favicon.py | 5 +++-- mvt/ios/modules/mixed/firefox_history.py | 1 + mvt/ios/modules/mixed/idstatuscache.py | 3 ++- mvt/ios/modules/mixed/interactionc.py | 8 ++++---- mvt/ios/modules/mixed/locationd.py | 1 + mvt/ios/modules/mixed/net_datausage.py | 1 + mvt/ios/modules/mixed/osanalytics_addaily.py | 5 +++-- mvt/ios/modules/mixed/safari_browserstate.py | 3 ++- mvt/ios/modules/mixed/safari_history.py | 3 ++- mvt/ios/modules/mixed/sms.py | 5 +++-- mvt/ios/modules/mixed/sms_attachments.py | 5 +++-- mvt/ios/modules/mixed/tcc.py | 3 ++- .../mixed/webkit_resource_load_statistics.py | 5 +++-- .../modules/mixed/webkit_session_resource_log.py | 1 + mvt/ios/modules/mixed/whatsapp.py | 1 + mvt/ios/modules/net_base.py | 2 +- mvt/ios/versions.py | 2 ++ setup.py | 2 ++ 63 files changed, 127 insertions(+), 65 deletions(-) diff --git a/mvt/android/cli.py b/mvt/android/cli.py index 9f2c824..47142e3 100644 --- a/mvt/android/cli.py +++ b/mvt/android/cli.py @@ -9,7 +9,9 @@ import os import click from rich.logging import RichHandler -from mvt.common.help import * +from mvt.common.help import HELP_MSG_MODULE, HELP_MSG_IOC +from mvt.common.help import HELP_MSG_OUTPUT, HELP_MSG_LIST_MODULES +from mvt.common.help import HELP_MSG_SERIAL from mvt.common.indicators import Indicators, IndicatorsFileBadFormat from mvt.common.logo import logo from mvt.common.module import run_module, save_timeline @@ -26,6 +28,7 @@ logging.basicConfig(level="INFO", format=LOG_FORMAT, handlers=[ RichHandler(show_path=False, log_time_format="%X")]) log = logging.getLogger(__name__) + #============================================================================== # Main #============================================================================== @@ -191,7 +194,7 @@ def check_backup(ctx, iocs, output, backup_path, serial): log.critical("The path you specified is a not a folder!") if os.path.basename(backup_path) == "backup.ab": - log.info("You can use ABE (https://github.com/nelenkov/android-backup-extractor) " \ + log.info("You can use ABE (https://github.com/nelenkov/android-backup-extractor) " "to extract 'backup.ab' files!") ctx.exit(1) diff --git a/mvt/android/download_apks.py b/mvt/android/download_apks.py index 66c87c0..7a9b8b2 100644 --- a/mvt/android/download_apks.py +++ b/mvt/android/download_apks.py @@ -16,6 +16,7 @@ from .modules.adb.packages import Packages log = logging.getLogger(__name__) + # TODO: Would be better to replace tqdm with rich.progress to reduce # the number of dependencies. Need to investigate whether # it's possible to have a similar callback system. @@ -137,7 +138,7 @@ class DownloadAPKs(AndroidExtraction): packages_selection.append(package) log.info("Selected only %d packages which are not marked as system", - len(packages_selection)) + len(packages_selection)) if len(packages_selection) == 0: log.info("No packages were selected for download") diff --git a/mvt/android/lookups/koodous.py b/mvt/android/lookups/koodous.py index 1e5b576..e2c4bd7 100644 --- a/mvt/android/lookups/koodous.py +++ b/mvt/android/lookups/koodous.py @@ -13,6 +13,7 @@ from rich.text import Text log = logging.getLogger(__name__) + def koodous_lookup(packages): log.info("Looking up all extracted files on Koodous (www.koodous.com)") log.info("This might take a while...") diff --git a/mvt/android/lookups/virustotal.py b/mvt/android/lookups/virustotal.py index c5266f1..0046b25 100644 --- a/mvt/android/lookups/virustotal.py +++ b/mvt/android/lookups/virustotal.py @@ -13,6 +13,7 @@ from rich.text import Text log = logging.getLogger(__name__) + def get_virustotal_report(hashes): apikey = "233f22e200ca5822bd91103043ccac138b910db79f29af5616a9afe8b6f215ad" url = f"https://www.virustotal.com/partners/sysinternals/file-reports?apikey={apikey}" @@ -36,6 +37,7 @@ def get_virustotal_report(hashes): log.error("Unexpected response from VirusTotal: %s", res.status_code) return None + def virustotal_lookup(packages): log.info("Looking up all extracted files on VirusTotal (www.virustotal.com)") @@ -48,6 +50,7 @@ def virustotal_lookup(packages): total_unique_hashes = len(unique_hashes) detections = {} + def virustotal_query(batch): report = get_virustotal_report(batch) if not report: diff --git a/mvt/android/modules/adb/base.py b/mvt/android/modules/adb/base.py index e86f04a..c4a25c6 100644 --- a/mvt/android/modules/adb/base.py +++ b/mvt/android/modules/adb/base.py @@ -25,6 +25,7 @@ log = logging.getLogger(__name__) ADB_KEY_PATH = os.path.expanduser("~/.android/adbkey") ADB_PUB_KEY_PATH = os.path.expanduser("~/.android/adbkey.pub") + class AndroidExtraction(MVTModule): """This class provides a base for all Android extraction modules.""" @@ -89,7 +90,7 @@ class AndroidExtraction(MVTModule): except OSError as e: if e.errno == 113 and self.serial: log.critical("Unable to connect to the device %s: did you specify the correct IP addres?", - self.serial) + self.serial) sys.exit(-1) else: break diff --git a/mvt/android/modules/adb/chrome_history.py b/mvt/android/modules/adb/chrome_history.py index 1aac934..88c3af5 100644 --- a/mvt/android/modules/adb/chrome_history.py +++ b/mvt/android/modules/adb/chrome_history.py @@ -16,6 +16,7 @@ log = logging.getLogger(__name__) CHROME_HISTORY_PATH = "data/data/com.android.chrome/app_chrome/Default/History" + class ChromeHistory(AndroidExtraction): """This module extracts records from Android's Chrome browsing history.""" diff --git a/mvt/android/modules/adb/dumpsys_batterystats.py b/mvt/android/modules/adb/dumpsys_batterystats.py index b804c2f..ecec627 100644 --- a/mvt/android/modules/adb/dumpsys_batterystats.py +++ b/mvt/android/modules/adb/dumpsys_batterystats.py @@ -10,6 +10,7 @@ from .base import AndroidExtraction log = logging.getLogger(__name__) + class DumpsysBatterystats(AndroidExtraction): """This module extracts stats on battery consumption by processes.""" @@ -30,7 +31,7 @@ class DumpsysBatterystats(AndroidExtraction): handle.write(stats) log.info("Records from dumpsys batterystats stored at %s", - stats_path) + stats_path) history = self._adb_command("dumpsys batterystats --history") if self.output_folder: diff --git a/mvt/android/modules/adb/dumpsys_full.py b/mvt/android/modules/adb/dumpsys_full.py index 23311d2..ffed0dc 100644 --- a/mvt/android/modules/adb/dumpsys_full.py +++ b/mvt/android/modules/adb/dumpsys_full.py @@ -10,6 +10,7 @@ from .base import AndroidExtraction log = logging.getLogger(__name__) + class DumpsysFull(AndroidExtraction): """This module extracts stats on battery consumption by processes.""" @@ -30,6 +31,6 @@ class DumpsysFull(AndroidExtraction): handle.write(stats) log.info("Full dumpsys output stored at %s", - stats_path) + stats_path) self._adb_disconnect() diff --git a/mvt/android/modules/adb/dumpsys_procstats.py b/mvt/android/modules/adb/dumpsys_procstats.py index a2a69c7..74a321d 100644 --- a/mvt/android/modules/adb/dumpsys_procstats.py +++ b/mvt/android/modules/adb/dumpsys_procstats.py @@ -10,6 +10,7 @@ from .base import AndroidExtraction log = logging.getLogger(__name__) + class DumpsysProcstats(AndroidExtraction): """This module extracts stats on memory consumption by processes.""" diff --git a/mvt/android/modules/adb/dumpsys_receivers.py b/mvt/android/modules/adb/dumpsys_receivers.py index 18730dc..342fc37 100644 --- a/mvt/android/modules/adb/dumpsys_receivers.py +++ b/mvt/android/modules/adb/dumpsys_receivers.py @@ -14,6 +14,7 @@ ACTION_SMS_RECEIVED = "android.provider.Telephony.SMS_RECEIVED" ACTION_DATA_SMS_RECEIVED = "android.intent.action.DATA_SMS_RECEIVED" ACTION_PHONE_STATE = "android.intent.action.PHONE_STATE" + class DumpsysReceivers(AndroidExtraction): """This module extracts details on receivers for risky activities.""" @@ -66,16 +67,16 @@ class DumpsysReceivers(AndroidExtraction): if activity == ACTION_NEW_OUTGOING_SMS: self.log.info("Found a receiver to intercept outgoing SMS messages: \"%s\"", - receiver) + receiver) elif activity == ACTION_SMS_RECEIVED: self.log.info("Found a receiver to intercept incoming SMS messages: \"%s\"", - receiver) + receiver) elif activity == ACTION_DATA_SMS_RECEIVED: self.log.info("Found a receiver to intercept incoming data SMS message: \"%s\"", - receiver) + receiver) elif activity == ACTION_PHONE_STATE: self.log.info("Found a receiver monitoring telephony state: \"%s\"", - receiver) + receiver) self.results.append({ "activity": activity, diff --git a/mvt/android/modules/adb/files.py b/mvt/android/modules/adb/files.py index d1b8bcf..521f349 100644 --- a/mvt/android/modules/adb/files.py +++ b/mvt/android/modules/adb/files.py @@ -10,6 +10,7 @@ from .base import AndroidExtraction log = logging.getLogger(__name__) + class Files(AndroidExtraction): """This module extracts the list of installed packages.""" diff --git a/mvt/android/modules/adb/packages.py b/mvt/android/modules/adb/packages.py index 538e451..c415348 100644 --- a/mvt/android/modules/adb/packages.py +++ b/mvt/android/modules/adb/packages.py @@ -12,6 +12,7 @@ from .base import AndroidExtraction log = logging.getLogger(__name__) + class Packages(AndroidExtraction): """This module extracts the list of installed packages.""" @@ -49,11 +50,10 @@ class Packages(AndroidExtraction): root_packages = root_packages_string.decode("utf-8").split("\n") root_packages = [rp.strip() for rp in root_packages] - for result in self.results: if result["package_name"] in root_packages: self.log.warning("Found an installed package related to rooting/jailbreaking: \"%s\"", - result["package_name"]) + result["package_name"]) self.detected.append(result) if result["package_name"] in self.indicators.ioc_app_ids: self.log.warning("Found a malicious package name: \"%s\"", diff --git a/mvt/android/modules/adb/processes.py b/mvt/android/modules/adb/processes.py index ac18526..1d2d872 100644 --- a/mvt/android/modules/adb/processes.py +++ b/mvt/android/modules/adb/processes.py @@ -9,6 +9,7 @@ from .base import AndroidExtraction log = logging.getLogger(__name__) + class Processes(AndroidExtraction): """This module extracts details on running processes.""" diff --git a/mvt/android/modules/adb/rootbinaries.py b/mvt/android/modules/adb/rootbinaries.py index 65e45dd..a9e6c27 100644 --- a/mvt/android/modules/adb/rootbinaries.py +++ b/mvt/android/modules/adb/rootbinaries.py @@ -12,6 +12,7 @@ from .base import AndroidExtraction log = logging.getLogger(__name__) + class RootBinaries(AndroidExtraction): """This module extracts the list of installed packages.""" diff --git a/mvt/android/modules/adb/sms.py b/mvt/android/modules/adb/sms.py index f13f269..dc4fbef 100644 --- a/mvt/android/modules/adb/sms.py +++ b/mvt/android/modules/adb/sms.py @@ -15,12 +15,12 @@ log = logging.getLogger(__name__) SMS_BUGLE_PATH = "data/data/com.google.android.apps.messaging/databases/bugle_db" SMS_BUGLE_QUERY = """ -SELECT +SELECT ppl.normalized_destination AS number, p.timestamp AS timestamp, -CASE WHEN m.sender_id IN +CASE WHEN m.sender_id IN (SELECT _id FROM participants WHERE contact_id=-1) -THEN 2 ELSE 1 END incoming, p.text AS text +THEN 2 ELSE 1 END incoming, p.text AS text FROM messages m, conversations c, parts p, participants ppl, conversation_participants cp WHERE (m.conversation_id = c._id) @@ -31,14 +31,15 @@ WHERE (m.conversation_id = c._id) SMS_MMSSMS_PATH = "data/data/com.android.providers.telephony/databases/mmssms.db" SMS_MMSMS_QUERY = """ -SELECT +SELECT address AS number, date_sent AS timestamp, type as incoming, - body AS text + body AS text FROM sms; """ + class SMS(AndroidExtraction): """This module extracts all SMS messages containing links.""" @@ -62,7 +63,7 @@ class SMS(AndroidExtraction): return for message in self.results: - if not "text" in message: + if "text" not in message: continue message_links = check_for_links(message["text"]) @@ -77,7 +78,7 @@ class SMS(AndroidExtraction): """ conn = sqlite3.connect(db_path) cur = conn.cursor() - + if (self.SMS_DB_TYPE == 1): cur.execute(SMS_BUGLE_QUERY) elif (self.SMS_DB_TYPE == 2): diff --git a/mvt/android/modules/adb/whatsapp.py b/mvt/android/modules/adb/whatsapp.py index d04a7aa..9282d89 100644 --- a/mvt/android/modules/adb/whatsapp.py +++ b/mvt/android/modules/adb/whatsapp.py @@ -16,6 +16,7 @@ log = logging.getLogger(__name__) WHATSAPP_PATH = "data/data/com.whatsapp/databases/msgstore.db" + class Whatsapp(AndroidExtraction): """This module extracts all WhatsApp messages containing links.""" @@ -39,7 +40,7 @@ class Whatsapp(AndroidExtraction): return for message in self.results: - if not "data" in message: + if "data" not in message: continue message_links = check_for_links(message["data"]) diff --git a/mvt/android/modules/backup/__init__.py b/mvt/android/modules/backup/__init__.py index 10736b7..40432c3 100644 --- a/mvt/android/modules/backup/__init__.py +++ b/mvt/android/modules/backup/__init__.py @@ -5,4 +5,4 @@ from .sms import SMS -BACKUP_MODULES = [SMS,] +BACKUP_MODULES = [SMS] diff --git a/mvt/android/modules/backup/sms.py b/mvt/android/modules/backup/sms.py index f24d22d..58de6a2 100644 --- a/mvt/android/modules/backup/sms.py +++ b/mvt/android/modules/backup/sms.py @@ -24,7 +24,7 @@ class SMS(MVTModule): return for message in self.results: - if not "body" in message: + if "body" not in message: continue message_links = check_for_links(message["body"]) diff --git a/mvt/common/indicators.py b/mvt/common/indicators.py index 1f59f49..6e8b458 100644 --- a/mvt/common/indicators.py +++ b/mvt/common/indicators.py @@ -12,6 +12,7 @@ from .url import URL class IndicatorsFileBadFormat(Exception): pass + class Indicators: """This class is used to parse indicators from a STIX2 file and provide functions to compare extracted artifacts to the indicators. @@ -115,7 +116,7 @@ class Indicators: else: # If it's not shortened, we just use the original URL object. final_url = orig_url - except Exception as e: + except Exception: # If URL parsing failed, we just try to do a simple substring # match. for ioc in self.ioc_domains: diff --git a/mvt/common/logo.py b/mvt/common/logo.py index 8119818..22d3b1a 100644 --- a/mvt/common/logo.py +++ b/mvt/common/logo.py @@ -16,7 +16,7 @@ def logo(): try: latest_version = check_for_updates() - except: + except Exception: pass else: if latest_version: diff --git a/mvt/common/module.py b/mvt/common/module.py index 9362b5d..c0c3ac2 100644 --- a/mvt/common/module.py +++ b/mvt/common/module.py @@ -14,12 +14,15 @@ import simplejson as json class DatabaseNotFoundError(Exception): pass + class DatabaseCorruptedError(Exception): pass + class InsufficientPrivileges(Exception): pass + class MVTModule(object): """This class provides a base for all extraction modules.""" diff --git a/mvt/common/url.py b/mvt/common/url.py index ba210d4..3c830a0 100644 --- a/mvt/common/url.py +++ b/mvt/common/url.py @@ -250,6 +250,7 @@ SHORTENER_DOMAINS = [ "zz.gd", ] + class URL: def __init__(self, url): @@ -273,7 +274,7 @@ class URL: # TODO: Properly handle exception. try: return get_tld(self.url, as_object=True, fix_protocol=True).parsed_url.netloc.lower().lstrip("www.") - except: + except Exception: return None def get_top_level(self): @@ -288,7 +289,7 @@ class URL: # TODO: Properly handle exception. try: return get_tld(self.url, as_object=True, fix_protocol=True).fld.lower() - except: + except Exception: return None def check_if_shortened(self) -> bool: diff --git a/mvt/common/utils.py b/mvt/common/utils.py index aef8ad1..d382e1e 100644 --- a/mvt/common/utils.py +++ b/mvt/common/utils.py @@ -45,7 +45,7 @@ def convert_chrometime_to_unix(timestamp): :returns: Unix epoch timestamp. """ - epoch_start = datetime.datetime(1601, 1 , 1) + epoch_start = datetime.datetime(1601, 1, 1) delta = datetime.timedelta(microseconds=timestamp) return epoch_start + delta @@ -64,6 +64,7 @@ def convert_timestamp_to_iso(timestamp): except Exception: return None + def check_for_links(text): """Checks if a given text contains HTTP links. @@ -74,6 +75,7 @@ def check_for_links(text): """ return re.findall("(?Phttps?://[^\s]+)", text, re.IGNORECASE) + def get_sha256_from_file_path(file_path): """Calculate the SHA256 hash of a file from a file path. @@ -88,6 +90,7 @@ def get_sha256_from_file_path(file_path): return sha256_hash.hexdigest() + # Note: taken from here: # https://stackoverflow.com/questions/57014259/json-dumps-on-dictionary-with-bytes-for-keys def keys_bytes_to_string(obj): diff --git a/mvt/common/version.py b/mvt/common/version.py index d1c7e89..924e741 100644 --- a/mvt/common/version.py +++ b/mvt/common/version.py @@ -8,6 +8,7 @@ from packaging import version MVT_VERSION = "1.2.14" + def check_for_updates(): res = requests.get("https://pypi.org/pypi/mvt/json") data = res.json() diff --git a/mvt/ios/cli.py b/mvt/ios/cli.py index 2485749..0110c8b 100644 --- a/mvt/ios/cli.py +++ b/mvt/ios/cli.py @@ -10,7 +10,9 @@ import click from rich.logging import RichHandler from rich.prompt import Prompt -from mvt.common.help import * +from mvt.common.help import HELP_MSG_MODULE, HELP_MSG_IOC +from mvt.common.help import HELP_MSG_FAST, HELP_MSG_OUTPUT +from mvt.common.help import HELP_MSG_LIST_MODULES from mvt.common.indicators import Indicators, IndicatorsFileBadFormat from mvt.common.logo import logo from mvt.common.module import run_module, save_timeline @@ -30,6 +32,7 @@ log = logging.getLogger(__name__) # Set this environment variable to a password if needed. PASSWD_ENV = "MVT_IOS_BACKUP_PASSWORD" + #============================================================================== # Main #============================================================================== diff --git a/mvt/ios/decrypt.py b/mvt/ios/decrypt.py index 5108b54..f827b56 100644 --- a/mvt/ios/decrypt.py +++ b/mvt/ios/decrypt.py @@ -14,6 +14,7 @@ from iOSbackup import iOSbackup log = logging.getLogger(__name__) + class DecryptBackup: """This class provides functions to decrypt an encrypted iTunes backup using either a password or a key file. diff --git a/mvt/ios/modules/backup/configuration_profiles.py b/mvt/ios/modules/backup/configuration_profiles.py index 3e9c741..20159ca 100644 --- a/mvt/ios/modules/backup/configuration_profiles.py +++ b/mvt/ios/modules/backup/configuration_profiles.py @@ -10,6 +10,7 @@ from ..base import IOSExtraction CONF_PROFILES_DOMAIN = "SysSharedContainerDomain-systemgroup.com.apple.configurationprofiles" + class ConfigurationProfiles(IOSExtraction): """This module extracts the full plist data from configuration profiles.""" diff --git a/mvt/ios/modules/backup/manifest.py b/mvt/ios/modules/backup/manifest.py index f631486..4865a66 100644 --- a/mvt/ios/modules/backup/manifest.py +++ b/mvt/ios/modules/backup/manifest.py @@ -28,8 +28,8 @@ class Manifest(IOSExtraction): """Unserialized plist objects can have keys which are str or byte types This is a helper to try fetch a key as both a byte or string type. - :param dictionary: param key: - :param key: + :param dictionary: + :param key: """ return dictionary.get(key.encode("utf-8"), None) or dictionary.get(key, None) @@ -38,7 +38,7 @@ class Manifest(IOSExtraction): def _convert_timestamp(timestamp_or_unix_time_int): """Older iOS versions stored the manifest times as unix timestamps. - :param timestamp_or_unix_time_int: + :param timestamp_or_unix_time_int: """ if isinstance(timestamp_or_unix_time_int, datetime.datetime): @@ -72,7 +72,7 @@ class Manifest(IOSExtraction): return for result in self.results: - if not "relative_path" in result: + if "relative_path" not in result: continue if not result["relative_path"]: continue @@ -133,7 +133,7 @@ class Manifest(IOSExtraction): "owner": self._get_key(file_metadata, "UserID"), "size": self._get_key(file_metadata, "Size"), }) - except: + except Exception: self.log.exception("Error reading manifest file metadata for file with ID %s and relative path %s", file_data["fileID"], file_data["relativePath"]) pass diff --git a/mvt/ios/modules/backup/profile_events.py b/mvt/ios/modules/backup/profile_events.py index 327b0e2..ac409e4 100644 --- a/mvt/ios/modules/backup/profile_events.py +++ b/mvt/ios/modules/backup/profile_events.py @@ -11,6 +11,7 @@ from ..base import IOSExtraction CONF_PROFILES_EVENTS_RELPATH = "Library/ConfigurationProfiles/MCProfileEvents.plist" + class ProfileEvents(IOSExtraction): """This module extracts events related to the installation of configuration profiles. diff --git a/mvt/ios/modules/fs/__init__.py b/mvt/ios/modules/fs/__init__.py index 9f7259e..29a6895 100644 --- a/mvt/ios/modules/fs/__init__.py +++ b/mvt/ios/modules/fs/__init__.py @@ -16,4 +16,4 @@ from .webkit_safariviewservice import WebkitSafariViewService FS_MODULES = [CacheFiles, Filesystem, Netusage, Analytics, SafariFavicon, ShutdownLog, IOSVersionHistory, WebkitIndexedDB, WebkitLocalStorage, - WebkitSafariViewService,] + WebkitSafariViewService] diff --git a/mvt/ios/modules/fs/analytics.py b/mvt/ios/modules/fs/analytics.py index b69282d..7567f9d 100644 --- a/mvt/ios/modules/fs/analytics.py +++ b/mvt/ios/modules/fs/analytics.py @@ -14,6 +14,7 @@ ANALYTICS_DB_PATH = [ "private/var/Keychains/Analytics/*.db", ] + class Analytics(IOSExtraction): """This module extracts information from the private/var/Keychains/Analytics/*.db files.""" @@ -30,7 +31,7 @@ class Analytics(IOSExtraction): "event": record["artifact"], "data": f"{record}", } - + def check_indicators(self): if not self.indicators: return @@ -50,7 +51,7 @@ class Analytics(IOSExtraction): ioc, result["artifact"], result["timestamp"]) self.detected.append(result) break - + def _extract_analytics_data(self): artifact = self.file_path.split("/")[-1] @@ -87,7 +88,6 @@ class Analytics(IOSExtraction): FROM soft_failures; """) - for row in cur: if row[0] and row[1]: timestamp = convert_timestamp_to_iso(convert_mactime_to_unix(row[0], False)) diff --git a/mvt/ios/modules/fs/cache_files.py b/mvt/ios/modules/fs/cache_files.py index e0e3683..eaa5e8d 100644 --- a/mvt/ios/modules/fs/cache_files.py +++ b/mvt/ios/modules/fs/cache_files.py @@ -38,7 +38,7 @@ class CacheFiles(IOSExtraction): for item in items: if self.indicators.check_domain(item["url"]): if key not in self.detected: - self.detected[key] = [item,] + self.detected[key] = [item, ] else: self.detected[key].append(item) @@ -54,7 +54,7 @@ class CacheFiles(IOSExtraction): return key_name = os.path.relpath(file_path, self.base_folder) - if not key_name in self.results: + if key_name not in self.results: self.results[key_name] = [] for row in cur: diff --git a/mvt/ios/modules/fs/filesystem.py b/mvt/ios/modules/fs/filesystem.py index 866eb1f..acfe89c 100644 --- a/mvt/ios/modules/fs/filesystem.py +++ b/mvt/ios/modules/fs/filesystem.py @@ -60,7 +60,7 @@ class Filesystem(IOSExtraction): "path": os.path.relpath(dir_path, self.base_folder), "modified": convert_timestamp_to_iso(datetime.datetime.utcfromtimestamp(os.stat(dir_path).st_mtime)), } - except: + except Exception: continue else: self.results.append(result) @@ -72,7 +72,7 @@ class Filesystem(IOSExtraction): "path": os.path.relpath(file_path, self.base_folder), "modified": convert_timestamp_to_iso(datetime.datetime.utcfromtimestamp(os.stat(file_path).st_mtime)), } - except: + except Exception: continue else: self.results.append(result) diff --git a/mvt/ios/modules/fs/net_netusage.py b/mvt/ios/modules/fs/net_netusage.py index d9d1ecb..eed813c 100644 --- a/mvt/ios/modules/fs/net_netusage.py +++ b/mvt/ios/modules/fs/net_netusage.py @@ -12,6 +12,7 @@ NETUSAGE_ROOT_PATHS = [ "private/var/networkd/db/netusage.sqlite" ] + class Netusage(NetBase): """This class extracts data from netusage.sqlite and attempts to identify any suspicious processes if running on a full filesystem dump. diff --git a/mvt/ios/modules/fs/safari_favicon.py b/mvt/ios/modules/fs/safari_favicon.py index 3b03c12..f2b84fc 100644 --- a/mvt/ios/modules/fs/safari_favicon.py +++ b/mvt/ios/modules/fs/safari_favicon.py @@ -14,6 +14,7 @@ SAFARI_FAVICON_ROOT_PATHS = [ "private/var/mobile/Containers/Data/Application/*/Library/Image Cache/Favicons/Favicons.db", ] + class SafariFavicon(IOSExtraction): """This module extracts all Safari favicon records.""" diff --git a/mvt/ios/modules/fs/shutdownlog.py b/mvt/ios/modules/fs/shutdownlog.py index 9ac7e05..3a3fa8c 100644 --- a/mvt/ios/modules/fs/shutdownlog.py +++ b/mvt/ios/modules/fs/shutdownlog.py @@ -11,6 +11,7 @@ SHUTDOWN_LOG_PATH = [ "private/var/db/diagnostics/shutdown.log", ] + class ShutdownLog(IOSExtraction): """This module extracts processes information from the shutdown log file.""" @@ -27,7 +28,7 @@ class ShutdownLog(IOSExtraction): "event": "shutdown", "data": f"Client {record['client']} with PID {record['pid']} was running when the device was shut down", } - + def check_indicators(self): if not self.indicators: return @@ -57,7 +58,7 @@ class ShutdownLog(IOSExtraction): try: start = line.find(" @")+2 mac_timestamp = int(line[start:start+10]) - except: + except Exception: mac_timestamp = 0 timestamp = convert_mactime_to_unix(mac_timestamp, from_2001=False) diff --git a/mvt/ios/modules/fs/version_history.py b/mvt/ios/modules/fs/version_history.py index 45166a6..b6379ea 100644 --- a/mvt/ios/modules/fs/version_history.py +++ b/mvt/ios/modules/fs/version_history.py @@ -14,6 +14,7 @@ IOS_ANALYTICS_JOURNAL_PATHS = [ "private/var/db/analyticsd/Analytics-Journal-*.ips", ] + class IOSVersionHistory(IOSExtraction): """This module extracts iOS update history from Analytics Journal log files.""" diff --git a/mvt/ios/modules/fs/webkit_indexeddb.py b/mvt/ios/modules/fs/webkit_indexeddb.py index e3b309a..afcd80e 100644 --- a/mvt/ios/modules/fs/webkit_indexeddb.py +++ b/mvt/ios/modules/fs/webkit_indexeddb.py @@ -9,6 +9,7 @@ WEBKIT_INDEXEDDB_ROOT_PATHS = [ "private/var/mobile/Containers/Data/Application/*/Library/WebKit/WebsiteData/IndexedDB", ] + class WebkitIndexedDB(WebkitBase): """This module looks extracts records from WebKit IndexedDB folders, and checks them against any provided list of suspicious domains. diff --git a/mvt/ios/modules/fs/webkit_localstorage.py b/mvt/ios/modules/fs/webkit_localstorage.py index f7df962..33ef9a4 100644 --- a/mvt/ios/modules/fs/webkit_localstorage.py +++ b/mvt/ios/modules/fs/webkit_localstorage.py @@ -9,6 +9,7 @@ WEBKIT_LOCALSTORAGE_ROOT_PATHS = [ "private/var/mobile/Containers/Data/Application/*/Library/WebKit/WebsiteData/LocalStorage/", ] + class WebkitLocalStorage(WebkitBase): """This module looks extracts records from WebKit LocalStorage folders, and checks them against any provided list of suspicious domains. diff --git a/mvt/ios/modules/fs/webkit_safariviewservice.py b/mvt/ios/modules/fs/webkit_safariviewservice.py index 72f8eb2..ffa3d36 100644 --- a/mvt/ios/modules/fs/webkit_safariviewservice.py +++ b/mvt/ios/modules/fs/webkit_safariviewservice.py @@ -9,6 +9,7 @@ WEBKIT_SAFARIVIEWSERVICE_ROOT_PATHS = [ "private/var/mobile/Containers/Data/Application/*/SystemData/com.apple.SafariViewService/Library/WebKit/WebsiteData/", ] + class WebkitSafariViewService(WebkitBase): """This module looks extracts records from WebKit LocalStorage folders, and checks them against any provided list of suspicious domains. diff --git a/mvt/ios/modules/mixed/__init__.py b/mvt/ios/modules/mixed/__init__.py index 5eb0070..7df723d 100644 --- a/mvt/ios/modules/mixed/__init__.py +++ b/mvt/ios/modules/mixed/__init__.py @@ -27,4 +27,4 @@ MIXED_MODULES = [Calls, ChromeFavicon, ChromeHistory, Contacts, FirefoxFavicon, FirefoxHistory, IDStatusCache, InteractionC, LocationdClients, OSAnalyticsADDaily, Datausage, SafariBrowserState, SafariHistory, TCC, SMS, SMSAttachments, WebkitResourceLoadStatistics, - WebkitSessionResourceLog, Whatsapp,] + WebkitSessionResourceLog, Whatsapp] diff --git a/mvt/ios/modules/mixed/calls.py b/mvt/ios/modules/mixed/calls.py index 44676da..2811473 100644 --- a/mvt/ios/modules/mixed/calls.py +++ b/mvt/ios/modules/mixed/calls.py @@ -16,6 +16,7 @@ CALLS_ROOT_PATHS = [ "private/var/mobile/Library/CallHistoryDB/CallHistory.storedata" ] + class Calls(IOSExtraction): """This module extracts phone calls details""" @@ -45,7 +46,7 @@ class Calls(IOSExtraction): ZDATE, ZDURATION, ZLOCATION, ZADDRESS, ZSERVICE_PROVIDER FROM ZCALLRECORD; """) - names = [description[0] for description in cur.description] + # names = [description[0] for description in cur.description] for row in cur: self.results.append({ diff --git a/mvt/ios/modules/mixed/chrome_favicon.py b/mvt/ios/modules/mixed/chrome_favicon.py index 2f5c5b2..97812df 100644 --- a/mvt/ios/modules/mixed/chrome_favicon.py +++ b/mvt/ios/modules/mixed/chrome_favicon.py @@ -19,6 +19,7 @@ CHROME_FAVICON_ROOT_PATHS = [ "private/var/mobile/Containers/Data/Application/*/Library/Application Support/Google/Chrome/Default/Favicons", ] + class ChromeFavicon(IOSExtraction): """This module extracts all Chrome favicon records.""" diff --git a/mvt/ios/modules/mixed/chrome_history.py b/mvt/ios/modules/mixed/chrome_history.py index 2715809..ae8bfe0 100644 --- a/mvt/ios/modules/mixed/chrome_history.py +++ b/mvt/ios/modules/mixed/chrome_history.py @@ -13,12 +13,12 @@ from ..base import IOSExtraction CHROME_HISTORY_BACKUP_IDS = [ "faf971ce92c3ac508c018dce1bef2a8b8e9838f1", ] - # TODO: Confirm Chrome database path. CHROME_HISTORY_ROOT_PATHS = [ "private/var/mobile/Containers/Data/Application/*/Library/Application Support/Google/Chrome/Default/History", ] + class ChromeHistory(IOSExtraction): """This module extracts all Chome visits.""" diff --git a/mvt/ios/modules/mixed/contacts.py b/mvt/ios/modules/mixed/contacts.py index 3148ca3..dba2a5d 100644 --- a/mvt/ios/modules/mixed/contacts.py +++ b/mvt/ios/modules/mixed/contacts.py @@ -14,6 +14,7 @@ CONTACTS_ROOT_PATHS = [ "private/var/mobile/Library/AddressBook/AddressBook.sqlitedb", ] + class Contacts(IOSExtraction): """This module extracts all contact details from the phone's address book.""" diff --git a/mvt/ios/modules/mixed/firefox_favicon.py b/mvt/ios/modules/mixed/firefox_favicon.py index 174a264..b4de540 100644 --- a/mvt/ios/modules/mixed/firefox_favicon.py +++ b/mvt/ios/modules/mixed/firefox_favicon.py @@ -17,6 +17,7 @@ FIREFOX_HISTORY_ROOT_PATHS = [ "private/var/mobile/profile.profile/browser.db", ] + class FirefoxFavicon(IOSExtraction): """This module extracts all Firefox favicon""" @@ -39,8 +40,8 @@ class FirefoxFavicon(IOSExtraction): return for result in self.results: - if (self.indicators.check_domain(result.get("url", "")) or - self.indicators.check_domain(result.get("history_url", ""))): + if (self.indicators.check_domain(result.get("url", "")) or + self.indicators.check_domain(result.get("history_url", ""))): self.detected.append(result) def run(self): diff --git a/mvt/ios/modules/mixed/firefox_history.py b/mvt/ios/modules/mixed/firefox_history.py index c9fb247..892fc1e 100644 --- a/mvt/ios/modules/mixed/firefox_history.py +++ b/mvt/ios/modules/mixed/firefox_history.py @@ -17,6 +17,7 @@ FIREFOX_HISTORY_ROOT_PATHS = [ "private/var/mobile/profile.profile/browser.db", ] + class FirefoxHistory(IOSExtraction): """This module extracts all Firefox visits and tries to detect potential network injection attacks. diff --git a/mvt/ios/modules/mixed/idstatuscache.py b/mvt/ios/modules/mixed/idstatuscache.py index 4a5781d..dcc990a 100644 --- a/mvt/ios/modules/mixed/idstatuscache.py +++ b/mvt/ios/modules/mixed/idstatuscache.py @@ -18,6 +18,7 @@ IDSTATUSCACHE_ROOT_PATHS = [ "private/var/mobile/Library/IdentityServices/idstatuscache.plist", ] + class IDStatusCache(IOSExtraction): """Extracts Apple Authentication information from idstatuscache.plist""" @@ -91,5 +92,5 @@ class IDStatusCache(IOSExtraction): self.file_path = idstatuscache_path self.log.info("Found IDStatusCache plist at path: %s", self.file_path) self._extract_idstatuscache_entries(self.file_path) - + self.log.info("Extracted a total of %d ID Status Cache entries", len(self.results)) diff --git a/mvt/ios/modules/mixed/interactionc.py b/mvt/ios/modules/mixed/interactionc.py index afcff63..6093aaf 100644 --- a/mvt/ios/modules/mixed/interactionc.py +++ b/mvt/ios/modules/mixed/interactionc.py @@ -16,6 +16,7 @@ INTERACTIONC_ROOT_PATHS = [ "private/var/mobile/Library/CoreDuet/People/interactionC.db", ] + class InteractionC(IOSExtraction): """This module extracts data from InteractionC db.""" @@ -54,8 +55,8 @@ class InteractionC(IOSExtraction): "timestamp": record[ts], "module": self.__class__.__name__, "event": ts, - "data": f"[{record['bundle_id']}] {record['account']} - from {record['sender_display_name']} " \ - f"({record['sender_identifier']}) to {record['recipient_display_name']} " \ + "data": f"[{record['bundle_id']}] {record['account']} - from {record['sender_display_name']} " + f"({record['sender_identifier']}) to {record['recipient_display_name']} " f"({record['recipient_identifier']}): {record['content']}" }) processed.append(record[ts]) @@ -123,8 +124,7 @@ class InteractionC(IOSExtraction): LEFT JOIN Z_2INTERACTIONRECIPIENT ON ZINTERACTIONS.Z_PK== Z_2INTERACTIONRECIPIENT.Z_3INTERACTIONRECIPIENT LEFT JOIN ZCONTACTS RECEIPIENTCONACT ON Z_2INTERACTIONRECIPIENT.Z_2RECIPIENTS== RECEIPIENTCONACT.Z_PK; """) - - names = [description[0] for description in cur.description] + # names = [description[0] for description in cur.description] for row in cur: self.results.append({ diff --git a/mvt/ios/modules/mixed/locationd.py b/mvt/ios/modules/mixed/locationd.py index 64f9458..8d97103 100644 --- a/mvt/ios/modules/mixed/locationd.py +++ b/mvt/ios/modules/mixed/locationd.py @@ -17,6 +17,7 @@ LOCATIOND_ROOT_PATHS = [ "private/var/root/Library/Caches/locationd/clients.plist" ] + class LocationdClients(IOSExtraction): """Extract information from apps who used geolocation.""" diff --git a/mvt/ios/modules/mixed/net_datausage.py b/mvt/ios/modules/mixed/net_datausage.py index 3d5e2e1..74657cc 100644 --- a/mvt/ios/modules/mixed/net_datausage.py +++ b/mvt/ios/modules/mixed/net_datausage.py @@ -12,6 +12,7 @@ DATAUSAGE_ROOT_PATHS = [ "private/var/wireless/Library/Databases/DataUsage.sqlite", ] + class Datausage(NetBase): """This class extracts data from DataUsage.sqlite and attempts to identify any suspicious processes if running on a full filesystem dump. diff --git a/mvt/ios/modules/mixed/osanalytics_addaily.py b/mvt/ios/modules/mixed/osanalytics_addaily.py index e1abcb8..b3d7f2d 100644 --- a/mvt/ios/modules/mixed/osanalytics_addaily.py +++ b/mvt/ios/modules/mixed/osanalytics_addaily.py @@ -16,6 +16,7 @@ OSANALYTICS_ADDAILY_ROOT_PATHS = [ "private/var/mobile/Library/Preferences/com.apple.osanalytics.addaily.plist", ] + class OSAnalyticsADDaily(IOSExtraction): """Extract network usage information by process, from com.apple.osanalytics.addaily.plist""" @@ -34,14 +35,14 @@ class OSAnalyticsADDaily(IOSExtraction): "event": "osanalytics_addaily", "data": record_data, } - + def check_indicators(self): if not self.indicators: return for result in self.results: if self.indicators.check_process(result["package"]): - self.detected.append(result) + self.detected.append(result) def run(self): self._find_ios_database(backup_ids=OSANALYTICS_ADDAILY_BACKUP_IDS, diff --git a/mvt/ios/modules/mixed/safari_browserstate.py b/mvt/ios/modules/mixed/safari_browserstate.py index 54739f0..14de1ff 100644 --- a/mvt/ios/modules/mixed/safari_browserstate.py +++ b/mvt/ios/modules/mixed/safari_browserstate.py @@ -19,6 +19,7 @@ SAFARI_BROWSER_STATE_ROOT_PATHS = [ "private/var/mobile/Containers/Data/Application/*/Library/Safari/BrowserState.db", ] + class SafariBrowserState(IOSExtraction): """This module extracts all Safari browser state records.""" @@ -47,7 +48,7 @@ class SafariBrowserState(IOSExtraction): self.detected.append(result) continue - if not "session_data" in result: + if "session_data" not in result: continue for session_entry in result["session_data"]: diff --git a/mvt/ios/modules/mixed/safari_history.py b/mvt/ios/modules/mixed/safari_history.py index 292d643..4fc4113 100644 --- a/mvt/ios/modules/mixed/safari_history.py +++ b/mvt/ios/modules/mixed/safari_history.py @@ -17,6 +17,7 @@ SAFARI_HISTORY_ROOT_PATHS = [ "private/var/mobile/Containers/Data/Application/*/Library/Safari/History.db", ] + class SafariHistory(IOSExtraction): """This module extracts all Safari visits and tries to detect potential network injection attacks. @@ -62,7 +63,7 @@ class SafariHistory(IOSExtraction): continue self.log.info("Found HTTP redirect to different domain: \"%s\" -> \"%s\"", - origin_domain, redirect_domain) + origin_domain, redirect_domain) redirect_time = convert_mactime_to_unix(redirect["timestamp"]) origin_time = convert_mactime_to_unix(result["timestamp"]) diff --git a/mvt/ios/modules/mixed/sms.py b/mvt/ios/modules/mixed/sms.py index 71a2331..c5cc3ea 100644 --- a/mvt/ios/modules/mixed/sms.py +++ b/mvt/ios/modules/mixed/sms.py @@ -18,6 +18,7 @@ SMS_ROOT_PATHS = [ "private/var/mobile/Library/SMS/sms.db", ] + class SMS(IOSExtraction): """This module extracts all SMS messages containing links.""" @@ -67,8 +68,8 @@ class SMS(IOSExtraction): # We base64 escape some of the attributes that could contain # binary data. if (names[index] == "attributedBody" or - names[index] == "payload_data" or - names[index] == "message_summary_info") and value: + names[index] == "payload_data" or + names[index] == "message_summary_info") and value: value = b64encode(value).decode() # We store the value of each column under the proper key. diff --git a/mvt/ios/modules/mixed/sms_attachments.py b/mvt/ios/modules/mixed/sms_attachments.py index ad6d006..67e3875 100644 --- a/mvt/ios/modules/mixed/sms_attachments.py +++ b/mvt/ios/modules/mixed/sms_attachments.py @@ -17,6 +17,7 @@ SMS_ROOT_PATHS = [ "private/var/mobile/Library/SMS/sms.db", ] + class SMSAttachments(IOSExtraction): """This module extracts all info about SMS/iMessage attachments.""" @@ -45,7 +46,7 @@ class SMSAttachments(IOSExtraction): cur.execute(""" SELECT attachment.ROWID as "attachment_id", - attachment.*, + attachment.*, message.service as "service", handle.id as "phone_number" FROM attachment @@ -73,7 +74,7 @@ class SMSAttachments(IOSExtraction): attachment["filename"] = attachment["filename"] or "NULL" if (attachment["filename"].startswith("/var/tmp/") and attachment["filename"].endswith("-1") and - attachment["direction"] == "received"): + attachment["direction"] == "received"): self.log.warn(f"Suspicious iMessage attachment '{attachment['filename']}' on {attachment['isodate']}") self.detected.append(attachment) diff --git a/mvt/ios/modules/mixed/tcc.py b/mvt/ios/modules/mixed/tcc.py index f024f5c..d5f89cd 100644 --- a/mvt/ios/modules/mixed/tcc.py +++ b/mvt/ios/modules/mixed/tcc.py @@ -38,6 +38,7 @@ AUTH_REASONS = { 12: "app_type_policy", } + class TCC(IOSExtraction): """This module extracts records from the TCC.db SQLite database.""" @@ -50,7 +51,7 @@ class TCC(IOSExtraction): def process_db(self, file_path): conn = sqlite3.connect(file_path) cur = conn.cursor() - cur.execute("""SELECT + cur.execute("""SELECT service, client, client_type, auth_value, auth_reason, last_modified FROM access;""") diff --git a/mvt/ios/modules/mixed/webkit_resource_load_statistics.py b/mvt/ios/modules/mixed/webkit_resource_load_statistics.py index a7561ef..fb93a72 100644 --- a/mvt/ios/modules/mixed/webkit_resource_load_statistics.py +++ b/mvt/ios/modules/mixed/webkit_resource_load_statistics.py @@ -17,6 +17,7 @@ WEBKIT_RESOURCELOADSTATICS_ROOT_PATHS = [ "private/var/mobile/Containers/Data/Application/*/SystemData/com.apple.SafariViewService/Library/WebKit/WebsiteData/observations.db", ] + class WebkitResourceLoadStatistics(IOSExtraction): """This module extracts records from WebKit ResourceLoadStatistics observations.db.""" # TODO: Add serialize(). @@ -38,7 +39,7 @@ class WebkitResourceLoadStatistics(IOSExtraction): for item in items: if self.indicators.check_domain(item["registrable_domain"]): if key not in self.detected: - self.detected[key] = [item,] + self.detected[key] = [item, ] else: self.detected[key].append(item) @@ -55,7 +56,7 @@ class WebkitResourceLoadStatistics(IOSExtraction): except sqlite3.OperationalError: return - if not key in self.results: + if key not in self.results: self.results[key] = [] for row in cur: diff --git a/mvt/ios/modules/mixed/webkit_session_resource_log.py b/mvt/ios/modules/mixed/webkit_session_resource_log.py index 841091f..947de82 100644 --- a/mvt/ios/modules/mixed/webkit_session_resource_log.py +++ b/mvt/ios/modules/mixed/webkit_session_resource_log.py @@ -20,6 +20,7 @@ WEBKIT_SESSION_RESOURCE_LOG_ROOT_PATHS = [ "private/var/mobile/Library/WebClips/*/Storage/full_browsing_session_resourceLog.plist", ] + class WebkitSessionResourceLog(IOSExtraction): """This module extracts records from WebKit browsing session resource logs, and checks them against any provided list of diff --git a/mvt/ios/modules/mixed/whatsapp.py b/mvt/ios/modules/mixed/whatsapp.py index e73e0ca..b76a2a8 100644 --- a/mvt/ios/modules/mixed/whatsapp.py +++ b/mvt/ios/modules/mixed/whatsapp.py @@ -20,6 +20,7 @@ WHATSAPP_ROOT_PATHS = [ "private/var/mobile/Containers/Shared/AppGroup/*/ChatStorage.sqlite", ] + class Whatsapp(IOSExtraction): """This module extracts all WhatsApp messages containing links.""" diff --git a/mvt/ios/modules/net_base.py b/mvt/ios/modules/net_base.py index adc92f5..4e170b9 100644 --- a/mvt/ios/modules/net_base.py +++ b/mvt/ios/modules/net_base.py @@ -81,7 +81,7 @@ class NetBase(IOSExtraction): def serialize(self, record): record_data = f"{record['proc_name']} (Bundle ID: {record['bundle_id']}, ID: {record['proc_id']})" record_data_usage = record_data + f" WIFI IN: {record['wifi_in']}, WIFI OUT: {record['wifi_out']} - " \ - f"WWAN IN: {record['wwan_in']}, WWAN OUT: {record['wwan_out']}" + f"WWAN IN: {record['wwan_in']}, WWAN OUT: {record['wwan_out']}" records = [{ "timestamp": record["live_isodate"], diff --git a/mvt/ios/versions.py b/mvt/ios/versions.py index 36a92bd..f539f32 100644 --- a/mvt/ios/versions.py +++ b/mvt/ios/versions.py @@ -233,11 +233,13 @@ IPHONE_IOS_VERSIONS = [ {"build": "19B74", "version": "15.1"}, ] + def get_device_desc_from_id(identifier, devices_list=IPHONE_MODELS): for model in IPHONE_MODELS: if identifier == model["identifier"]: return model["description"] + def find_version_by_build(build): build = build.upper() for version in IPHONE_IOS_VERSIONS: diff --git a/setup.py b/setup.py index dc107b6..6af594e 100755 --- a/setup.py +++ b/setup.py @@ -30,6 +30,7 @@ requires = ( "libusb1>=2.0.1", ) + def get_package_data(package): walk = [(dirpath.replace(package + os.sep, "", 1), filenames) for dirpath, dirnames, filenames in os.walk(package) @@ -41,6 +42,7 @@ def get_package_data(package): for filename in filenames]) return {package: filepaths} + setup( name="mvt", version=MVT_VERSION,