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

Compare commits

...

121 Commits

Author SHA1 Message Date
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
Nex
fe8c013b0f Bumped version 2021-07-27 21:40:15 +02:00
Nex
caa5d8ee8c Rename lint_python.yml to lint-python.yml 2021-07-27 21:37:26 +02:00
Nex
2baac1f52c Create python-publish.yml 2021-07-27 21:37:06 +02:00
Nex
dec7616a3d Merge pull request #124 from cclauss/patch-1
GitHub Action to lint Python code
2021-07-27 21:30:11 +02:00
Nex
b1ae777621 Fixed variable name 2021-07-27 21:29:14 +02:00
Nex
404edfee9a Merge branch 'main' of github.com:mvt-project/mvt 2021-07-27 21:28:36 +02:00
Nex
3bb0d5020c Fixed variable name 2021-07-27 21:27:43 +02:00
Christian Clauss
b500ee9429 codespell 2021-07-27 12:11:31 +02:00
Christian Clauss
3f2058441a bandit --recursive --skip B108,B112,B404,B602 . 2021-07-27 12:09:52 +02:00
Christian Clauss
9931edccc4 GitHub Action to lint Python code
Output:
2021-07-27 12:06:47 +02:00
tek
9e33ece3e9 Fixes issue with Manifest format 2021-07-27 01:23:22 +02:00
Nex
32aeaaf91c Update README.md 2021-07-26 21:48:55 +02:00
Nex
8b253b5e7c Update README.md 2021-07-26 21:39:49 +02:00
Nex
362bce7c76 Update README.md 2021-07-26 21:38:36 +02:00
Nex
e821421ca7 Update README.md 2021-07-26 21:35:35 +02:00
Nex
95ab269671 Fixed some formatting 2021-07-26 19:33:12 +02:00
Tek
49f592ebe8 Merge pull request #116 from adamstiefel/patch-1
fix: readme grammar
2021-07-26 10:53:24 +02:00
Adam Stiefel
6b436f2057 fix: readme grammar
Changed "evidences" to "evidence". Changed "understanding basics" to "understanding the basics". Changed "command line" to "command-line"
2021-07-25 17:16:26 -04:00
Nex
13ce55f4ac Added some context to error message 2021-07-25 15:51:24 +02:00
Tek
2ca0081833 Merge pull request #110 from EmilienCourt/fix_whatsapp
[ADB] Fix WhatsApp database parsing (thumb_image)
2021-07-25 15:25:39 +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
emilien
3d9574682c Fix WhatsApp thumb image 2021-07-25 14:13:10 +02:00
Nex
3dcc24acd5 Added build 18G69 2021-07-25 12:19:45 +02:00
Nex
8f558db60b Fixed version number 2021-07-25 12:07:22 +02:00
Nex
7a02df4592 Merge branch 'main' of github.com:mvt-project/mvt 2021-07-25 12:04:07 +02:00
Nex
a61d4e17eb Snapshotting dependencies 2021-07-25 12:03:45 +02:00
Nex
3fd8d1524f Updated LICENSE 2021-07-25 12:01:23 +02:00
Nex
d8310797ef Merge pull request #109 from U039b/fix-#108
Fix #108
2021-07-25 11:49:12 +02:00
Nex
7fffef77ce Automatically recover malformed sqlite3 databases (closes: #25 #37) 2021-07-25 11:47:05 +02:00
U039b
b7d65e6123 Fix #108 2021-07-25 11:03:28 +02:00
Nex
9d9b77e02e Changing error message to info, to avoid confusion 2021-07-25 10:46:10 +02:00
Nex
6d0ff11540 Restored empty spaces for new line 2021-07-24 14:27:16 +02:00
Nex
97558ec3af Merge pull request #19 from goshawk22/patch-2
Better check for if device has root
2021-07-24 13:56:12 +02:00
Nex
4fdb868216 Merge pull request #76 from bryeetz/patch-1
Typo
2021-07-24 13:54:59 +02:00
Nex
25d6d52557 Merge pull request #98 from Trigus42/main
Fix download of APKs that require root privileges #2
2021-07-24 13:53:43 +02:00
Nex
d172a3fe69 Merge branch 'febrezo-dockerizing' 2021-07-24 13:24:12 +02:00
Nex
d6f49e76d6 Included Docker details in the documentation 2021-07-24 13:23:45 +02:00
Nex
8883306558 Merge branch 'dockerizing' of https://github.com/febrezo/mvt into febrezo-dockerizing 2021-07-24 13:10:04 +02:00
Trigus42
03523a40c0 Fix _adb_process_file & Improve _adb_download_root
- The _adb_download function doesn't need a package_name argument. This broke _adb_process_file and unnecessarily clutters function calls. Also, the function may be used to download other files or folders too. Generating a random filename seems like the best solution to me since it is less likely to get a duplicate filename and thus to replace an existing file.

- The path /sdcard/Download doesn't necessarily exist. Using /sdcard seems more reliable.
2021-07-24 12:09:59 +02:00
Nex
6c496ec3c2 Merge pull request #84 from pkirkovsky/package-versions
Require click >= 8.0.1
2021-07-23 21:08:07 +02:00
Pavel Kirkovsky
143ceafee2 Merge branch 'mvt-project:main' into package-versions 2021-07-23 12:02:11 -07:00
Pavel Kirkovsky
99640ac08c Merge branch 'mvt-project:main' into extract-key 2021-07-23 12:02:02 -07:00
Nex
ba84b3c18d Fixed variable name (closes: #72) 2021-07-23 18:05:51 +02:00
Nex
8e099e5985 Checking for valid indicators before continuing (closes: #35) 2021-07-23 18:04:41 +02:00
goshawk22
ad3faa186b Use command -v instead of which to check for root
`command` is built in, unlike `which`, and is more reliable.
https://github.com/mvt-project/mvt/pull/19#issuecomment-885650430
https://stackoverflow.com/questions/592620/how-can-i-check-if-a-program-exists-from-a-bash-script/677212#677212
2021-07-23 15:35:56 +01:00
Pavel Kirkovsky
30d0348256 Added extract-key info to main docs 2021-07-23 03:46:48 -07:00
Pavel Kirkovsky
8048ed8c3a Require click >= 8.0.1 2021-07-23 02:08:15 -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
Bryan Scheetz
fa49203c9b Typo
adversial -> adversarial
2021-07-22 22:49:26 -04:00
tek
e69449a2f0 Fixes typos 2021-07-22 23:21:31 +02:00
febrezo
684aed8d11 Add compilation of libimobiledevice for iOS compatibility
Added considering the feedback reported in the #16 discussion.
2021-07-22 17:44:17 +02:00
tek
b19db5543b Update README 2021-07-21 13:59:54 +02:00
Nex
af7c45ae22 Merge branch 'master' of github.com:mvt-project/mvt 2021-07-21 11:54:13 +02:00
Nex
8d68e7a166 Better handling of special characters when saving a timeline 2021-07-21 11:53:41 +02:00
Nex
3004690fd1 Merge pull request #21 from pkirkovsky/prompt-password
Prompt for password if none is given
2021-07-21 11:20:24 +02:00
Nex
2f05d4b4f9 Fixed typo 2021-07-21 11:07:15 +02:00
tek
f0a9196094 Merge branch 'master' of github.com:mvt-project/mvt 2021-07-21 10:44:43 +02:00
tek
ce46e608de fixes documentation 2021-07-21 10:44:10 +02:00
Tek
791e7db59c Merge pull request #7 from lunakk-PL/patch-1
Update download_apks.md
2021-07-21 10:32:48 +02:00
tek
3e048c4338 updated readme 2021-07-21 10:25:02 +02:00
Tek
a23b890350 Merge pull request #30 from runasand/patch-1
Update README.md
2021-07-21 10:16:29 +02:00
Tek
8fbf95a262 Merge pull request #31 from recurrence/master
[iOS CLI] Remove non-existent SYSDIAGNOSE_MODULES reference
2021-07-21 10:15:56 +02:00
Tyler Kellogg
967eb75e7c [iOS CLI] Remove non-existent SYSDIAGNOSE_MODULES reference 2021-07-20 15:01:09 -07:00
Runa Sandvik
2276df4f1b Update README.md
Use pip3 to install mvt from pypi
2021-07-20 17:55:22 -04:00
Pavel Kirkovsky
695555f26f Prompt for password if none is given 2021-07-20 05:44:36 -07:00
febrezo
1adf3f430b Add welcome message when the terminal is launched 2021-07-20 14:20:27 +02:00
Adam Lawson
9317586851 Better check for if device has root
"which su" will return the path of the su binary, or it will return nothing. 
The python boolean of a string with something in it (such as the path of the su binary), will be True.
An empty string (where there is no su binary) will be False.
2021-07-20 12:55:10 +01:00
Adam Lawson
cb6bde5b8c Fix download of APKs that require root privileges
Some system APKs are stored in directories that require root privileges, such as /system/product.
2021-07-20 12:53:44 +01:00
febrezo
f3afc871cd Create alias for abe instead of custom command 2021-07-20 13:45:55 +02:00
febrezo
8c855b645d Add Dockerfile with Android dependencies solved 2021-07-20 12:10:37 +02:00
febrezo
732db070f2 Add implicit creation of output folders 2021-07-20 03:09:53 +02:00
lunakk-PL
167f7e3d77 Update download_apks.md
proper Koodous link -> https://koodous.com/
2021-07-19 13:45:47 +02:00
63 changed files with 1035 additions and 377 deletions

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

2
.gitignore vendored
View File

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

66
Dockerfile Normal file
View File

@@ -0,0 +1,66 @@
FROM ubuntu:20.04
# Ref. https://github.com/mvt-project/mvt
# Fixing major OS dependencies
# ----------------------------
RUN apt update \
&& apt install -y python3 python3-pip libusb-1.0-0-dev \
&& apt install -y wget \
&& apt install -y adb \
&& DEBIAN_FRONTEND=noninteractive apt-get -y install default-jre-headless
# Install build tools for libimobiledevice
# ----------------------------------------
RUN apt install -y build-essential \
checkinstall \
git \
autoconf \
automake \
libtool-bin \
libplist-dev \
libusbmuxd-dev \
libssl-dev \
sqlite3 \
pkg-config
# Clean up
# --------
RUN apt-get clean \
&& rm -rf /var/lib/apt/lists/*
# Build libimobiledevice
# ----------------------
RUN git clone https://github.com/libimobiledevice/libplist
RUN git clone https://github.com/libimobiledevice/libusbmuxd
RUN git clone https://github.com/libimobiledevice/libimobiledevice
RUN git clone https://github.com/libimobiledevice/usbmuxd
RUN cd libplist && ./autogen.sh && make && make install && ldconfig
RUN cd libusbmuxd && PKG_CONFIG_PATH=/usr/local/lib/pkgconfig ./autogen.sh && make && make install && ldconfig
RUN cd libimobiledevice && PKG_CONFIG_PATH=/usr/local/lib/pkgconfig ./autogen.sh --enable-debug && make && make install && ldconfig
RUN cd usbmuxd && PKG_CONFIG_PATH=/usr/local/lib/pkgconfig ./autogen.sh --prefix=/usr --sysconfdir=/etc --localstatedir=/var --runstatedir=/run && make && make install
# Installing MVT
# --------------
RUN pip3 install mvt
# Installing ABE
# --------------
RUN mkdir /opt/abe
RUN wget https://github.com/nelenkov/android-backup-extractor/releases/download/20210709062403-4c55371/abe.jar -O /opt/abe/abe.jar
# Create alias for abe
RUN echo 'alias abe="java -jar /opt/abe/abe.jar"' >> ~/.bashrc
# Setup investigations environment
# --------------------------------
RUN mkdir /home/cases
WORKDIR /home/cases
RUN echo 'echo "Mobile Verification Toolkit @ Docker\n------------------------------------\n\nYou can find information about how to use this image for Android (https://github.com/mvt-project/mvt/tree/master/docs/android) and iOS (https://github.com/mvt-project/mvt/tree/master/docs/ios) in the official docs of the project.\n"' >> ~/.bashrc
RUN echo 'echo "Note that to perform the debug via USB you might need to give the Docker image access to the USB using \"docker run -it --privileged -v /dev/bus/usb:/dev/bus/usb mvt\" or, preferably, the \"--device=\" parameter.\n"' >> ~/.bashrc
CMD /bin/bash

20
LICENSE
View File

@@ -1,4 +1,4 @@
MVT License 1.0
MVT License 1.1
===============
1. Definitions
@@ -35,7 +35,7 @@ MVT License 1.0
means any form of the work other than Source Code Form.
1.7. "Larger Work"
means a work that combines Covered Software with other material, in
means a work that combines Covered Software with other material, in
a separate file or files, that is not Covered Software.
1.8. "License"
@@ -89,16 +89,16 @@ MVT License 1.0
a Larger Work.
1.16. "Device Owner" (or "Device Owners")
means an individal or a legal entity with legal ownership of an
means an individual or a legal entity with legal ownership of an
electronic device which is being analysed through the use of
Covered Software or a Larger Work, or from which Data was extracted
for subsequent analysis.
1.17. "Data Owner" (or "Data Owners")
means an individial or group of individuals who made use of the
electronic device from which Data that is extracted and/or analyzed
originated. "Data Owner" might or might not differ from "Device
Owner".
means an individual or group of individuals who made legitimate use
of the electronic device from which Data that is extracted and/or
analyzed originated. "Data Owner" might or might not differ from
"Device Owner".
2. License Grants and Conditions
--------------------------------
@@ -381,8 +381,8 @@ Exhibit A - Source Code Form License Notice
-------------------------------------------
This Source Code Form is subject to the terms of the MVT License,
v. 1.0. If a copy of the MVT License was not distributed with this
file, You can obtain one at TODO.
v. 1.1. If a copy of the MVT License was not distributed with this
file, You can obtain one at https://license.mvt.re/1.1/.
If it is not possible or desirable to put the notice in a particular
file, then You may include the notice in a location (such as a LICENSE
@@ -395,7 +395,7 @@ Exhibit B - "Incompatible With Secondary Licenses" Notice
---------------------------------------------------------
This Source Code Form is "Incompatible With Secondary Licenses", as
defined by the MVT License, v. 1.0.
defined by the MVT License, v. 1.1.
This license is an adaption of Mozilla Public License, v. 2.0.

View File

@@ -5,21 +5,26 @@
# Mobile Verification Toolkit
[![](https://img.shields.io/pypi/v/mvt)](https://pypi.org/project/mvt/)
[![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.
[Please check out the documentation.](https://mvt.readthedocs.io/en/latest/)
It has been developed and released by the [Amnesty International Security Lab](https://www.amnesty.org/en/tech/) in July 2021 in the context of the [Pegasus project](https://forbiddenstories.org/about-the-pegasus-project/) along with [a technical forensic methodology and forensic evidence](https://www.amnesty.org/en/latest/research/2021/07/forensic-methodology-report-how-to-catch-nso-groups-pegasus/).
*Warning*: MVT is a forensic research tool intended for technologists and investigators. Using it requires understanding the basics of forensic analysis 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 expert assistance.
## Installation
First you need to install dependencies, on Linux `sudo apt install python3 python3-pip libusb-1.0-0` or on MacOS `brew install python3 libusb`.
MVT can be installed from sources or conveniently using:
Then you can install mvt from pypi with `pip install mvt`, or directly form sources:
```bash
git clone https://github.com/mvt-project/mvt.git
cd mvt
pip3 install .
```
pip3 install mvt
```
You will need some dependencies, so please check the [documentation](https://docs.mvt.re/en/latest/install.html).
Alternatively, you can decide to run MVT and all relevant tools through a [Docker container](https://docs.mvt.re/en/latest/docker.html).
## Usage
@@ -30,11 +35,13 @@ MVT provides two commands `mvt-ios` and `mvt-android` with the following subcomm
* `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
* `extract-key`: Extract decryption key from an 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/).
Check out [the documentation to see how to use them](https://docs.mvt.re/).
## License

View File

@@ -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

@@ -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()

View File

@@ -25,7 +25,7 @@ tar xvf backup.tar
You can then extract SMSs containing links with MVT:
```bash
$ mvt-android check-backup --output sms .
$ mvt-android check-backup --output . .
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

View File

@@ -10,7 +10,7 @@ Now you can launch `mvt-android` and specify the `download-apks` command and the
mvt-android download-apks --output /path/to/folder
```
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://www.koodous.com). While these lookups do not provide any conclusive assessment on all of the extracted APKs, they might highlight any known malicious ones:
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
mvt-android download-apks --output /path/to/folder --virustotal

33
docs/docker.md Normal file
View File

@@ -0,0 +1,33 @@
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/).
Once installed, you can clone MVT's repository and build its Docker image:
```bash
git clone https://github.com/mvt-project/mvt.git
cd mvt
docker build -t mvt .
```
Test if the image was created successfully:
```bash
docker run -it mvt
```
If a prompt is spawned successfully, you can close it with `exit`.
If you wish to use MVT to test an Android device you will need to enable the container's access to the host's USB devices. You can do so by enabling the `--privileged` flag and mounting the USB bus device as a volume:
```bash
docker run -it --privileged -v /dev/bus/usb:/dev/bus/usb mvt
```
**Please note:** the `--privileged` parameter is generally regarded as a security risk. If you want to learn more about this check out [this explainer on container escapes](https://blog.trailofbits.com/2019/07/19/understanding-docker-container-escapes/) as it gives access to the whole system.
Recent versions of Docker provide a `--device` parameter allowing to specify a precise USB device without enabling `--privileged`:
```bash
docker run -it --device=/dev/<your_usb_port> mvt
```

View File

@@ -7,7 +7,7 @@ Before proceeding, please note that mvt requires Python 3.6+ to run. While it sh
First install some basic dependencies that will be necessary to build all required tools:
```bash
sudo apt install python3 python3-pip libusb-1.0-0
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`.
@@ -19,7 +19,7 @@ Running MVT on Mac requires Xcode and [homebrew](https://brew.sh) to be installe
In order to install dependencies use:
```bash
brew install python3 libusb
brew install python3 libusb sqlite3
```
*libusb* is not required if you intend to only use `mvt-ios` and not `mvt-android`.
@@ -35,7 +35,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:

View File

@@ -14,4 +14,4 @@ Mobile Verification Toolkit (MVT) is a collection of utilities designed to facil
While MVT is capable of extracting and processing various types of very personal records typically found on a mobile phone (such as calls history, SMS and WhatsApp messages, etc.), this is intended to help identify potential attack vectors such as malicious SMS messages leading to exploitation.
MVT's purpose is not to facilitate adversial forensics of non-consenting individuals' devices. The use of MVT and derivative products to extract and/or analyse data originating from devices used by individuals not consenting to the procedure is explicitly prohibited in the [license](license.md).
MVT's purpose is not to facilitate adversarial forensics of non-consenting individuals' devices. The use of MVT and derivative products to extract and/or analyse data originating from devices used by individuals not consenting to the procedure is explicitly prohibited in the [license](license.md).

32
docs/iocs.md Normal file
View File

@@ -0,0 +1,32 @@
# 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/
```
If you're looking for indicators of compromise for a specific piece of malware or adversary, please ask investigators or anti-malware researchers who have the relevant expertise for a STIX file.
## 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

@@ -1,6 +1,6 @@
# Dumping the filesystem
While iTunes backup provide a lot of very useful databases and diagnistic 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](https://checkra.in/), which provides an easy way to obtain root on most recent iPhone models.
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](https://checkra.in/), 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](https://github.com/checkra1n/BugTracker/issues/279) and stop functioning.

View File

@@ -6,7 +6,7 @@ Before jumping into acquiring and analyzing data from an iOS device, you should
You will need to decide whether to attempt to jailbreak the device and obtain a full filesystem dump, or not.
While access the full filesystem allows to extact data that would otherwise be unavailable, it might not always be possible to jailbreak a certain iPhone model or version of iOS. In addition, depending on the type of jailbreak available, doing so might compromise some important records, pollute others, or potentially cause unintended malfunctioning of the device later in case it is used again.
While access the full filesystem allows to extract data that would otherwise be unavailable, it might not always be possible to jailbreak a certain iPhone model or version of iOS. In addition, depending on the type of jailbreak available, doing so might compromise some important records, pollute others, or potentially cause unintended malfunctioning of the device later in case it is used again.
If you are not expected to return the phone, you might want to consider to attempt a jailbreak after having exhausted all other options, including a backup.

View File

@@ -236,7 +236,7 @@ If indicators are provided through the command-line, they are checked against th
Backup: :material-close:
Full filesystem dump: :material-check:
This JSON file is created by mvt-ios' `WebkitLocalStorage` module. The module extracts a lsit of file and folder names located at the following path */private/var/mobile/Containers/Data/Application/\*/Library/WebKit/WebsiteData/LocalStorage/*, which contains local storage files created by any app installed on the device.
This JSON file is created by mvt-ios' `WebkitLocalStorage` module. The module extracts a list of file and folder names located at the following path */private/var/mobile/Containers/Data/Application/\*/Library/WebKit/WebsiteData/LocalStorage/*, which contains local storage files created by any app installed on the device.
If indicators are provided through the command-line, they are checked against the extracted names. Any matches are stored in *webkit_local_storage_detected.json*.

View File

@@ -28,6 +28,7 @@ nav:
- Welcome: "index.md"
- Introduction: "introduction.md"
- Installation: "install.md"
- Using Docker: "docker.md"
- MVT for iOS:
- iOS Forensic Methodology: "ios/methodology.md"
- Install libimobiledevice: "ios/install.md"
@@ -43,4 +44,5 @@ nav:
- Android Forensic Methodology: "android/methodology.md"
- Check APKs: "android/download_apks.md"
- Check an Android Backup: "android/backup.md"
- Indicators of Compromise: "iocs.md"
- License: "license.md"

View File

@@ -3,15 +3,17 @@
# See the file 'LICENSE' for usage and copying permissions, or find a copy at
# https://github.com/mvt-project/mvt/blob/main/LICENSE
import os
import sys
import click
import argparse
import logging
import os
import sys
import click
from rich.logging import RichHandler
from mvt.common.module import run_module, save_timeline
from mvt.common.indicators import Indicators
from mvt.common.module import run_module, save_timeline
from .download_apks import DownloadAPKs
from .lookups.koodous import koodous_lookup
from .lookups.virustotal import virustotal_lookup
@@ -45,8 +47,8 @@ def cli():
@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):
@@ -54,9 +56,12 @@ def download_apks(all_apks, virustotal, koodous, all_checks, output, from_file):
if from_file:
download = DownloadAPKs.from_json(from_file)
else:
if not output:
log.critical("You need to specify an output folder (with --output, -o) when extracting APKs from a device")
sys.exit(-1)
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)
sys.exit(-1)
download = DownloadAPKs(output_folder=output, all_apks=all_apks)
download.run()
@@ -81,7 +86,7 @@ def download_apks(all_apks, virustotal, koodous, all_checks, output, from_file):
#==============================================================================
@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("--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")
@@ -95,6 +100,13 @@ def check_adb(iocs, output, list_modules, module):
log.info("Checking Android through adb bridge")
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)
sys.exit(-1)
if iocs:
# Pre-load indicators for performance reasons.
log.info("Loading indicators from provided file at %s", iocs)
@@ -127,11 +139,18 @@ def check_adb(iocs, output, list_modules, module):
#==============================================================================
@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("--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):
log.info("Checking ADB backup located at: %s", backup_path)
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)
sys.exit(-1)
if iocs:
# Pre-load indicators for performance reasons.
log.info("Loading indicators from provided file at %s", iocs)

View File

@@ -3,20 +3,22 @@
# See the file 'LICENSE' for usage and copying permissions, or find a copy at
# https://github.com/mvt-project/mvt/blob/main/LICENSE
import os
import json
import logging
import os
import pkg_resources
from tqdm import tqdm
from mvt.common.utils import get_sha256_from_file_path
from .modules.adb.base import AndroidExtraction
log = logging.getLogger(__name__)
# TODO: Would be better to replace tqdm with rich.progress to reduce
# the number of dependencies. Need to investigate whether
# it's possible to have a simialr callback system.
# it's possible to have a similar callback system.
class PullProgress(tqdm):
"""PullProgress is a tqdm update system for APK downloads."""
@@ -42,7 +44,7 @@ class DownloadAPKs(AndroidExtraction):
"""Initialize module.
:param output_folder: Path to the folder where data should be stored
:param all_apks: Boolean indicating whether to download all packages
or filter known-goods
or filter known-goods
:param packages: Provided list of packages, typically for JSON checks
"""
super().__init__(file_path=None, base_folder=None,

View File

@@ -3,13 +3,13 @@
# See the file 'LICENSE' for usage and copying permissions, or find a copy at
# https://github.com/mvt-project/mvt/blob/main/LICENSE
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

@@ -3,12 +3,13 @@
# See the file 'LICENSE' for usage and copying permissions, or find a copy at
# https://github.com/mvt-project/mvt/blob/main/LICENSE
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

@@ -7,11 +7,11 @@ 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

@@ -3,16 +3,19 @@
# See the file 'LICENSE' for usage and copying permissions, or find a copy at
# https://github.com/mvt-project/mvt/blob/main/LICENSE
import os
import sys
import time
import logging
import os
import random
import string
import sys
import tempfile
import time
from adb_shell.adb_device import 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
from usb1 import USBErrorAccess, USBErrorBusy
from mvt.common.module import MVTModule
@@ -96,7 +99,7 @@ class AndroidExtraction(MVTModule):
"""Check if we have a `su` binary on the Android device.
:returns: Boolean indicating whether a `su` binary is present or not
"""
return bool(self._adb_command("[ ! -f /sbin/su ] || echo 1"))
return bool(self._adb_command("command -v su"))
def _adb_root_or_die(self):
"""Check if we have a `su` binary, otherwise raise an Exception.
@@ -110,8 +113,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
"""
def _adb_download(self, remote_path, local_path, progress_callback=None):
# 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.
:param remote_path: Path to download from the device
:param local_path: Path to where to locally store the copy of the file
@@ -119,6 +135,37 @@ class AndroidExtraction(MVTModule):
"""
try:
self.device.pull(remote_path, local_path, progress_callback)
except AdbCommandFailureException as e:
if retry_root:
self._adb_download_root(remote_path, local_path, progress_callback)
else:
raise Exception(f"Unable to download file {remote_path}: {e}")
def _adb_download_root(self, remote_path, local_path, progress_callback=None):
try:
# Check if we have root, if not raise an Exception.
self._adb_root_or_die()
# We generate a random temporary filename.
tmp_filename = "tmp_" + ''.join(random.choices(string.ascii_uppercase + string.ascii_lowercase + string.digits, k=10))
# We create a temporary local file.
new_remote_path = f"/sdcard/{tmp_filename}"
# We copy the file from the data folder to /sdcard/.
cp = self._adb_command_as_root(f"cp {remote_path} {new_remote_path}")
if cp.startswith("cp: ") and "No such file or directory" in cp:
raise Exception(f"Unable to process file {remote_path}: File not found")
elif cp.startswith("cp: ") and "Permission denied" in cp:
raise Exception(f"Unable to process file {remote_path}: Permission denied")
# We download from /sdcard/ to the local temporary file.
# If it doesn't work now, don't try again (retry_root=False)
self._adb_download(new_remote_path, local_path, retry_root=False)
# Delete the copy on /sdcard/.
self._adb_command(f"rm -rf {new_remote_path}")
except AdbCommandFailureException as e:
raise Exception(f"Unable to download file {remote_path}: {e}")

View File

@@ -3,11 +3,12 @@
# See the file 'LICENSE' for usage and copying permissions, or find a copy at
# https://github.com/mvt-project/mvt/blob/main/LICENSE
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

View File

@@ -3,8 +3,8 @@
# See the file 'LICENSE' for usage and copying permissions, or find a copy at
# https://github.com/mvt-project/mvt/blob/main/LICENSE
import os
import logging
import os
from .base import AndroidExtraction

View File

@@ -3,8 +3,8 @@
# See the file 'LICENSE' for usage and copying permissions, or find a copy at
# https://github.com/mvt-project/mvt/blob/main/LICENSE
import os
import logging
import os
from .base import AndroidExtraction

View File

@@ -3,8 +3,8 @@
# See the file 'LICENSE' for usage and copying permissions, or find a copy at
# https://github.com/mvt-project/mvt/blob/main/LICENSE
import os
import logging
import os
from .base import AndroidExtraction

View File

@@ -3,8 +3,9 @@
# See the file 'LICENSE' for usage and copying permissions, or find a copy at
# https://github.com/mvt-project/mvt/blob/main/LICENSE
import os
import logging
import os
import pkg_resources
from .base import AndroidExtraction

View File

@@ -3,8 +3,9 @@
# See the file 'LICENSE' for usage and copying permissions, or find a copy at
# https://github.com/mvt-project/mvt/blob/main/LICENSE
import os
import logging
import os
import pkg_resources
from .base import AndroidExtraction

View File

@@ -3,16 +3,41 @@
# See the file 'LICENSE' for usage and copying permissions, or find a copy at
# https://github.com/mvt-project/mvt/blob/main/LICENSE
import logging
import os
import sqlite3
import logging
from mvt.common.utils import check_for_links, convert_timestamp_to_iso
from .base import AndroidExtraction
from mvt.common.utils import convert_timestamp_to_iso, check_for_links
log = logging.getLogger(__name__)
SMS_PATH = "data/data/com.google.android.apps.messaging/databases/bugle_db"
SMS_BUGLE_PATH = "data/data/com.google.android.apps.messaging/databases/bugle_db"
SMS_BUGLE_QUERY = """
SELECT
ppl.normalized_destination AS number,
p.timestamp AS timestamp,
CASE WHEN m.sender_id IN
(SELECT _id FROM participants WHERE contact_id=-1)
THEN 2 ELSE 1 END incoming, p.text AS text
FROM messages m, conversations c, parts p,
participants ppl, conversation_participants cp
WHERE (m.conversation_id = c._id)
AND (m._id = p.message_id)
AND (cp.conversation_id = c._id)
AND (cp.participant_id = ppl._id);
"""
SMS_MMSSMS_PATH = "data/data/com.android.providers.telephony/databases/mmssms.db"
SMS_MMSMS_QUERY = """
SELECT
address AS number,
date_sent AS timestamp,
type as incoming,
body AS text
FROM sms;
"""
class SMS(AndroidExtraction):
"""This module extracts all SMS messages containing links."""
@@ -50,20 +75,12 @@ class SMS(AndroidExtraction):
"""
conn = sqlite3.connect(db_path)
cur = conn.cursor()
cur.execute("""
SELECT
ppl.normalized_destination AS number,
p.timestamp AS timestamp,
CASE WHEN m.sender_id IN
(SELECT _id FROM participants WHERE contact_id=-1)
THEN 2 ELSE 1 END incoming, p.text AS text
FROM messages m, conversations c, parts p,
participants ppl, conversation_participants cp
WHERE (m.conversation_id = c._id)
AND (m._id = p.message_id)
AND (cp.conversation_id = c._id)
AND (cp.participant_id = ppl._id);
""")
if (self.SMS_DB_TYPE == 1):
cur.execute(SMS_BUGLE_QUERY)
elif (self.SMS_DB_TYPE == 2):
cur.execute(SMS_MMSMS_QUERY)
names = [description[0] for description in cur.description]
for item in cur:
@@ -85,7 +102,15 @@ class SMS(AndroidExtraction):
log.info("Extracted a total of %d SMS messages containing links", len(self.results))
def run(self):
# Checking the SMS database path
try:
self._adb_process_file(os.path.join("/", SMS_PATH), self._parse_db)
if (self._adb_check_file_exists(os.path.join("/", SMS_BUGLE_PATH))):
self.SMS_DB_TYPE = 1
self._adb_process_file(os.path.join("/", SMS_BUGLE_PATH), self._parse_db)
elif (self._adb_check_file_exists(os.path.join("/", SMS_MMSSMS_PATH))):
self.SMS_DB_TYPE = 2
self._adb_process_file(os.path.join("/", SMS_MMSSMS_PATH), self._parse_db)
else:
self.log.error("No SMS database found")
except Exception as e:
self.log.error(e)

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