diff --git a/src/mvt/common/command.py b/src/mvt/common/command.py index 0eb633a..858f7d8 100644 --- a/src/mvt/common/command.py +++ b/src/mvt/common/command.py @@ -11,7 +11,7 @@ from datetime import datetime from typing import Optional from mvt.common.indicators import Indicators -from mvt.common.module import MVTModule, run_module, save_timeline +from mvt.common.module import EncryptedBackupError, MVTModule, run_module, save_timeline from mvt.common.utils import ( convert_datetime_to_iso, generate_hashes_from_path, @@ -244,7 +244,14 @@ class Command: except NotImplementedError: pass - run_module(m) + try: + run_module(m) + except EncryptedBackupError: + log.critical( + "The backup appears to be encrypted. " + "Please decrypt it first using `mvt-ios decrypt-backup`." + ) + return self.executed.append(m) diff --git a/src/mvt/common/module.py b/src/mvt/common/module.py index 2a52677..9c26064 100644 --- a/src/mvt/common/module.py +++ b/src/mvt/common/module.py @@ -21,6 +21,10 @@ class DatabaseCorruptedError(Exception): pass +class EncryptedBackupError(Exception): + pass + + class InsufficientPrivileges(Exception): pass @@ -169,6 +173,8 @@ def run_module(module: MVTModule) -> None: try: exec_or_profile("module.run()", globals(), locals()) + except EncryptedBackupError: + raise except NotImplementedError: module.log.exception( "The run() procedure of module %s was not implemented yet!", diff --git a/src/mvt/ios/modules/backup/manifest.py b/src/mvt/ios/modules/backup/manifest.py index ccbc459..da5c1a8 100644 --- a/src/mvt/ios/modules/backup/manifest.py +++ b/src/mvt/ios/modules/backup/manifest.py @@ -8,9 +8,10 @@ import io import logging import os import plistlib +import sqlite3 from typing import Optional -from mvt.common.module import DatabaseNotFoundError +from mvt.common.module import DatabaseNotFoundError, EncryptedBackupError from mvt.common.url import URL from mvt.common.utils import convert_datetime_to_iso, convert_unix_to_iso @@ -127,7 +128,14 @@ class Manifest(IOSExtraction): conn = self._open_sqlite_db(manifest_db_path) cur = conn.cursor() - cur.execute("SELECT * FROM Files;") + try: + cur.execute("SELECT * FROM Files;") + except sqlite3.DatabaseError: + conn.close() + raise EncryptedBackupError( + "Manifest.db is not a valid SQLite database. " + "The backup may be encrypted." + ) names = [description[0] for description in cur.description] for file_entry in cur: