1
mirror of https://github.com/mvt-project/mvt synced 2025-10-21 22:42:15 +02:00

Compare commits

..

144 Commits

Author SHA1 Message Date
Nex
012a6ead77 Bumped version 2021-08-18 13:26:50 +02:00
Nex
803dd2ff3a Add note in documentation about ability to invoke multiple --iocs options 2021-08-18 13:25:52 +02:00
Nex
817aaab258 Indicate in help message that option can be invoked multiple times 2021-08-18 13:24:10 +02:00
Nex
4d8d91846c Added missing import of IndicatorsFileBadFormat 2021-08-18 13:21:54 +02:00
Nex
e31e08e710 Added multiple indicators to Android cli 2021-08-18 13:19:34 +02:00
Nex
27847bf16c Added counter for loaded indicators 2021-08-18 13:18:34 +02:00
Nex
f2b1311ff7 Sorted imports 2021-08-18 13:18:28 +02:00
Nex
48810af83d Fixed creation of Indicators instance 2021-08-18 13:12:37 +02:00
Nex
6a63256b5c Added ability to import multiple STIX2 indicators files 2021-08-18 13:08:32 +02:00
Nex
07cf14a921 Updated docs 2021-08-18 10:34:31 +02:00
Nex
d77809060f Added newline 2021-08-17 22:54:33 +02:00
Nex
d61d40ee5a Updated documentation on mvt-android 2021-08-17 16:36:48 +02:00
Nex
99d539b040 Renamed packages.json to apks.json to avoid conflicts with other module 2021-08-17 13:26:26 +02:00
Nex
7edf147112 Better handling of package parsing and more logging (closes: #102) 2021-08-17 13:26:04 +02:00
Nex
39b81214c2 Catching exception when unable to connect to device over TCP 2021-08-17 13:10:36 +02:00
Nex
94fd6b5208 Catching errors more gracefully when downloading apks (closes: #158) 2021-08-17 13:06:31 +02:00
Nex
71e270fdf8 Bumped version 2021-08-16 14:56:46 +02:00
Nex
8125f1ba14 Updated docs with new modules 2021-08-16 11:12:57 +02:00
Nex
96e4a9a4a4 Overhaul of mvt-ios modules 2021-08-16 10:50:35 +02:00
Nex
24d7187303 Fixed variable name 2021-08-15 20:02:17 +02:00
Nex
6af6c52f60 Renamed function for consistency 2021-08-15 20:01:33 +02:00
Nex
fdaf2fc760 Fixed WebkitSessionResourceLog module, still needs testing 2021-08-15 20:00:29 +02:00
Nex
fda621672d Renamed webkit helper function 2021-08-15 19:50:55 +02:00
Nex
ce6cc771b4 Replaced leftover dicts 2021-08-15 19:20:41 +02:00
Nex
e1e4476bee Standardizing Manifest results structure 2021-08-15 19:07:45 +02:00
Nex
9582778adf Getting rid of dict() 2021-08-15 19:05:15 +02:00
Nex
5e6e4fa8d0 Added modules to extract details on configuration profiles from backup 2021-08-15 18:53:02 +02:00
Nex
9e5a412fe2 Creating helper function to locate files in Manifest.db 2021-08-15 17:39:14 +02:00
Nex
763cb6e06c DeviceInfo module is now BackupInfo and only running on backups 2021-08-15 13:16:00 +02:00
Nex
cbdbf41e1e Restructured modules folders 2021-08-15 13:14:18 +02:00
Nex
cf630f7c2b Fixed unused imports 2021-08-14 18:56:33 +02:00
Nex
3d6e01179a Fixed typo 2021-08-14 18:52:00 +02:00
Nex
8260bda308 Got rid of biplist, using standard plistlib 2021-08-14 18:50:11 +02:00
Nex
30e00e0707 Added module to extract information on device 2021-08-14 18:39:46 +02:00
Nex
88e2576334 Copying plist files too when decrypting a backup 2021-08-14 18:25:41 +02:00
Nex
076930c2c9 Added newline 2021-08-14 18:06:30 +02:00
Nex
8a91e64bb9 Catching gracefully if indicators file parse fails 2021-08-12 20:17:37 +02:00
Nex
bdbfe02315 Bumped version 2021-08-12 18:44:14 +02:00
Nex
54eaf046b0 Standardizing base classes declarations 2021-08-12 18:36:31 +02:00
Nex
23e4babbc9 Sorted imports 2021-08-12 18:34:33 +02:00
Nex
78b9fcd50c Added super init to NetBase 2021-08-12 18:34:23 +02:00
Nex
4eb7a64614 Removed serial in declaration 2021-08-12 18:33:58 +02:00
Nex
e512e0b72f Fixed download_apks init 2021-08-12 18:25:57 +02:00
Nex
7884c28253 Merge branch 'j0k2r-main' 2021-08-12 18:21:36 +02:00
Nex
8ca7030195 Refactored serial specification for ADB 2021-08-12 18:21:21 +02:00
Nex
f78c671885 Merge branch 'main' of https://github.com/j0k2r/mvt into j0k2r-main 2021-08-12 18:07:50 +02:00
Nex
411ac53522 Letting module handler catch any exception 2021-08-12 17:57:40 +02:00
Nex
8be60e8a04 Checking all processes 2021-08-12 17:53:19 +02:00
Nex
8a484b3b24 Added a more clear message regarding rooted Androids 2021-08-12 17:47:20 +02:00
Nex
0a7512cfb2 Checking for manipulated entries even when no indicators are provided 2021-08-12 12:57:27 +02:00
Nex
257f3732e3 Merge branch 'DL6ER-main' 2021-08-12 12:56:17 +02:00
Nex
8d93ab66c9 Improved logging around detection results 2021-08-12 12:56:12 +02:00
Nex
6e19d34700 Merge branch 'main' of https://github.com/DL6ER/mvt into DL6ER-main 2021-08-12 12:49:36 +02:00
Nex
271cdede0f Merge branch 'dkg-error-cleanup' 2021-08-12 12:48:47 +02:00
Nex
88324c7c42 Standardized to logging format 2021-08-12 12:48:29 +02:00
Daniel Kahn Gillmor
ec93c3d8b8 Even friendlier behaviors when the user mis-specifies the backup path
As discussed in #147
2021-08-10 23:19:45 -04:00
Daniel Kahn Gillmor
1288f8ca53 handle error cases better 2021-08-10 22:57:15 -04:00
DL6ER
290776a286 Log if there was no detection made by the module
Signed-off-by: DL6ER <dl6er@dl6er.de>
2021-08-10 12:13:23 +02:00
Nex
44b677fdb2 Updated README 2021-08-09 16:14:48 +02:00
Nex
3ae822d3ac Updated README 2021-08-09 16:14:08 +02:00
Nex
7940fb2879 Updated README 2021-08-09 16:12:23 +02:00
Nex
af7bc3ca31 Updated README 2021-08-09 16:12:10 +02:00
Nex
d606f9570f Updated README 2021-08-09 16:10:42 +02:00
Hamza Z
15c0d71933 Fix merge conflicts 2021-08-08 20:05:50 +02:00
Nex
24c89183a3 Bumped version 2021-08-06 18:44:16 +02:00
Nex
e5f7727c80 Fixed typo (closes: #157) 2021-08-06 18:40:09 +02:00
Nex
7b00f03f03 Bumped version 2021-08-05 09:04:22 +02:00
Nex
9f696dcb72 Added version 14.7.1 2021-08-05 09:03:02 +02:00
Nex
ef139effdb Merge branch 'dkg-clearer-error-reporting' 2021-08-05 08:56:52 +02:00
Nex
2302c9fb1c Fixed language 2021-08-05 08:56:41 +02:00
Nex
9bb8ae5187 Merge branch 'clearer-error-reporting' of https://github.com/dkg/mvt into dkg-clearer-error-reporting 2021-08-05 08:54:29 +02:00
Nex
76e6138d77 Catching check if root exception more grafully (closes: #5) 2021-08-05 08:49:34 +02:00
Nex
0bc660a2b3 Updated documentation (closes: #3) 2021-08-04 19:14:06 +02:00
Nex
7ae9ecbf5a Removed newline 2021-08-03 17:25:16 +02:00
Nex
1e8278aeec Updated README 2021-08-03 15:51:58 +02:00
Nex
995ebc02cf Fixing language 2021-08-03 10:28:28 +02:00
Nex
12e0f14400 Added note on running MVT on Windows 2021-08-03 10:24:38 +02:00
Nex
6ef5b9d311 Merge pull request #148 from dkg/quotes
mvt-ios sqlite3 db recovery: fix quoting sent to sqlite3 .clone
2021-08-03 09:31:43 +02:00
Daniel Kahn Gillmor
33e90c1707 mvt-ios sqlite3 db recovery: fix quoting sent to sqlite3 .clone
In b2afce5c79, the db filename is
wrapped in double-quotes when passing it to the sqlite3 tool's
`.clone` helper command.

For parsing safety, we avoid performing this cleanup if the filename
itself has a double-quote character in it.  Otherwise, a malformed
filename could lead to arbitrary injection into the sqlite3 command.

In be24680046, the sqlite3 wrapping
changes to single-quotes.  Either the safety check should be amended
to block pathnames with single-quotes, or the sqlite3 wrapping should
revert to double-quotes.

I opted for the latter here because i think single-quotes are more
likely than double-quotes to show up in pathnames (e.g. a folder named
"Daniel's files"), but either change would be fine, of course.
2021-08-02 11:26:00 -04:00
Daniel Kahn Gillmor
706c429595 mvt-ios decrypt-backup: Improve error messages for known cases
The two most common reasons that `mvt-ios decrypt-backup` can fail are
wrong passwords and not pointing to an actual backup.

We can distinguish these cases based on the kinds of errors thrown
from iOSbackup (at least for the current versions that i'm testing
with).

When we encounter those particular exceptions, just report a simple
summary and don't overwhelm the user with a backtrace.  If we
encounter an unexpected exception, leave the reporting as-is.

Closes: #28, #36
2021-08-02 11:07:31 -04:00
Nex
f011fd19e8 More explicit copyright and licensing notes 2021-08-01 21:11:08 +02:00
Nex
bc48dc2cf5 Fixed import order 2021-08-01 19:53:20 +02:00
Nex
f3c0948283 Fixing exception name in Manifest module 2021-08-01 19:50:25 +02:00
Nex
be24680046 Enforcing double quotes 2021-08-01 19:50:04 +02:00
Nex
a3d10c1824 Merge pull request #140 from dkg/avoid-shell-True
Avoid breakage with paths with unusual names
2021-08-01 19:45:11 +02:00
Daniel Kahn Gillmor
b2afce5c79 Avoid breakage with paths with unusual names
If file_path has any whitespace or shell metacharacters in it, then
the invocation of subprocess.call would be likely to break (or even
accidentally execute code, depending on how perverse the pathnames
are).

It's generally a good plan to avoid shell=True for subprocess.call
where you can lay out the arguments deliberately in python.  This one
looks relatively straightforward (but note, i have not tested it,
sorry!)

Note that if a name has a `"` character in it, we still fail, out of
safety reasons.

in particular, we want to avoid command injection into the sqlite
binary with particularly malicious names that look something like the
following:

```
foo.db"; .shell touch should-not-exist; .nullvalue "
```
2021-08-01 11:35:38 -04:00
Nex
b2e210e91c Removed unused import 2021-08-01 14:16:28 +02:00
Nex
6f83bf5ae1 Removed duplicates 2021-08-01 14:05:21 +02:00
Nex
a979b82ec6 Bumped version 2021-08-01 13:59:59 +02:00
Nex
eaef75d931 Added iPhone models definitions 2021-08-01 13:59:30 +02:00
Nex
1650aea248 pip3 for clarity 2021-07-31 19:48:19 +02:00
Nex
bc3634bf30 Specifying it is a password prompt 2021-07-31 10:27:44 +02:00
Nex
87ffd9e003 Bumped version 2021-07-31 10:23:38 +02:00
Nex
19f355810a Merge branch 'dkg-update-libimobiledevice-docs' 2021-07-31 10:19:46 +02:00
Nex
38b7aa6032 Updated doc on backup 2021-07-31 10:19:38 +02:00
Nex
feb285015a Merge branch 'update-libimobiledevice-docs' of https://github.com/dkg/mvt into dkg-update-libimobiledevice-docs 2021-07-31 10:16:58 +02:00
Nex
933ee65897 Merge branch 'dkg-mvt_decrypt-backup_password_from_env' 2021-07-31 10:13:43 +02:00
Nex
ad9ab1aeba Switched to using rich Prompt 2021-07-31 10:13:18 +02:00
Nex
4debee72cd Merge branch 'mvt_decrypt-backup_password_from_env' of https://github.com/dkg/mvt into dkg-mvt_decrypt-backup_password_from_env 2021-07-31 10:07:14 +02:00
Nex
d7031bd25f Merge branch 'dkg-ioc-docs' 2021-07-31 10:05:55 +02:00
Nex
5b5b065bc4 Updated doc page on IOCs 2021-07-31 10:05:41 +02:00
Daniel Kahn Gillmor
59206fc450 Describe how to use and find IOCs
This offers generic documentation, to show how MVT can be used with
arbitrary STIX-formatted IOCs, while still pointing users at some
known-to-be-useful sample files.
2021-07-31 00:46:36 -04:00
Daniel Kahn Gillmor
7b1b31f7be Update libimobiledevice docs about backup password reset
In this stage, the user is likely to want to run `idevicebackup2` in
interactive mode, so clearly specify the `-i` flag in the right place
(just dropping `-i` at the end of the command does not work as
expected -- i think `idevicebackup2 backup encryption on -i` tries to
set the password to `-i`).

More importantly, note that resetting the password by resetting all
the settings runs a risk of removing some of the forensic information.
Etienne identified a file that he thought was wiped as a result of
this in the call this morning, but I don't remember which file it was.

Maybe `id_status_cache.json` ?  If you have more concrete info, please
add it here too!
2021-07-30 23:49:06 -04:00
Daniel Kahn Gillmor
270e002f1b mvt-ios extract-key: enable pulling password from the environment
This enables automated use of extract-key without requiring a password
to be placed in the command line, where it might leak.
2021-07-30 23:10:54 -04:00
Daniel Kahn Gillmor
53adc05338 mvt-ios decrypt-backup: Enable pulling password from the environment.
Specifying the password on the command line with `--password XXX`
leaves the password itself visible to any process on the machine which
can scan the process table.

On some systems (including common GNU/Linux distributions) this
visibility is possible by default.

This change should make it possible to offer the password without
putting it into the process table; rather, the user puts the password
in the environment, and specifies the name of the environment
variable, like so:

```
$ export MVT_IOS_BACKUP_PASSWORD=WronglySconeRoundnessUnruffled
$ mvt-ios decrypt-backup -d /path/to/dest /path/to/data/XXXXXXXX-YYYYYYYYYYYYYYY/
$ unset MVT_IOS_BACKUP_PASSWORD
```

or you can do so using a prefixed env var, as described in the updated
check.md documentation.
2021-07-30 23:10:54 -04:00
Nex
d7f29a4e88 Updated README 2021-07-30 21:26:48 +02:00
Nex
444e70a6eb Merge branch 'pkirkovsky-extract-key' 2021-07-30 18:47:05 +02:00
Nex
b264ae946d Refactored to include functionality in existing DecryptBackup class 2021-07-30 18:46:45 +02:00
Nex
bfcfb3aa06 Merge branch 'extract-key' of https://github.com/pkirkovsky/mvt into pkirkovsky-extract-key 2021-07-30 18:29:47 +02:00
Nex
3e7d85039a Merge branch 'EmilienCourt-fix_SMS_PATH' 2021-07-30 18:09:13 +02:00
Nex
632409c81d Using consistent constant names 2021-07-30 18:08:52 +02:00
Nex
6df6064370 Merge branch 'fix_SMS_PATH' of https://github.com/EmilienCourt/mvt into EmilienCourt-fix_SMS_PATH 2021-07-30 18:04:16 +02:00
Nex
99e80fd942 Updated documentation links 2021-07-30 17:59:17 +02:00
Nex
9451da4514 Removed duplicate title 2021-07-30 17:56:05 +02:00
Tek
5ac0025470 Merge pull request #137 from opsec-infosec/main
Update Dockerfile missing sqlite3
2021-07-30 14:34:07 +02:00
opsec-infosec
9a6c4d251e Update Dockerfile
Add sqlite3 to Dockerfile for extraction of SMS messages
2021-07-30 16:13:06 +04:00
Nex
eda1976518 Added missing space in workflow file 2021-07-30 11:43:52 +02:00
Nex
c966eea7e6 Sorted imports 2021-07-30 11:40:09 +02:00
Nex
abcbefe359 Added safety checks to workflow 2021-07-30 11:39:43 +02:00
Nex
22d090569c Disabled pytest until unit tests are available 2021-07-30 11:20:59 +02:00
Nex
d490344142 Removed lint 2021-07-30 11:19:51 +02:00
Nex
7f361fb600 Create python-package.yml 2021-07-30 11:19:20 +02:00
Nex
18ed58cbf9 Removed unused dependency 2021-07-30 11:19:15 +02:00
Nex
3a6f57502e Merge branch 'febrezo-master' 2021-07-30 11:08:47 +02:00
Nex
490fb12302 Refactored creation of output folders 2021-07-30 11:08:32 +02:00
Nex
e2d82b0349 Merge branch 'master' of https://github.com/febrezo/mvt into febrezo-master 2021-07-30 10:48:34 +02:00
Nex
1bf7f54c72 Merge pull request #131 from macmade/main
Chrome History - Cheking extracted URLs against indicators.
2021-07-29 13:48:34 +02:00
Nex
60a2dbb860 Added module to parse WebKit ResourceLoadStatistics observations.db (ref: #133) 2021-07-29 13:46:58 +02:00
macmade
5e03c28dbd Chrome History - Cheking extracted URLs against indicators. 2021-07-29 02:33:32 +02:00
Nex
4fb6e204d1 Ordered iOS versions 2021-07-28 08:33:33 +02:00
Pavel Kirkovsky
f4340bd4f9 Merge branch 'mvt-project:main' into extract-key 2021-07-27 17:15:37 -07:00
Nex
7947d413b5 Update lint-python.yml 2021-07-27 21:44:31 +02:00
Nex
45beb6eeda Update lint-python.yml 2021-07-27 21:43:25 +02:00
Nex
ad81d5c450 Delete python-publish.yml 2021-07-27 21:42:21 +02:00
emilien
47df94fa12 fix typo 2021-07-25 15:13:23 +02:00
emilien
e5003b6490 Handle SMS bases in mmssms.db instead of bugle_db 2021-07-25 15:06:22 +02:00
Pavel Kirkovsky
99640ac08c Merge branch 'mvt-project:main' into extract-key 2021-07-23 12:02:02 -07:00
Pavel Kirkovsky
30d0348256 Added extract-key info to main docs 2021-07-23 03:46:48 -07:00
Pavel Kirkovsky
af4826070a Update README with extract-key command 2021-07-22 23:55:08 -07:00
Pavel Kirkovsky
9fbcce4340 Add extract-key command 2021-07-22 23:52:52 -07:00
Pavel Kirkovsky
ece88744ed KeyUtils class for working with decryption keys 2021-07-22 23:52:39 -07:00
Hamza Z
2389d5e52d Add Android TCP connection support 2021-07-21 13:35:46 +02:00
Hamza Z
ccf0f3f18e Add Android device serial specification 2021-07-21 13:17:58 +02:00
febrezo
732db070f2 Add implicit creation of output folders 2021-07-20 03:09:53 +02:00
89 changed files with 2043 additions and 1245 deletions

View File

@@ -1,21 +0,0 @@
name: lint_python
on: [pull_request, push]
jobs:
lint_python:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v2
- run: pip install bandit black codespell flake8 isort mypy pytest pyupgrade safety
- run: bandit --recursive --skip B108,B112,B404,B602 .
- run: black --check . || true
- run: codespell
- run: flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
- run: flake8 . --count --exit-zero --max-complexity=10 --max-line-length=88 --show-source --statistics
- run: isort --check-only --profile black . || true
- run: pip install -r requirements.txt || true
- run: mypy --install-types --non-interactive . || true
- run: pytest . || true
- run: pytest --doctest-modules . || true
- run: shopt -s globstar && pyupgrade --py36-plus **/*.py || true
- run: safety check

43
.github/workflows/python-package.yml vendored Normal file
View File

@@ -0,0 +1,43 @@
# This workflow will install Python dependencies, run tests and lint with a variety of Python versions
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions
name: Python package
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
build:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python-version: [3.7, 3.8, 3.9]
steps:
- uses: actions/checkout@v2
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip
python -m pip install flake8 pytest safety
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
- name: Lint with flake8
run: |
# stop the build if there are Python syntax errors or undefined names
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
- name: Safety checks
run: safety check
# - name: Test with pytest
# run: |
# pytest

View File

@@ -1,36 +0,0 @@
# This workflow will upload a Python Package using Twine when a release is created
# For more information see: https://help.github.com/en/actions/language-and-framework-guides/using-python-with-github-actions#publishing-to-package-registries
# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.
name: Upload Python Package
on:
release:
types: [published]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: '3.x'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install build
- name: Build package
run: python -m build
- name: Publish package
uses: pypa/gh-action-pypi-publish@27b31702a0e7fc50959f5ad993c78deac1bdfc29
with:
user: __token__
password: ${{ secrets.PYPI_API_TOKEN }}

2
.gitignore vendored
View File

@@ -129,3 +129,5 @@ dmypy.json
.pyre/
*.pyc
# Temporal files
*~

7
AUTHORS Normal file
View File

@@ -0,0 +1,7 @@
MVT was originally authored by Claudio Guarnieri <nex@nex.sx>.
For an up-to-date list of all contributors visit:
https://github.com/mvt-project/mvt/graphs/contributors
Or run:
git shortlog -s -n

View File

@@ -21,6 +21,7 @@ RUN apt install -y build-essential \
libplist-dev \
libusbmuxd-dev \
libssl-dev \
sqlite3 \
pkg-config
# Clean up

View File

@@ -5,7 +5,7 @@
# Mobile Verification Toolkit
[![](https://img.shields.io/pypi/v/mvt)](https://pypi.org/project/mvt/)
[![](https://img.shields.io/badge/docs-blue.svg)](https://mvt.readthedocs.io)
[![Documentation Status](https://readthedocs.org/projects/mvt/badge/?version=latest)](https://docs.mvt.re/en/latest/?badge=latest)
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.
@@ -15,37 +15,20 @@ It has been developed and released by the [Amnesty International Security Lab](h
## Installation
MVT can be installed from sources or conveniently using:
MVT can be installed from sources or from [PyPi](https://pypi.org/project/mvt/) (you will need some dependencies, check the [documentation](https://docs.mvt.re/en/latest/install.html)):
```
pip3 install mvt
```
You will need some dependencies, so please check the [documentation](https://mvt.readthedocs.io/en/latest/install.html).
Alternatively, you can decide to run MVT and all relevant tools through a [Docker container](https://mvt.readthedocs.io/en/latest/docker.html).
Alternatively, you can decide to run MVT and all relevant tools through a [Docker container](https://docs.mvt.re/en/latest/docker.html).
**Please note:** MVT is best run on Linux or Mac systems. [It does not currently support running natively on Windows.](https://docs.mvt.re/en/latest/install.html#mvt-on-windows)
## Usage
MVT provides two commands `mvt-ios` and `mvt-android` with the following subcommands available:
* `mvt-ios`:
* `check-backup`: Extract artifacts from an iTunes backup
* `check-fs`: Extract artifacts from a full filesystem dump
* `check-iocs`: Compare stored JSON results to provided indicators
* `decrypt-backup`: Decrypt an encrypted iTunes backup
* `mvt-android`:
* `check-backup`: Check an Android Backup
* `download-apks`: Download all or non-safelisted installed APKs
Check out [the documentation to see how to use them](https://mvt.readthedocs.io/en/latest/).
MVT provides two commands `mvt-ios` and `mvt-android`. [Check out the documentation to learn how to use them!](https://docs.mvt.re/).
## 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. Therefore, the goal of this license is to prohibit the use of MVT (and any other software licensed the same) for the purpose of *adversarial forensics*.
In order to achieve this, MVT is released under an adaptation of [Mozilla Public License v2.0](https://www.mozilla.org/MPL). This modified license includes a new clause 3.0, "Consensual Use Restriction" which permits the use of the licensed software (and any *"Larger Work"* derived from it) exclusively with the explicit consent of the person/s whose data is being extracted and/or analysed (*"Data Owner"*).
[Read the LICENSE](https://github.com/mvt-project/mvt/blob/main/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.](https://docs.mvt.re/en/latest/license.html)

View File

@@ -1,8 +1,8 @@
#!/usr/bin/env python3
# Mobile Verification Toolkit (MVT)
# Copyright (c) 2021 MVT Project Developers.
# See the file 'LICENSE' for usage and copying permissions, or find a copy at
# https://github.com/mvt-project/mvt/blob/main/LICENSE
# Copyright (c) 2021 The MVT Project Authors.
# Use of this software is governed by the MVT License 1.1 that can be found at
# https://license.mvt.re/1.1/
import os
import sys
@@ -10,4 +10,5 @@ import sys
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from mvt import android
android.cli()

View File

@@ -1,8 +1,8 @@
#!/usr/bin/env python3
# Mobile Verification Toolkit (MVT)
# Copyright (c) 2021 MVT Project Developers.
# See the file 'LICENSE' for usage and copying permissions, or find a copy at
# https://github.com/mvt-project/mvt/blob/main/LICENSE
# Copyright (c) 2021 The MVT Project Authors.
# Use of this software is governed by the MVT License 1.1 that can be found at
# https://license.mvt.re/1.1/
import os
import sys
@@ -10,4 +10,5 @@ import sys
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from mvt import ios
ios.cli()

8
docs/android/adb.md Normal file
View File

@@ -0,0 +1,8 @@
# Check over ADB
TODO
<!-- In order to use `mvt-android` you need to connect your Android device to your computer. You will then need to [enable USB debugging](https://developer.android.com/studio/debug/dev-options#enable>) on the Android device.
If this is the first time you connect to this device, you will need to approve the authentication keys through a prompt that will appear on your Android device.
-->

View File

@@ -1,36 +1,45 @@
# Checking SMSs from Android backup
# Check an Android Backup (SMS messages)
Some attacks against Android phones are done by sending malicious links by SMS. The Android backup feature does not allow to gather much information that can be interesting for a forensic analysis, but it can be used to extract SMSs and check them with MVT.
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.
To do so, you need to connect your Android device to your computer. You will then need to [enable USB debugging](https://developer.android.com/studio/debug/dev-options#enable>) on the Android device.
At the time of writing, the Android Debug Bridge (adb) command to generate backups is still available but marked as deprecated.
If this is the first time you connect to this device, you will need to approve the authentication keys through a prompt that will appear on your Android device.
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.
Then you can use adb to extract the backup for SMS only with the following command:
## Generate a backup
Because `mvt-android check-backup` currently only supports checking SMS messages, you can indicate to backup only those:
```bash
adb backup com.android.providers.telephony
```
You will need to approve the backup on the phone and potentially enter a password to encrypt the backup. The backup will then be stored in a file named `backup.ab`.
In case you nonetheless wish to take a full backup, you can do so with
You will need to use [Android Backup Extractor](https://github.com/nelenkov/android-backup-extractor) 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 ~/Download/abe.jar unpack backup.ab backup.tar
adb backup -all
```
## Unpack the backup
In order to reliable unpack th [Android Backup Extractor (ABE)](https://github.com/nelenkov/android-backup-extractor) 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, the password will be asked by Android Backup Extractor).
If the backup is encrypted, ABE will prompt you to enter the password.
## Check the backup
You can then extract SMSs containing links with MVT:
```bash
$ mvt-android check-backup --output . .
$ mvt-android check-backup --output /path/to/results/ /path/to/backup/
16:18:38 INFO [mvt.android.cli] Checking ADB backup located at: .
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/000
000_sms_backup
INFO [mvt.android.modules.backup.sms] Processing SMS backup file at /path/to/backup/apps/com.android.providers.telephony/d_f/000000_sms_backup
16:18:39 INFO [mvt.android.modules.backup.sms] Extracted a total of
64 SMS messages containing links
```

View File

@@ -1,15 +1,18 @@
# Downloading APKs from an Android phone
In order to use `mvt-android` you need to connect your Android device to your computer. You will then need to [enable USB debugging](https://developer.android.com/studio/debug/dev-options#enable>) on the Android device.
MVT allows to attempt to download all available installed packages (APKs) in order to further inspect them and potentially identify any which might be malicious in nature.
If this is the first time you connect to this device, you will need to approve the authentication keys through a prompt that will appear on your Android device.
Now you can launch `mvt-android` and specify the `download-apks` command and the path to the folder where you want to store the extracted data:
You can do so by launching the following command:
```bash
mvt-android download-apks --output /path/to/folder
```
It might take several minutes to complete.
!!! info
MVT will likely warn you it was unable to download certain installed packages. There is no reason to be alarmed: this is typically expected behavior when MVT attempts to download a system package it has no privileges to access.
Optionally, you can decide to enable lookups of the SHA256 hash of all the extracted APKs on [VirusTotal](https://www.virustotal.com) and/or [Koodous](https://koodous.com). While these lookups do not provide any conclusive assessment on all of the extracted APKs, they might highlight any known malicious ones:
```bash
@@ -22,3 +25,10 @@ Or, to launch all available lookups::
```bash
mvt-android download-apks --output /path/to/folder --all-checks
```
In case you have a previous extraction of APKs you want to later check against VirusTotal and Koodous, you can do so with the following arguments:
```bash
mvt-android download-apks --from-file /path/to/folder/apks.json --all-checks
```

View File

@@ -1,8 +1,20 @@
# Methodology for Android forensic
For different technical reasons, it is more complex to do a forensic analysis of an Android phone.
Unfortunately Android devices provide much less observability than their iOS cousins. Android stores very little diagnostic information useful to triage potential compromises, and because of this `mvt-android` capabilities are limited as well.
Currently MVT allows to perform two different checks on an Android phone:
However, not all is lost.
* Download APKs installed in order to analyze them
* Extract Android backup in order to look for suspicious SMS
## Check installed Apps
Because malware attacks over Android typically take the form of malicious or backdoored apps, the very first thing you might want to do is to extract and verify all installed Android packages and triage quickly if there are any which stand out as malicious or which might be atypical.
While it is out of the scope of this documentation to dwell into details on how to analyze Android apps, MVT does allow to easily and automatically extract information about installed apps, download copies of them, and quickly lookup services such as [VirusTotal](https://www.virustotal.com) or [Koodous](https://www.koodous.com) which might quickly indicate known bad apps.
## Check the device over Android Debug Bridge
TODO
## Check an Android Backup (SMS messages)
TODO

View File

@@ -1,5 +1,3 @@
## Using Docker
Using Docker simplifies having all the required dependencies and tools (including most recent versions of [libimobiledevice](https://libimobiledevice.org)) readily installed.
Install Docker following the [official documentation](https://docs.docker.com/get-docker/).

View File

@@ -12,6 +12,8 @@ sudo apt install python3 python3-pip libusb-1.0-0 sqlite3
*libusb-1.0-0* is not required if you intend to only use `mvt-ios` and not `mvt-android`.
When working with Android devices you should additionally install [Android SDK Platform Tools](https://developer.android.com/studio/releases/platform-tools). If you prefer to install a package made available by your distribution of choice, please make sure the version is recent to ensure compatibility with modern Android devices.
## Dependencies on Mac
Running MVT on Mac requires Xcode and [homebrew](https://brew.sh) to be installed.
@@ -24,6 +26,20 @@ brew install python3 libusb sqlite3
*libusb* is not required if you intend to only use `mvt-ios` and not `mvt-android`.
When working with Android devices you should additionally install Android SDK Platform Tools:
```bash
brew install --cask android-platform-tools
```
Or by downloading the [official binary releases](https://developer.android.com/studio/releases/platform-tools).
## MVT on Windows
MVT does not currently officially support running natively on Windows. While most functionality should work out of the box, there are known issues especially with `mvt-android`.
It is recommended to try installing and running MVT from [Windows Subsystem Linux (WSL)](https://docs.microsoft.com/en-us/windows/wsl/about) and follow Linux installation instructions for your distribution of choice.
## Installing MVT
If you haven't done so, you can add this to your `.bashrc` or `.zshrc` file in order to add locally installed Pypi binaries to your `$PATH`:
@@ -35,7 +51,7 @@ export PATH=$PATH:~/.local/bin
Then you can install MVT directly from [pypi](https://pypi.org/project/mvt/)
```bash
pip install mvt
pip3 install mvt
```
Or from the source code:

36
docs/iocs.md Normal file
View File

@@ -0,0 +1,36 @@
# Indicators of Compromise (IOCs)
MVT uses [Structured Threat Information Expression (STIX)](https://oasis-open.github.io/cti-documentation/stix/intro.html) files to identify potential traces of compromise.
These indicators of compromise are contained in a file with a particular structure of [JSON](https://en.wikipedia.org/wiki/JSON) with the `.stix2` or `.json` extensions.
You can indicate a path to a STIX2 indicators file when checking iPhone backups or filesystem dumps. For example:
```bash
mvt-ios check-backup --iocs ~/ios/malware.stix2 --output /path/to/iphone/output /path/to/backup
```
Or, with data from an Android backup:
```bash
mvt-android check-backup --iocs ~/iocs/malware.stix2 /path/to/android/backup/
```
After extracting forensics data from a device, you are also able to compare it with any STIX2 file you indicate:
```bash
mvt-ios check-iocs --iocs ~/iocs/malware.stix2 /path/to/iphone/output/
```
The `--iocs` option can be invoked multiple times to let MVT import multiple STIX2 files at once. For example:
```bash
mvt-ios check-backup --iocs ~/iocs/malware1.stix --iocs ~/iocs/malware2.stix2 /path/to/backup
```
## Known repositories of STIX2 IOCs
- The [Amnesty International investigations repository](https://github.com/AmnestyTech/investigations) contains STIX-formatted IOCs for:
- [Pegasus](https://en.wikipedia.org/wiki/Pegasus_(spyware)) ([STIX2](https://raw.githubusercontent.com/AmnestyTech/investigations/master/2021-07-18_nso/pegasus.stix2))
Please [open an issue](https://github.com/mvt-project/mvt/issues/) to suggest new sources of STIX-formatted IOCs.

View File

@@ -2,6 +2,32 @@
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:
$ 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:
@@ -15,9 +41,10 @@ In case you have an encrypted backup, you will need to decrypt it first. This ca
-d, --destination TEXT Path to the folder where to store the decrypted
backup [required]
-p, --password TEXT Password to use to decrypt the backup NOTE: This
argument is mutually exclusive with arguments:
[key_file].
-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
@@ -25,10 +52,10 @@ In case you have an encrypted backup, you will need to decrypt it first. This ca
--help Show this message and exit.
You can specify either a password via command-line or pass a key file, and you need to specify a destination path where the decrypted backup will be stored. Following is an example usage of `decrypt-backup`:
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 decrypt-backup -p password -d /path/to/decrypted /path/to/backup
MVT_IOS_BACKUP_PASSWORD="mypassword" mvt-ios decrypt-backup -d /path/to/decrypted /path/to/backup
```
## Run `mvt-ios` on a Backup

View File

@@ -3,10 +3,14 @@
If you have correctly [installed libimobiledevice](../install.md) 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 backup encryption on
idevicebackup2 -i backup 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 backup changepw` or resetting the password by resetting only the settings through the iPhone's Settings app.
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 backup changepw`, or by turning off encryption (`idevicebackup2 -i backup 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](https://support.apple.com/en-us/HT205220), 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:

View File

@@ -4,6 +4,16 @@ In this page you can find a (reasonably) up-to-date breakdown of the files creat
## Records extracted by `check-fs` or `check-backup`
### `backup_info.json`
!!! info "Availabiliy"
Backup: :material-check:
Full filesystem dump: :material-close:
This JSON file is created by mvt-ios' `BackupInfo` module. The module extracts some details about the backup and the device, such as name, phone number, IMEI, product type and version.
---
### `cache_files.json`
!!! info "Availability"
@@ -50,6 +60,16 @@ If indicators a provided through the command-line, they are checked against the
---
### `configuration_profiles.json`
!!! info "Availability"
Backup: :material-check:
Full filesystem dump: :material-close:
This JSON file is created by mvt-ios' `ConfigurationProfiles` module. The module extracts details about iOS configuration profiles that have been installed on the device. These should include both default iOS as well as third-party profiles.
---
### `contacts.json`
!!! info "Availability"
@@ -150,6 +170,16 @@ If indicators are provided through the command-line, they are checked against th
---
### `profile_events.json`
!!! info "Availability"
Backup: :material-check:
Full filesystem dump: :material-close:
This JSON file is created by mvt-ios' `ProfileEvents` module. The module extracts a timeline of configuration profile operations. For example, it should indicate when a new profile was installed from the Settings app, or when one was removed.
---
### `safari_browser_state.json`
!!! info "Availability"
@@ -242,6 +272,18 @@ If indicators are provided through the command-line, they are checked against th
---
### `webkit_resource_load_statistics.json`
!!! info "Availability"
Backup: :material-check:
Full filesystem dump: :material-check:
This JSON file is created by mvt-ios `WebkitResourceLoadStatistics` module. The module extracts records from available WebKit ResourceLoadStatistics *observations.db* SQLite3 databases. These records should indicate domain names contacted by apps, including a timestamp.
If indicators are provided through the command-line, they are checked against the extracted domain names. Any matches are stored in *webkit_resource_load_statistics_detected.json*.
---
### `webkit_safari_view_service.json`
!!! info "Availability"

View File

@@ -42,6 +42,8 @@ nav:
- Records extracted by mvt-ios: "ios/records.md"
- MVT for Android:
- Android Forensic Methodology: "android/methodology.md"
- Check APKs: "android/download_apks.md"
- Check an Android Backup: "android/backup.md"
- Check over ADB: "android/adb.md"
- Check an Android Backup (SMS messages): "android/backup.md"
- Download APKs: "android/download_apks.md"
- Indicators of Compromise: "iocs.md"
- License: "license.md"

View File

@@ -1,4 +1,4 @@
# Mobile Verification Toolkit (MVT)
# Copyright (c) 2021 MVT Project Developers.
# See the file 'LICENSE' for usage and copying permissions, or find a copy at
# https://github.com/mvt-project/mvt/blob/main/LICENSE
# Copyright (c) 2021 The MVT Project Authors.
# Use of this software is governed by the MVT License 1.1 that can be found at
# https://license.mvt.re/1.1/

View File

@@ -1,6 +1,6 @@
# Mobile Verification Toolkit (MVT)
# Copyright (c) 2021 MVT Project Developers.
# See the file 'LICENSE' for usage and copying permissions, or find a copy at
# https://github.com/mvt-project/mvt/blob/main/LICENSE
# Copyright (c) 2021 The MVT Project Authors.
# Use of this software is governed by the MVT License 1.1 that can be found at
# https://license.mvt.re/1.1/
from .cli import cli

View File

@@ -1,17 +1,17 @@
# Mobile Verification Toolkit (MVT)
# Copyright (c) 2021 MVT Project Developers.
# See the file 'LICENSE' for usage and copying permissions, or find a copy at
# https://github.com/mvt-project/mvt/blob/main/LICENSE
# Copyright (c) 2021 The MVT Project Authors.
# Use of this software is governed by the MVT License 1.1 that can be found at
# https://license.mvt.re/1.1/
import os
import sys
import click
import argparse
import logging
import os
import click
from rich.logging import RichHandler
from mvt.common.indicators import Indicators, IndicatorsFileBadFormat
from mvt.common.module import run_module, save_timeline
from mvt.common.indicators import Indicators
from .download_apks import DownloadAPKs
from .lookups.koodous import koodous_lookup
from .lookups.virustotal import virustotal_lookup
@@ -26,7 +26,7 @@ log = logging.getLogger(__name__)
# Help messages of repeating options.
OUTPUT_HELP_MESSAGE = "Specify a path to a folder where you want to store JSON results"
SERIAL_HELP_MESSAGE = "Specify a device serial number or HOST:PORT connection string"
#==============================================================================
# Main
@@ -40,25 +40,37 @@ def cli():
# Download APKs
#==============================================================================
@cli.command("download-apks", help="Download all or non-safelisted installed APKs installed on the device")
@click.option("--serial", "-s", type=str, help=SERIAL_HELP_MESSAGE)
@click.option("--all-apks", "-a", is_flag=True,
help="Extract all packages installed on the phone, even those marked as safe")
@click.option("--virustotal", "-v", is_flag=True, help="Check packages on VirusTotal")
@click.option("--koodous", "-k", is_flag=True, help="Check packages on Koodous")
@click.option("--all-checks", "-A", is_flag=True, help="Run all available checks")
@click.option("--output", "-o", type=click.Path(exists=True),
help="Specify a path to a folder where you want to store JSON results")
@click.option("--output", "-o", type=click.Path(exists=False),
help="Specify a path to a folder where you want to store the APKs")
@click.option("--from-file", "-f", type=click.Path(exists=True),
help="Instead of acquiring from phone, load an existing packages.json file for lookups (mainly for debug purposes)")
def download_apks(all_apks, virustotal, koodous, all_checks, output, from_file):
@click.pass_context
def download_apks(ctx, all_apks, virustotal, koodous, all_checks, output, from_file, serial):
try:
if from_file:
download = DownloadAPKs.from_json(from_file)
else:
# TODO: Do we actually want to be able to run without storing any file?
if not output:
log.critical("You need to specify an output folder (with --output, -o) when extracting APKs from a device")
sys.exit(-1)
log.critical("You need to specify an output folder with --output!")
ctx.exit(1)
if not os.path.exists(output):
try:
os.makedirs(output)
except Exception as e:
log.critical("Unable to create output folder %s: %s", output, e)
ctx.exit(1)
download = DownloadAPKs(output_folder=output, all_apks=all_apks)
if serial:
download.serial = serial
download.run()
packages = download.packages
@@ -73,19 +85,22 @@ def download_apks(all_apks, virustotal, koodous, all_checks, output, from_file):
koodous_lookup(packages)
except KeyboardInterrupt:
print("")
sys.exit(-1)
ctx.exit(1)
#==============================================================================
# Checks through ADB
#==============================================================================
@cli.command("check-adb", help="Check an Android device over adb")
@click.option("--iocs", "-i", type=click.Path(exists=True), help="Path to indicators file")
@click.option("--output", "-o", type=click.Path(exists=True),
@click.option("--serial", "-s", type=str, help=SERIAL_HELP_MESSAGE)
@click.option("--iocs", "-i", type=click.Path(exists=True), multiple=True,
default=[], help="Path to indicators file (can be invoked multiple times)")
@click.option("--output", "-o", type=click.Path(exists=False),
help="Specify a path to a folder where you want to store JSON results")
@click.option("--list-modules", "-l", is_flag=True, help="Print list of available modules and exit")
@click.option("--module", "-m", help="Name of a single module you would like to run instead of all")
def check_adb(iocs, output, list_modules, module):
@click.pass_context
def check_adb(ctx, iocs, output, list_modules, module, serial):
if list_modules:
log.info("Following is the list of available check-adb modules:")
for adb_module in ADB_MODULES:
@@ -95,10 +110,21 @@ def check_adb(iocs, output, list_modules, module):
log.info("Checking Android through adb bridge")
if iocs:
# Pre-load indicators for performance reasons.
log.info("Loading indicators from provided file at %s", iocs)
indicators = Indicators(iocs)
if output and not os.path.exists(output):
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)
for ioc_path in iocs:
try:
indicators.parse_stix2(ioc_path)
except IndicatorsFileBadFormat as e:
log.critical(e)
ctx.exit(1)
log.info("Loaded a total of %d indicators", indicators.ioc_count)
timeline = []
timeline_detected = []
@@ -107,6 +133,8 @@ def check_adb(iocs, output, list_modules, module):
continue
m = adb_module(output_folder=output, log=logging.getLogger(adb_module.__module__))
if serial:
m.serial = serial
if iocs:
indicators.log = m.log
@@ -122,20 +150,35 @@ def check_adb(iocs, output, list_modules, module):
if len(timeline_detected) > 0:
save_timeline(timeline_detected, os.path.join(output, "timeline_detected.csv"))
#==============================================================================
# Check ADB backup
#==============================================================================
@cli.command("check-backup", help="Check an Android Backup")
@click.option("--iocs", "-i", type=click.Path(exists=True), help="Path to indicators file")
@click.option("--output", "-o", type=click.Path(exists=True), help=OUTPUT_HELP_MESSAGE)
@click.option("--serial", "-s", type=str, help=SERIAL_HELP_MESSAGE)
@click.option("--iocs", "-i", type=click.Path(exists=True), multiple=True,
default=[], help="Path to indicators file (can be invoked multiple times)")
@click.option("--output", "-o", type=click.Path(exists=False), help=OUTPUT_HELP_MESSAGE)
@click.argument("BACKUP_PATH", type=click.Path(exists=True))
def check_backup(iocs, output, backup_path):
@click.pass_context
def check_backup(ctx, iocs, output, backup_path, serial):
log.info("Checking ADB backup located at: %s", backup_path)
if iocs:
# Pre-load indicators for performance reasons.
log.info("Loading indicators from provided file at %s", iocs)
indicators = Indicators(iocs)
if output and not os.path.exists(output):
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)
for ioc_path in iocs:
try:
indicators.parse_stix2(ioc_path)
except IndicatorsFileBadFormat as e:
log.critical(e)
ctx.exit(1)
log.info("Loaded a total of %d indicators", indicators.ioc_count)
if os.path.isfile(backup_path):
log.critical("The path you specified is a not a folder!")
@@ -143,12 +186,15 @@ def check_backup(iocs, output, backup_path):
if os.path.basename(backup_path) == "backup.ab":
log.info("You can use ABE (https://github.com/nelenkov/android-backup-extractor) " \
"to extract 'backup.ab' files!")
sys.exit(-1)
ctx.exit(1)
for module in BACKUP_MODULES:
m = module(base_folder=backup_path, output_folder=output,
log=logging.getLogger(module.__module__))
if serial:
m.serial = serial
if iocs:
indicators.log = m.log
m.indicators = indicators

View File

@@ -1,15 +1,18 @@
# Mobile Verification Toolkit (MVT)
# Copyright (c) 2021 MVT Project Developers.
# See the file 'LICENSE' for usage and copying permissions, or find a copy at
# https://github.com/mvt-project/mvt/blob/main/LICENSE
# Copyright (c) 2021 The MVT Project Authors.
# Use of this software is governed by the MVT License 1.1 that can be found at
# https://license.mvt.re/1.1/
import os
import json
import logging
import os
import pkg_resources
from tqdm import tqdm
from mvt.common.module import InsufficientPrivileges
from mvt.common.utils import get_sha256_from_file_path
from .modules.adb.base import AndroidExtraction
log = logging.getLogger(__name__)
@@ -56,8 +59,8 @@ class DownloadAPKs(AndroidExtraction):
@classmethod
def from_json(cls, json_path):
"""Initialize this class from an existing packages.json file.
:param json_path: Path to the packages.json file to parse.
"""Initialize this class from an existing apks.json file.
:param json_path: Path to the apks.json file to parse.
"""
with open(json_path, "r") as handle:
data = json.load(handle)
@@ -137,6 +140,11 @@ class DownloadAPKs(AndroidExtraction):
miniters=1) as pp:
self._adb_download(remote_path, local_path,
progress_callback=pp.update_to)
except InsufficientPrivileges:
log.warn("Unable to pull package file from %s: insufficient privileges, it might be a system app",
remote_path)
self._adb_reconnect()
return None
except Exception as e:
log.exception("Failed to pull package file from %s: %s",
remote_path, e)
@@ -194,7 +202,7 @@ class DownloadAPKs(AndroidExtraction):
def save_json(self):
"""Save the results to the package.json file.
"""
json_path = os.path.join(self.output_folder, "packages.json")
json_path = os.path.join(self.output_folder, "apks.json")
packages = []
for package in self.packages:
packages.append(package.__dict__)

View File

@@ -1,4 +1,4 @@
# Mobile Verification Toolkit (MVT)
# Copyright (c) 2021 MVT Project Developers.
# See the file 'LICENSE' for usage and copying permissions, or find a copy at
# https://github.com/mvt-project/mvt/blob/main/LICENSE
# Copyright (c) 2021 The MVT Project Authors.
# Use of this software is governed by the MVT License 1.1 that can be found at
# https://license.mvt.re/1.1/

View File

@@ -1,15 +1,15 @@
# Mobile Verification Toolkit (MVT)
# Copyright (c) 2021 MVT Project Developers.
# See the file 'LICENSE' for usage and copying permissions, or find a copy at
# https://github.com/mvt-project/mvt/blob/main/LICENSE
# Copyright (c) 2021 The MVT Project Authors.
# Use of this software is governed by the MVT License 1.1 that can be found at
# https://license.mvt.re/1.1/
import requests
import logging
from rich.text import Text
from rich.table import Table
from rich.progress import track
import requests
from rich.console import Console
from rich.progress import track
from rich.table import Table
from rich.text import Text
log = logging.getLogger(__name__)

View File

@@ -1,14 +1,15 @@
# Mobile Verification Toolkit (MVT)
# Copyright (c) 2021 MVT Project Developers.
# See the file 'LICENSE' for usage and copying permissions, or find a copy at
# https://github.com/mvt-project/mvt/blob/main/LICENSE
# Copyright (c) 2021 The MVT Project Authors.
# 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 requests
import logging
from rich.text import Text
from rich.table import Table
from rich.progress import track
from rich.console import Console
from rich.progress import track
from rich.table import Table
from rich.text import Text
log = logging.getLogger(__name__)

View File

@@ -1,4 +1,4 @@
# Mobile Verification Toolkit (MVT)
# Copyright (c) 2021 MVT Project Developers.
# See the file 'LICENSE' for usage and copying permissions, or find a copy at
# https://github.com/mvt-project/mvt/blob/main/LICENSE
# Copyright (c) 2021 The MVT Project Authors.
# Use of this software is governed by the MVT License 1.1 that can be found at
# https://license.mvt.re/1.1/

View File

@@ -1,17 +1,17 @@
# Mobile Verification Toolkit (MVT)
# Copyright (c) 2021 MVT Project Developers.
# See the file 'LICENSE' for usage and copying permissions, or find a copy at
# https://github.com/mvt-project/mvt/blob/main/LICENSE
# Copyright (c) 2021 The MVT Project Authors.
# Use of this software is governed by the MVT License 1.1 that can be found at
# https://license.mvt.re/1.1/
from .chrome_history import ChromeHistory
from .dumpsys_batterystats import DumpsysBatterystats
from .dumpsys_packages import DumpsysPackages
from .dumpsys_procstats import DumpsysProcstats
from .packages import Packages
from .processes import Processes
from .rootbinaries import RootBinaries
from .sms import SMS
from .whatsapp import Whatsapp
from .packages import Packages
from .rootbinaries import RootBinaries
ADB_MODULES = [ChromeHistory, SMS, Whatsapp, Processes,
DumpsysBatterystats, DumpsysProcstats,

View File

@@ -1,22 +1,24 @@
# Mobile Verification Toolkit (MVT)
# Copyright (c) 2021 MVT Project Developers.
# See the file 'LICENSE' for usage and copying permissions, or find a copy at
# https://github.com/mvt-project/mvt/blob/main/LICENSE
# Copyright (c) 2021 The MVT Project Authors.
# 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
import random
import string
import sys
import time
import logging
import tempfile
from adb_shell.adb_device import AdbDeviceUsb
import time
from adb_shell.adb_device import AdbDeviceTcp, AdbDeviceUsb
from adb_shell.auth.keygen import keygen, write_public_keyfile
from adb_shell.auth.sign_pythonrsa import PythonRSASigner
from adb_shell.exceptions import DeviceAuthError, AdbCommandFailureException
from usb1 import USBErrorBusy, USBErrorAccess
from adb_shell.exceptions import (AdbCommandFailureException, DeviceAuthError,
UsbReadFailedError)
from usb1 import USBErrorAccess, USBErrorBusy
from mvt.common.module import MVTModule
from mvt.common.module import InsufficientPrivileges, MVTModule
log = logging.getLogger(__name__)
@@ -28,17 +30,12 @@ class AndroidExtraction(MVTModule):
def __init__(self, file_path=None, base_folder=None, output_folder=None,
fast_mode=False, log=None, results=[]):
"""Initialize Android extraction module.
:param file_path: Path to the database file to parse
:param base_folder: Path to a base folder containing an Android dump
:param output_folder: Path to the folder where to store extraction
results
"""
super().__init__(file_path=file_path, base_folder=base_folder,
output_folder=output_folder, fast_mode=fast_mode,
log=log, results=results)
self.device = None
self.serial = None
def _adb_check_keys(self):
"""Make sure Android adb keys exist.
@@ -58,7 +55,19 @@ class AndroidExtraction(MVTModule):
priv_key = handle.read()
signer = PythonRSASigner("", priv_key)
self.device = AdbDeviceUsb()
# If no serial was specified or if the serial does not seem to be
# a HOST:PORT definition, we use the USB transport.
if not self.serial or ":" not in self.serial:
self.device = AdbDeviceUsb(serial=self.serial)
# Otherwise we try to use the TCP transport.
else:
addr = self.serial.split(":")
if len(addr) < 2:
raise ValueError("TCP serial number must follow the format: `address:port`")
self.device = AdbDeviceTcp(addr[0], int(addr[1]),
default_transport_timeout_s=30.)
while True:
try:
@@ -69,9 +78,14 @@ class AndroidExtraction(MVTModule):
except DeviceAuthError:
log.error("You need to authorize this computer on the Android device. Retrying in 5 seconds...")
time.sleep(5)
except Exception as e:
log.critical(e)
except UsbReadFailedError:
log.error("Unable to connect to the device over USB. Try to unplug, plug the device and start again.")
sys.exit(-1)
except OSError as e:
if e.errno == 113 and self.serial:
log.critical("Unable to connect to the device %s: did you specify the correct IP addres?",
self.serial)
sys.exit(-1)
else:
break
@@ -104,7 +118,7 @@ class AndroidExtraction(MVTModule):
"""Check if we have a `su` binary, otherwise raise an Exception.
"""
if not self._adb_check_if_root():
raise Exception("The Android device does not seem to have a `su` binary. Cannot run this module.")
raise InsufficientPrivileges("This module is optionally available in case the device is already rooted. Do NOT root your own device!")
def _adb_command_as_root(self, command):
"""Execute an adb shell command.
@@ -112,6 +126,21 @@ class AndroidExtraction(MVTModule):
:returns: Output of command
"""
return self._adb_command(f"su -c {command}")
def _adb_check_file_exists(self, file):
"""Verify that a file exists.
:param file: Path of the file
:returns: Boolean indicating whether the file exists or not
"""
# TODO: Need to support checking files without root privileges as well.
# Connect to the device over adb.
self._adb_connect()
# Check if we have root, if not raise an Exception.
self._adb_root_or_die()
return bool(self._adb_command_as_root(f"[ ! -f {file} ] || echo 1"))
def _adb_download(self, remote_path, local_path, progress_callback=None, retry_root=True):
"""Download a file form the device.

View File

@@ -1,13 +1,14 @@
# Mobile Verification Toolkit (MVT)
# Copyright (c) 2021 MVT Project Developers.
# See the file 'LICENSE' for usage and copying permissions, or find a copy at
# https://github.com/mvt-project/mvt/blob/main/LICENSE
# Copyright (c) 2021 The MVT Project Authors.
# 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
import sqlite3
import logging
from mvt.common.utils import convert_chrometime_to_unix, convert_timestamp_to_iso
from mvt.common.utils import (convert_chrometime_to_unix,
convert_timestamp_to_iso)
from .base import AndroidExtraction
@@ -19,7 +20,7 @@ class ChromeHistory(AndroidExtraction):
"""This module extracts records from Android's Chrome browsing history."""
def __init__(self, file_path=None, base_folder=None, output_folder=None,
fast_mode=False, log=None, results=[]):
serial=None, fast_mode=False, log=None, results=[]):
super().__init__(file_path=file_path, base_folder=base_folder,
output_folder=output_folder, fast_mode=fast_mode,
log=log, results=results)
@@ -51,14 +52,14 @@ class ChromeHistory(AndroidExtraction):
""")
for item in cur:
self.results.append(dict(
id=item[0],
url=item[1],
visit_id=item[2],
timestamp=item[3],
isodate=convert_timestamp_to_iso(convert_chrometime_to_unix(item[3])),
redirect_source=item[4],
))
self.results.append({
"id": item[0],
"url": item[1],
"visit_id": item[2],
"timestamp": item[3],
"isodate": convert_timestamp_to_iso(convert_chrometime_to_unix[item[3]]),
"redirect_source": item[4],
})
cur.close()
conn.close()

View File

@@ -1,10 +1,10 @@
# Mobile Verification Toolkit (MVT)
# Copyright (c) 2021 MVT Project Developers.
# See the file 'LICENSE' for usage and copying permissions, or find a copy at
# https://github.com/mvt-project/mvt/blob/main/LICENSE
# Copyright (c) 2021 The MVT Project Authors.
# Use of this software is governed by the MVT License 1.1 that can be found at
# https://license.mvt.re/1.1/
import os
import logging
import os
from .base import AndroidExtraction
@@ -14,7 +14,7 @@ class DumpsysBatterystats(AndroidExtraction):
"""This module extracts stats on battery consumption by processes."""
def __init__(self, file_path=None, base_folder=None, output_folder=None,
fast_mode=False, log=None, results=[]):
serial=None, fast_mode=False, log=None, results=[]):
super().__init__(file_path=file_path, base_folder=base_folder,
output_folder=output_folder, fast_mode=fast_mode,
log=log, results=results)

Some files were not shown because too many files have changed in this diff Show More