Remove duplicated detection logic from GetProp modules

This commit is contained in:
Donncha Ó Cearbhaill 2023-07-21 11:08:20 +02:00
parent 76d7534b05
commit 94de174563
5 changed files with 66 additions and 79 deletions

View File

@ -4,15 +4,15 @@
# https://license.mvt.re/1.1/
import logging
from datetime import datetime, timedelta
from typing import Optional
from mvt.android.modules.detection_mixins import GetPropDetectionMixin
from mvt.android.parsers import parse_getprop
from .base import AndroidExtraction
class Getprop(AndroidExtraction):
class Getprop(GetPropDetectionMixin, AndroidExtraction):
"""This module extracts device properties from getprop command."""
def __init__(
@ -35,33 +35,10 @@ class Getprop(AndroidExtraction):
self.results = {} if not results else results
def check_indicators(self) -> None:
if not self.indicators:
return
for result in self.results:
ioc = self.indicators.check_android_property_name(result.get("name", ""))
if ioc:
result["matched_indicator"] = ioc
self.detected.append(result)
def run(self) -> None:
self._adb_connect()
output = self._adb_command("getprop")
self._adb_disconnect()
self.results = parse_getprop(output)
# Alert if phone is outdated.
for entry in self.results:
if entry.get("name", "") != "ro.build.version.security_patch":
continue
patch_date = datetime.strptime(entry["value"], "%Y-%m-%d")
if (datetime.now() - patch_date) > timedelta(days=6 * 30):
self.log.warning(
"This phone has not received security updates "
"for more than six months (last update: %s)",
entry["value"],
)
self.log.info("Extracted %d Android system properties", len(self.results))

View File

@ -4,29 +4,15 @@
# https://license.mvt.re/1.1/
import logging
from datetime import datetime, timedelta
from typing import Optional
from mvt.android.modules.detection_mixins import GetPropDetectionMixin
from mvt.android.parsers.getprop import parse_getprop
from .base import AndroidQFModule
INTERESTING_PROPERTIES = [
"gsm.sim.operator.alpha",
"gsm.sim.operator.iso-country",
"persist.sys.timezone",
"ro.boot.serialno",
"ro.build.version.sdk",
"ro.build.version.security_patch",
"ro.product.cpu.abi",
"ro.product.locale",
"ro.product.vendor.manufacturer",
"ro.product.vendor.model",
"ro.product.vendor.name",
]
class Getprop(AndroidQFModule):
class Getprop(GetPropDetectionMixin, AndroidQFModule):
"""This module extracts data from get properties."""
def __init__(
@ -48,16 +34,6 @@ class Getprop(AndroidQFModule):
)
self.results = []
def check_indicators(self) -> None:
if not self.indicators:
return
for result in self.results:
ioc = self.indicators.check_android_property_name(result.get("name", ""))
if ioc:
result["matched_indicator"] = ioc
self.detected.append(result)
def run(self) -> None:
getprop_files = self._get_files_by_pattern("*/getprop.txt")
if not getprop_files:
@ -68,17 +44,4 @@ class Getprop(AndroidQFModule):
data = f.read()
self.results = parse_getprop(data)
for entry in self.results:
if entry["name"] in INTERESTING_PROPERTIES:
self.log.info("%s: %s", entry["name"], entry["value"])
if entry["name"] == "ro.build.version.security_patch":
last_patch = datetime.strptime(entry["value"], "%Y-%m-%d")
if (datetime.now() - last_patch) > timedelta(days=6 * 31):
self.log.warning(
"This phone has not received security "
"updates for more than six months "
"(last update: %s)",
entry["value"],
)
self.log.info("Extracted a total of %d properties", len(self.results))

View File

@ -4,15 +4,15 @@
# https://license.mvt.re/1.1/
import logging
from datetime import datetime, timedelta
from typing import Optional
from mvt.android.modules.detection_mixins import GetPropDetectionMixin
from mvt.android.parsers import parse_getprop
from .base import BugReportModule
class Getprop(BugReportModule):
class Getprop(GetPropDetectionMixin, BugReportModule):
"""This module extracts device properties from getprop command."""
def __init__(
@ -61,17 +61,4 @@ class Getprop(BugReportModule):
lines.append(line)
self.results = parse_getprop("\n".join(lines))
# Alert if phone is outdated.
for entry in self.results:
if entry["name"] == "ro.build.version.security_patch":
security_patch = entry["value"]
patch_date = datetime.strptime(security_patch, "%Y-%m-%d")
if (datetime.now() - patch_date) > timedelta(days=6 * 30):
self.log.warning(
"This phone has not received security updates "
"for more than six months (last update: %s)",
security_patch,
)
self.log.info("Extracted %d Android system properties", len(self.results))

View File

@ -0,0 +1,41 @@
# Mobile Verification Toolkit (MVT)
# Copyright (c) 2021-2023 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/
from mvt.android.utils import warn_android_patch_level
INTERESTING_PROPERTIES = [
"gsm.sim.operator.alpha",
"gsm.sim.operator.iso-country",
"persist.sys.timezone",
"ro.boot.serialno",
"ro.build.version.sdk",
"ro.build.version.security_patch",
"ro.product.cpu.abi",
"ro.product.locale",
"ro.product.vendor.manufacturer",
"ro.product.vendor.model",
"ro.product.vendor.name",
]
class GetPropDetectionMixin(object):
"""Mixin to have cosistent detection logic across various extraction modules."""
def check_indicators(self) -> None:
for entry in self.results:
if entry["name"] in INTERESTING_PROPERTIES:
self.log.info("%s: %s", entry["name"], entry["value"])
if entry["name"] == "ro.build.version.security_patch":
warn_android_patch_level(entry["value"], self.log)
if not self.indicators:
return
for result in self.results:
ioc = self.indicators.check_android_property_name(result.get("name", ""))
print(result.get("name", ""), ioc)
if ioc:
result["matched_indicator"] = ioc
self.detected.append(result)

19
mvt/android/utils.py Normal file
View File

@ -0,0 +1,19 @@
# Mobile Verification Toolkit (MVT)
# Copyright (c) 2021-2023 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/
from datetime import datetime, timedelta
def warn_android_patch_level(patch_level: str, log) -> bool:
"""Alert if Android patch level out-of-date"""
patch_date = datetime.strptime(patch_level, "%Y-%m-%d")
if (datetime.now() - patch_date) > timedelta(months=6):
log.warning(
"This phone has not received security updates "
"for more than six months (last update: %s)",
patch_level,
)
return True
return False