1
mirror of https://github.com/mvt-project/mvt synced 2025-10-21 22:42:15 +02:00

Compare commits

...

13 Commits

Author SHA1 Message Date
Rory Flynn
cf5cf3b85d Mark 2.5.4 release (#504) 2024-06-21 14:51:16 +02:00
Rory Flynn
f0dbe0bfa6 Prevent command.log from being appended to when run in a loop (#501)
* Prevent command.log from being appended to when run in a loop

* Ignore a rather stupid vulnerability scan alert for pip
2024-05-27 19:15:32 +02:00
github-actions[bot]
555e49fda7 Add new iOS versions and build numbers (#499)
Co-authored-by: DonnchaC <DonnchaC@users.noreply.github.com>
2024-05-20 23:12:04 +02:00
Rory Flynn
a6d32e1c88 Fix dumpsys accessibility detections for v14+ (#483) 2024-05-19 22:27:28 +02:00
github-actions[bot]
f155146f1e Add new iOS versions and build numbers (#498)
Co-authored-by: DonnchaC <DonnchaC@users.noreply.github.com>
2024-05-14 10:58:00 +02:00
Tek
9d47acc228 Returns empty string when no date in date converter (#493) 2024-04-30 16:51:58 +02:00
Rory Flynn
cbd41b2aff Mark 2.5.3 release (#490) 2024-04-19 17:23:55 +02:00
Rory Flynn
0509eaa162 Use backwards-compatible datetime.timezone.utc (#488) 2024-04-19 17:22:10 +02:00
Rory Flynn
59e6dff1e1 Fail builds on test failure (#489)
* Fail builds on test failure

* Deliberately fail a build to test

* Revert "Deliberately fail a build to test"

This reverts commit 666140a954.
2024-04-19 17:18:27 +02:00
Rory Flynn
f1821d1a02 Mark release 2.5.2 (#486) 2024-04-18 16:53:41 +02:00
Rory Flynn
6c7ad0ac95 Convert timezone-aware datetimes automatically to UTC (#485) 2024-04-18 16:49:30 +02:00
tek
3a997d30d2 Updates SMS module to highlight new text of Apple notifications 2024-04-15 23:28:36 +02:00
tek
6f56939dd7 Requires latest cryptography version 2024-04-15 22:41:01 +02:00
13 changed files with 139 additions and 10 deletions

View File

@@ -40,7 +40,9 @@ jobs:
- name: Safety checks
run: safety check
- name: Test with pytest and coverage
run: pytest --junitxml=pytest.xml --cov-report=term-missing:skip-covered --cov=mvt tests/ | tee pytest-coverage.txt
run: |
set -o pipefail
pytest --junitxml=pytest.xml --cov-report=term-missing:skip-covered --cov=mvt tests/ | tee pytest-coverage.txt
- name: Pytest coverage comment
continue-on-error: true # Workflows running on a fork can't post comments
uses: MishaKav/pytest-coverage-comment@main

9
.safety-policy.yml Normal file
View File

@@ -0,0 +1,9 @@
# Safety Security and License Configuration file
# We recommend checking this file into your source control in the root of your Python project
# If this file is named .safety-policy.yml and is in the same directory where you run `safety check` it will be used by default.
# Otherwise, you can use the flag `safety check --policy-file <path-to-this-file>` to specify a custom location and name for the file.
# To validate and review your policy file, run the validate command: `safety validate policy_file --path <path-to-this-file>`
security: # configuration for the `safety check` command
ignore-vulnerabilities: # Here you can list multiple specific vulnerabilities you want to ignore (optionally for a time period)
67599: # Example vulnerability ID
reason: disputed, inapplicable

View File

@@ -4,6 +4,7 @@
# https://license.mvt.re/1.1/
from .artifact import AndroidArtifact
import re
class DumpsysAccessibilityArtifact(AndroidArtifact):
@@ -25,6 +26,8 @@ class DumpsysAccessibilityArtifact(AndroidArtifact):
:param content: content of the accessibility section (string)
"""
# "Old" syntax
in_services = False
for line in content.splitlines():
if line.strip().startswith("installed services:"):
@@ -35,6 +38,7 @@ class DumpsysAccessibilityArtifact(AndroidArtifact):
continue
if line.strip() == "}":
# At end of installed services
break
service = line.split(":")[1].strip()
@@ -45,3 +49,19 @@ class DumpsysAccessibilityArtifact(AndroidArtifact):
"service": service,
}
)
# "New" syntax - AOSP >= 14 (?)
# Looks like:
# Enabled services:{{com.azure.authenticator/com.microsoft.brooklyn.module.accessibility.BrooklynAccessibilityService}, {com.agilebits.onepassword/com.agilebits.onepassword.filling.accessibility.FillingAccessibilityService}}
for line in content.splitlines():
if line.strip().startswith("Enabled services:"):
matches = re.finditer(r"{([^{]+?)}", line)
for match in matches:
# Each match is in format: <package_name>/<service>
package_name, _, service = match.group(1).partition("/")
self.results.append(
{"package_name": package_name, "service": service}
)

View File

@@ -51,6 +51,11 @@ ANDROID_DANGEROUS_SETTINGS = [
"key": "install_non_market_apps",
"safe_value": "0",
},
{
"description": "enabled accessibility services",
"key": "accessibility_enabled",
"safe_value": "0",
},
]

View File

@@ -85,6 +85,15 @@ class Command:
)
file_handler.setLevel(logging.DEBUG)
file_handler.setFormatter(formatter)
# MVT can be run in a loop
# Old file handlers stick around in subsequent loops
# Remove any existing logging.FileHandler instances
for handler in logger.handlers:
if isinstance(handler, logging.FileHandler):
logger.removeHandler(handler)
# And finally add the new one
logger.addHandler(file_handler)
def _store_timeline(self) -> None:

View File

@@ -53,20 +53,23 @@ def convert_chrometime_to_datetime(timestamp: int) -> datetime.datetime:
def convert_datetime_to_iso(date_time: datetime.datetime) -> str:
"""Converts datetime to ISO string.
:param datetime: datetime.
:param datetime: datetime, naive or timezone aware
:type datetime: datetime.datetime
:returns: ISO datetime string in YYYY-mm-dd HH:MM:SS.ms format.
:rtype: str
"""
try:
return date_time.strftime("%Y-%m-%d %H:%M:%S.%f")
except Exception:
if not date_time:
return ""
if date_time.tzinfo:
# Timezone aware object - convert to UTC
date_time = date_time.astimezone(tz=datetime.timezone.utc)
return date_time.strftime("%Y-%m-%d %H:%M:%S.%f")
def convert_unix_to_utc_datetime(
timestamp: Union[int, float, str]
timestamp: Union[int, float, str],
) -> datetime.datetime:
"""Converts a unix epoch timestamp to UTC datetime.

View File

@@ -3,4 +3,4 @@
# Use of this software is governed by the MVT License 1.1 that can be found at
# https://license.mvt.re/1.1/
MVT_VERSION = "2.5.1"
MVT_VERSION = "2.5.4"

View File

@@ -988,6 +988,10 @@
"version": "16.7.7",
"build": "20H330"
},
{
"version": "16.7.8",
"build": "20H343"
},
{
"version": "17.0",
"build": "21A327"
@@ -1055,5 +1059,13 @@
{
"version": "17.4.1",
"build": "21E237"
},
{
"version": "17.5",
"build": "21F79"
},
{
"version": "17.5.1",
"build": "21F90"
}
]

View File

@@ -66,8 +66,11 @@ class SMS(IOSExtraction):
def check_indicators(self) -> None:
for message in self.results:
alert = "ALERT: State-sponsored attackers may be targeting your iPhone"
if message.get("text", "").startswith(alert):
alert_old = "ALERT: State-sponsored attackers may be targeting your iPhone"
alert_new = "ALERT: Apple detected a targeted mercenary spyware attack against your iPhone"
if message.get("text", "").startswith(alert_old) or message.get(
"text", ""
).startswith(alert_new):
self.log.warning(
"Apple warning about state-sponsored attack received on the %s",
message["isodate"],

View File

@@ -31,7 +31,7 @@ install_requires =
iOSbackup >=0.9.923
adb-shell >=0.4.3
libusb1 >=3.0.0
cryptography >=38.0.1
cryptography >=42.0.5
pyyaml >=6.0
pyahocorasick >= 2.0.0

View File

@@ -26,6 +26,18 @@ class TestDumpsysAccessibilityArtifact:
== "com.android.settings/com.samsung.android.settings.development.gpuwatch.GPUWatchInterceptor"
)
def test_parsing_v14_aosp_format(self):
da = DumpsysAccessibilityArtifact()
file = get_artifact("android_data/dumpsys_accessibility_v14_or_later.txt")
with open(file) as f:
data = f.read()
assert len(da.results) == 0
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"
def test_ioc_check(self, indicator_file):
da = DumpsysAccessibilityArtifact()
file = get_artifact("android_data/dumpsys_accessibility.txt")

File diff suppressed because one or more lines are too long

View File

@@ -42,6 +42,14 @@ class TestDateConversions:
converted = convert_unix_to_utc_datetime(TEST_DATE_EPOCH)
assert convert_datetime_to_iso(converted) == TEST_DATE_ISO
def test_convert_timezone_aware_to_iso(self):
assert (
convert_datetime_to_iso(
datetime.strptime("2024-09-30 11:21:20+0200", "%Y-%m-%d %H:%M:%S%z")
)
== "2024-09-30 09:21:20.000000"
)
class TestHashes:
def test_hash_from_file(self):