mirror of
https://github.com/mvt-project/mvt.git
synced 2024-06-29 07:39:00 +00:00
Compare commits
5 Commits
7fddf75dba
...
3973597136
Author | SHA1 | Date | |
---|---|---|---|
|
3973597136 | ||
|
2c5ae696b1 | ||
|
5d2ff32e3a | ||
|
2838bac63f | ||
|
ac157a4421 |
|
@ -12,7 +12,7 @@ from .base import AndroidQFModule
|
||||||
|
|
||||||
|
|
||||||
class DumpsysAccessibility(DumpsysAccessibilityArtifact, AndroidQFModule):
|
class DumpsysAccessibility(DumpsysAccessibilityArtifact, AndroidQFModule):
|
||||||
"""This module analyse dumpsys accessbility"""
|
"""This module analyses dumpsys accessibility"""
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
|
|
138
mvt/common/alerting.py
Normal file
138
mvt/common/alerting.py
Normal file
|
@ -0,0 +1,138 @@
|
||||||
|
# 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 enum import Enum
|
||||||
|
|
||||||
|
|
||||||
|
class AlertLevel(Enum):
|
||||||
|
"""
|
||||||
|
informational: Rule is intended for enrichment of events, e.g. by tagging them. No case or alerting should be triggered by such rules because it is expected that a huge amount of events will match these rules.
|
||||||
|
low: Notable event but rarely an incident. Low rated events can be relevant in high numbers or combination with others. Immediate reaction shouldn’t be necessary, but a regular review is recommended.
|
||||||
|
medium: Relevant event that should be reviewed manually on a more frequent basis.
|
||||||
|
high: Relevant event that should trigger an internal alert and requires a prompt review.
|
||||||
|
critical: Highly relevant event that indicates an incident. Critical events should be reviewed immediately.
|
||||||
|
"""
|
||||||
|
|
||||||
|
INFORMATIONAL = 0
|
||||||
|
LOW = 10
|
||||||
|
MEDIUM = 20
|
||||||
|
HIGH = 30
|
||||||
|
CRITICAL = 40
|
||||||
|
|
||||||
|
|
||||||
|
class AlertStore(object):
|
||||||
|
"""
|
||||||
|
Track all of the alerts and detections generated during an analysis.
|
||||||
|
|
||||||
|
Results can be logged as log messages or in JSON format for processing by other tools.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self) -> None:
|
||||||
|
self.alerts = []
|
||||||
|
|
||||||
|
def add_alert(
|
||||||
|
self, level, message=None, event_time=None, event=None, ioc=None, detected=True
|
||||||
|
):
|
||||||
|
"""
|
||||||
|
Add an alert to the alert store.
|
||||||
|
"""
|
||||||
|
self.alerts.append(
|
||||||
|
Alert(
|
||||||
|
level=level,
|
||||||
|
message=message,
|
||||||
|
event_time=event_time,
|
||||||
|
event=event,
|
||||||
|
ioc=ioc,
|
||||||
|
detected=detected,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
def informational(
|
||||||
|
self, message=None, event_time=None, event=None, ioc=None, detected=False
|
||||||
|
):
|
||||||
|
self.add_alert(
|
||||||
|
AlertLevel.INFORMATIONAL,
|
||||||
|
message=message,
|
||||||
|
event_time=event_time,
|
||||||
|
event=event,
|
||||||
|
ioc=ioc,
|
||||||
|
detected=detected,
|
||||||
|
)
|
||||||
|
|
||||||
|
def low(self, message=None, event_time=None, event=None, ioc=None, detected=False):
|
||||||
|
self.add_alert(
|
||||||
|
AlertLevel.LOW,
|
||||||
|
message=message,
|
||||||
|
event_time=event_time,
|
||||||
|
event=event,
|
||||||
|
ioc=ioc,
|
||||||
|
detected=detected,
|
||||||
|
)
|
||||||
|
|
||||||
|
def medium(
|
||||||
|
self, message=None, event_time=None, event=None, ioc=None, detected=False
|
||||||
|
):
|
||||||
|
self.add_alert(
|
||||||
|
AlertLevel.MEDIUM,
|
||||||
|
message=message,
|
||||||
|
event_time=event_time,
|
||||||
|
event=event,
|
||||||
|
ioc=ioc,
|
||||||
|
detected=detected,
|
||||||
|
)
|
||||||
|
|
||||||
|
def high(self, message=None, event_time=None, event=None, ioc=None, detected=False):
|
||||||
|
self.add_alert(
|
||||||
|
AlertLevel.HIGH,
|
||||||
|
message=message,
|
||||||
|
event_time=event_time,
|
||||||
|
event=event,
|
||||||
|
ioc=ioc,
|
||||||
|
detected=detected,
|
||||||
|
)
|
||||||
|
|
||||||
|
def critical(
|
||||||
|
self, message=None, event_time=None, event=None, ioc=None, detected=False
|
||||||
|
):
|
||||||
|
self.add_alert(
|
||||||
|
AlertLevel.CRITICAL,
|
||||||
|
message=message,
|
||||||
|
event_time=event_time,
|
||||||
|
event=event,
|
||||||
|
ioc=ioc,
|
||||||
|
detected=detected,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class Alert(object):
|
||||||
|
"""
|
||||||
|
An alert generated by an MVT module.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, level, message, event_time, event, ioc, detected):
|
||||||
|
self.level = level
|
||||||
|
self.message = message
|
||||||
|
self.event_time = event_time
|
||||||
|
self.event = event
|
||||||
|
self.ioc = ioc
|
||||||
|
self.detected = detected
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return f"<Alert level={self.level} message={self.message} event_time={self.event_time} event={self.event}>"
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return f"{self.level} {self.message} {self.event_time} {self.event}"
|
||||||
|
|
||||||
|
def to_log(self):
|
||||||
|
return f"{self.level} {self.message} {self.event_time} {self.event}"
|
||||||
|
|
||||||
|
def to_json(self):
|
||||||
|
return {
|
||||||
|
"level": self.level,
|
||||||
|
"message": self.message,
|
||||||
|
"event_time": self.event_time,
|
||||||
|
"event": self.event,
|
||||||
|
"ioc": self.ioc,
|
||||||
|
"detected": self.detected,
|
||||||
|
}
|
|
@ -10,7 +10,7 @@ from .version import MVT_VERSION
|
||||||
|
|
||||||
|
|
||||||
def check_updates() -> None:
|
def check_updates() -> None:
|
||||||
# First we check for MVT version udpates.
|
# First we check for MVT version updates.
|
||||||
mvt_updates = MVTUpdates()
|
mvt_updates = MVTUpdates()
|
||||||
try:
|
try:
|
||||||
latest_version = mvt_updates.check()
|
latest_version = mvt_updates.check()
|
||||||
|
|
|
@ -964,6 +964,10 @@
|
||||||
"version": "16.7.3",
|
"version": "16.7.3",
|
||||||
"build": "20H232"
|
"build": "20H232"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"version": "16.7.4",
|
||||||
|
"build": "20H240"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"version": "17.0",
|
"version": "17.0",
|
||||||
"build": "21A327"
|
"build": "21A327"
|
||||||
|
@ -1007,5 +1011,9 @@
|
||||||
{
|
{
|
||||||
"version": "17.2",
|
"version": "17.2",
|
||||||
"build": "21C62"
|
"build": "21C62"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"version": "17.2.1",
|
||||||
|
"build": "21C66"
|
||||||
}
|
}
|
||||||
]
|
]
|
|
@ -44,7 +44,7 @@ class SMS(IOSExtraction):
|
||||||
def serialize(self, record: dict) -> Union[dict, list]:
|
def serialize(self, record: dict) -> Union[dict, list]:
|
||||||
text = record["text"].replace("\n", "\\n")
|
text = record["text"].replace("\n", "\\n")
|
||||||
sms_data = f"{record['service']}: {record['guid']} \"{text}\" from {record['phone_number']} ({record['account']})"
|
sms_data = f"{record['service']}: {record['guid']} \"{text}\" from {record['phone_number']} ({record['account']})"
|
||||||
sms_data = [
|
records = [
|
||||||
{
|
{
|
||||||
"timestamp": record["isodate"],
|
"timestamp": record["isodate"],
|
||||||
"module": self.__class__.__name__,
|
"module": self.__class__.__name__,
|
||||||
|
@ -54,7 +54,7 @@ class SMS(IOSExtraction):
|
||||||
]
|
]
|
||||||
# If the message was read, we add an extra event.
|
# If the message was read, we add an extra event.
|
||||||
if record["isodate_read"]:
|
if record["isodate_read"]:
|
||||||
sms_data.append(
|
records.append(
|
||||||
{
|
{
|
||||||
"timestamp": record["isodate_read"],
|
"timestamp": record["isodate_read"],
|
||||||
"module": self.__class__.__name__,
|
"module": self.__class__.__name__,
|
||||||
|
@ -62,15 +62,16 @@ class SMS(IOSExtraction):
|
||||||
"data": sms_data,
|
"data": sms_data,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
return sms_data
|
return records
|
||||||
|
|
||||||
def check_indicators(self) -> None:
|
def check_indicators(self) -> None:
|
||||||
for message in self.results:
|
for message in self.results:
|
||||||
alert = "ALERT: State-sponsored attackers may be targeting your iPhone"
|
alert = "ALERT: State-sponsored attackers may be targeting your iPhone"
|
||||||
if message.get("text", "").startswith(alert):
|
if message.get("text", "").startswith(alert):
|
||||||
self.log.warning(
|
self.alerts.medium(
|
||||||
"Apple warning about state-sponsored attack received on the %s",
|
f"Apple warning about state-sponsored attack received on the {message['isodate']}",
|
||||||
message["isodate"],
|
event_time=message["isodate"],
|
||||||
|
event=message,
|
||||||
)
|
)
|
||||||
|
|
||||||
if not self.indicators:
|
if not self.indicators:
|
||||||
|
|
Binary file not shown.
|
@ -17,7 +17,7 @@ class TestSMSModule:
|
||||||
m = SMS(target_path=get_ios_backup_folder())
|
m = SMS(target_path=get_ios_backup_folder())
|
||||||
run_module(m)
|
run_module(m)
|
||||||
assert len(m.results) == 1
|
assert len(m.results) == 1
|
||||||
assert len(m.timeline) == 1
|
assert len(m.timeline) == 2
|
||||||
assert len(m.detected) == 0
|
assert len(m.detected) == 0
|
||||||
|
|
||||||
def test_detection(self, indicator_file):
|
def test_detection(self, indicator_file):
|
||||||
|
|
Loading…
Reference in New Issue
Block a user