Refactoring cli commands for iOS too

This commit is contained in:
Nex 2022-06-16 15:18:50 +02:00
parent c54a01ca59
commit e7fe30e201
41 changed files with 195 additions and 207 deletions

View File

@ -9,15 +9,15 @@ import os
import click import click
from rich.logging import RichHandler from rich.logging import RichHandler
from mvt.android.cmd_check_adb import CmdAndroidCheckADB
from mvt.android.cmd_check_backup import CmdAndroidCheckBackup
from mvt.android.cmd_check_bugreport import CmdAndroidCheckBugreport
from mvt.common.help import (HELP_MSG_FAST, HELP_MSG_IOC, from mvt.common.help import (HELP_MSG_FAST, HELP_MSG_IOC,
HELP_MSG_LIST_MODULES, HELP_MSG_MODULE, HELP_MSG_LIST_MODULES, HELP_MSG_MODULE,
HELP_MSG_OUTPUT, HELP_MSG_SERIAL) HELP_MSG_OUTPUT, HELP_MSG_SERIAL)
from mvt.common.indicators import Indicators, download_indicators_files from mvt.common.indicators import Indicators, download_indicators_files
from mvt.common.logo import logo from mvt.common.logo import logo
from .cmd_check_adb import CmdAndroidCheckADB
from .cmd_check_backup import CmdAndroidCheckBackup
from .cmd_check_bugreport import CmdAndroidCheckBugreport
from .cmd_download_apks import DownloadAPKs from .cmd_download_apks import DownloadAPKs
from .modules.adb import ADB_MODULES from .modules.adb import ADB_MODULES
from .modules.adb.packages import Packages from .modules.adb.packages import Packages

View File

@ -15,9 +15,10 @@ from mvt.common.help import (HELP_MSG_FAST, HELP_MSG_IOC,
HELP_MSG_OUTPUT) HELP_MSG_OUTPUT)
from mvt.common.indicators import Indicators, download_indicators_files from mvt.common.indicators import Indicators, download_indicators_files
from mvt.common.logo import logo from mvt.common.logo import logo
from mvt.common.module import run_module, save_timeline
from mvt.common.options import MutuallyExclusiveOption from mvt.common.options import MutuallyExclusiveOption
from .cmd_check_backup import CmdIOSCheckBackup
from .cmd_check_fs import CmdIOSCheckFS
from .decrypt import DecryptBackup from .decrypt import DecryptBackup
from .modules.backup import BACKUP_MODULES from .modules.backup import BACKUP_MODULES
from .modules.fs import FS_MODULES from .modules.fs import FS_MODULES
@ -140,51 +141,20 @@ def extract_key(password, backup_path, key_file):
@click.argument("BACKUP_PATH", type=click.Path(exists=True)) @click.argument("BACKUP_PATH", type=click.Path(exists=True))
@click.pass_context @click.pass_context
def check_backup(ctx, iocs, output, fast, backup_path, list_modules, module): def check_backup(ctx, iocs, output, fast, backup_path, list_modules, module):
if list_modules: cmd = CmdIOSCheckBackup(target_path=backup_path, results_path=output,
log.info("Following is the list of available check-backup modules:") ioc_files=iocs, module_name=module, fast_mode=fast)
for backup_module in BACKUP_MODULES + MIXED_MODULES:
log.info(" - %s", backup_module.__name__)
if list_modules:
cmd.list_modules()
return return
log.info("Checking iTunes backup located at: %s", backup_path) log.info("Checking iTunes backup located at: %s", backup_path)
if output and not os.path.exists(output): cmd.run()
try:
os.makedirs(output)
except Exception as e:
log.critical("Unable to create output folder %s: %s", output, e)
ctx.exit(1)
indicators = Indicators(log=log) if len(cmd.timeline_detected) > 0:
indicators.load_indicators_files(iocs)
timeline = []
timeline_detected = []
for backup_module in BACKUP_MODULES + MIXED_MODULES:
if module and backup_module.__name__ != module:
continue
m = backup_module(base_folder=backup_path, output_folder=output, fast_mode=fast,
log=logging.getLogger(backup_module.__module__))
m.is_backup = True
if indicators.total_ioc_count > 0:
m.indicators = indicators
m.indicators.log = m.log
run_module(m)
timeline.extend(m.timeline)
timeline_detected.extend(m.timeline_detected)
if output:
if len(timeline) > 0:
save_timeline(timeline, os.path.join(output, "timeline.csv"))
if len(timeline_detected) > 0:
save_timeline(timeline_detected, os.path.join(output, "timeline_detected.csv"))
if len(timeline_detected) > 0:
log.warning("The analysis of the backup produced %d detections!", log.warning("The analysis of the backup produced %d detections!",
len(timeline_detected)) len(cmd.timeline_detected))
#============================================================================== #==============================================================================
@ -200,52 +170,20 @@ def check_backup(ctx, iocs, output, fast, backup_path, list_modules, module):
@click.argument("DUMP_PATH", type=click.Path(exists=True)) @click.argument("DUMP_PATH", type=click.Path(exists=True))
@click.pass_context @click.pass_context
def check_fs(ctx, iocs, output, fast, dump_path, list_modules, module): def check_fs(ctx, iocs, output, fast, dump_path, list_modules, module):
if list_modules: cmd = CmdIOSCheckFS(target_path=dump_path, results_path=output,
log.info("Following is the list of available check-fs modules:") ioc_files=iocs, module_name=module, fast_mode=fast)
for fs_module in FS_MODULES + MIXED_MODULES:
log.info(" - %s", fs_module.__name__)
if list_modules:
cmd.list_modules()
return return
log.info("Checking filesystem dump located at: %s", dump_path) log.info("Checking iOS filesystem located at: %s", dump_path)
if output and not os.path.exists(output): cmd.run()
try:
os.makedirs(output)
except Exception as e:
log.critical("Unable to create output folder %s: %s", output, e)
ctx.exit(1)
indicators = Indicators(log=log) if len(cmd.timeline_detected) > 0:
indicators.load_indicators_files(iocs) log.warning("The analysis of the iOS filesystem produced %d detections!",
len(cmd.timeline_detected))
timeline = []
timeline_detected = []
for fs_module in FS_MODULES + MIXED_MODULES:
if module and fs_module.__name__ != module:
continue
m = fs_module(base_folder=dump_path, output_folder=output, fast_mode=fast,
log=logging.getLogger(fs_module.__module__))
m.is_fs_dump = True
if indicators.total_ioc_count > 0:
m.indicators = indicators
m.indicators.log = m.log
run_module(m)
timeline.extend(m.timeline)
timeline_detected.extend(m.timeline_detected)
if output:
if len(timeline) > 0:
save_timeline(timeline, os.path.join(output, "timeline.csv"))
if len(timeline_detected) > 0:
save_timeline(timeline_detected, os.path.join(output, "timeline_detected.csv"))
if len(timeline_detected) > 0:
log.warning("The analysis of the filesystem produced %d detections!",
len(timeline_detected))
#============================================================================== #==============================================================================

