mvt Documentation

MVT (Mobile Verification Toolkit) helps with conducting forensics of mobile devices in order to find signs of a potential compromise.

12,383 stars Python Python 1 file ยท ~7,098 tokens #android#forensics#forensics-tools#ios#mobile#security
RAW Doc

Docker & Self-Hosted Deployment Verified OCI

Deploy mvt on any server, homelab, or cloud container platform.

1-Click Terminal Command
bash (docker run)
docker run -d --name mvt --restart always mvt-project/mvt:latest

File: README.md

Mobile Verification Toolkit

[!IMPORTANT]
We recently merged the "v3" branch. This introduced breaking changes. If you relied on mvt output in other scripts They might have broken. More details: https://github.com/mvt-project/mvt/issues/757




Mobile Verification Toolkit (MVT) is a collection of utilities to simplify and automate the process of gathering forensic traces helpful to identify a potential compromise of Android and iOS devices.

It has been developed and released by the Amnesty International Security Lab in July 2021 in the context of the Pegasus Project along with a technical forensic methodology. It continues to be maintained by Amnesty International and other contributors.

Note
MVT is a forensic research tool intended for technologists and investigators. It requires understanding digital forensics and using command-line tools. This is not intended for end-user self-assessment. If you are concerned with the security of your device please seek reputable expert assistance.

Indicators of Compromise

MVT supports using public indicators of compromise (IOCs) to scan mobile devices for potential traces of targeting or infection by known spyware campaigns. This includes IOCs published by Amnesty International and other research groups.

Warning
Public indicators of compromise are insufficient to determine that a device is "clean", and not targeted with a particular spyware tool. Reliance on public indicators alone can miss recent forensic traces and give a false sense of security.

Reliable and comprehensive digital forensic support and triage requires access to non-public indicators, research and threat intelligence.

Such support is available to civil society through Amnesty International's Security Lab or through our forensic partnership with Access Nowโ€™s Digital Security Helpline.

More information about using indicators of compromise with MVT is available in the documentation.

Installation

MVT can be installed from sources or from PyPI (you will need some dependencies, check the documentation):

text
pip3 install mvt

You can also install MVT from PyPI with uv. First, install uv:

bash
curl -LsSf https://astral.sh/uv/install.sh | sh

Then install MVT as a command-line tool:

bash
uv tool install mvt

For alternative installation options and known issues, please refer to the documentation as well as GitHub Issues.

Usage

MVT provides two commands mvt-ios and mvt-android. Check out the documentation to learn how to use them!

Shell completion

MVT can generate shell completion scripts for Bash, Zsh, and Fish:

bash
mvt-ios completion
mvt-android completion

The commands print setup instructions by default. To generate a completion script directly, pass the shell name:

bash
mvt-ios completion bash
mvt-android completion zsh

MVT only writes completion files or shell configuration when --install is passed. See the command completion documentation for details.
Module-running check-* commands can load custom Python modules with
--load-module PATH or from a folder set in MVT_CUSTOM_MODULES. See the
development documentation for
details.

Users can also add top-level commands to mvt-ios and mvt-android from
installed Python packages or local files and folders. See the
custom CLI command documentation
for the plugin entry points and --load-command interface.

License

The purpose of MVT is to facilitate the consensual forensic analysis of devices of those who might be targets of sophisticated mobile spyware attacks, especially members of civil society and marginalized communities. We do not want MVT to enable privacy violations of non-consenting individuals. In order to achieve this, MVT is released under its own license. Read more here.


File: docs/android/adb.md

ADB Analysis Removed

The ability to analyze Android devices directly over the Android Debug Bridge (adb) has been removed from MVT.

Use AndroidQF to collect forensic artifacts from an Android device, then analyze the collected output with:

bash
mvt-android check-androidqf /path/to/androidqf-output

For a standalone Android bug report, use:

bash
mvt-android check-bugreport /path/to/bugreport.zip

Reasons for Removal

  1. Inconsistent Data Collection Across Devices
    Android devices vary significantly in system architecture, security policy, and diagnostic log availability. This made it difficult to collect reliable forensic data across devices.

  2. Incomplete Forensic Data Acquisition
    Direct ADB analysis did not retrieve a complete forensic snapshot. Critical artifacts such as full bug reports could be missing.

  3. Duplicated Analysis Paths
    Similar artifacts were parsed through separate ADB, AndroidQF, and bugreport modules, which made behavior harder to keep consistent.

  4. Workflow Consistency
    MVT now focuses on analyzing acquired artifacts rather than interacting with live devices directly.


