mirror of
https://github.com/mvt-project/mvt.git
synced 2026-09-30 21:19:41 +02:00
Merge branch 'main' of https://github.com/j0k2r/mvt into j0k2r-main
This commit is contained in:
commit
f78c671885
13 files changed
+57
-42
No files matched your search
+9
-6
@@ -51,7 +51,8 @@ def cli():
|
|||||||
help="Specify a path to a folder where you want to store the APKs")
|
help="Specify a path to a folder where you want to store the APKs")
|
||||||
@click.option("--from-file", "-f", type=click.Path(exists=True),
|
@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)")
|
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.option("--serial", "-s", type=str, help="Use the Android device with a given serial number")
|
||||||
|
def download_apks(all_apks, virustotal, koodous, all_checks, output, from_file, serial):
|
||||||
try:
|
try:
|
||||||
if from_file:
|
if from_file:
|
||||||
download = DownloadAPKs.from_json(from_file)
|
download = DownloadAPKs.from_json(from_file)
|
||||||
@@ -63,7 +64,7 @@ def download_apks(all_apks, virustotal, koodous, all_checks, output, from_file):
|
|||||||
log.critical("Unable to create output folder %s: %s", output, e)
|
log.critical("Unable to create output folder %s: %s", output, e)
|
||||||
sys.exit(-1)
|
sys.exit(-1)
|
||||||
|
|
||||||
download = DownloadAPKs(output_folder=output, all_apks=all_apks)
|
download = DownloadAPKs(output_folder=output, all_apks=all_apks, serial=serial)
|
||||||
download.run()
|
download.run()
|
||||||
|
|
||||||
packages = download.packages
|
packages = download.packages
|
||||||
@@ -90,7 +91,8 @@ def download_apks(all_apks, virustotal, koodous, all_checks, output, from_file):
|
|||||||
help="Specify a path to a folder where you want to store JSON results")
|
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("--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")
|
@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.option("--serial", "-s", type=str, help="Use the Android device with a given serial")
|
||||||
|
def check_adb(iocs, output, list_modules, module, serial):
|
||||||
if list_modules:
|
if list_modules:
|
||||||
log.info("Following is the list of available check-adb modules:")
|
log.info("Following is the list of available check-adb modules:")
|
||||||
for adb_module in ADB_MODULES:
|
for adb_module in ADB_MODULES:
|
||||||
@@ -118,7 +120,7 @@ def check_adb(iocs, output, list_modules, module):
|
|||||||
if module and adb_module.__name__ != module:
|
if module and adb_module.__name__ != module:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
m = adb_module(output_folder=output, log=logging.getLogger(adb_module.__module__))
|
m = adb_module(output_folder=output, serial=serial, log=logging.getLogger(adb_module.__module__))
|
||||||
|
|
||||||
if iocs:
|
if iocs:
|
||||||
indicators.log = m.log
|
indicators.log = m.log
|
||||||
@@ -140,8 +142,9 @@ def check_adb(iocs, output, list_modules, module):
|
|||||||
@cli.command("check-backup", help="Check an Android 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("--iocs", "-i", type=click.Path(exists=True), help="Path to indicators file")
|
||||||
@click.option("--output", "-o", type=click.Path(exists=False), help=OUTPUT_HELP_MESSAGE)
|
@click.option("--output", "-o", type=click.Path(exists=False), help=OUTPUT_HELP_MESSAGE)
|
||||||
|
@click.option("--serial", "-s", type=str, help="Use the Android device with a given serial")
|
||||||
@click.argument("BACKUP_PATH", type=click.Path(exists=True))
|
@click.argument("BACKUP_PATH", type=click.Path(exists=True))
|
||||||
def check_backup(iocs, output, backup_path):
|
def check_backup(iocs, output, backup_path, serial):
|
||||||
log.info("Checking ADB backup located at: %s", backup_path)
|
log.info("Checking ADB backup located at: %s", backup_path)
|
||||||
|
|
||||||
if output and not os.path.exists(output):
|
if output and not os.path.exists(output):
|
||||||
@@ -166,7 +169,7 @@ def check_backup(iocs, output, backup_path):
|
|||||||
|
|
||||||
for module in BACKUP_MODULES:
|
for module in BACKUP_MODULES:
|
||||||
m = module(base_folder=backup_path, output_folder=output,
|
m = module(base_folder=backup_path, output_folder=output,
|
||||||
log=logging.getLogger(module.__module__))
|
serial=serial, log=logging.getLogger(module.__module__))
|
||||||
|
|
||||||
if iocs:
|
if iocs:
|
||||||
indicators.log = m.log
|
indicators.log = m.log
|
||||||
|
|||||||
@@ -40,15 +40,16 @@ class DownloadAPKs(AndroidExtraction):
|
|||||||
"""DownloadAPKs is the main class operating the download of APKs
|
"""DownloadAPKs is the main class operating the download of APKs
|
||||||
from the device."""
|
from the device."""
|
||||||
|
|
||||||
def __init__(self, output_folder=None, all_apks=False, packages=None):
|
def __init__(self, output_folder=None, all_apks=False, packages=None, serial=None):
|
||||||
"""Initialize module.
|
"""Initialize module.
|
||||||
:param output_folder: Path to the folder where data should be stored
|
:param output_folder: Path to the folder where data should be stored
|
||||||
:param all_apks: Boolean indicating whether to download all packages
|
: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
|
:param packages: Provided list of packages, typically for JSON checks
|
||||||
|
:param serial: The USB device serial ID
|
||||||
"""
|
"""
|
||||||
super().__init__(file_path=None, base_folder=None,
|
super().__init__(file_path=None, base_folder=None,
|
||||||
output_folder=output_folder)
|
output_folder=output_folder, serial=serial)
|
||||||
|
|
||||||
self.output_folder_apk = None
|
self.output_folder_apk = None
|
||||||
self.packages = packages or []
|
self.packages = packages or []
|
||||||
|
|||||||
@@ -10,8 +10,7 @@ import string
|
|||||||
import sys
|
import sys
|
||||||
import tempfile
|
import tempfile
|
||||||
import time
|
import time
|
||||||
|
from adb_shell.adb_device import AdbDeviceUsb, AdbDeviceTcp
|
||||||
from adb_shell.adb_device import AdbDeviceUsb
|
|
||||||
from adb_shell.auth.keygen import keygen, write_public_keyfile
|
from adb_shell.auth.keygen import keygen, write_public_keyfile
|
||||||
from adb_shell.auth.sign_pythonrsa import PythonRSASigner
|
from adb_shell.auth.sign_pythonrsa import PythonRSASigner
|
||||||
from adb_shell.exceptions import AdbCommandFailureException, DeviceAuthError
|
from adb_shell.exceptions import AdbCommandFailureException, DeviceAuthError
|
||||||
@@ -28,16 +27,17 @@ class AndroidExtraction(MVTModule):
|
|||||||
"""This class provides a base for all Android extraction modules."""
|
"""This class provides a base for all Android extraction modules."""
|
||||||
|
|
||||||
def __init__(self, file_path=None, base_folder=None, output_folder=None,
|
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=[]):
|
||||||
"""Initialize Android extraction module.
|
"""Initialize Android extraction module.
|
||||||
:param file_path: Path to the database file to parse
|
:param file_path: Path to the database file to parse
|
||||||
:param base_folder: Path to a base folder containing an Android dump
|
:param base_folder: Path to a base folder containing an Android dump
|
||||||
:param output_folder: Path to the folder where to store extraction
|
:param output_folder: Path to the folder where to store extraction
|
||||||
results
|
results
|
||||||
|
:param serial: The USB device serial ID
|
||||||
"""
|
"""
|
||||||
super().__init__(file_path=file_path, base_folder=base_folder,
|
super().__init__(file_path=file_path, base_folder=base_folder,
|
||||||
output_folder=output_folder, fast_mode=fast_mode,
|
output_folder=output_folder, serial=serial,
|
||||||
log=log, results=results)
|
fast_mode=fast_mode, log=log, results=results)
|
||||||
|
|
||||||
self.device = None
|
self.device = None
|
||||||
|
|
||||||
@@ -59,7 +59,16 @@ class AndroidExtraction(MVTModule):
|
|||||||
priv_key = handle.read()
|
priv_key = handle.read()
|
||||||
|
|
||||||
signer = PythonRSASigner("", priv_key)
|
signer = PythonRSASigner("", priv_key)
|
||||||
self.device = AdbDeviceUsb()
|
|
||||||
|
if self.serial is None or ":" not in self.serial:
|
||||||
|
self.device = AdbDeviceUsb(serial=self.serial)
|
||||||
|
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=9.)
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
|
|||||||
@@ -20,10 +20,10 @@ class ChromeHistory(AndroidExtraction):
|
|||||||
"""This module extracts records from Android's Chrome browsing history."""
|
"""This module extracts records from Android's Chrome browsing history."""
|
||||||
|
|
||||||
def __init__(self, file_path=None, base_folder=None, output_folder=None,
|
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,
|
super().__init__(file_path=file_path, base_folder=base_folder,
|
||||||
output_folder=output_folder, fast_mode=fast_mode,
|
output_folder=output_folder, serial=serial,
|
||||||
log=log, results=results)
|
fast_mode=fast_mode, log=log, results=results)
|
||||||
|
|
||||||
def serialize(self, record):
|
def serialize(self, record):
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -14,10 +14,10 @@ class DumpsysBatterystats(AndroidExtraction):
|
|||||||
"""This module extracts stats on battery consumption by processes."""
|
"""This module extracts stats on battery consumption by processes."""
|
||||||
|
|
||||||
def __init__(self, file_path=None, base_folder=None, output_folder=None,
|
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,
|
super().__init__(file_path=file_path, base_folder=base_folder,
|
||||||
output_folder=output_folder, fast_mode=fast_mode,
|
output_folder=output_folder, serial=serial,
|
||||||
log=log, results=results)
|
fast_mode=fast_mode, log=log, results=results)
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
self._adb_connect()
|
self._adb_connect()
|
||||||
|
|||||||
@@ -14,10 +14,10 @@ class DumpsysPackages(AndroidExtraction):
|
|||||||
"""This module extracts stats on installed packages."""
|
"""This module extracts stats on installed packages."""
|
||||||
|
|
||||||
def __init__(self, file_path=None, base_folder=None, output_folder=None,
|
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,
|
super().__init__(file_path=file_path, base_folder=base_folder,
|
||||||
output_folder=output_folder, fast_mode=fast_mode,
|
output_folder=output_folder, serial=serial,
|
||||||
log=log, results=results)
|
fast_mode=fast_mode, log=log, results=results)
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
self._adb_connect()
|
self._adb_connect()
|
||||||
|
|||||||
@@ -14,10 +14,10 @@ class DumpsysProcstats(AndroidExtraction):
|
|||||||
"""This module extracts stats on memory consumption by processes."""
|
"""This module extracts stats on memory consumption by processes."""
|
||||||
|
|
||||||
def __init__(self, file_path=None, base_folder=None, output_folder=None,
|
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,
|
super().__init__(file_path=file_path, base_folder=base_folder,
|
||||||
output_folder=output_folder, fast_mode=fast_mode,
|
output_folder=output_folder, serial=serial,
|
||||||
log=log, results=results)
|
fast_mode=fast_mode, log=log, results=results)
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
self._adb_connect()
|
self._adb_connect()
|
||||||
|
|||||||
@@ -16,10 +16,10 @@ class Packages(AndroidExtraction):
|
|||||||
"""This module extracts the list of installed packages."""
|
"""This module extracts the list of installed packages."""
|
||||||
|
|
||||||
def __init__(self, file_path=None, base_folder=None, output_folder=None,
|
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,
|
super().__init__(file_path=file_path, base_folder=base_folder,
|
||||||
output_folder=output_folder, fast_mode=fast_mode,
|
output_folder=output_folder, serial=serial,
|
||||||
log=log, results=results)
|
fast_mode=fast_mode, log=log, results=results)
|
||||||
|
|
||||||
def serialize(self, record):
|
def serialize(self, record):
|
||||||
records = []
|
records = []
|
||||||
|
|||||||
@@ -13,10 +13,10 @@ class Processes(AndroidExtraction):
|
|||||||
"""This module extracts details on running processes."""
|
"""This module extracts details on running processes."""
|
||||||
|
|
||||||
def __init__(self, file_path=None, base_folder=None, output_folder=None,
|
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,
|
super().__init__(file_path=file_path, base_folder=base_folder,
|
||||||
output_folder=output_folder, fast_mode=fast_mode,
|
output_folder=output_folder, serial=serial,
|
||||||
log=log, results=results)
|
fast_mode=fast_mode, log=log, results=results)
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
self._adb_connect()
|
self._adb_connect()
|
||||||
|
|||||||
@@ -16,10 +16,10 @@ class RootBinaries(AndroidExtraction):
|
|||||||
"""This module extracts the list of installed packages."""
|
"""This module extracts the list of installed packages."""
|
||||||
|
|
||||||
def __init__(self, file_path=None, base_folder=None, output_folder=None,
|
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,
|
super().__init__(file_path=file_path, base_folder=base_folder,
|
||||||
output_folder=output_folder, fast_mode=fast_mode,
|
output_folder=output_folder, serial=serial,
|
||||||
log=log, results=results)
|
fast_mode=fast_mode, log=log, results=results)
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
root_binaries_path = os.path.join("..", "..", "data", "root_binaries.txt")
|
root_binaries_path = os.path.join("..", "..", "data", "root_binaries.txt")
|
||||||
|
|||||||
@@ -43,10 +43,10 @@ class SMS(AndroidExtraction):
|
|||||||
"""This module extracts all SMS messages containing links."""
|
"""This module extracts all SMS messages containing links."""
|
||||||
|
|
||||||
def __init__(self, file_path=None, base_folder=None, output_folder=None,
|
def __init__(self, file_path=None, 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,
|
super().__init__(file_path=file_path, base_folder=base_folder,
|
||||||
output_folder=output_folder, fast_mode=fast_mode,
|
output_folder=output_folder, serial=serial,
|
||||||
log=log, results=results)
|
fast_mode=fast_mode, log=log, results=results)
|
||||||
|
|
||||||
def serialize(self, record):
|
def serialize(self, record):
|
||||||
text = record["text"].replace("\n", "\\n")
|
text = record["text"].replace("\n", "\\n")
|
||||||
|
|||||||
@@ -20,10 +20,10 @@ class Whatsapp(AndroidExtraction):
|
|||||||
"""This module extracts all WhatsApp messages containing links."""
|
"""This module extracts all WhatsApp messages containing links."""
|
||||||
|
|
||||||
def __init__(self, file_path=None, base_folder=None, output_folder=None,
|
def __init__(self, file_path=None, 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,
|
super().__init__(file_path=file_path, base_folder=base_folder,
|
||||||
output_folder=output_folder, fast_mode=fast_mode,
|
output_folder=output_folder, serial=serial,
|
||||||
log=log, results=results)
|
fast_mode=fast_mode, log=log, results=results)
|
||||||
|
|
||||||
def serialize(self, record):
|
def serialize(self, record):
|
||||||
text = record["data"].replace("\n", "\\n")
|
text = record["data"].replace("\n", "\\n")
|
||||||
|
|||||||
@@ -31,11 +31,12 @@ class MVTModule(object):
|
|||||||
slug = None
|
slug = None
|
||||||
|
|
||||||
def __init__(self, file_path=None, base_folder=None, output_folder=None,
|
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=[]):
|
||||||
"""Initialize module.
|
"""Initialize module.
|
||||||
:param file_path: Path to the module's database file, if there is any.
|
:param file_path: Path to the module's database file, if there is any.
|
||||||
:param base_folder: Path to the base folder (backup or filesystem dump)
|
:param base_folder: Path to the base folder (backup or filesystem dump)
|
||||||
:param output_folder: Folder where results will be stored
|
:param output_folder: Folder where results will be stored
|
||||||
|
:param serial: The USB device serial ID
|
||||||
:param fast_mode: Flag to enable or disable slow modules
|
:param fast_mode: Flag to enable or disable slow modules
|
||||||
:param log: Handle to logger
|
:param log: Handle to logger
|
||||||
:param results: Provided list of results entries
|
:param results: Provided list of results entries
|
||||||
@@ -43,6 +44,7 @@ class MVTModule(object):
|
|||||||
self.file_path = file_path
|
self.file_path = file_path
|
||||||
self.base_folder = base_folder
|
self.base_folder = base_folder
|
||||||
self.output_folder = output_folder
|
self.output_folder = output_folder
|
||||||
|
self.serial= serial
|
||||||
self.fast_mode = fast_mode
|
self.fast_mode = fast_mode
|
||||||
self.log = log
|
self.log = log
|
||||||
self.indicators = None
|
self.indicators = None
|
||||||
|
|||||||
Reference in new issue
Block a user