mirror of
https://github.com/mvt-project/mvt.git
synced 2026-03-24 12:30:36 +01:00
Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f2d9f420f2 | ||
|
|
e2f8437831 | ||
|
|
0134bf80d1 | ||
|
|
c8f82f796b | ||
|
|
61947d17af | ||
|
|
7173e02a6f |
@@ -14,12 +14,23 @@ class DumpsysBatteryDailyArtifact(AndroidArtifact):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
def serialize(self, record: dict) -> Union[dict, list]:
|
def serialize(self, record: dict) -> Union[dict, list]:
|
||||||
|
action = record.get("action", "update")
|
||||||
|
package_name = record["package_name"]
|
||||||
|
vers = record["vers"]
|
||||||
|
|
||||||
|
if vers == "0":
|
||||||
|
data = f"Recorded uninstall of package {package_name} (vers 0)"
|
||||||
|
elif action == "downgrade":
|
||||||
|
prev_vers = record.get("previous_vers", "unknown")
|
||||||
|
data = f"Recorded downgrade of package {package_name} from vers {prev_vers} to vers {vers}"
|
||||||
|
else:
|
||||||
|
data = f"Recorded update of package {package_name} with vers {vers}"
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"timestamp": record["from"],
|
"timestamp": record["from"],
|
||||||
"module": self.__class__.__name__,
|
"module": self.__class__.__name__,
|
||||||
"event": "battery_daily",
|
"event": "battery_daily",
|
||||||
"data": f"Recorded update of package {record['package_name']} "
|
"data": data,
|
||||||
f"with vers {record['vers']}",
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def check_indicators(self) -> None:
|
def check_indicators(self) -> None:
|
||||||
@@ -36,6 +47,7 @@ class DumpsysBatteryDailyArtifact(AndroidArtifact):
|
|||||||
def parse(self, output: str) -> None:
|
def parse(self, output: str) -> None:
|
||||||
daily = None
|
daily = None
|
||||||
daily_updates = []
|
daily_updates = []
|
||||||
|
package_versions = {} # Track package versions to detect downgrades
|
||||||
for line in output.splitlines():
|
for line in output.splitlines():
|
||||||
if line.startswith(" Daily from "):
|
if line.startswith(" Daily from "):
|
||||||
if len(daily_updates) > 0:
|
if len(daily_updates) > 0:
|
||||||
@@ -64,15 +76,44 @@ class DumpsysBatteryDailyArtifact(AndroidArtifact):
|
|||||||
break
|
break
|
||||||
|
|
||||||
if not already_seen:
|
if not already_seen:
|
||||||
daily_updates.append(
|
update_record = {
|
||||||
{
|
"action": "update",
|
||||||
"action": "update",
|
"from": daily["from"],
|
||||||
"from": daily["from"],
|
"to": daily["to"],
|
||||||
"to": daily["to"],
|
"package_name": package_name,
|
||||||
"package_name": package_name,
|
"vers": vers_nr,
|
||||||
"vers": vers_nr,
|
}
|
||||||
}
|
|
||||||
)
|
# Check for uninstall (version 0)
|
||||||
|
if vers_nr == "0":
|
||||||
|
self.log.warning(
|
||||||
|
"Detected uninstall of package %s (vers 0) on %s",
|
||||||
|
package_name,
|
||||||
|
daily["from"],
|
||||||
|
)
|
||||||
|
# Check for downgrade
|
||||||
|
elif package_name in package_versions:
|
||||||
|
try:
|
||||||
|
current_vers = int(vers_nr)
|
||||||
|
previous_vers = int(package_versions[package_name])
|
||||||
|
if current_vers < previous_vers:
|
||||||
|
update_record["action"] = "downgrade"
|
||||||
|
update_record["previous_vers"] = str(previous_vers)
|
||||||
|
self.log.warning(
|
||||||
|
"Detected downgrade of package %s from vers %d to vers %d on %s",
|
||||||
|
package_name,
|
||||||
|
previous_vers,
|
||||||
|
current_vers,
|
||||||
|
daily["from"],
|
||||||
|
)
|
||||||
|
except ValueError:
|
||||||
|
# If version numbers aren't integers, skip comparison
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Update tracking dictionary
|
||||||
|
package_versions[package_name] = vers_nr
|
||||||
|
|
||||||
|
daily_updates.append(update_record)
|
||||||
|
|
||||||
if len(daily_updates) > 0:
|
if len(daily_updates) > 0:
|
||||||
self.results.extend(daily_updates)
|
self.results.extend(daily_updates)
|
||||||
|
|||||||
@@ -84,13 +84,17 @@ class BugReportModule(MVTModule):
|
|||||||
return self._get_file_content(main_content.decode().strip())
|
return self._get_file_content(main_content.decode().strip())
|
||||||
except KeyError:
|
except KeyError:
|
||||||
return None
|
return None
|
||||||
else:
|
|
||||||
dumpstate_logs = self._get_files_by_pattern("dumpState_*.log")
|
|
||||||
if not dumpstate_logs:
|
|
||||||
return None
|
|
||||||
|
|
||||||
|
dumpstate_logs = self._get_files_by_pattern("dumpState_*.log")
|
||||||
|
if dumpstate_logs:
|
||||||
return self._get_file_content(dumpstate_logs[0])
|
return self._get_file_content(dumpstate_logs[0])
|
||||||
|
|
||||||
|
dumpsys_files = self._get_files_by_pattern("*/dumpsys.txt")
|
||||||
|
if dumpsys_files:
|
||||||
|
return self._get_file_content(dumpsys_files[0])
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
def _get_file_modification_time(self, file_path: str) -> dict:
|
def _get_file_modification_time(self, file_path: str) -> dict:
|
||||||
if self.zip_archive:
|
if self.zip_archive:
|
||||||
file_timetuple = self.zip_archive.getinfo(file_path).date_time
|
file_timetuple = self.zip_archive.getinfo(file_path).date_time
|
||||||
|
|||||||
@@ -34,6 +34,20 @@ class DumpsysReceivers(DumpsysReceiversArtifact, BugReportModule):
|
|||||||
|
|
||||||
self.results = results if results else {}
|
self.results = results if results else {}
|
||||||
|
|
||||||
|
def check_indicators(self) -> None:
|
||||||
|
for result in self.results:
|
||||||
|
if self.indicators:
|
||||||
|
receiver_name = self.results[result][0]["receiver"]
|
||||||
|
|
||||||
|
# return IoC if the stix2 process name a substring of the receiver name
|
||||||
|
ioc = self.indicators.check_receiver_prefix(receiver_name)
|
||||||
|
if ioc:
|
||||||
|
self.results[result][0]["matched_indicator"] = ioc
|
||||||
|
self.detected.append(result)
|
||||||
|
continue
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def run(self) -> None:
|
def run(self) -> None:
|
||||||
content = self._get_dumpstate_file()
|
content = self._get_dumpstate_file()
|
||||||
if not content:
|
if not content:
|
||||||
|
|||||||
@@ -768,6 +768,30 @@ class Indicators:
|
|||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def check_receiver_prefix(self, receiver_name: str) -> Union[dict, None]:
|
||||||
|
"""Check the provided receiver name against the list of indicators.
|
||||||
|
An IoC match is detected when a substring of the receiver matches the indicator
|
||||||
|
:param app_id: App ID to check against the list of indicators
|
||||||
|
:type app_id: str
|
||||||
|
:returns: Indicator details if matched, otherwise None
|
||||||
|
|
||||||
|
"""
|
||||||
|
if not receiver_name:
|
||||||
|
return None
|
||||||
|
|
||||||
|
for ioc in self.get_iocs("app_ids"):
|
||||||
|
if ioc["value"].lower() in receiver_name.lower():
|
||||||
|
self.log.warning(
|
||||||
|
'Found a known suspicious receiver with name "%s" '
|
||||||
|
'matching indicators from "%s"',
|
||||||
|
receiver_name,
|
||||||
|
ioc["name"],
|
||||||
|
)
|
||||||
|
return ioc
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
def check_android_property_name(self, property_name: str) -> Optional[dict]:
|
def check_android_property_name(self, property_name: str) -> Optional[dict]:
|
||||||
"""Check the android property name against the list of indicators.
|
"""Check the android property name against the list of indicators.
|
||||||
|
|
||||||
|
|||||||
@@ -631,6 +631,10 @@
|
|||||||
"build": "16H81",
|
"build": "16H81",
|
||||||
"version": "12.5.7"
|
"version": "12.5.7"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"version": "12.5.8",
|
||||||
|
"build": "16H88"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"build": "17A577",
|
"build": "17A577",
|
||||||
"version": "13.0"
|
"version": "13.0"
|
||||||
@@ -899,6 +903,10 @@
|
|||||||
"version": "15.8.5",
|
"version": "15.8.5",
|
||||||
"build": "19H394"
|
"build": "19H394"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"version": "15.8.6",
|
||||||
|
"build": "19H402"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"build": "20A362",
|
"build": "20A362",
|
||||||
"version": "16.0"
|
"version": "16.0"
|
||||||
@@ -1008,6 +1016,10 @@
|
|||||||
"version": "16.7.12",
|
"version": "16.7.12",
|
||||||
"build": "20H364"
|
"build": "20H364"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"version": "16.7.14",
|
||||||
|
"build": "20H370"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"version": "17.0",
|
"version": "17.0",
|
||||||
"build": "21A327"
|
"build": "21A327"
|
||||||
@@ -1164,6 +1176,18 @@
|
|||||||
"version": "18.7.3",
|
"version": "18.7.3",
|
||||||
"build": "22H217"
|
"build": "22H217"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"version": "18.7.4",
|
||||||
|
"build": "22H218"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"version": "18.7.5",
|
||||||
|
"build": "22H311"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"version": "18.7.6",
|
||||||
|
"build": "22H320"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"version": "26",
|
"version": "26",
|
||||||
"build": "23A341"
|
"build": "23A341"
|
||||||
@@ -1179,5 +1203,17 @@
|
|||||||
{
|
{
|
||||||
"version": "26.2",
|
"version": "26.2",
|
||||||
"build": "23C55"
|
"build": "23C55"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"version": "26.2.1",
|
||||||
|
"build": "23C71"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"version": "26.3",
|
||||||
|
"build": "23D127"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"version": "26.3.1",
|
||||||
|
"build": "23D8133"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
Reference in New Issue
Block a user