Adds SMS androidqf module and improves tests

This commit is contained in:
tek 2022-10-11 12:41:42 +02:00
parent 41826d7951
commit ba0106c476
12 changed files with 211 additions and 1 deletions

View File

@ -71,6 +71,16 @@ SECURITY_PACKAGES = [
"com.samsung.android.app.omcagent",
"com.samsung.android.securitylogagent",
"com.sec.android.soagent",
]
SYSTEM_UPDATE_PACKAGES = [
"com.android.updater",
"com.google.android.gms",
"com.huawei.android.hwouc",
"com.lge.lgdmsclient",
"com.motorola.ccc.ota",
"com.oneplus.opbackup",
"com.oppo.ota",
"com.transsion.systemupdate",
"com.wssyncmldm",
]
@ -133,6 +143,10 @@ class Packages(AndroidExtraction):
self.log.warning("Found a security package disabled: \"%s\"",
result["package_name"])
if result["package_name"] in SYSTEM_UPDATE_PACKAGES and result["disabled"]:
self.log.warning("System OTA update package \"%s\" disabled on the phone",
result["package_name"])
if not self.indicators:
continue

View File

@ -10,6 +10,7 @@ from .dumpsys_receivers import DumpsysReceivers
from .getprop import Getprop
from .processes import Processes
from .settings import Settings
from .sms import SMS
ANDROIDQF_MODULES = [DumpsysActivities, DumpsysReceivers, DumpsysAccessibility,
DumpsysAppops, Processes, Getprop, Settings]
DumpsysAppops, Processes, Getprop, Settings, SMS]

View File

@ -0,0 +1,85 @@
# Mobile Verification Toolkit (MVT) - Private
# Copyright (c) 2021-2022 Claudio Guarnieri.
# This file is part of MVT Private and its content is confidential.
# Please refer to the project maintainers before sharing with others.
import getpass
import logging
from typing import Optional
from mvt.android.parsers.backup import (AndroidBackupParsingError,
InvalidBackupPassword, parse_ab_header,
parse_backup_file, parse_tar_for_sms)
from .base import AndroidQFModule
class SMS(AndroidQFModule):
"""This module analyse SMS file in backup"""
def __init__(
self,
file_path: Optional[str] = None,
target_path: Optional[str] = None,
results_path: Optional[str] = None,
fast_mode: Optional[bool] = False,
log: logging.Logger = logging.getLogger(__name__),
results: Optional[list] = None
) -> None:
super().__init__(file_path=file_path, target_path=target_path,
results_path=results_path, fast_mode=fast_mode,
log=log, results=results)
def check_indicators(self) -> None:
if not self.indicators:
return
for message in self.results:
if "body" not in message:
continue
if self.indicators.check_domains(message["links"]):
self.detected.append(message)
def parse_backup(self, data):
header = parse_ab_header(data)
if not header["backup"]:
self.log.critical("Invalid backup format, backup.ab was not analysed")
return
password = None
if header["encryption"] != "none":
password = getpass.getpass(prompt="Backup Password: ", stream=None)
try:
tardata = parse_backup_file(data, password=password)
except InvalidBackupPassword:
self.log.critical("Invalid backup password")
return
except AndroidBackupParsingError:
self.log.critical("Impossible to parse this backup file, please use"
" Android Backup Extractor instead")
return
if not tardata:
return
try:
self.results = parse_tar_for_sms(tardata)
except AndroidBackupParsingError:
self.log.info("Impossible to read SMS from the Android Backup, "
"please extract the SMS and try extracting it with "
"Android Backup Extractor")
return
def run(self) -> None:
files = self._get_files_by_pattern("*/backup.ab")
if not files:
self.log.info("No backup data found")
return
with open(files[0], "rb") as handle:
data = handle.read()
self.parse_backup(data)
self.log.info("Identified %d SMS in backup data",
len(self.results))

View File