View File

@ -0,0 +1,25 @@
# 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.command import Command
from .modules.backup import BACKUP_MODULES
from .modules.mixed import MIXED_MODULES
log = logging.getLogger(__name__)
class CmdIOSCheckBackup(Command):
name = "check-backup"
modules = BACKUP_MODULES + MIXED_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)

25
mvt/ios/cmd_check_fs.py Normal file
View File

@ -0,0 +1,25 @@
# 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.command import Command
from .modules.fs import FS_MODULES
from .modules.mixed import MIXED_MODULES
log = logging.getLogger(__name__)
class CmdIOSChecKFS(Command):
name = "check-fs"
modules = FS_MODULES + MIXED_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)

View File

@ -15,16 +15,16 @@ from ..base import IOSExtraction
class BackupInfo(IOSExtraction): class BackupInfo(IOSExtraction):
"""This module extracts information about the device and the backup.""" """This module extracts information about the device and the backup."""
def __init__(self, file_path=None, base_folder=None, output_folder=None, def __init__(self, file_path=None, target_path=None, results_path=None,
fast_mode=False, log=None, results=[]): fast_mode=False, log=None, results=[]):
super().__init__(file_path=file_path, base_folder=base_folder, super().__init__(file_path=file_path, target_path=target_path,
output_folder=output_folder, fast_mode=fast_mode, results_path=results_path, fast_mode=fast_mode,
log=log, results=results) log=log, results=results)
self.results = {} self.results = {}
def run(self): def run(self):
info_path = os.path.join(self.base_folder, "Info.plist") info_path = os.path.join(self.target_path, "Info.plist")
if not os.path.exists(info_path): if not os.path.exists(info_path):
raise DatabaseNotFoundError("No Info.plist at backup path, unable to extract device information") raise DatabaseNotFoundError("No Info.plist at backup path, unable to extract device information")

View File

@ -17,10 +17,10 @@ CONF_PROFILES_DOMAIN = "SysSharedContainerDomain-systemgroup.com.apple.configura
class ConfigurationProfiles(IOSExtraction): class ConfigurationProfiles(IOSExtraction):
"""This module extracts the full plist data from configuration profiles.""" """This module extracts the full plist data from configuration profiles."""
def __init__(self, file_path=None, base_folder=None, output_folder=None, def __init__(self, file_path=None, target_path=None, results_path=None,
fast_mode=False, log=None, results=[]): fast_mode=False, log=None, results=[]):
super().__init__(file_path=file_path, base_folder=base_folder, super().__init__(file_path=file_path, target_path=target_path,
output_folder=output_folder, fast_mode=fast_mode, results_path=results_path, fast_mode=fast_mode,
log=log, results=results) log=log, results=results)
def serialize(self, record): def serialize(self, record):

View File

@ -18,10 +18,10 @@ from ..base import IOSExtraction
class Manifest(IOSExtraction): class Manifest(IOSExtraction):
"""This module extracts information from a backup Manifest.db file.""" """This module extracts information from a backup Manifest.db file."""
def __init__(self, file_path=None, base_folder=None, output_folder=None, def __init__(self, file_path=None, target_path=None, results_path=None,
fast_mode=False, log=None, results=[]): fast_mode=False, log=None, results=[]):
super().__init__(file_path=file_path, base_folder=base_folder, super().__init__(file_path=file_path, target_path=target_path,
output_folder=output_folder, fast_mode=fast_mode, results_path=results_path, fast_mode=fast_mode,
log=log, results=results) log=log, results=results)
def _get_key(self, dictionary, key): def _get_key(self, dictionary, key):
@ -93,7 +93,7 @@ class Manifest(IOSExtraction):
self.detected.append(result) self.detected.append(result)
def run(self): def run(self):
manifest_db_path = os.path.join(self.base_folder, "Manifest.db") manifest_db_path = os.path.join(self.target_path, "Manifest.db")
if not os.path.isfile(manifest_db_path): if not os.path.isfile(manifest_db_path):
raise DatabaseNotFoundError("unable to find backup's Manifest.db") raise DatabaseNotFoundError("unable to find backup's Manifest.db")

