mirror of
https://github.com/mvt-project/mvt.git
synced 2026-09-14 21:55:27 +02:00
Merge branch 'main' into fix/settings-env-persist
This commit is contained in:
@@ -0,0 +1,170 @@
|
||||
# Mobile Verification Toolkit (MVT)
|
||||
# Copyright (c) 2021-2023 The MVT Authors.
|
||||
# Use of this software is governed by the MVT License 1.1 that can be found at
|
||||
# https://license.mvt.re/1.1/
|
||||
|
||||
from mvt.android.artifacts.settings import Settings
|
||||
|
||||
from ..utils import get_artifact
|
||||
|
||||
|
||||
def parse_bugreport_settings() -> Settings:
|
||||
settings = Settings()
|
||||
with open(get_artifact("android_data/bugreport/dumpstate.txt")) as handle:
|
||||
data = handle.read()
|
||||
|
||||
settings.parse(settings.extract_dumpsys_section(data, "DUMP OF SERVICE settings:"))
|
||||
return settings
|
||||
|
||||
|
||||
def find(settings: Settings, name: str) -> list:
|
||||
return [result for result in settings.results if result["name"] == name]
|
||||
|
||||
|
||||
class TestSettingsArtifact:
|
||||
def test_parsing(self):
|
||||
settings = parse_bugreport_settings()
|
||||
|
||||
assert len(settings.results) == 12
|
||||
assert {result["namespace"] for result in settings.results} == {
|
||||
"config",
|
||||
"global",
|
||||
"secure",
|
||||
}
|
||||
assert settings.results[0] == {
|
||||
"namespace": "config",
|
||||
"user": "0",
|
||||
"_id": "682",
|
||||
"name": "namespace_one/blocked_components",
|
||||
"pkg": "com.example.services",
|
||||
"value": (
|
||||
"com.android.settings,com.android.vending,\n"
|
||||
"com.example.dialer,\n"
|
||||
"com.example.camera"
|
||||
),
|
||||
"default": (
|
||||
"com.android.settings,\n"
|
||||
" com.android.vending,\n"
|
||||
" com.example.dialer"
|
||||
),
|
||||
"defaultSystemSet": "false",
|
||||
"history": [],
|
||||
}
|
||||
|
||||
def test_multiline_values_are_kept_whole(self):
|
||||
settings = parse_bugreport_settings()
|
||||
|
||||
assert find(settings, "namespace_one/allowed_packages")[0]["value"] == (
|
||||
"com.example.messaging,\ncom.example.chat"
|
||||
)
|
||||
assert find(settings, "widget_instance_data")[0]["value"] == (
|
||||
'{\n "version": 1,\n "data": [\n {\n "number": 10000,\n'
|
||||
' "package_name": "com.example.widget"\n }\n ]\n}'
|
||||
)
|
||||
|
||||
def test_trailing_default_is_not_part_of_the_value(self):
|
||||
settings = parse_bugreport_settings()
|
||||
|
||||
record = find(settings, "namespace_one/streaming_blocked_components")[0]
|
||||
assert record["value"] == "com.example.dialer,com.example.camera"
|
||||
assert record["default"] == "com.android.settings,\n com.android.vending"
|
||||
|
||||
def test_trailing_metadata_is_not_part_of_the_value(self):
|
||||
settings = parse_bugreport_settings()
|
||||
|
||||
record = find(settings, "lock_screen_show_notifications")[0]
|
||||
assert record["value"] == "1"
|
||||
assert record["defaultSystemSet"] == "true"
|
||||
assert record["isValuePreservedInRestore"] == "true"
|
||||
|
||||
# Without a default, the tag or the restore token follows the value.
|
||||
record = find(settings, "accessibility_enabled")[1]
|
||||
assert record["value"] == "0"
|
||||
assert record["tag"] == "null"
|
||||
assert "default" not in record
|
||||
|
||||
record = find(settings, "send_action_app_error")[0]
|
||||
assert record["value"] == "1"
|
||||
assert record["isValuePreservedInRestore"] == "false"
|
||||
|
||||
def test_dumps_after_the_last_block_are_not_part_of_the_last_row(self):
|
||||
settings = parse_bugreport_settings()
|
||||
|
||||
assert settings.results[-1] == {
|
||||
"namespace": "secure",
|
||||
"user": "10",
|
||||
"_id": "311",
|
||||
"name": "accessibility_enabled",
|
||||
"pkg": "android",
|
||||
"value": "0",
|
||||
"tag": "null",
|
||||
"history": [],
|
||||
}
|
||||
|
||||
def test_repeated_names_are_kept_as_separate_records(self):
|
||||
settings = parse_bugreport_settings()
|
||||
|
||||
widgets = find(settings, "widget_instance_data")
|
||||
assert [record["_id"] for record in widgets] == ["771", "41654"]
|
||||
|
||||
accessibility = find(settings, "accessibility_enabled")
|
||||
assert [(record["user"], record["value"]) for record in accessibility] == [
|
||||
("0", "1"),
|
||||
("10", "0"),
|
||||
]
|
||||
|
||||
def test_setting_without_recording_package(self):
|
||||
settings = parse_bugreport_settings()
|
||||
|
||||
record = find(settings, "hidden_api_blacklist_exemptions")[0]
|
||||
assert "pkg" not in record
|
||||
assert record["value"] == "{null}"
|
||||
|
||||
def test_history_timestamps_resolved_against_section_end(self):
|
||||
settings = parse_bugreport_settings()
|
||||
|
||||
# The section was dumped on 2022-03-29, so an 11-02 entry belongs to
|
||||
# the previous year and an 03-14 entry to the same year.
|
||||
assert find(settings, "development_settings_enabled")[0]["history"] == [
|
||||
{
|
||||
"timestamp": "2021-11-02 11:21:22.212000",
|
||||
"oldValue": "null",
|
||||
"newValue": "1",
|
||||
"pkg": "com.android.settings",
|
||||
},
|
||||
{
|
||||
"timestamp": "2022-03-14 09:02:11.100000",
|
||||
"oldValue": "1",
|
||||
"newValue": "0",
|
||||
"pkg": "com.example.updater",
|
||||
},
|
||||
]
|
||||
|
||||
def test_history_without_a_section_end_has_no_timestamp(self):
|
||||
settings = Settings()
|
||||
settings.parse(
|
||||
"SECURE SETTINGS (user 0)\n"
|
||||
"_id:240 name:accessibility_enabled pkg:android value:1\n"
|
||||
"\tHistory (accessibility_enabled)\n"
|
||||
"\t\ttime:03-28 22:41:07.980 mode:update oldValue:0 newValue:1 "
|
||||
"package:com.example.helper\n"
|
||||
)
|
||||
|
||||
assert settings.results[0]["history"] == [
|
||||
{
|
||||
"timestamp": None,
|
||||
"oldValue": "0",
|
||||
"newValue": "1",
|
||||
"pkg": "com.example.helper",
|
||||
}
|
||||
]
|
||||
|
||||
def test_dangerous_setting_is_detected_with_the_changing_package(self):
|
||||
settings = parse_bugreport_settings()
|
||||
settings.check_indicators()
|
||||
|
||||
assert len(settings.alertstore.alerts) == 1
|
||||
alert = settings.alertstore.alerts[0]
|
||||
assert "accessibility_enabled = 1" in alert.message
|
||||
assert alert.event_time == "2022-03-28 22:41:07.980000"
|
||||
assert alert.event["history"][0]["pkg"] == "com.example.helper"
|
||||
@@ -6,27 +6,12 @@
|
||||
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)
|
||||
@@ -34,7 +19,13 @@ class TestSettingsModule:
|
||||
parent_path = Path(data_path).absolute().parent.as_posix()
|
||||
m.from_dir(parent_path, files)
|
||||
run_module(m)
|
||||
assert len(m.results) == 1
|
||||
assert "random" in m.results.keys()
|
||||
assert len(m.results) == 9
|
||||
assert {result["namespace"] for result in m.results} == {"random"}
|
||||
assert m.results[0] == {
|
||||
"namespace": "random",
|
||||
"user": None,
|
||||
"name": "samsung_errorlog_agree",
|
||||
"value": "0",
|
||||
}
|
||||
assert len(m.alertstore.alerts) == 1
|
||||
assert "samsung_errorlog_agree" in m.alertstore.alerts[0].message
|
||||
|
||||
@@ -10,6 +10,7 @@ from mvt.android.modules.bugreport.dumpsys_appops import DumpsysAppops
|
||||
from mvt.android.modules.bugreport.dumpsys_getprop import DumpsysGetProp
|
||||
from mvt.android.modules.bugreport.dumpsys_packages import DumpsysPackages
|
||||
from mvt.android.modules.bugreport.dumpsys_receivers import DumpsysReceivers
|
||||
from mvt.android.modules.bugreport.settings import Settings
|
||||
from mvt.android.modules.bugreport.tombstones import Tombstones
|
||||
from mvt.common.module import run_module
|
||||
|
||||
@@ -93,6 +94,25 @@ class TestBugreportAnalysis:
|
||||
assert alert.event == malicious_receiver
|
||||
assert alert.matched_indicator.value == "com.android.services"
|
||||
|
||||
def test_settings_module(self):
|
||||
m = self.launch_bug_report_module(Settings)
|
||||
assert len(m.results) == 12
|
||||
|
||||
assert len(m.alertstore.alerts) == 1
|
||||
assert "accessibility_enabled = 1" in m.alertstore.alerts[0].message
|
||||
|
||||
assert len(m.timeline) == 3
|
||||
change = [
|
||||
entry
|
||||
for entry in m.timeline
|
||||
if entry["timestamp"] == "2022-03-28 22:41:07.980000"
|
||||
][0]
|
||||
assert change["event"] == "settings_change"
|
||||
assert change["data"] == (
|
||||
'secure setting "accessibility_enabled" changed from "0" to "1" '
|
||||
"by com.example.helper"
|
||||
)
|
||||
|
||||
def test_tombstones_modules(self):
|
||||
m = self.launch_bug_report_module(Tombstones)
|
||||
assert len(m.results) == 2
|
||||
|
||||
@@ -264,5 +264,53 @@ ChangeId(143539591; name=SELINUX_LATEST_CHANGES; disabled)
|
||||
ChangeId(247079863; name=DISALLOW_INVALID_GROUP_REFERENCE; enableSinceTargetSdk=34)
|
||||
ChangeId(174227820; name=FORCE_DISABLE_HEVC_SUPPORT; disabled)
|
||||
ChangeId(168419799; name=DOWNSCALED; disabled; packageOverrides={com.google.android.apps.tachyon=false, org.torproject.torbrowser=false}; rawOverrides={org.torproject.torbrowser=false, org.article19.circulo.next=false}; overridable)
|
||||
-------------------------------------------------------------------------------
|
||||
DUMP OF SERVICE settings:
|
||||
CONFIG SETTINGS (user 0)
|
||||
_id:682 name:namespace_one/blocked_components pkg:com.example.services value:com.android.settings,com.android.vending,
|
||||
com.example.dialer,
|
||||
com.example.camera default:com.android.settings,
|
||||
com.android.vending,
|
||||
com.example.dialer defaultSystemSet:false
|
||||
_id:684 name:namespace_one/streaming_blocked_components pkg:com.example.services value:com.example.dialer,com.example.camera default:com.android.settings,
|
||||
com.android.vending defaultSystemSet:false
|
||||
_id:680 name:namespace_one/allowed_packages pkg:com.example.services value:com.example.messaging,
|
||||
com.example.chat
|
||||
|
||||
GLOBAL SETTINGS (user 0)
|
||||
_id:2070 name:adb_wifi_enabled pkg:android value:0 default:0 defaultSystemSet:true
|
||||
_id:778 name:hidden_api_blacklist_exemptions value:{null}
|
||||
_id:9640 name:send_action_app_error pkg:android value:1 notPreservedInRestore
|
||||
_id:9631 name:development_settings_enabled pkg:com.android.settings value:1 default:1 defaultSystemSet:true
|
||||
History (development_settings_enabled)
|
||||
time:11-02 11:21:22.212 mode:update oldValue:null newValue:1 package:com.android.settings
|
||||
time:03-14 09:02:11.100 mode:update oldValue:1 newValue:0 package:com.example.updater
|
||||
_id:771 name:widget_instance_data pkg:com.android.systemui value:{
|
||||
"version": 1,
|
||||
"data": [
|
||||
{
|
||||
"number": 10000,
|
||||
"package_name": "com.example.widget"
|
||||
}
|
||||
]
|
||||
} defaultSystemSet:true
|
||||
_id:41654 name:widget_instance_data pkg:com.android.systemui value:{
|
||||
"version": 3,
|
||||
"data": []
|
||||
} defaultSystemSet:true
|
||||
|
||||
SECURE SETTINGS (user 0)
|
||||
_id:907 name:lock_screen_show_notifications pkg:com.android.settings value:1 default:1 defaultSystemSet:true isValuePreservedInRestore:true
|
||||
_id:240 name:accessibility_enabled pkg:android value:1 default:0 defaultSystemSet:true
|
||||
History (accessibility_enabled)
|
||||
time:03-28 22:41:07.980 mode:update oldValue:0 newValue:1 package:com.example.helper
|
||||
|
||||
SECURE SETTINGS (user 10)
|
||||
_id:311 name:accessibility_enabled pkg:android value:0 tag:null
|
||||
|
||||
GENERATION REGISTRY
|
||||
Maximum number of backing stores:8
|
||||
Number of backing stores:1
|
||||
_Backing store for type:SETTINGS_SECURE user:10 size:1024 cachedEntries:1
|
||||
|
||||
--------- 0.019s was the duration of dumpsys settings, ending at: 2022-03-29 23:14:28
|
||||
|
||||
Reference in New Issue
Block a user