File: docs/android/backup.md

Check an Android Backup (SMS messages)

Android supports generating a backup archive of all the installed applications which supports it. However, over the years this functionality has been increasingly abandoned in favor of enabling users to remotely backup their personal data over the cloud. App developers can therefore decide to opt out from allowing the apps' data from being exported locally.

At the time of writing, the Android Debug Bridge (adb) command to generate backups is still available but marked as deprecated.

That said, most versions of Android should still allow to locally backup SMS messages, and since messages are still a prime vehicle for phishing and malware attacks, you might still want to take advantage of this functionality while it is supported.

Generate a backup

Because mvt-android check-backup currently only supports checking SMS messages, you can indicate to backup only those:

bash
adb backup -nocompress com.android.providers.telephony

In case you nonetheless wish to take a full backup, you can do so with

bash
adb backup -nocompress -all

Some recent phones will enforce the utilisation of a password to encrypt the backup archive. In that case, the password will obviously be needed to extract and analyse the data later on.

Unpack and check the backup

MVT includes a partial implementation of the Android Backup parsing, because of the implementation difference in the compression algorithm between Java and Python. The -nocompress option passed to adb in the section above allows to avoid this issue. You can analyse and extract SMSs from the backup directly with MVT:

bash
$ mvt-android check-backup --output /path/to/results/ /path/to/backup.ab
14:09:45 INFO     [mvt.android.cli] Checking ADB backup located at: backup.ab
         INFO     [mvt.android.modules.backup.sms] Running module SMS...
         INFO     [mvt.android.modules.backup.sms] Processing SMS backup file at
                  apps/com.android.providers.telephony/d_f/000000_sms_backup
         INFO     [mvt.android.modules.backup.sms] Extracted a total of 64 SMS messages

If the backup is encrypted, MVT will prompt you to enter the password. A backup password can also be provided with the --backup-password command line option or through the MVT_ANDROID_BACKUP_PASSWORD environment variable. The same options can also be used to when analysing an encrypted backup collected through AndroidQF in the mvt-android check-androidqf command:

bash
$ mvt-android check-backup --backup-password "password123" --output /path/to/results/ /path/to/backup.ab

Through the --iocs argument you can specify a STIX2 file defining a list of malicious indicators to check against the records extracted from the backup by MVT. Any matches will be highlighted in the terminal output.

Alternative ways to unpack and check the backup

If you encounter an issue during the analysis of the backup, you can alternatively use Android Backup Extractor (ABE) to convert it to a readable file format. Make sure that java is installed on your system and use the following command:

bash
java -jar ~/path/to/abe.jar unpack backup.ab backup.tar
tar xvf backup.tar

If the backup is encrypted, ABE will prompt you to enter the password.

Alternatively, ab-decrypt can be used for that purpose.

You can then extract SMSs with MVT by passing the folder path as parameter instead of the .ab file: mvt-android check-backup --output /path/to/results/ /path/to/backup/ (the path to backup given should be the folder containing the apps folder).

When an output folder is specified, URLs extracted from SMS and MMS messages
are also written to urls.json. Each entry contains the URL, its expanded
destination when MVT resolved a shortened URL during indicator checking, the
message timestamp, and the sms source. The same file is created by
check-androidqf when its nested Android backup contains messages with URLs.


File: docs/android/methodology.md

Methodology for Android forensic

Unfortunately Android devices provide fewer complete forensically useful datasources than their iOS cousins. Unlike iOS, the Android backup feature only provides a limited about of relevant data.

Android diagnostic logs such as bugreport files can be inconsistent in format and structure across different Android versions and device vendors. The limited diagnostic information available makes it difficult to triage potential compromises, and because of this mvt-android capabilities are limited as well.

However, not all is lost.

Check Android devices with AndroidQF and MVT

The AndroidQF tool can be used to collect a wide range of forensic artifacts from an Android device including an Android backup, a bugreport file, and a range of system logs. MVT natively supports analyzing the generated AndroidQF output for signs of device compromise.

Why Use AndroidQF?

  • Complete and raw data extraction
    AndroidQF collects full forensic artifacts using an on-device forensic collection agent, ensuring that no crucial data is overlooked. The data collection does not depended on the shell environment or utilities available on the device.

  • Consistent and standardized output
    By collecting a predefined and complete set of forensic files, AndroidQF ensures consistency in data acquisition across different Android devices.

  • Future-proof analysis
    Since the full forensic artifacts are preserved, analysts can extract new evidence or apply updated analysis techniques without requiring access to the original device.

  • Cross-platform tool without dependencies
    AndroidQF is a standalone Go binary which can be used to remotely collect data from an Android device without the device owner needing to install MVT or a Python environment.