View File

@ -19,10 +19,10 @@ class ProfileEvents(IOSExtraction):
""" """
def __init__(self, file_path=None, base_folder=None, output_folder=None, def __init__(self, file_path=None, target_path=None, results_path=None,
fast_mode=False, log=None, results=[]): fast_mode=False, log=None, results=[]):
super().__init__(file_path=file_path, base_folder=base_folder, super().__init__(file_path=file_path, target_path=target_path,
output_folder=output_folder, fast_mode=fast_mode, results_path=results_path, fast_mode=fast_mode,
log=log, results=results) log=log, results=results)
def serialize(self, record): def serialize(self, record):

View File

@ -16,10 +16,10 @@ from mvt.common.module import (DatabaseCorruptedError, DatabaseNotFoundError,
class IOSExtraction(MVTModule): class IOSExtraction(MVTModule):
"""This class provides a base for all iOS filesystem/backup extraction modules.""" """This class provides a base for all iOS filesystem/backup extraction modules."""
def __init__(self, file_path=None, base_folder=None, output_folder=None, def __init__(self, file_path=None, target_path=None, results_path=None,
fast_mode=False, log=None, results=[]): fast_mode=False, log=None, results=[]):
super().__init__(file_path=file_path, base_folder=base_folder, super().__init__(file_path=file_path, target_path=target_path,
output_folder=output_folder, fast_mode=fast_mode, results_path=results_path, fast_mode=fast_mode,
log=log, results=results) log=log, results=results)
self.is_backup = False self.is_backup = False
@ -73,7 +73,7 @@ class IOSExtraction(MVTModule):
:param domain: Domain to use as filter from Manifest.db. (Default value = None) :param domain: Domain to use as filter from Manifest.db. (Default value = None)
""" """
manifest_db_path = os.path.join(self.base_folder, "Manifest.db") manifest_db_path = os.path.join(self.target_path, "Manifest.db")
if not os.path.exists(manifest_db_path): if not os.path.exists(manifest_db_path):
raise DatabaseNotFoundError("unable to find backup's Manifest.db") raise DatabaseNotFoundError("unable to find backup's Manifest.db")
@ -101,7 +101,7 @@ class IOSExtraction(MVTModule):
} }
def _get_backup_file_from_id(self, file_id): def _get_backup_file_from_id(self, file_id):
file_path = os.path.join(self.base_folder, file_id[0:2], file_id) file_path = os.path.join(self.target_path, file_id[0:2], file_id)
if os.path.exists(file_path): if os.path.exists(file_path):
return file_path return file_path
@ -109,7 +109,7 @@ class IOSExtraction(MVTModule):
def _get_fs_files_from_patterns(self, root_paths): def _get_fs_files_from_patterns(self, root_paths):
for root_path in root_paths: for root_path in root_paths:
for found_path in glob.glob(os.path.join(self.base_folder, root_path)): for found_path in glob.glob(os.path.join(self.target_path, root_path)):
if not os.path.exists(found_path): if not os.path.exists(found_path):
continue continue

View File

