mirror of
https://github.com/mvt-project/mvt.git
synced 2026-10-12 18:57:45 +02:00
Merge branch 'main' into feature/config-file
This commit is contained in:
commit
086871e21d
7 files changed
+79
-11
No files matched your search
@@ -11,6 +11,10 @@ from mvt.common.utils import convert_datetime_to_iso
|
|||||||
from .artifact import AndroidArtifact
|
from .artifact import AndroidArtifact
|
||||||
|
|
||||||
|
|
||||||
|
RISKY_PERMISSIONS = ["REQUEST_INSTALL_PACKAGES"]
|
||||||
|
RISKY_PACKAGES = ["com.android.shell"]
|
||||||
|
|
||||||
|
|
||||||
class DumpsysAppopsArtifact(AndroidArtifact):
|
class DumpsysAppopsArtifact(AndroidArtifact):
|
||||||
"""
|
"""
|
||||||
Parser for dumpsys app ops info
|
Parser for dumpsys app ops info
|
||||||
@@ -45,15 +49,39 @@ class DumpsysAppopsArtifact(AndroidArtifact):
|
|||||||
self.detected.append(result)
|
self.detected.append(result)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
detected_permissions = []
|
||||||
for perm in result["permissions"]:
|
for perm in result["permissions"]:
|
||||||
if (
|
if (
|
||||||
perm["name"] == "REQUEST_INSTALL_PACKAGES"
|
perm["name"] in RISKY_PERMISSIONS
|
||||||
and perm["access"] == "allow"
|
# and perm["access"] == "allow"
|
||||||
):
|
):
|
||||||
self.log.info(
|
detected_permissions.append(perm)
|
||||||
"Package %s with REQUEST_INSTALL_PACKAGES permission",
|
for entry in sorted(perm["entries"], key=lambda x: x["timestamp"]):
|
||||||
result["package_name"],
|
self.log.warning(
|
||||||
)
|
"Package '%s' had risky permission '%s' set to '%s' at %s",
|
||||||
|
result["package_name"],
|
||||||
|
perm["name"],
|
||||||
|
entry["access"],
|
||||||
|
entry["timestamp"],
|
||||||
|
)
|
||||||
|
|
||||||
|
elif result["package_name"] in RISKY_PACKAGES:
|
||||||
|
detected_permissions.append(perm)
|
||||||
|
for entry in sorted(perm["entries"], key=lambda x: x["timestamp"]):
|
||||||
|
self.log.warning(
|
||||||
|
"Risky package '%s' had '%s' permission set to '%s' at %s",
|
||||||
|
result["package_name"],
|
||||||
|
perm["name"],
|
||||||
|
entry["access"],
|
||||||
|
entry["timestamp"],
|
||||||
|
)
|
||||||
|
|
||||||
|
if detected_permissions:
|
||||||
|
# We clean the result to only include the risky permission, otherwise the timeline
|
||||||
|
# will be polluted with all the other irrelevant permissions
|
||||||
|
cleaned_result = result.copy()
|
||||||
|
cleaned_result["permissions"] = detected_permissions
|
||||||
|
self.detected.append(cleaned_result)
|
||||||
|
|
||||||
def parse(self, output: str) -> None:
|
def parse(self, output: str) -> None:
|
||||||
self.results: List[Dict[str, Any]] = []
|
self.results: List[Dict[str, Any]] = []
|
||||||
@@ -121,11 +149,16 @@ class DumpsysAppopsArtifact(AndroidArtifact):
|
|||||||
if line.startswith(" "):
|
if line.startswith(" "):
|
||||||
# Permission entry like:
|
# Permission entry like:
|
||||||
# Reject: [fg-s]2021-05-19 22:02:52.054 (-314d1h25m2s33ms)
|
# Reject: [fg-s]2021-05-19 22:02:52.054 (-314d1h25m2s33ms)
|
||||||
|
access_type = line.split(":")[0].strip()
|
||||||
|
if access_type not in ["Access", "Reject"]:
|
||||||
|
# Skipping invalid access type. Some entries are not in the format we expect
|
||||||
|
continue
|
||||||
|
|
||||||
if entry:
|
if entry:
|
||||||
perm["entries"].append(entry)
|
perm["entries"].append(entry)
|
||||||
entry = {}
|
entry = {}
|
||||||
|
|
||||||
entry["access"] = line.split(":")[0].strip()
|
entry["access"] = access_type
|
||||||
entry["type"] = line[line.find("[") + 1 : line.find("]")]
|
entry["type"] = line[line.find("[") + 1 : line.find("]")]
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|||||||
@@ -16,6 +16,11 @@ ANDROID_DANGEROUS_SETTINGS = [
|
|||||||
"key": "package_verifier_enable",
|
"key": "package_verifier_enable",
|
||||||
"safe_value": "1",
|
"safe_value": "1",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"description": "disabled APK package verification",
|
||||||
|
"key": "package_verifier_state",
|
||||||
|
"safe_value": "1",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"description": "disabled Google Play Protect",
|
"description": "disabled Google Play Protect",
|
||||||
"key": "package_verifier_user_consent",
|
"key": "package_verifier_user_consent",
|
||||||
|
|||||||
@@ -3,4 +3,4 @@
|
|||||||
# Use of this software is governed by the MVT License 1.1 that can be found at
|
# Use of this software is governed by the MVT License 1.1 that can be found at
|
||||||
# https://license.mvt.re/1.1/
|
# https://license.mvt.re/1.1/
|
||||||
|
|
||||||
MVT_VERSION = "2.5.4"
|
MVT_VERSION = "2.6.0"
|
||||||
@@ -1099,5 +1099,9 @@
|
|||||||
{
|
{
|
||||||
"version": "18.2.1",
|
"version": "18.2.1",
|
||||||
"build": "22C161"
|
"build": "22C161"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"version": "18.3",
|
||||||
|
"build": "22D63"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -43,5 +43,21 @@ class TestDumpsysAppopsArtifact:
|
|||||||
ind.ioc_collections[0]["app_ids"].append("com.facebook.katana")
|
ind.ioc_collections[0]["app_ids"].append("com.facebook.katana")
|
||||||
da.indicators = ind
|
da.indicators = ind
|
||||||
assert len(da.detected) == 0
|
assert len(da.detected) == 0
|
||||||
|
|
||||||
da.check_indicators()
|
da.check_indicators()
|
||||||
assert len(da.detected) == 1
|
detected_by_ioc = [
|
||||||
|
detected for detected in da.detected if detected.get("matched_indicator")
|
||||||
|
]
|
||||||
|
detected_by_permission_heuristic = [
|
||||||
|
detected
|
||||||
|
for detected in da.detected
|
||||||
|
if all(
|
||||||
|
[
|
||||||
|
perm["name"] == "REQUEST_INSTALL_PACKAGES"
|
||||||
|
for perm in detected["permissions"]
|
||||||
|
]
|
||||||
|
)
|
||||||
|
]
|
||||||
|
assert len(da.detected) == 3
|
||||||
|
assert len(detected_by_ioc) == 1
|
||||||
|
assert len(detected_by_permission_heuristic) == 2
|
||||||
@@ -21,4 +21,9 @@ class TestDumpsysAppOpsModule:
|
|||||||
run_module(m)
|
run_module(m)
|
||||||
assert len(m.results) == 12
|
assert len(m.results) == 12
|
||||||
assert len(m.timeline) == 16
|
assert len(m.timeline) == 16
|
||||||
assert len(m.detected) == 0
|
|
||||||
|
detected_by_ioc = [
|
||||||
|
detected for detected in m.detected if detected.get("matched_indicator")
|
||||||
|
]
|
||||||
|
assert len(m.detected) == 1
|
||||||
|
assert len(detected_by_ioc) == 0
|
||||||
@@ -33,7 +33,12 @@ class TestBugreportAnalysis:
|
|||||||
m = self.launch_bug_report_module(Appops)
|
m = self.launch_bug_report_module(Appops)
|
||||||
assert len(m.results) == 12
|
assert len(m.results) == 12
|
||||||
assert len(m.timeline) == 16
|
assert len(m.timeline) == 16
|
||||||
assert len(m.detected) == 0
|
|
||||||
|
detected_by_ioc = [
|
||||||
|
detected for detected in m.detected if detected.get("matched_indicator")
|
||||||
|
]
|
||||||
|
assert len(m.detected) == 1 # Hueristic detection for suspicious permissions
|
||||||
|
assert len(detected_by_ioc) == 0
|
||||||
|
|
||||||
def test_packages_module(self):
|
def test_packages_module(self):
|
||||||
m = self.launch_bug_report_module(Packages)
|
m = self.launch_bug_report_module(Packages)
|
||||||
|
|||||||
Reference in new issue
Block a user