Workflow for Android Forensic Analysis with AndroidQF

With AndroidQF the analysis process is split into a separate data collection and data analysis stages.

  1. Extract Data Using AndroidQF
    Deploy the AndroidQF forensic collector to acquire all relevant forensic artifacts from the Android device.

  2. Analyze Extracted Data with MVT
    Use the mvt-android check-androidqf command to perform forensic analysis on the extracted artifacts.

By separating artifact collection from forensic analysis, this approach ensures a more reliable and scalable methodology for Android forensic investigations.

For more information, refer to the AndroidQF project documentation.

VirusTotal package lookups

AndroidQF records APK file hashes in packages.json. MVT can optionally look up non-system APK hashes on VirusTotal while checking an AndroidQF acquisition:

bash
MVT_VT_API_KEY=<key> mvt-android check-androidqf --virustotal /path/to/androidqf-output

The --virustotal option is disabled by default because it sends APK hashes to VirusTotal and requires network access. It uses the VT_API_KEY MVT configuration value, which can also be provided through the MVT_VT_API_KEY environment variable.

To avoid exhausting free VirusTotal API quotas, MVT waits 16 seconds between package hash requests by default. Use --delay to change the delay, or --delay 0 to disable throttling:

bash
mvt-android check-androidqf --virustotal --delay 30 /path/to/androidqf-output

Android Intrusion Logs

On devices where the user has opted into Android's Advanced Protection Mode and turned on the optional Intrusion Logging featrue, Android can create and archive structured Intrusion Logs in an encrypted format. These logs record DNS queries, outbound network connections, process starts, ADB activity and other security-relevant events, and are a high-fidelity complement to the rest of an AndroidQF acquisition. The logs are generated on-device and encrypted before being stored in the Google account associated with the device. The encryption key is protected by the user device PIN. The intrusion log data is not accessible to Google.

AndroidQF will prompt the user to download, decrypt and collect device intrusion logs as part of an acquisition. When they are present, mvt-android check-androidqf will automatically run the intrusion-log checks alongside the other AndroidQF modules โ€” no extra command is required. This is the recommended workflow for Android forensic analysis with MVT.

For cases where intrusion logs were collected outside of an AndroidQF acquisition, the standalone mvt-android check-intrusion-logs command can analyse them directly. See Check Android Intrusion Logs for details, and the feature announcment from Amnesty International's Security Lab for background on the data source.

Android Debug Bridge analysis removed

The ability to analyze Android devices directly over ADB has been removed from MVT. Direct extraction of data from ADB was error-prone and frequently resulted in inconsistent data collection between ADB and AndroidQF acquisitions. Use AndroidQF for device acquisition and mvt-android check-androidqf for analysis.

Check an Android Backup (SMS messages)

Although Android backups are becoming deprecated, it is still possible to generate one. Unfortunately, because apps these days typically favor backup over the cloud, the amount of data available is limited.

The mvt-android check-androidqf command will automatically check an Android backup and SMS messages if an SMS backup is included in the AndroidQF extraction.

The mvt-android check-backup command can also be used directly with an Android backup file.


File: docs/ios/filesystem/check.md

Check a Filesystem Dump with `mvt-ios`

When you are ready, you can proceed running mvt-ios against the filesystemp dump or mount point:

text
$ mvt-ios check-fs --help
Usage: mvt-ios check-fs [OPTIONS] DUMP_PATH

  Extract artifacts from a full filesystem dump

Options:
  -i, --iocs PATH     Path to indicators file
  -o, --output PATH   Specify a path to a folder where you want to store JSON
                      results

  -f, --fast          Avoid running time/resource consuming features
  -l, --list-modules  Print list of available modules and exit
  -m, --module TEXT   Name of a single module you would like to run instead of
                      all

  --help              Show this message and exit.

Following is an example of basic usage of check-fs:

bash
mvt-ios check-fs /path/to/filesystem/dump/ --output /path/to/output/

This command will create a few JSON files containing the results from the extraction. If you do not specify a --output option, mvt-ios will just process the data without storing results on disk.