@ -18,10 +18,10 @@ ANALYTICS_DB_PATH = [
class Analytics(IOSExtraction): class Analytics(IOSExtraction):
"""This module extracts information from the private/var/Keychains/Analytics/*.db files.""" """This module extracts information from the private/var/Keychains/Analytics/*.db files."""
def __init__(self, file_path=None, base_folder=None, output_folder=None, def __init__(self, file_path=None, target_path=None, results_path=None,
fast_mode=False, log=None, results=[]): fast_mode=False, log=None, results=[]):
super().__init__(file_path=file_path, base_folder=base_folder, super().__init__(file_path=file_path, target_path=target_path,
output_folder=output_folder, fast_mode=fast_mode, results_path=results_path, fast_mode=fast_mode,
log=log, results=results) log=log, results=results)
def serialize(self, record): def serialize(self, record):

View File

@ -11,10 +11,10 @@ from ..base import IOSExtraction
class CacheFiles(IOSExtraction): class CacheFiles(IOSExtraction):
def __init__(self, file_path=None, base_folder=None, output_folder=None, def __init__(self, file_path=None, target_path=None, results_path=None,
fast_mode=False, log=None, results=[]): fast_mode=False, log=None, results=[]):
super().__init__(file_path=file_path, base_folder=base_folder, super().__init__(file_path=file_path, target_path=target_path,
output_folder=output_folder, fast_mode=fast_mode, results_path=results_path, fast_mode=fast_mode,
log=log, results=results) log=log, results=results)
def serialize(self, record): def serialize(self, record):
@ -55,7 +55,7 @@ class CacheFiles(IOSExtraction):
except sqlite3.OperationalError: except sqlite3.OperationalError:
return return
key_name = os.path.relpath(file_path, self.base_folder) key_name = os.path.relpath(file_path, self.target_path)
if key_name not in self.results: if key_name not in self.results:
self.results[key_name] = [] self.results[key_name] = []
@ -71,7 +71,7 @@ class CacheFiles(IOSExtraction):
def run(self): def run(self):
self.results = {} self.results = {}
for root, dirs, files in os.walk(self.base_folder): for root, dirs, files in os.walk(self.target_path):
for file_name in files: for file_name in files:
if file_name != "Cache.db": if file_name != "Cache.db":
continue continue

View File

@ -18,10 +18,10 @@ class Filesystem(IOSExtraction):
""" """
def __init__(self, file_path=None, base_folder=None, output_folder=None, def __init__(self, file_path=None, target_path=None, results_path=None,
fast_mode=False, log=None, results=[]): fast_mode=False, log=None, results=[]):
super().__init__(file_path=file_path, base_folder=base_folder, super().__init__(file_path=file_path, target_path=target_path,
output_folder=output_folder, fast_mode=fast_mode, results_path=results_path, fast_mode=fast_mode,
log=log, results=results) log=log, results=results)
def serialize(self, record): def serialize(self, record):
@ -58,12 +58,12 @@ class Filesystem(IOSExtraction):
self.detected.append(result) self.detected.append(result)
def run(self): def run(self):
for root, dirs, files in os.walk(self.base_folder): for root, dirs, files in os.walk(self.target_path):
for dir_name in dirs: for dir_name in dirs:
try: try:
dir_path = os.path.join(root, dir_name) dir_path = os.path.join(root, dir_name)
result = { result = {
"path": os.path.relpath(dir_path, self.base_folder), "path": os.path.relpath(dir_path, self.target_path),
"modified": convert_timestamp_to_iso(datetime.datetime.utcfromtimestamp(os.stat(dir_path).st_mtime)), "modified": convert_timestamp_to_iso(datetime.datetime.utcfromtimestamp(os.stat(dir_path).st_mtime)),
} }
except Exception: except Exception:
@ -75,7 +75,7 @@ class Filesystem(IOSExtraction):
try: try:
file_path = os.path.join(root, file_name) file_path = os.path.join(root, file_name)
result = { result = {
"path": os.path.relpath(file_path, self.base_folder), "path": os.path.relpath(file_path, self.target_path),
"modified": convert_timestamp_to_iso(datetime.datetime.utcfromtimestamp(os.stat(file_path).st_mtime)), "modified": convert_timestamp_to_iso(datetime.datetime.utcfromtimestamp(os.stat(file_path).st_mtime)),
} }
except Exception: except Exception:

View File

@ -20,10 +20,10 @@ class Netusage(NetBase):
""" """
def __init__(self, file_path=None, base_folder=None, output_folder=None, def __init__(self, file_path=None, target_path=None, results_path=None,
fast_mode=False, log=None, results=[]): fast_mode=False, log=None, results=[]):
super().__init__(file_path=file_path, base_folder=base_folder, super().__init__(file_path=file_path, target_path=target_path,
output_folder=output_folder, fast_mode=fast_mode, results_path=results_path, fast_mode=fast_mode,
log=log, results=results) log=log, results=results)
def run(self): def run(self):

View File

@ -18,10 +18,10 @@ SAFARI_FAVICON_ROOT_PATHS = [
class SafariFavicon(IOSExtraction): class SafariFavicon(IOSExtraction):
"""This module extracts all Safari favicon records.""" """This module extracts all Safari favicon records."""
def __init__(self, file_path=None, base_folder=None, output_folder=None, def __init__(self, file_path=None, target_path=None, results_path=None,
fast_mode=False, log=None, results=[]): fast_mode=False, log=None, results=[]):
super().__init__(file_path=file_path, base_folder=base_folder, super().__init__(file_path=file_path, target_path=target_path,
output_folder=output_folder, fast_mode=fast_mode, results_path=results_path, fast_mode=fast_mode,
log=log, results=results) log=log, results=results)
def serialize(self, record): def serialize(self, record):

View File

@ -15,10 +15,10 @@ SHUTDOWN_LOG_PATH = [
class ShutdownLog(IOSExtraction): class ShutdownLog(IOSExtraction):
"""This module extracts processes information from the shutdown log file.""" """This module extracts processes information from the shutdown log file."""
def __init__(self, file_path=None, base_folder=None, output_folder=None, def __init__(self, file_path=None, target_path=None, results_path=None,
fast_mode=False, log=None, results=[]): fast_mode=False, log=None, results=[]):
super().__init__(file_path=file_path, base_folder=base_folder, super().__init__(file_path=file_path, target_path=target_path,
output_folder=output_folder, fast_mode=fast_mode, results_path=results_path, fast_mode=fast_mode,
log=log, results=results) log=log, results=results)
def serialize(self, record): def serialize(self, record):

View File

@ -18,10 +18,10 @@ IOS_ANALYTICS_JOURNAL_PATHS = [
class IOSVersionHistory(IOSExtraction): class IOSVersionHistory(IOSExtraction):
"""This module extracts iOS update history from Analytics Journal log files.""" """This module extracts iOS update history from Analytics Journal log files."""
def __init__(self, file_path=None, base_folder=None, output_folder=None, def __init__(self, file_path=None, target_path=None, results_path=None,
fast_mode=False, log=None, results=[]): fast_mode=False, log=None, results=[]):
super().__init__(file_path=file_path, base_folder=base_folder, super().__init__(file_path=file_path, target_path=target_path,
output_folder=output_folder, fast_mode=fast_mode, results_path=results_path, fast_mode=fast_mode,
log=log, results=results) log=log, results=results)
def serialize(self, record): def serialize(self, record):

View File

@ -26,7 +26,7 @@ class WebkitBase(IOSExtraction):
def _process_webkit_folder(self, root_paths): def _process_webkit_folder(self, root_paths):
for found_path in self._get_fs_files_from_patterns(root_paths): for found_path in self._get_fs_files_from_patterns(root_paths):
key = os.path.relpath(found_path, self.base_folder) key = os.path.relpath(found_path, self.target_path)
for name in os.listdir(found_path): for name in os.listdir(found_path):
if not name.startswith("http"): if not name.startswith("http"):

View File

@ -19,10 +19,10 @@ class WebkitIndexedDB(WebkitBase):
slug = "webkit_indexeddb" slug = "webkit_indexeddb"
def __init__(self, file_path=None, base_folder=None, output_folder=None, def __init__(self, file_path=None, target_path=None, results_path=None,
fast_mode=False, log=None, results=[]): fast_mode=False, log=None, results=[]):
super().__init__(file_path=file_path, base_folder=base_folder, super().__init__(file_path=file_path, target_path=target_path,
output_folder=output_folder, fast_mode=fast_mode, results_path=results_path, fast_mode=fast_mode,
log=log, results=results) log=log, results=results)
def serialize(self, record): def serialize(self, record):

View File

@ -17,10 +17,10 @@ class WebkitLocalStorage(WebkitBase):
""" """
def __init__(self, file_path=None, base_folder=None, output_folder=None, def __init__(self, file_path=None, target_path=None, results_path=None,
fast_mode=False, log=None, results=[]): fast_mode=False, log=None, results=[]):
super().__init__(file_path=file_path, base_folder=base_folder, super().__init__(file_path=file_path, target_path=target_path,
output_folder=output_folder, fast_mode=fast_mode, results_path=results_path, fast_mode=fast_mode,
log=log, results=results) log=log, results=results)
def serialize(self, record): def serialize(self, record):

View File

@ -17,10 +17,10 @@ class WebkitSafariViewService(WebkitBase):
""" """
def __init__(self, file_path=None, base_folder=None, output_folder=None, def __init__(self, file_path=None, target_path=None, results_path=None,
fast_mode=False, log=None, results=[]): fast_mode=False, log=None, results=[]):
super().__init__(file_path=file_path, base_folder=base_folder, super().__init__(file_path=file_path, target_path=target_path,
output_folder=output_folder, fast_mode=fast_mode, results_path=results_path, fast_mode=fast_mode,
log=log, results=results) log=log, results=results)
def run(self): def run(self):

View File

@ -20,10 +20,10 @@ CALLS_ROOT_PATHS = [
class Calls(IOSExtraction): class Calls(IOSExtraction):
"""This module extracts phone calls details""" """This module extracts phone calls details"""
def __init__(self, file_path=None, base_folder=None, output_folder=None, def __init__(self, file_path=None, target_path=None, results_path=None,
fast_mode=False, log=None, results=[]): fast_mode=False, log=None, results=[]):
super().__init__(file_path=file_path, base_folder=base_folder, super().__init__(file_path=file_path, target_path=target_path,
output_folder=output_folder, fast_mode=fast_mode, results_path=results_path, fast_mode=fast_mode,
log=log, results=results) log=log, results=results)
def serialize(self, record): def serialize(self, record):

View File

@ -23,10 +23,10 @@ CHROME_FAVICON_ROOT_PATHS = [
class ChromeFavicon(IOSExtraction): class ChromeFavicon(IOSExtraction):
"""This module extracts all Chrome favicon records.""" """This module extracts all Chrome favicon records."""
def __init__(self, file_path=None, base_folder=None, output_folder=None, def __init__(self, file_path=None, target_path=None, results_path=None,
fast_mode=False, log=None, results=[]): fast_mode=False, log=None, results=[]):
super().__init__(file_path=file_path, base_folder=base_folder, super().__init__(file_path=file_path, target_path=target_path,
output_folder=output_folder, fast_mode=fast_mode, results_path=results_path, fast_mode=fast_mode,
log=log, results=results) log=log, results=results)
def serialize(self, record): def serialize(self, record):

View File

@ -22,10 +22,10 @@ CHROME_HISTORY_ROOT_PATHS = [
class ChromeHistory(IOSExtraction): class ChromeHistory(IOSExtraction):
"""This module extracts all Chome visits.""" """This module extracts all Chome visits."""
def __init__(self, file_path=None, base_folder=None, output_folder=None, def __init__(self, file_path=None, target_path=None, results_path=None,
fast_mode=False, log=None, results=[]): fast_mode=False, log=None, results=[]):
super().__init__(file_path=file_path, base_folder=base_folder, super().__init__(file_path=file_path, target_path=target_path,
output_folder=output_folder, fast_mode=fast_mode, results_path=results_path, fast_mode=fast_mode,
log=log, results=results) log=log, results=results)
def serialize(self, record): def serialize(self, record):

View File

@ -18,10 +18,10 @@ CONTACTS_ROOT_PATHS = [
class Contacts(IOSExtraction): class Contacts(IOSExtraction):
"""This module extracts all contact details from the phone's address book.""" """This module extracts all contact details from the phone's address book."""
def __init__(self, file_path=None, base_folder=None, output_folder=None, def __init__(self, file_path=None, target_path=None, results_path=None,
fast_mode=False, log=None, results=[]): fast_mode=False, log=None, results=[]):
super().__init__(file_path=file_path, base_folder=base_folder, super().__init__(file_path=file_path, target_path=target_path,
output_folder=output_folder, fast_mode=fast_mode, results_path=results_path, fast_mode=fast_mode,
log=log, results=results) log=log, results=results)
def run(self): def run(self):

View File

@ -21,10 +21,10 @@ FIREFOX_HISTORY_ROOT_PATHS = [
class FirefoxFavicon(IOSExtraction): class FirefoxFavicon(IOSExtraction):
"""This module extracts all Firefox favicon""" """This module extracts all Firefox favicon"""
def __init__(self, file_path=None, base_folder=None, output_folder=None, def __init__(self, file_path=None, target_path=None, results_path=None,
fast_mode=False, log=None, results=[]): fast_mode=False, log=None, results=[]):
super().__init__(file_path=file_path, base_folder=base_folder, super().__init__(file_path=file_path, target_path=target_path,
output_folder=output_folder, fast_mode=fast_mode, results_path=results_path, fast_mode=fast_mode,
log=log, results=results) log=log, results=results)
def serialize(self, record): def serialize(self, record):

View File

@ -25,10 +25,10 @@ class FirefoxHistory(IOSExtraction):
""" """
def __init__(self, file_path=None, base_folder=None, output_folder=None, def __init__(self, file_path=None, target_path=None, results_path=None,
fast_mode=False, log=None, results=[]): fast_mode=False, log=None, results=[]):
super().__init__(file_path=file_path, base_folder=base_folder, super().__init__(file_path=file_path, target_path=target_path,
output_folder=output_folder, fast_mode=fast_mode, results_path=results_path, fast_mode=fast_mode,
log=log, results=results) log=log, results=results)
def serialize(self, record): def serialize(self, record):

View File

@ -22,10 +22,10 @@ IDSTATUSCACHE_ROOT_PATHS = [
class IDStatusCache(IOSExtraction): class IDStatusCache(IOSExtraction):
"""Extracts Apple Authentication information from idstatuscache.plist""" """Extracts Apple Authentication information from idstatuscache.plist"""
def __init__(self, file_path=None, base_folder=None, output_folder=None, def __init__(self, file_path=None, target_path=None, results_path=None,
fast_mode=False, log=None, results=[]): fast_mode=False, log=None, results=[]):
super().__init__(file_path=file_path, base_folder=base_folder, super().__init__(file_path=file_path, target_path=target_path,
output_folder=output_folder, fast_mode=fast_mode, results_path=results_path, fast_mode=fast_mode,
log=log, results=results) log=log, results=results)
def serialize(self, record): def serialize(self, record):

View File

@ -20,10 +20,10 @@ INTERACTIONC_ROOT_PATHS = [
class InteractionC(IOSExtraction): class InteractionC(IOSExtraction):
"""This module extracts data from InteractionC db.""" """This module extracts data from InteractionC db."""
def __init__(self, file_path=None, base_folder=None, output_folder=None, def __init__(self, file_path=None, target_path=None, results_path=None,
fast_mode=False, log=None, results=[]): fast_mode=False, log=None, results=[]):
super().__init__(file_path=file_path, base_folder=base_folder, super().__init__(file_path=file_path, target_path=target_path,
output_folder=output_folder, fast_mode=fast_mode, results_path=results_path, fast_mode=fast_mode,
log=log, results=results) log=log, results=results)
self.timestamps = [ self.timestamps = [

View File

@ -21,10 +21,10 @@ LOCATIOND_ROOT_PATHS = [
class LocationdClients(IOSExtraction): class LocationdClients(IOSExtraction):
"""Extract information from apps who used geolocation.""" """Extract information from apps who used geolocation."""
def __init__(self, file_path=None, base_folder=None, output_folder=None, def __init__(self, file_path=None, target_path=None, results_path=None,
fast_mode=False, log=None, results=[]): fast_mode=False, log=None, results=[]):
super().__init__(file_path=file_path, base_folder=base_folder, super().__init__(file_path=file_path, target_path=target_path,
output_folder=output_folder, fast_mode=fast_mode, results_path=results_path, fast_mode=fast_mode,
log=log, results=results) log=log, results=results)
self.timestamps = [ self.timestamps = [

View File

@ -20,10 +20,10 @@ class Datausage(NetBase):
""" """
def __init__(self, file_path=None, base_folder=None, output_folder=None, def __init__(self, file_path=None, target_path=None, results_path=None,
fast_mode=False, log=None, results=[]): fast_mode=False, log=None, results=[]):
super().__init__(file_path=file_path, base_folder=base_folder, super().__init__(file_path=file_path, target_path=target_path,
output_folder=output_folder, fast_mode=fast_mode, results_path=results_path, fast_mode=fast_mode,
log=log, results=results) log=log, results=results)
def run(self): def run(self):

View File

@ -20,10 +20,10 @@ OSANALYTICS_ADDAILY_ROOT_PATHS = [
class OSAnalyticsADDaily(IOSExtraction): class OSAnalyticsADDaily(IOSExtraction):
"""Extract network usage information by process, from com.apple.osanalytics.addaily.plist""" """Extract network usage information by process, from com.apple.osanalytics.addaily.plist"""
def __init__(self, file_path=None, base_folder=None, output_folder=None, def __init__(self, file_path=None, target_path=None, results_path=None,
fast_mode=False, log=None, results=[]): fast_mode=False, log=None, results=[]):
super().__init__(file_path=file_path, base_folder=base_folder, super().__init__(file_path=file_path, target_path=target_path,
output_folder=output_folder, fast_mode=fast_mode, results_path=results_path, fast_mode=fast_mode,
log=log, results=results) log=log, results=results)
def serialize(self, record): def serialize(self, record):

View File

@ -23,10 +23,10 @@ SAFARI_BROWSER_STATE_ROOT_PATHS = [
class SafariBrowserState(IOSExtraction): class SafariBrowserState(IOSExtraction):
"""This module extracts all Safari browser state records.""" """This module extracts all Safari browser state records."""
def __init__(self, file_path=None, base_folder=None, output_folder=None, def __init__(self, file_path=None, target_path=None, results_path=None,
fast_mode=False, log=None, results=[]): fast_mode=False, log=None, results=[]):
super().__init__(file_path=file_path, base_folder=base_folder, super().__init__(file_path=file_path, target_path=target_path,
output_folder=output_folder, fast_mode=fast_mode, results_path=results_path, fast_mode=fast_mode,
log=log, results=results) log=log, results=results)
self._session_history_count = 0 self._session_history_count = 0
@ -115,7 +115,7 @@ class SafariBrowserState(IOSExtraction):
"tab_visible_url": row[2], "tab_visible_url": row[2],
"last_viewed_timestamp": convert_timestamp_to_iso(convert_mactime_to_unix(row[3])), "last_viewed_timestamp": convert_timestamp_to_iso(convert_mactime_to_unix(row[3])),
"session_data": session_entries, "session_data": session_entries,
"safari_browser_state_db": os.path.relpath(db_path, self.base_folder), "safari_browser_state_db": os.path.relpath(db_path, self.target_path),
}) })
def run(self): def run(self):

View File

@ -25,10 +25,10 @@ class SafariHistory(IOSExtraction):
""" """
def __init__(self, file_path=None, base_folder=None, output_folder=None, def __init__(self, file_path=None, target_path=None, results_path=None,
fast_mode=False, log=None, results=[]): fast_mode=False, log=None, results=[]):
super().__init__(file_path=file_path, base_folder=base_folder, super().__init__(file_path=file_path, target_path=target_path,
output_folder=output_folder, fast_mode=fast_mode, results_path=results_path, fast_mode=fast_mode,
log=log, results=results) log=log, results=results)
def serialize(self, record): def serialize(self, record):
@ -111,7 +111,7 @@ class SafariHistory(IOSExtraction):
"isodate": convert_timestamp_to_iso(convert_mactime_to_unix(row[3])), "isodate": convert_timestamp_to_iso(convert_mactime_to_unix(row[3])),
"redirect_source": row[4], "redirect_source": row[4],
"redirect_destination": row[5], "redirect_destination": row[5],
"safari_history_db": os.path.relpath(history_path, self.base_folder), "safari_history_db": os.path.relpath(history_path, self.target_path),
}) })
cur.close() cur.close()

View File

@ -24,10 +24,10 @@ SHORTCUT_ROOT_PATHS = [
class Shortcuts(IOSExtraction): class Shortcuts(IOSExtraction):
"""This module extracts all info about SMS/iMessage attachments.""" """This module extracts all info about SMS/iMessage attachments."""
def __init__(self, file_path=None, base_folder=None, output_folder=None, def __init__(self, file_path=None, target_path=None, results_path=None,
fast_mode=False, log=None, results=[]): fast_mode=False, log=None, results=[]):
super().__init__(file_path=file_path, base_folder=base_folder, super().__init__(file_path=file_path, target_path=target_path,
output_folder=output_folder, fast_mode=fast_mode, results_path=results_path, fast_mode=fast_mode,
log=log, results=results) log=log, results=results)
def serialize(self, record): def serialize(self, record):

View File

@ -22,10 +22,10 @@ SMS_ROOT_PATHS = [
class SMS(IOSExtraction): class SMS(IOSExtraction):
"""This module extracts all SMS messages containing links.""" """This module extracts all SMS messages containing links."""
def __init__(self, file_path=None, base_folder=None, output_folder=None, def __init__(self, file_path=None, target_path=None, results_path=None,
fast_mode=False, log=None, results=[]): fast_mode=False, log=None, results=[]):
super().__init__(file_path=file_path, base_folder=base_folder, super().__init__(file_path=file_path, target_path=target_path,
output_folder=output_folder, fast_mode=fast_mode, results_path=results_path, fast_mode=fast_mode,
log=log, results=results) log=log, results=results)
def serialize(self, record): def serialize(self, record):

View File

@ -21,10 +21,10 @@ SMS_ROOT_PATHS = [
class SMSAttachments(IOSExtraction): class SMSAttachments(IOSExtraction):
"""This module extracts all info about SMS/iMessage attachments.""" """This module extracts all info about SMS/iMessage attachments."""
def __init__(self, file_path=None, base_folder=None, output_folder=None, def __init__(self, file_path=None, target_path=None, results_path=None,
fast_mode=False, log=None, results=[]): fast_mode=False, log=None, results=[]):
super().__init__(file_path=file_path, base_folder=base_folder, super().__init__(file_path=file_path, target_path=target_path,
output_folder=output_folder, fast_mode=fast_mode, results_path=results_path, fast_mode=fast_mode,
log=log, results=results) log=log, results=results)
def serialize(self, record): def serialize(self, record):

View File

@ -47,10 +47,10 @@ AUTH_REASONS = {
class TCC(IOSExtraction): class TCC(IOSExtraction):
"""This module extracts records from the TCC.db SQLite database.""" """This module extracts records from the TCC.db SQLite database."""
def __init__(self, file_path=None, base_folder=None, output_folder=None, def __init__(self, file_path=None, target_path=None, results_path=None,
fast_mode=False, log=None, results=[]): fast_mode=False, log=None, results=[]):
super().__init__(file_path=file_path, base_folder=base_folder, super().__init__(file_path=file_path, target_path=target_path,
output_folder=output_folder, fast_mode=fast_mode, results_path=results_path, fast_mode=fast_mode,
log=log, results=results) log=log, results=results)
def serialize(self, record): def serialize(self, record):

View File

@ -22,10 +22,10 @@ class WebkitResourceLoadStatistics(IOSExtraction):
"""This module extracts records from WebKit ResourceLoadStatistics observations.db.""" """This module extracts records from WebKit ResourceLoadStatistics observations.db."""
# TODO: Add serialize(). # TODO: Add serialize().
def __init__(self, file_path=None, base_folder=None, output_folder=None, def __init__(self, file_path=None, target_path=None, results_path=None,
fast_mode=False, log=None, results=[]): fast_mode=False, log=None, results=[]):
super().__init__(file_path=file_path, base_folder=base_folder, super().__init__(file_path=file_path, target_path=target_path,
output_folder=output_folder, fast_mode=fast_mode, results_path=results_path, fast_mode=fast_mode,
log=log, results=results) log=log, results=results)
self.results = {} if not results else results self.results = {} if not results else results
@ -85,4 +85,4 @@ class WebkitResourceLoadStatistics(IOSExtraction):
self.log.info("Unable to search for WebKit observations.db: %s", e) self.log.info("Unable to search for WebKit observations.db: %s", e)
elif self.is_fs_dump: elif self.is_fs_dump:
for db_path in self._get_fs_files_from_patterns(WEBKIT_RESOURCELOADSTATICS_ROOT_PATHS): for db_path in self._get_fs_files_from_patterns(WEBKIT_RESOURCELOADSTATICS_ROOT_PATHS):
self._process_observations_db(db_path=db_path, key=os.path.relpath(db_path, self.base_folder)) self._process_observations_db(db_path=db_path, key=os.path.relpath(db_path, self.target_path))

View File

@ -29,10 +29,10 @@ class WebkitSessionResourceLog(IOSExtraction):
""" """
def __init__(self, file_path=None, base_folder=None, output_folder=None, def __init__(self, file_path=None, target_path=None, results_path=None,
fast_mode=False, log=None, results=[]): fast_mode=False, log=None, results=[]):
super().__init__(file_path=file_path, base_folder=base_folder, super().__init__(file_path=file_path, target_path=target_path,
output_folder=output_folder, fast_mode=fast_mode, results_path=results_path, fast_mode=fast_mode,
log=log, results=results) log=log, results=results)
self.results = {} if not results else results self.results = {} if not results else results
@ -128,7 +128,7 @@ class WebkitSessionResourceLog(IOSExtraction):
elif self.is_fs_dump: elif self.is_fs_dump:
for log_path in self._get_fs_files_from_patterns(WEBKIT_SESSION_RESOURCE_LOG_ROOT_PATHS): for log_path in self._get_fs_files_from_patterns(WEBKIT_SESSION_RESOURCE_LOG_ROOT_PATHS):
self.log.info("Found Safari browsing session resource log at path: %s", log_path) self.log.info("Found Safari browsing session resource log at path: %s", log_path)
key = os.path.relpath(log_path, self.base_folder) key = os.path.relpath(log_path, self.target_path)
self.results[key] = self._extract_browsing_stats(log_path) self.results[key] = self._extract_browsing_stats(log_path)
self.log.info("Extracted records from %d Safari browsing session resource logs", self.log.info("Extracted records from %d Safari browsing session resource logs",

View File

@ -24,10 +24,10 @@ WHATSAPP_ROOT_PATHS = [
class Whatsapp(IOSExtraction): class Whatsapp(IOSExtraction):
"""This module extracts all WhatsApp messages containing links.""" """This module extracts all WhatsApp messages containing links."""
def __init__(self, file_path=None, base_folder=None, output_folder=None, def __init__(self, file_path=None, target_path=None, results_path=None,
fast_mode=False, log=None, results=[]): fast_mode=False, log=None, results=[]):
super().__init__(file_path=file_path, base_folder=base_folder, super().__init__(file_path=file_path, target_path=target_path,
output_folder=output_folder, fast_mode=fast_mode, results_path=results_path, fast_mode=fast_mode,
log=log, results=results) log=log, results=results)
def serialize(self, record): def serialize(self, record):

View File

@ -15,10 +15,10 @@ from .base import IOSExtraction
class NetBase(IOSExtraction): class NetBase(IOSExtraction):
"""This class provides a base for DataUsage and NetUsage extraction modules.""" """This class provides a base for DataUsage and NetUsage extraction modules."""
def __init__(self, file_path=None, base_folder=None, output_folder=None, def __init__(self, file_path=None, target_path=None, results_path=None,
fast_mode=False, log=None, results=[]): fast_mode=False, log=None, results=[]):
super().__init__(file_path=file_path, base_folder=base_folder, super().__init__(file_path=file_path, target_path=target_path,
output_folder=output_folder, fast_mode=fast_mode, results_path=results_path, fast_mode=fast_mode,
log=log, results=results) log=log, results=results)
def _extract_net_data(self): def _extract_net_data(self):
@ -124,7 +124,7 @@ class NetBase(IOSExtraction):
self.log.info("Extended search for suspicious processes ...") self.log.info("Extended search for suspicious processes ...")
files = [] files = []
for posix_path in Path(self.base_folder).rglob("*"): for posix_path in Path(self.target_path).rglob("*"):
try: try:
if not posix_path.is_file(): if not posix_path.is_file():
continue continue