@ -0,0 +1,22 @@
# Mobile Verification Toolkit (MVT)
# Copyright (c) 2021-2022 Claudio Guarnieri.
# 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
from mvt.android.modules.androidqf.getprop import Getprop
from mvt.common.module import run_module
from ..utils import get_artifact_folder
class TestAndroidqfGetpropAnalysis:
def test_androidqf_getprop(self):
m = Getprop(target_path=os.path.join(get_artifact_folder(), "androidqf"), log=logging)
run_module(m)
assert len(m.results) == 10
assert len(m.timeline) == 0
assert len(m.detected) == 0

View File

@ -0,0 +1,21 @@
# Mobile Verification Toolkit (MVT)
# Copyright (c) 2021-2022 Claudio Guarnieri.
# 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
from mvt.android.modules.androidqf.processes import Processes
from mvt.common.module import run_module
from ..utils import get_artifact_folder
class TestAndroidqfProcessesAnalysis:
def test_androidqf_processes(self):
m = Processes(target_path=os.path.join(get_artifact_folder(), "androidqf"), log=logging)
run_module(m)
assert len(m.results) == 15
assert len(m.timeline) == 0
assert len(m.detected) == 0

View File

@ -0,0 +1,21 @@
# Mobile Verification Toolkit (MVT)
# Copyright (c) 2021-2022 Claudio Guarnieri.
# 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
from mvt.android.modules.androidqf.sms import SMS
from mvt.common.module import run_module
from ..utils import get_artifact_folder
class TestAndroidqfSMSAnalysis:
def test_androidqf_sms(self):
m = SMS(target_path=os.path.join(get_artifact_folder(), "androidqf"), log=logging)
run_module(m)
assert len(m.results) == 2
assert len(m.timeline) == 0
assert len(m.detected) == 0

Binary file not shown.

View File

@ -0,0 +1,10 @@
[dalvik.vm.appimageformat]: [lz4]
[dalvik.vm.dex2oat-Xms]: [64m]
[dalvik.vm.dex2oat-Xmx]: [512m]
[dalvik.vm.dex2oat-max-image-block-size]: [524288]
[dalvik.vm.dex2oat-minidebuginfo]: [true]
[dalvik.vm.dex2oat-resolve-startup-strings]: [true]
[dalvik.vm.dexopt.secondary]: [true]
[dalvik.vm.heapgrowthlimit]: [128m]
[dalvik.vm.heapmaxfree]: [8m]
[dalvik.vm.heapminfree]: [512k]

View File

@ -0,0 +1,16 @@
USER PID PPID VSZ RSS WCHAN ADDR S NAME
root 1 0 57912 2084 0 0 S init
root 2 0 0 0 0 0 S [kthreadd]
root 3 2 0 0 0 0 S [ksoftirqd/0]
root 5 2 0 0 0 0 S [kworker/0:0H]
root 6 2 0 0 0 0 S [kworker/u16:0]
root 7 2 0 0 0 0 S [rcu_preempt]
root 8 2 0 0 0 0 S [rcu_sched]
root 9 2 0 0 0 0 S [rcu_bh]
root 10 2 0 0 0 0 S [migration/0]
root 11 2 0 0 0 0 D [tz_worker_threa]
root 12 2 0 0 0 0 S [watchdog/0]
root 13 2 0 0 0 0 S [watchdog/1]
root 14 2 0 0 0 0 D [tz_worker_threa]
root 15 2 0 0 0 0 S [migration/1]
root 16 2 0 0 0 0 S [ksoftirqd/1]

View File

@ -0,0 +1,20 @@
# Mobile Verification Toolkit (MVT)
# Copyright (c) 2021-2022 Claudio Guarnieri.
# 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
from click.testing import CliRunner
from mvt.android.cli import check_androidqf
from .utils import get_artifact_folder
class TestCheckAndroidqfCommand:
def test_check(self):
runner = CliRunner()
path = os.path.join(get_artifact_folder(), "androidqf")
result = runner.invoke(check_androidqf, [path])
assert result.exit_code == 0