Through the --iocs argument you can specify a STIX2 file defining a list of malicious indicators to check against the records extracted from the backup by mvt. Any matches will be highlighted in the terminal output as well as saved in the output folder using a "_detected" suffix to the JSON file name.


File: docs/ios/filesystem/dump.md

Dumping the filesystem

While iTunes backup provide a lot of very useful databases and diagnostic data, in some cases you might want to jailbreak the device and perform a full filesystem dump. In that case, you should take a look at checkra1n, which provides an easy way to obtain root on most recent iPhone models.

!!! warning
Before you checkra1n any device, make sure you take a full backup, and that you are prepared to do a full factory reset before restoring it. Even after using checkra1n's "Restore System", some traces of the jailbreak are still left on the device and apps with anti-jailbreaks will be able to detect them and stop functioning.

After having jailbroken the device, you should be able to access the phone over ssh. In order to do this you will typically need to use iproxy, which on Debian/Ubuntu systems can be installed with libusbmuxd-tools. Run the command:

bash
iproxy 2222 44

Now you will be able to ssh as root to localhost on port 2222 and password alpine. Note: if you used a jailbreak other than checkra1n, you might need to specify a different port number instead of 44.

At this point you need to get access to the content of the device from your computer. One way is to run a command like ssh root@localhost -p 2222 tar czf - /private > dump.tar.gz which will save a tarball on the host of the /private/ folder from the phone. This will take a while.

Alternatively, you can try run sftp-server for iOS and mount the filesystem locally using sshfs.

Use `sshfs` on iOS

If you decide to try to use sshfs, you first have to download locally a compiled copy of sftp-server:

bash
wget https://github.com/dweinstein/openssh-ios/releases/download/v7.5/sftp-server

Then upload the binary to the iPhone:

bash
scp -P2222 sftp-server root@localhost:.

You will need to ssh into the device and set some entitlements in order to allow sftp-server to run. This entitlements can be copied from an existing binary:

bash
chmod +x sftp-server
ldid -e /binpack/bin/sh > /tmp/sh-ents
ldid -S /tmp/sh-ents sftp-server

Now you can create a folder on the host and use it as a mount point (note: do not create this folder in /tmp/):

bash
mkdir root_mount
sshfs -p 2222 -o sftp_server=/var/root/sftp-server root@localhost:/ root_mount

File: docs/ios/backup/check.md

Check a Backup with mvt-ios

The backup might take some time. It is best to make sure the phone remains unlocked during the backup process. Afterwards, a new folder will be created under the path you specified using the UDID of the iPhone you backed up.

Extracting and saving the decryption key (optional)

If you do not wish to enter a password every time when decrypting a backup, MVT can accept a key file instead. This key can be used with the decrypt-backup command.

To generate a key file, you will need your device backup and the backup password:

text
$ mvt-ios extract-key --help
Usage: mvt-ios extract-key [OPTIONS] BACKUP_PATH

  Extract decryption key from an iTunes backup

Options:
  -p, --password TEXT  Password to use to decrypt the backup  [required]
  -k, --key-file FILE  Key file to be written (if unset, will print to STDOUT)
  --help               Show this message and exit.

You can specify the password on the command line, or omit the -p option to have MVT prompt for a password. The -k option specifies where to save the file containing the decryption key. If -k is omitted, MVT will display the decryption key without saving.

Note: This decryption key is sensitive data! Keep the file safe.

To extract the key and have MVT prompt for a password:

bash
mvt-ios extract-key -k /path/to/save/key /path/to/backup

Decrypting a backup

In case you have an encrypted backup, you will need to decrypt it first. This can be done with mvt-ios as well:

text
$ mvt-ios decrypt-backup --help
Usage: mvt-ios decrypt-backup [OPTIONS] BACKUP_PATH

  Decrypt an encrypted iTunes backup

Options:
  -d, --destination TEXT  Path to the folder where to store the decrypted
                          backup  [required]

  -p, --password TEXT     Password to use to decrypt the backup (or, set
                          MVT_IOS_BACKUP_PASSWORD environment variable)
                          NOTE: This argument is mutually exclusive with
                          arguments: [key_file].

  -k, --key-file PATH     File containing raw encryption key to use to decrypt
                          the backup NOTE: This argument is mutually exclusive
                          with arguments: [password].

  --help                  Show this message and exit.

You can specify the password in the environment variable MVT_IOS_BACKUP_PASSWORD, or via command-line argument, or you can pass a key file. You need to specify a destination path where the decrypted backup will be stored. If a password cannot be found and no key file is specified, MVT will ask for a password. Following is an example usage of decrypt-backup sending the password via an environment variable:

bash
MVT_IOS_BACKUP_PASSWORD="mypassword" mvt-ios decrypt-backup -d /path/to/decrypted /path/to/backup

Run `mvt-ios` on a Backup

Once you have a decrypted backup available for analysis you can use the check-backup subcommand:

text
$ mvt-ios check-backup --help
Usage: mvt-ios check-backup [OPTIONS] BACKUP_PATH

  Extract artifacts from an iTunes backup

Options:
  -i, --iocs PATH     Path to indicators file
  -o, --output PATH   Specify a path to a folder where you want to store JSON
                      results

  -f, --fast          Avoid running time/resource consuming features
  -l, --list-modules  Print list of available modules and exit
  -m, --module TEXT   Name of a single module you would like to run instead of
                      all

  --help              Show this message and exit.

Following is a basic usage of check-backup:

bash
mvt-ios check-backup --output /path/to/output/ /path/to/backup/udid/

This command will create a few JSON files containing the results from the extraction. If you do not specify a --output option, mvt-ios will just process the data without storing results on disk.

Through the --iocs argument you can specify a STIX2 file defining a list of malicious indicators to check against the records extracted from the backup by mvt. Any matches will be highlighted in the terminal output as well as saved in the output folder using a "_detected" suffix to the JSON file name.


File: docs/ios/backup/itunes.md

Backup with iTunes app

It is possible to do an iPhone backup by using iTunes on Windows or macOS computers (in most recent versions of macOS, this feature is included in Finder, see below).

To do that:

  1. Make sure iTunes is installed.
  2. Connect your iPhone to your computer using a Lightning/USB cable.
  3. Open the device in iTunes (or Finder on macOS).
  4. If you want to have a more accurate detection, ensure that the encrypted backup option is activated and choose a secure password for the backup.
  5. Start the backup and wait for it to finish (this may take up to 30 minutes).

Source: Apple Support

Once the backup is done, find its location and copy it to a place where it can be analyzed by MVT. On Windows, the backup can be stored either in %USERPROFILE%\Apple\MobileSync\ or %USERPROFILE%\AppData\Roaming\Apple Computer\MobileSync\. On macOS, the backup is stored in ~/Library/Application Support/MobileSync/.

Backup with Finder

On more recent MacOS versions, this feature is included in Finder. To do a backup:

  1. Launch Finder on your Mac.
  2. Connect your iPhone to your Mac using a Lightning/USB cable.
  3. Select your device from the list of devices located at the bottom of the left side bar labeled "locations".
  4. In the General tab, select Back up all the data on your iPhone to this Mac from the options under the Backups section.
  5. Check the box that says Encrypt local backup. If it is your first time selecting this option, you may need to enter a password to encrypt the backup.

Source: Apple Support

  1. Click Back Up Now to start the back-up process.
  2. The encrypted backup for your iPhone should now start. Once the process finishes, you can check the backup by opening Finder, clicking on the General tab, then click on Manage Backups. Now you should see a list of your backups like the image below:

Source: Apple Support

If your backup has a lock next to it like in the image above, then the backup is encrypted. You should also see the date and time when the encrypted backup was created. The backup files are stored in ~/Library/Application Support/MobileSync/.

Notes:

  • Remember to keep the backup encryption password that you created safe, since without it you will not be able to access/modify/decrypt the backup file.

File: docs/ios/backup/libimobiledevice.md

Backup with libimobiledevice

If you have correctly installed libimobiledevice you can easily generate an iTunes backup using the idevicebackup2 tool included in the suite. First, you might want to ensure that backup encryption is enabled (note: encrypted backup contain more data than unencrypted backups):

bash
idevicebackup2 -i encryption on

Note that if a backup password was previously set on this device, you might need to use the same or change it. You can try changing password using idevicebackup2 -i changepw, or by turning off encryption (idevicebackup2 -i encryption off) and turning it back on again.

If you are not able to recover or change the password, you should try to disable encryption and obtain an unencrypted backup.

If all else fails, as a last resort you can try resetting the password by resetting all the settings through the iPhone's Settings app, via Settings ยป General ยป Reset ยป Reset All Settings. Note that resetting the settings through the iPhone's Settings app will wipe some of the files that contain useful forensic traces, so try the options explained above first.

Once ready, you can proceed performing the backup:

bash
idevicebackup2 backup --full /path/to/backup/