From fba4e27757dcfb8cd28bf458d52bd52f45c46afa Mon Sep 17 00:00:00 2001 From: Nex Date: Thu, 16 Jun 2022 17:02:38 +0200 Subject: [PATCH] Refactored check-iocs command for Android as well --- mvt/android/cli.py | 75 ++++++++++------------------- mvt/android/modules/adb/packages.py | 2 +- mvt/common/cmd_check_iocs.py | 63 ++++++++++++++++++++++++ mvt/ios/cli.py | 51 +++----------------- 4 files changed, 95 insertions(+), 96 deletions(-) create mode 100644 mvt/common/cmd_check_iocs.py diff --git a/mvt/android/cli.py b/mvt/android/cli.py index 8cba92c..6359246 100644 --- a/mvt/android/cli.py +++ b/mvt/android/cli.py @@ -9,10 +9,11 @@ import os import click from rich.logging import RichHandler +from mvt.common.cmd_check_iocs import CmdCheckIOCS from mvt.common.help import (HELP_MSG_FAST, HELP_MSG_IOC, HELP_MSG_LIST_MODULES, HELP_MSG_MODULE, HELP_MSG_OUTPUT, HELP_MSG_SERIAL) -from mvt.common.indicators import Indicators, download_indicators_files +from mvt.common.indicators import download_indicators_files from mvt.common.logo import logo from .cmd_check_adb import CmdAndroidCheckADB @@ -22,6 +23,7 @@ from .cmd_download_apks import DownloadAPKs from .modules.adb import ADB_MODULES from .modules.adb.packages import Packages from .modules.backup import BACKUP_MODULES +from .modules.bugreport import BUGREPORT_MODULES # Setup logging using Rich. LOG_FORMAT = "[%(name)s] %(message)s" @@ -122,8 +124,14 @@ def check_adb(ctx, iocs, output, fast, list_modules, module, serial): cmd.list_modules() return + log.info("Checking Android device over debug bridge") + cmd.run() + if len(cmd.timeline_detected) > 0: + log.warning("The analysis of the Android device produced %d detections!", + len(cmd.timeline_detected)) + #============================================================================== # Command: check-bugreport @@ -144,8 +152,14 @@ def check_bugreport(ctx, iocs, output, list_modules, module, bugreport_path): cmd.list_modules() return + log.info("Checking Android bug report at path: %s", bugreport_path) + cmd.run() + if len(cmd.timeline_detected) > 0: + log.warning("The analysis of the Android bug report produced %d detections!", + len(cmd.timeline_detected)) + #============================================================================== # Command: check-backup @@ -166,8 +180,14 @@ def check_backup(ctx, iocs, output, list_modules, backup_path, serial): cmd.list_modules() return + log.info("Checking Android backup at path: %s", backup_path) + cmd.run() + if len(cmd.timeline_detected) > 0: + log.warning("The analysis of the Android backup produced %d detections!", + len(cmd.timeline_detected)) + #============================================================================== # Command: check-iocs @@ -180,59 +200,14 @@ def check_backup(ctx, iocs, output, list_modules, backup_path, serial): @click.argument("FOLDER", type=click.Path(exists=True)) @click.pass_context def check_iocs(ctx, iocs, list_modules, module, folder): - all_modules = [] - for entry in BACKUP_MODULES + ADB_MODULES: - if entry not in all_modules: - all_modules.append(entry) + cmd = CmdCheckIOCS(target_path=folder, ioc_files=iocs, module_name=module) + cmd.modules = BACKUP_MODULES + ADB_MODULES + BUGREPORT_MODULES if list_modules: - log.info("Following is the list of available check-iocs modules:") - for iocs_module in all_modules: - log.info(" - %s", iocs_module.__name__) - + cmd.list_modules() return - log.info("Checking stored results against provided indicators...") - - indicators = Indicators(log=log) - indicators.load_indicators_files(iocs) - - total_detections = 0 - for file_name in os.listdir(folder): - name_only, ext = os.path.splitext(file_name) - file_path = os.path.join(folder, file_name) - - # TODO: Skipping processing of result files that are not json. - # We might want to revisit this eventually. - if ext != ".json": - continue - - for iocs_module in all_modules: - if module and iocs_module.__name__ != module: - continue - - if iocs_module().get_slug() != name_only: - continue - - log.info("Loading results from \"%s\" with module %s", file_name, - iocs_module.__name__) - - m = iocs_module.from_json(file_path, - log=logging.getLogger(iocs_module.__module__)) - if indicators.total_ioc_count > 0: - m.indicators = indicators - m.indicators.log = m.log - - try: - m.check_indicators() - except NotImplementedError: - continue - else: - total_detections += len(m.detected) - - if total_detections > 0: - log.warning("The check of the results produced %d detections!", - total_detections) + cmd.run() #============================================================================== diff --git a/mvt/android/modules/adb/packages.py b/mvt/android/modules/adb/packages.py index ddec724..ca9d7b3 100644 --- a/mvt/android/modules/adb/packages.py +++ b/mvt/android/modules/adb/packages.py @@ -114,7 +114,7 @@ class Packages(AndroidExtraction): self.detected.append(result) continue - for package_file in result["files"]: + for package_file in result.get("files", []): ioc = self.indicators.check_file_hash(package_file["sha256"]) if ioc: result["matched_indicator"] = ioc diff --git a/mvt/common/cmd_check_iocs.py b/mvt/common/cmd_check_iocs.py new file mode 100644 index 0000000..10467fe --- /dev/null +++ b/mvt/common/cmd_check_iocs.py @@ -0,0 +1,63 @@ +# Mobile Verification Toolkit (MVT) +# Copyright (c) 2021-2022 Claudio Guarnieri. +# Use of this software is governed by the MVT License 1.1 that can be found at +# https://license.mvt.re/1.1/ + +import logging +import os + +from mvt.common.command import Command + +log = logging.getLogger(__name__) + + +class CmdCheckIOCS(Command): + + name = "check-iocs" + modules = [] + + def __init__(self, target_path=None, results_path=None, ioc_files=[], + module_name=None, serial=None, fast_mode=False): + super().__init__(target_path=target_path, results_path=results_path, + ioc_files=ioc_files, module_name=module_name, + serial=serial, fast_mode=fast_mode, log=log) + + def run(self): + all_modules = [] + for entry in self.modules: + if entry not in all_modules: + all_modules.append(entry) + + log.info("Checking stored results against provided indicators...") + + total_detections = 0 + for file_name in os.listdir(self.target_path): + name_only, ext = os.path.splitext(file_name) + file_path = os.path.join(self.target_path, file_name) + + for iocs_module in all_modules: + if self.module_name and iocs_module.__name__ != self.module_name: + continue + + if iocs_module().get_slug() != name_only: + continue + + log.info("Loading results from \"%s\" with module %s", file_name, + iocs_module.__name__) + + m = iocs_module.from_json(file_path, + log=logging.getLogger(iocs_module.__module__)) + if self.iocs.total_ioc_count > 0: + m.indicators = self.iocs + m.indicators.log = m.log + + try: + m.check_indicators() + except NotImplementedError: + continue + else: + total_detections += len(m.detected) + + if total_detections > 0: + log.warning("The check of the results produced %d detections!", + total_detections) diff --git a/mvt/ios/cli.py b/mvt/ios/cli.py index 26bba39..212d1a1 100644 --- a/mvt/ios/cli.py +++ b/mvt/ios/cli.py @@ -10,10 +10,11 @@ import click from rich.logging import RichHandler from rich.prompt import Prompt +from mvt.common.cmd_check_iocs import CmdCheckIOCS from mvt.common.help import (HELP_MSG_FAST, HELP_MSG_IOC, HELP_MSG_LIST_MODULES, HELP_MSG_MODULE, HELP_MSG_OUTPUT) -from mvt.common.indicators import Indicators, download_indicators_files +from mvt.common.indicators import download_indicators_files from mvt.common.logo import logo from mvt.common.options import MutuallyExclusiveOption @@ -197,54 +198,14 @@ def check_fs(ctx, iocs, output, fast, dump_path, list_modules, module): @click.argument("FOLDER", type=click.Path(exists=True)) @click.pass_context def check_iocs(ctx, iocs, list_modules, module, folder): - all_modules = [] - for entry in BACKUP_MODULES + FS_MODULES + MIXED_MODULES: - if entry not in all_modules: - all_modules.append(entry) + cmd = CmdCheckIOCS(target_path=folder, ioc_files=iocs, module_name=module) + cmd.modules = BACKUP_MODULES + FS_MODULES + MIXED_MODULES if list_modules: - log.info("Following is the list of available check-iocs modules:") - for iocs_module in all_modules: - log.info(" - %s", iocs_module.__name__) - + cmd.list_modules() return - log.info("Checking stored results against provided indicators...") - - indicators = Indicators(log=log) - indicators.load_indicators_files(iocs) - - total_detections = 0 - for file_name in os.listdir(folder): - name_only, ext = os.path.splitext(file_name) - file_path = os.path.join(folder, file_name) - - for iocs_module in all_modules: - if module and iocs_module.__name__ != module: - continue - - if iocs_module().get_slug() != name_only: - continue - - log.info("Loading results from \"%s\" with module %s", file_name, - iocs_module.__name__) - - m = iocs_module.from_json(file_path, - log=logging.getLogger(iocs_module.__module__)) - if indicators.total_ioc_count > 0: - m.indicators = indicators - m.indicators.log = m.log - - try: - m.check_indicators() - except NotImplementedError: - continue - else: - total_detections += len(m.detected) - - if total_detections > 0: - log.warning("The check of the results produced %d detections!", - total_detections) + cmd.run() #==============================================================================