mirror of
https://github.com/mvt-project/mvt.git
synced 2026-09-03 16:41:05 +02:00
Merge branch 'main' into fix/alert-timestamps
This commit is contained in:
@@ -23,7 +23,7 @@ class TestDumpsysAccessibilityArtifact:
|
||||
assert len(da.results) == 4
|
||||
assert da.results[0]["package_name"] == "com.android.settings"
|
||||
assert (
|
||||
da.results[0]["service"]
|
||||
da.results[0]["component"]
|
||||
== "com.android.settings/com.samsung.android.settings.development.gpuwatch.GPUWatchInterceptor"
|
||||
)
|
||||
|
||||
@@ -37,7 +37,9 @@ class TestDumpsysAccessibilityArtifact:
|
||||
da.parse(data)
|
||||
assert len(da.results) == 1
|
||||
assert da.results[0]["package_name"] == "com.malware.accessibility"
|
||||
assert da.results[0]["service"] == "com.malware.service.malwareservice"
|
||||
assert da.results[0]["service_name"] == "com.malware.service.malwareservice"
|
||||
assert da.results[0]["enabled"] is True
|
||||
assert da.results[0]["installed"] is False
|
||||
|
||||
def test_accessibility_service_alert(self):
|
||||
da = DumpsysAccessibilityArtifact()
|
||||
@@ -52,6 +54,22 @@ class TestDumpsysAccessibilityArtifact:
|
||||
assert da.alertstore.alerts[0].level == AlertLevel.MEDIUM
|
||||
assert da.alertstore.alerts[0].event == da.results[0]
|
||||
|
||||
def test_same_component_is_kept_for_each_user(self):
|
||||
da = DumpsysAccessibilityArtifact()
|
||||
da.parse(
|
||||
"""User state[attributes:{id=0
|
||||
installed services: {
|
||||
0 : com.example/.Service
|
||||
}
|
||||
User state[attributes:{id=10
|
||||
installed services: {
|
||||
0 : com.example/.Service
|
||||
}
|
||||
"""
|
||||
)
|
||||
|
||||
assert [result["user_id"] for result in da.results] == [0, 10]
|
||||
|
||||
def test_ioc_check(self, indicator_file):
|
||||
da = DumpsysAccessibilityArtifact()
|
||||
file = get_artifact("android_data/dumpsys_accessibility.txt")
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
# Use of this software is governed by the MVT License 1.1 that can be found at
|
||||
# https://license.mvt.re/1.1/
|
||||
|
||||
import base64
|
||||
|
||||
from mvt.android.artifacts.dumpsys_adb import DumpsysADBArtifact
|
||||
from mvt.android.modules.bugreport.dumpsys_adb_state import DumpsysADBState
|
||||
from mvt.common.alerts import AlertLevel
|
||||
@@ -11,6 +13,17 @@ from ..utils import get_artifact
|
||||
|
||||
|
||||
class TestDumpsysADBArtifact:
|
||||
def test_parsing_binary_xml_recovers_key(self):
|
||||
public_key = base64.b64encode(bytes(range(256)))
|
||||
keystore = DumpsysADBArtifact().parse_binary_xml(
|
||||
b"ABX\x00binary-key=" + public_key + b" user@host\x00lastConnection"
|
||||
)
|
||||
|
||||
assert len(keystore) == 1
|
||||
assert keystore[0]["key"] == public_key.decode()
|
||||
assert keystore[0]["user"] == "user@host"
|
||||
assert keystore[0]["last_connected"] is None
|
||||
|
||||
def test_parsing(self):
|
||||
da_adb = DumpsysADBArtifact()
|
||||
file = get_artifact("android_data/dumpsys_adb.txt")
|
||||
|
||||
@@ -25,10 +25,37 @@ class TestDumpsysAppopsArtifact:
|
||||
assert da.results[0]["uid"] == "0"
|
||||
assert len(da.results[0]["permissions"]) == 1
|
||||
assert da.results[0]["permissions"][0]["name"] == "MANAGE_IPSEC_TUNNELS"
|
||||
assert da.results[0]["permissions"][0]["access"] == "allow"
|
||||
assert da.results[0]["permissions"][0]["mode"] == "allow"
|
||||
assert da.results[6]["package_name"] == "com.sec.factory.camera"
|
||||
assert len(da.results[6]["permissions"][1]["entries"]) == 1
|
||||
assert len(da.results[11]["permissions"]) == 4
|
||||
wake_lock = next(
|
||||
permission
|
||||
for permission in da.results[11]["permissions"]
|
||||
if permission["name"] == "WAKE_LOCK"
|
||||
)
|
||||
assert wake_lock["entries"][0]["duration"] == "+126ms"
|
||||
|
||||
def test_running_and_attribution_are_retained(self):
|
||||
da = DumpsysAppopsArtifact()
|
||||
da.parse(
|
||||
""" Uid 0:
|
||||
state=cch
|
||||
Package com.example:
|
||||
CAMERA (allow):
|
||||
camera=[
|
||||
Access: [fg-s] 2025-01-01 00:00:00.000 (-1s) duration=+2ms
|
||||
]
|
||||
RECORD_AUDIO (allow):
|
||||
Running start at: +3s
|
||||
"""
|
||||
)
|
||||
|
||||
camera = da.results[0]["permissions"][0]["entries"][0]
|
||||
running = da.results[0]["permissions"][1]["entries"][0]
|
||||
assert camera["attribution"] == "camera"
|
||||
assert running["event"] == "running"
|
||||
assert running["relative_time"] == "+3s"
|
||||
|
||||
def test_ioc_check(self, indicator_file):
|
||||
da = DumpsysAppopsArtifact()
|
||||
|
||||
@@ -57,18 +57,19 @@ class TestDumpsysBatteryDailyArtifact:
|
||||
assert uninstall_alert.message == (
|
||||
"Detected uninstall of package com.example.removed (vers 0)"
|
||||
)
|
||||
assert uninstall_alert.event_time == "2022-08-16"
|
||||
assert uninstall_alert.event_time == "2022-08-16 15:56:39"
|
||||
assert uninstall_alert.event["package_name"] == "com.example.removed"
|
||||
assert uninstall_alert.event["vers"] == "0"
|
||||
assert uninstall_alert.event["version_code"] == 0
|
||||
assert uninstall_alert.event["action"] == "uninstall"
|
||||
|
||||
assert downgrade_alert.level == AlertLevel.MEDIUM
|
||||
assert downgrade_alert.message == (
|
||||
"Detected downgrade of package com.example.app from vers 10 to vers 9"
|
||||
)
|
||||
assert downgrade_alert.event_time == "2022-08-17"
|
||||
assert downgrade_alert.event_time == "2022-08-17 15:56:39"
|
||||
assert downgrade_alert.event["package_name"] == "com.example.app"
|
||||
assert downgrade_alert.event["action"] == "downgrade"
|
||||
assert downgrade_alert.event["previous_vers"] == "10"
|
||||
assert downgrade_alert.event["previous_version_code"] == 10
|
||||
|
||||
def test_newest_first_update_is_not_reported_as_downgrade(self):
|
||||
dba = DumpsysBatteryDailyArtifact()
|
||||
@@ -107,7 +108,19 @@ class TestDumpsysBatteryDailyArtifact:
|
||||
assert downgrade_alert.event_time == "2026-01-10"
|
||||
assert downgrade_alert.event["package_name"] == "com.example.app"
|
||||
assert downgrade_alert.event["action"] == "downgrade"
|
||||
assert downgrade_alert.event["previous_vers"] == "102"
|
||||
assert downgrade_alert.event["previous_version_code"] == 102
|
||||
|
||||
def test_duplicate_updates_retain_occurrence_count(self):
|
||||
dba = DumpsysBatteryDailyArtifact()
|
||||
dba.parse(
|
||||
""" Daily from 2026-01-10-01-02-03 to 2026-01-11-04-05-06:
|
||||
Update com.example.app vers=12
|
||||
Update com.example.app vers=12
|
||||
"""
|
||||
)
|
||||
|
||||
assert dba.results[0]["occurrences"] == 2
|
||||
assert dba.results[0]["period_start"] == "2026-01-10 01:02:03"
|
||||
|
||||
def test_reinstall_after_uninstall_is_not_reported_as_downgrade(self):
|
||||
dba = DumpsysBatteryDailyArtifact()
|
||||
|
||||
@@ -54,6 +54,7 @@ class TestDumpsysBatteryHistoryArtifact:
|
||||
assert len(dba.results) == 2
|
||||
assert dba.results[0] == {
|
||||
"time_elapsed": "07-15 20:27:39.431",
|
||||
"timestamp": "1900-07-15 20:27:39.431000",
|
||||
"event": "start_job",
|
||||
"uid": "u0a123",
|
||||
"package_name": "com.example",
|
||||
@@ -61,3 +62,23 @@ class TestDumpsysBatteryHistoryArtifact:
|
||||
}
|
||||
assert dba.results[1]["event"] == "end_job"
|
||||
assert dba.results[1]["uid"] == "u0a123"
|
||||
|
||||
def test_wake_lock_without_component_is_retained(self):
|
||||
dba = DumpsysBatteryHistoryArtifact()
|
||||
dba.parse(
|
||||
"Battery History:\n"
|
||||
" 0 (2) 100 RESET:TIME: 2025-09-05-01-04-52-139\n"
|
||||
' +1s (2) 100 +running +wake_lock=1000:"*alarm*:TIME_TICK"\n'
|
||||
' +2s (2) 100 +running +wake_lock=u0a1:"*walarm*:com.whatsapp.MessageHandler.LOGOUT_ACTION"\n'
|
||||
"\n"
|
||||
)
|
||||
|
||||
assert [record["event"] for record in dba.results] == ["wake", "wake"]
|
||||
assert dba.results[0]["package_name"] is None
|
||||
assert dba.results[1]["package_name"] == "com.whatsapp"
|
||||
|
||||
def test_decorated_sync_job_uses_component_package(self):
|
||||
dba = DumpsysBatteryHistoryArtifact()
|
||||
dba.parse('+1s (2) 100 +job=u0a1:"@SyncManager@gmail-ls/com.google:android"\n')
|
||||
|
||||
assert dba.results[0]["package_name"] == "com.google"
|
||||
|
||||
@@ -53,9 +53,32 @@ Connection pool for /data/user/0/com.example/databases/current.db:
|
||||
|
||||
assert dbi.results == [
|
||||
{
|
||||
"isodate": "07-15 20:27:39.431",
|
||||
"timestamp": "07-15 20:27:39.431",
|
||||
"pid": None,
|
||||
"action": "executeForCursorWindow",
|
||||
"duration_ms": 1,
|
||||
"status": "succeeded",
|
||||
"sql": "SELECT 1",
|
||||
"path": "/data/user/0/com.example/databases/current.db",
|
||||
"pool_path": "/data/user/0/com.example/databases/current.db",
|
||||
"connection_number": None,
|
||||
"is_primary": None,
|
||||
}
|
||||
]
|
||||
|
||||
def test_parses_operations_from_multiple_connections(self):
|
||||
dbi = DumpsysDBInfoArtifact()
|
||||
dbi.parse(
|
||||
"""Connection pool for /data/example.db:
|
||||
Connection #0:
|
||||
isPrimaryConnection: true
|
||||
Most recently executed operations:
|
||||
0: [2025-01-01 00:00:00.000] execute took 1ms - succeeded, sql="SELECT 1", path=/data/example.db
|
||||
Connection #1:
|
||||
isPrimaryConnection: false
|
||||
Most recently executed operations:
|
||||
0: [2025-01-01 00:00:01.000] execute took 2ms - succeeded, sql="SELECT 2", path=/data/example.db
|
||||
"""
|
||||
)
|
||||
|
||||
assert [record["connection_number"] for record in dbi.results] == [0, 1]
|
||||
|
||||
@@ -21,12 +21,16 @@ class TestDumpsysPackageActivitiesArtifact:
|
||||
|
||||
assert len(dpa.results) == 0
|
||||
dpa.parse(data)
|
||||
assert len(dpa.results) == 4
|
||||
assert dpa.results[0]["package_name"] == "com.samsung.android.app.social"
|
||||
assert len(dpa.results) == 10
|
||||
assert dpa.results[0]["package_name"] == "com.samsung.android.messaging"
|
||||
assert (
|
||||
dpa.results[0]["activity"]
|
||||
== "com.samsung.android.app.social/.feed.FeedsActivity"
|
||||
dpa.results[0]["component"]
|
||||
== "com.samsung.android.messaging/.ui.RcsTransferContent"
|
||||
)
|
||||
assert {result["resolver_type"] for result in dpa.results} == {
|
||||
"full_mime_type",
|
||||
"non_data_action",
|
||||
}
|
||||
|
||||
def test_ioc_check(self, indicator_file):
|
||||
dpa = DumpsysPackageActivitiesArtifact()
|
||||
@@ -41,4 +45,4 @@ class TestDumpsysPackageActivitiesArtifact:
|
||||
dpa.indicators = ind
|
||||
assert len(dpa.alertstore.alerts) == 0
|
||||
dpa.check_indicators()
|
||||
assert len(dpa.alertstore.alerts) == 1
|
||||
assert len(dpa.alertstore.alerts) == 2
|
||||
|
||||
@@ -25,7 +25,11 @@ class TestDumpsysPackagesArtifact:
|
||||
== "com.samsung.android.provider.filterprovider"
|
||||
)
|
||||
assert dpa.results[0]["version_name"] == "5.0.07"
|
||||
assert dpa.results[0]["first_install_time"] == "2008-12-31 16:00:00"
|
||||
assert dpa.results[0]["version_code"] == 500700000
|
||||
assert dpa.results[0]["min_sdk"] == 28
|
||||
assert dpa.results[0]["target_sdk"] == 28
|
||||
assert dpa.results[0]["package_type"] == "active"
|
||||
assert dpa.results[0]["users"][0]["user_id"] == 0
|
||||
assert dpa.results[0]["system"] is True
|
||||
|
||||
def test_parsing_system_flag(self):
|
||||
@@ -60,42 +64,27 @@ class TestDumpsysPackagesArtifact:
|
||||
dpa.check_indicators()
|
||||
assert len(dpa.alertstore.alerts) == 1
|
||||
|
||||
def test_per_user_fields_use_primary_user(self):
|
||||
details = DumpsysPackagesArtifact.parse_dumpsys_package_for_details(
|
||||
""" User 0: installed=true
|
||||
firstInstallTime=2024-01-10 09:19:39
|
||||
runtime permissions:
|
||||
android.permission.CAMERA: granted=true
|
||||
User 95: installed=false
|
||||
firstInstallTime=1970-01-01 01:00:00
|
||||
runtime permissions:
|
||||
android.permission.CAMERA: granted=false
|
||||
android.permission.RECORD_AUDIO: granted=false
|
||||
def test_hidden_packages_and_per_user_state(self):
|
||||
dpa = DumpsysPackagesArtifact()
|
||||
dpa.parse(
|
||||
"""Packages:
|
||||
Package [com.example.active]:
|
||||
appId=10001
|
||||
versionCode=12 minSdk=29 targetSdk=35
|
||||
User 0: installed=true hidden=false
|
||||
firstInstallTime=2025-01-01 01:02:03
|
||||
User 10: installed=false hidden=true
|
||||
firstInstallTime=2025-01-02 01:02:03
|
||||
Hidden system packages:
|
||||
Package [com.example.hidden]:
|
||||
appId=10002
|
||||
installerPackageName=null
|
||||
"""
|
||||
)
|
||||
|
||||
assert details["first_install_time"] == "2024-01-10 09:19:39"
|
||||
runtime_permissions = [
|
||||
permission
|
||||
for permission in details["permissions"]
|
||||
if permission["type"] == "runtime"
|
||||
assert [record["package_type"] for record in dpa.results] == [
|
||||
"active",
|
||||
"hidden_system",
|
||||
]
|
||||
assert runtime_permissions == [
|
||||
{
|
||||
"name": "android.permission.CAMERA",
|
||||
"granted": True,
|
||||
"type": "runtime",
|
||||
}
|
||||
]
|
||||
|
||||
def test_per_user_fields_fall_back_when_user_zero_is_missing(self):
|
||||
details = DumpsysPackagesArtifact.parse_dumpsys_package_for_details(
|
||||
""" User 10: installed=true
|
||||
firstInstallTime=2024-02-10 09:19:39
|
||||
runtime permissions:
|
||||
android.permission.CAMERA: granted=true
|
||||
"""
|
||||
)
|
||||
|
||||
assert details["first_install_time"] == "2024-02-10 09:19:39"
|
||||
assert details["permissions"][-1]["name"] == "android.permission.CAMERA"
|
||||
assert len(dpa.results[0]["users"]) == 2
|
||||
assert dpa.results[1]["installer"] is None
|
||||
|
||||
@@ -22,6 +22,9 @@ class TestDumpsysPlatformCompatArtifact:
|
||||
assert len(dbi.results) == 2
|
||||
assert dbi.results[0]["package_name"] == "org.torproject.torbrowser"
|
||||
assert dbi.results[1]["package_name"] == "org.article19.circulo.next"
|
||||
assert dbi.results[0]["change_id"] == 168419799
|
||||
assert dbi.results[0]["change_name"] == "DOWNSCALED"
|
||||
assert dbi.results[0]["override_value"] is False
|
||||
|
||||
def test_ioc_check(self, indicator_file):
|
||||
dbi = DumpsysPlatformCompatArtifact()
|
||||
|
||||
@@ -19,17 +19,14 @@ class TestDumpsysReceiversArtifact:
|
||||
|
||||
assert len(dr.results) == 0
|
||||
dr.parse(data)
|
||||
assert len(dr.results) == 4
|
||||
assert (
|
||||
list(dr.results.keys())[0]
|
||||
== "com.android.storagemanager.automatic.SHOW_NOTIFICATION"
|
||||
)
|
||||
assert (
|
||||
dr.results["com.android.storagemanager.automatic.SHOW_NOTIFICATION"][0][
|
||||
"package_name"
|
||||
]
|
||||
== "com.android.storagemanager"
|
||||
assert len(dr.results) == 9
|
||||
assert dr.results[0]["resolver_type"] == "full_mime_type"
|
||||
storage_manager = next(
|
||||
result
|
||||
for result in dr.results
|
||||
if result["key"] == "com.android.storagemanager.automatic.SHOW_NOTIFICATION"
|
||||
)
|
||||
assert storage_manager["package_name"] == "com.android.storagemanager"
|
||||
|
||||
def test_parsing_misindented_action(self):
|
||||
dr = DumpsysReceiversArtifact()
|
||||
@@ -44,12 +41,8 @@ Receiver Resolver Table:
|
||||
|
||||
dr.parse(data)
|
||||
|
||||
assert (
|
||||
dr.results["android.intent.action.MY_PACKAGE_REPLACED"][0][
|
||||
"package_name"
|
||||
]
|
||||
== "com.psycatgames.nhiegame"
|
||||
)
|
||||
assert dr.results[1]["key"] == "android.intent.action.MY_PACKAGE_REPLACED"
|
||||
assert dr.results[1]["package_name"] == "com.psycatgames.nhiegame"
|
||||
|
||||
def test_parsing_misindented_first_action(self):
|
||||
dr = DumpsysReceiversArtifact()
|
||||
@@ -62,12 +55,8 @@ Receiver Resolver Table:
|
||||
|
||||
dr.parse(data)
|
||||
|
||||
assert (
|
||||
dr.results["android.intent.action.MY_PACKAGE_REPLACED"][0][
|
||||
"package_name"
|
||||
]
|
||||
== "com.psycatgames.nhiegame"
|
||||
)
|
||||
assert dr.results[0]["key"] == "android.intent.action.MY_PACKAGE_REPLACED"
|
||||
assert dr.results[0]["package_name"] == "com.psycatgames.nhiegame"
|
||||
|
||||
def test_ioc_check(self, indicator_file):
|
||||
dr = DumpsysReceiversArtifact()
|
||||
|
||||
@@ -39,3 +39,29 @@ class TestGetPropArtifact:
|
||||
assert len(gp.alertstore.alerts) == 0
|
||||
gp.check_indicators()
|
||||
assert len(gp.alertstore.alerts) == 1
|
||||
|
||||
def test_empty_values_and_invalid_lines(self):
|
||||
gp = GetProp()
|
||||
gp.parse("[empty]: []\n[valid]: [value]\n0\n[broken]: [value")
|
||||
|
||||
assert gp.results == [
|
||||
{"name": "empty", "value": ""},
|
||||
{"name": "valid", "value": "value"},
|
||||
]
|
||||
|
||||
def test_multiline_value(self):
|
||||
gp = GetProp()
|
||||
gp.parse(
|
||||
"[persist.sys.boot.reason.history]: ["
|
||||
"reboot,ota,1697044974\n"
|
||||
"reboot,watchdog,1696958574]\n"
|
||||
"[ro.build.version.sdk]: [35]\n"
|
||||
)
|
||||
|
||||
assert gp.results == [
|
||||
{
|
||||
"name": "persist.sys.boot.reason.history",
|
||||
"value": "reboot,ota,1697044974\nreboot,watchdog,1696958574",
|
||||
},
|
||||
{"name": "ro.build.version.sdk", "value": "35"},
|
||||
]
|
||||
|
||||
@@ -20,7 +20,7 @@ class TestProcessesArtifact:
|
||||
assert len(p.results) == 0
|
||||
p.parse(data)
|
||||
assert len(p.results) == 17
|
||||
assert p.results[0]["proc_name"] == "init"
|
||||
assert p.results[0]["command"] == "init"
|
||||
|
||||
def test_ioc_check(self, indicator_file):
|
||||
p = Processes()
|
||||
@@ -36,3 +36,14 @@ class TestProcessesArtifact:
|
||||
assert len(p.alertstore.alerts) == 0
|
||||
p.check_indicators()
|
||||
assert len(p.alertstore.alerts) == 1
|
||||
|
||||
def test_bugreport_thread_columns(self):
|
||||
p = Processes()
|
||||
p.parse(
|
||||
"LABEL USER PID TID PPID VSZ RSS WCHAN ADDR S PRI NI RTPRIO SCH PCY TIME CMD\n"
|
||||
"u:r:init:s0 root 1 2 0 100 20 0 0 S 19 0 - 0 fg 00:00:01 init\n"
|
||||
)
|
||||
|
||||
assert p.results[0]["label"] == "u:r:init:s0"
|
||||
assert p.results[0]["tid"] == 2
|
||||
assert p.results[0]["command"] == "init"
|
||||
|
||||
@@ -128,8 +128,5 @@ class TestTombstoneCrashArtifact:
|
||||
assert tombstone_result.get("pid") == 25541
|
||||
assert tombstone_result.get("process_name") == "mtk.ape.decoder"
|
||||
|
||||
# With Android logs we want to keep timestamps as device local time for consistency.
|
||||
# We often don't know the time offset for a log entry and so can't convert everything to UTC.
|
||||
# MVT should output the local time only:
|
||||
# So original 2023-04-12 12:32:40.518290770+0200 -> 2023-04-12 12:32:40.000000
|
||||
assert tombstone_result.get("timestamp") == "2023-04-12 12:32:40.518290"
|
||||
# Tombstones include an explicit offset, so normalize them to UTC.
|
||||
assert tombstone_result.get("timestamp") == "2023-04-12 10:32:40.518290"
|
||||
|
||||
@@ -13,6 +13,19 @@ from ..utils import get_android_androidqf, list_files
|
||||
|
||||
|
||||
class TestAndroidqfMountsArtifact:
|
||||
def test_parse_proc_mountinfo(self):
|
||||
from mvt.android.artifacts.mounts import Mounts as MountsArtifact
|
||||
|
||||
results = MountsArtifact.parse_mountinfo(
|
||||
"41 40 254:13 / / ro,relatime shared:1 - erofs /dev/block/dm-13 ro,seclabel\n",
|
||||
123,
|
||||
)
|
||||
|
||||
assert results[0]["mount_id"] == 41
|
||||
assert results[0]["mount_point"] == "/"
|
||||
assert results[0]["filesystem_type"] == "erofs"
|
||||
assert results[0]["process_ids"] == [123]
|
||||
|
||||
def test_parse_mounts_token_checks(self):
|
||||
"""
|
||||
Test the artifact-level `parse` method using tolerant token checks.
|
||||
|
||||
@@ -6,12 +6,27 @@
|
||||
from pathlib import Path
|
||||
|
||||
from mvt.android.modules.androidqf.aqf_settings import AQFSettings
|
||||
from mvt.android.artifacts.settings import Settings
|
||||
from mvt.common.module import run_module
|
||||
|
||||
from ..utils import get_android_androidqf, list_files
|
||||
|
||||
|
||||
class TestSettingsModule:
|
||||
def test_bugreport_settings_format(self):
|
||||
settings = Settings()
|
||||
settings.parse(
|
||||
"GLOBAL SETTINGS (user 0)\n"
|
||||
"_id:1 name:adb_wifi_enabled pkg:android value:0 default:0 defaultSystemSet:true\n"
|
||||
"SECURE SETTINGS (user 10)\n"
|
||||
"_id:2 name:accessibility_enabled pkg:android value:1\n"
|
||||
)
|
||||
|
||||
assert settings.results == {
|
||||
"global:user_0": {"adb_wifi_enabled": "0"},
|
||||
"secure:user_10": {"accessibility_enabled": "1"},
|
||||
}
|
||||
|
||||
def test_parsing(self):
|
||||
data_path = get_android_androidqf()
|
||||
m = AQFSettings(target_path=data_path)
|
||||
|
||||
@@ -54,10 +54,11 @@ class TestBugreportAnalysis:
|
||||
== "com.samsung.android.provider.filterprovider"
|
||||
)
|
||||
assert m.results[1]["package_name"] == "com.instagram.android"
|
||||
assert m.results[0]["installer"] == ""
|
||||
assert m.results[0]["installer"] is None
|
||||
assert m.results[1]["installer"] == "com.android.vending"
|
||||
assert len(m.results[0]["permissions"]) == 4
|
||||
assert len(m.results[1]["permissions"]) == 32
|
||||
assert len(m.results[1]["permissions"]) == 20
|
||||
assert len(m.results[1]["users"][0]["permissions"]) == 19
|
||||
|
||||
def test_getprop_module(self):
|
||||
m = self.launch_bug_report_module(DumpsysGetProp)
|
||||
@@ -66,29 +67,34 @@ class TestBugreportAnalysis:
|
||||
def test_receivers_match_exact_package_name(self, indicators_factory):
|
||||
intent = "android.intent.action.PHONE_STATE"
|
||||
false_positive = {
|
||||
"resolver_type": "non_data_action",
|
||||
"key": intent,
|
||||
"package_name": "com.android.phone",
|
||||
"receiver": (
|
||||
"component": (
|
||||
"com.android.phone/"
|
||||
"com.android.services.telephony.sip.SipIncomingCallReceiver"
|
||||
),
|
||||
"filter_count": 1,
|
||||
}
|
||||
malicious_receiver = {
|
||||
"resolver_type": "non_data_action",
|
||||
"key": intent,
|
||||
"package_name": "com.android.services",
|
||||
"receiver": "com.android.services/com.example.SomeReceiver",
|
||||
"component": "com.android.services/com.example.SomeReceiver",
|
||||
"filter_count": 1,
|
||||
}
|
||||
module = DumpsysReceivers(
|
||||
results={intent: [false_positive, malicious_receiver]}
|
||||
)
|
||||
module = DumpsysReceivers(results=[false_positive, malicious_receiver])
|
||||
module.indicators = indicators_factory(app_ids=["com.android.services"])
|
||||
|
||||
module.check_indicators()
|
||||
|
||||
assert len(module.alertstore.alerts) == 1
|
||||
alert = module.alertstore.alerts[0]
|
||||
assert alert.event == {intent: malicious_receiver}
|
||||
assert alert.event == malicious_receiver
|
||||
assert alert.matched_indicator.value == "com.android.services"
|
||||
|
||||
def test_tombstones_modules(self):
|
||||
m = self.launch_bug_report_module(Tombstones)
|
||||
assert len(m.results) == 2
|
||||
assert m.results[1]["pid"] == 3559
|
||||
assert m.results[0]["sources"]["text"]["parsed"] is True
|
||||
|
||||
Reference in New Issue
Block a user