From f98282d6c5909ab0722c2a4729be67ee5e8e0885 Mon Sep 17 00:00:00 2001 From: tek Date: Tue, 28 Jun 2022 23:37:57 +0200 Subject: [PATCH] Adds applications and device info iOS USB modules --- mvt/ios/cli.py | 5 ++-- mvt/ios/modules/usb/__init__.py | 4 ++- mvt/ios/modules/usb/applications.py | 42 +++++++++++++++++++++++++++++ mvt/ios/modules/usb/device_info.py | 39 +++++++++++++++++++++++++++ tests/ios_usb/test_applications.py | 35 ++++++++++++++++++++++++ tests/ios_usb/test_device_info.py | 34 +++++++++++++++++++++++ 6 files changed, 156 insertions(+), 3 deletions(-) create mode 100644 mvt/ios/modules/usb/applications.py create mode 100644 mvt/ios/modules/usb/device_info.py create mode 100644 tests/ios_usb/test_applications.py create mode 100644 tests/ios_usb/test_device_info.py diff --git a/mvt/ios/cli.py b/mvt/ios/cli.py index 3e159fd..8979265 100644 --- a/mvt/ios/cli.py +++ b/mvt/ios/cli.py @@ -216,6 +216,7 @@ def check_iocs(ctx, iocs, list_modules, module, folder): def download_iocs(): download_indicators_files(log) + #============================================================================== # Command: check-usb #============================================================================== @@ -232,7 +233,8 @@ def download_iocs(): @click.pass_context def check_usb(ctx, serial, iocs, output, fast, list_modules, module): cmd = CmdIOSCheckUSB(results_path=output, ioc_files=iocs, - module_name=module, fast_mode=fast, serial=serial) + module_name=module, fast_mode=fast, + serial=serial) if list_modules: cmd.list_modules() @@ -244,4 +246,3 @@ def check_usb(ctx, serial, iocs, output, fast, list_modules, module): if len(cmd.timeline_detected) > 0: log.warning("The analysis of the data produced %d detections!", len(cmd.timeline_detected)) - diff --git a/mvt/ios/modules/usb/__init__.py b/mvt/ios/modules/usb/__init__.py index 67e985f..b957a4d 100644 --- a/mvt/ios/modules/usb/__init__.py +++ b/mvt/ios/modules/usb/__init__.py @@ -3,6 +3,8 @@ # Use of this software is governed by the MVT License 1.1 that can be found at # https://license.mvt.re/1.1/ +from .applications import Applications +from .device_info import DeviceInfo from .processes import Processes -USB_MODULES = [Processes] +USB_MODULES = [Applications, DeviceInfo, Processes] diff --git a/mvt/ios/modules/usb/applications.py b/mvt/ios/modules/usb/applications.py new file mode 100644 index 0000000..85e1c2d --- /dev/null +++ b/mvt/ios/modules/usb/applications.py @@ -0,0 +1,42 @@ +# 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 +from pymobiledevice3.services.installation_proxy import InstallationProxyService + +from .base import IOSUSBExtraction + + +class Applications(IOSUSBExtraction): + """This class extracts all applications installed on the phone""" + def __init__(self, file_path: str = None, target_path: str = None, + results_path: str = None, fast_mode: bool = False, + log: logging.Logger = None, results: list = []) -> None: + super().__init__(file_path=file_path, target_path=target_path, + results_path=results_path, fast_mode=fast_mode, + log=log, results=results) + + def check_indicators(self) -> None: + if not self.indicators: + return + + for result in self.results: + ioc = self.indicators.check_app_id(result["CFBundleIdentifier"]) + if ioc: + result["matched_indicator"] = ioc + self.detected.append(result) + + def run(self) -> None: + user_apps = InstallationProxyService(lockdown=self.lockdown).get_apps("User") + for u in user_apps: + u["type"] = "user" + + system_apps = InstallationProxyService(lockdown=self.lockdown).get_apps("System") + for s in system_apps: + s["type"] = "system" + + self.results = user_apps + system_apps + + self.log.info("{} applications identified on the phone".format(len(self.results))) diff --git a/mvt/ios/modules/usb/device_info.py b/mvt/ios/modules/usb/device_info.py new file mode 100644 index 0000000..16a03cb --- /dev/null +++ b/mvt/ios/modules/usb/device_info.py @@ -0,0 +1,39 @@ +# 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 base64 + +from mvt.ios.versions import latest_ios_version + +from .base import IOSUSBExtraction + + +class DeviceInfo(IOSUSBExtraction): + """This class extracts all processes running on the phone.""" + def __init__(self, file_path: str = None, target_path: str = None, + results_path: str = None, fast_mode: bool = False, + log: logging.Logger = None, results: list = []) -> None: + super().__init__(file_path=file_path, target_path=target_path, + results_path=results_path, fast_mode=fast_mode, + log=log, results=results) + + def run(self) -> None: + self.results = self.lockdown.all_values + + # Base64 encoding of bytes + for entry in self.results: + if isinstance(self.results[entry], bytes): + self.results[entry] = base64.b64encode(self.results[entry]) + elif isinstance(self.results[entry], dict): + for second_entry in self.results[entry]: + if isinstance(self.results[entry][second_entry], bytes): + self.results[entry][second_entry] = base64.b64encode(self.results[entry][second_entry]) + + if "ProductVersion" in self.results: + latest = latest_ios_version() + if self.results["ProductVersion"] != latest["version"]: + self.log.warning("This phone is running an outdated iOS version: %s (latest is %s)", + self.results["ProductVersion"], latest['version']) diff --git a/tests/ios_usb/test_applications.py b/tests/ios_usb/test_applications.py new file mode 100644 index 0000000..e8493fb --- /dev/null +++ b/tests/ios_usb/test_applications.py @@ -0,0 +1,35 @@ +# 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 + +from mvt.common.module import run_module +from mvt.ios.modules.usb.applications import Applications +from pymobiledevice3.lockdown import LockdownClient + + +class TestUSBApplication: + def test_run(self, mocker): + # Mock + mocker.patch("pymobiledevice3.lockdown.LockdownClient.start_service") + mocker.patch("pymobiledevice3.usbmux.select_device") + mocker.patch("pymobiledevice3.service_connection.ServiceConnection.create") + mocker.patch( + "pymobiledevice3.lockdown.LockdownClient.query_type", + return_value="com.apple.mobile.lockdown") + mocker.patch( + "pymobiledevice3.lockdown.LockdownClient.validate_pairing", + return_value=True) + mocker.patch( + "pymobiledevice3.services.installation_proxy.InstallationProxyService.get_apps", + return_value=[{"CFBundleIdentifier": "com.bad.app"}] + ) + + lockdown = LockdownClient() + + m = Applications(log=logging) + m.lockdown = lockdown + run_module(m) + assert len(m.results) == 2 diff --git a/tests/ios_usb/test_device_info.py b/tests/ios_usb/test_device_info.py new file mode 100644 index 0000000..ca435df --- /dev/null +++ b/tests/ios_usb/test_device_info.py @@ -0,0 +1,34 @@ +# 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 + +from mvt.common.module import run_module +from mvt.ios.modules.usb.device_info import DeviceInfo +from pymobiledevice3.lockdown import LockdownClient + + +class TestUSBDeviceInfo: + def test_run(self, mocker): + # Mock + mocker.patch("pymobiledevice3.usbmux.select_device") + mocker.patch("pymobiledevice3.service_connection.ServiceConnection.create") + mocker.patch( + "pymobiledevice3.lockdown.LockdownClient.query_type", + return_value="com.apple.mobile.lockdown") + mocker.patch( + "pymobiledevice3.lockdown.LockdownClient.validate_pairing", + return_value=True) + mocker.patch( + "pymobiledevice3.lockdown.LockdownClient.get_value", + return_value={'DeviceClass': 'iPhone', 'ProductVersion': '14.3'} + ) + + lockdown = LockdownClient() + + m = DeviceInfo(log=logging) + m.lockdown = lockdown + run_module(m) + assert len(m.results) == 2