From ac157a4421c171b32a8c9d7fc883a75caf590f22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Donncha=20=C3=93=20Cearbhaill?= Date: Mon, 17 Jul 2023 17:37:25 +0200 Subject: [PATCH] WIP: Add inital scoffolding for multiple alerting levels in MVT --- mvt/common/alerting.py | 138 +++++++++++++++++++++++++++++++++++ mvt/ios/modules/mixed/sms.py | 7 +- 2 files changed, 142 insertions(+), 3 deletions(-) create mode 100644 mvt/common/alerting.py diff --git a/mvt/common/alerting.py b/mvt/common/alerting.py new file mode 100644 index 000000000..61e75f4f4 --- /dev/null +++ b/mvt/common/alerting.py @@ -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"" + + 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, + } diff --git a/mvt/ios/modules/mixed/sms.py b/mvt/ios/modules/mixed/sms.py index 0f0cee740..6fd87a18c 100644 --- a/mvt/ios/modules/mixed/sms.py +++ b/mvt/ios/modules/mixed/sms.py @@ -63,9 +63,10 @@ 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): - self.log.warning( - "Apple warning about state-sponsored attack received on the %s", - message["isodate"], + self.alerts.medium( + f"Apple warning about state-sponsored attack received on the {message['isodate']}", + event_time=message["isodate"], + event=message, ) if not self.indicators: