Änderungen an sensitiven on-Prem Gruppen mit MDI alarmieren
Microsoft Defender for Identity ist ein mächtiges Werkzeug wenn es darum geht Änderungen an Benutzern und Gruppen im on-prem Active Directory zu identifizieren. Wenn man diese Daten im Microsoft 365 Defender Portal mittels Advanced Hunting analysiert und Custom Detection Rules nutzt kann man sehr einfach ein Change Tracking für sensitive Accounts etablieren.
Wenn du ein on-prem Active Directory beschützt sind Änderungen an hochprivilegierten Gruppen ein großes Risiko. Microsoft selbst definiert einen Teil dieser Gruppen in der Dokumentation zu Active Directory Domain Services in in der Defender for Identity Dokumentation werden zusätzliche Gruppen genannt. Insgesamt sind dies 17 Gruppen bei denen Änderungen überwacht werden sollten.
- Account Operators
- Administrators
- Backup Operators
- Domain Admins
- Domain Controllers
- Enterprise Admins
- Enterprise Read-only Domain Controllers
- Group Policy Creator Owners
- Incoming Forest Trust Builders
- Microsoft Exchange Servers
- Network Configuration Operators
- Power Users
- Print Operators
- Read-only Domain Controllers
- Replicators
- Schema Admins
- Server Operators
Wenn zusätzlich noch Exchange vorhanden ist und nicht für split permissions konfiguriert wurde, sollten folgende Gruppen ebenfalls überwacht werden.
- Exchange Trusted Subsystem
- Exchange Windows Permission
- Organization Management
Diese Überwachung gestaltet sich sehr komplex wenn kein zentrales Logging der Änderungen vorhanden ist. Hier kommt Defender for Identity ins Spiel. Alle Änderungen an AD Gruppen werden überwacht und an die Cloud weitergeleitet. Dafür muss die Windows Event Collection korrekt konfiguriert sein und alle Event Ids in diesem Artikel müssen überwacht werden.
Advanced Hunting
Wenn diese Vorraubsetzungen geschaffen sind können wir auf die Jagd gehen. Das Advanced Hunting Schema stellt die benötigten Daten in der Tabelle IdentityDirectoryEvents
bereit. Weitestgehend aufbereitet um Sie abfragen zu können.
Welche Events muss ich filtern
Der erste SChritt ist es zu prüfen welche Aktionen überhaupt geloggt werden und wie auf einen bestimmten ActionType
gefiltert werden kann. Die nachfolgende Abfrage listet alle Aktionen und Ihre Namen die im definierten Zeitraum aufgetreten sind.
IdentityDirectoryEvents
| distinct ActionType
| sort by ActionType asc
Für eine komplette Übersicht der möglichen ActionTypes muss die in-portal schema reference genutzt werden, da selbst Microsoft nicht alle möglichen Werte in der Online Dokumentation auflistet.
Das Ergebnis sollte ähnlich aussehen wie dieses:
In den meisten Fällen wird es eine Aktion mit dem Namen “Group Membership changed” geben. Mit diesem Wert werden wir weiter arbeiten.
Alle Gruppenänderungen finden
Um zu viele Ergebnisse zu vermeiden habe ich die Anzahl auf maximal 100 limitiert.
IdentityDirectoryEvents
| where ActionType == "Group Membership changed"
| limit 100
Die ausgegebenen Daten sind nicht unbedingt das womit man rechnet.
Es sind zwar alle wichtigen Informationen vorhanden, jedoch nicht unbedingt in einem einfach lesbaren Format sondern als JSON im Feld AdditionalFields
.
Die Daten entwirren
Kusto bietet für die Verarbeitung von JSON Daten ein mächtige Funktion: parse_json
Die folgende Abfrage wirkt erstmal abschreckend, daher werde ich Sie Zeile für Zeile erläutern.
|
|
Als erstes filtert die Abfrage alle Daten aus die einen Timestamp
älter als zwei Tage haben und gibt nur Zeilen mit dem ActionType
= “Group Membership changed” aus.
|
|
Nun extrahiert die Funktion parse_json
die JSON Daten aus dem Feld AdditionalFields
und speichert diese in einer dynamischen Spalte mit demselben Namen. Die ursprüngliche Zeile wird einfach überschrieben.
|
|
Durch diese Änderung können nun die einzelnen Felder in diesem Feld direkt ausgewertet werden und die beiden nächsten Zeilen speichern die Informationen über welche Gruppe verändert wurde in den neuen Felden FromGroup
und ToGroup
.
|
|
Um herauszufinden ob ein Benutzerobjekt, ein Computerobjekt oder eine Gruppe als Mitglied hinzugefügt bzw. entfernt wurden nutzen wir AI eine einfache if/then Prüfung.
Das erste iff prüft ob das Feld TARGET_OBJECT.USER
leer ist und wenn dies der Fall ist wird TARGET_OBJECT.GROUP
als Wert gespeichert. Wenn nicht wird TARGET_OBJECT.USER
genutzt.
Sollte kein dieser Felder die entsprechende Information beinhalten wird im zweiten iff
das Feld TARGET_OBJECT.DEVICE
verwendet.
|
|
Anschließend wird die Spalte AdditionalFields
entfernt, da sie nicht mehr benötigt wird. Zusätzlich verändert project-reorder
die Reihenfolge in der die Spalten angezeigt werden.
|
|
Das Ergebnis ist um einiges besser lesbar.
Nur wichtige Gruppen berücksichtigen
Die letzte Abfrage gibt jede Veränderung an einer Gruppe in den letzten zwei Tagen aus. Daher muss das Ergebnis noch weiter eingeschränkt werden um nur Änderungen an sensitive Gruppen zu sehen.
Dafür nutze ich eine ‘virtual table’ mit dem Namen GroupsToMonitor
. Diese Tabelle beinhaltet nur eine Spalte GroupName
und für jede Gruppe die überwacht werden soll eine Zeile mit dem Namen. So ist es super einfach die Abfrage für deine Umgebung anzupassen um weitere Gruppen hinzuzufügen oder nicht benötigte zu entfernen.
let GroupsToMonitor = datatable(GroupName:string)
[
"Account Operators",
"Administrators",
"Backup Operators",
"Domain Admins",
"Domain Controllers",
"Enterprise Admins",
"Enterprise Read-only Domain Controllers",
"Exchange Trusted Subsystem",
"Exchange Windows Permission",
"Group Policy Creator Owners",
"Incoming Forest Trust Builders",
"Microsoft Exchange Servers",
"Network Configuration Operators",
"Organization Management",
"Power Users",
"Print Operators",
"Read-only Domain Controllers",
"Replicators",
"Schema Admins",
"Server Operators",
];
IdentityDirectoryEvents
| where Timestamp >= now(-2d)
| where ActionType == "Group Membership changed"
| extend AdditionalFields = parse_json(AdditionalFields)
| extend FromGroup = AdditionalFields.["FROM.GROUP"]
| extend ToGroup = AdditionalFields.["TO.GROUP"]
// Extract target user or device name
| extend TargetObject = iff( isnull(AdditionalFields.["TARGET_OBJECT.USER"]), AdditionalFields.["TARGET_OBJECT.GROUP"], AdditionalFields.["TARGET_OBJECT.USER"])
// Special case group managed service accounts and devices
| extend TargetObject = iff( isnull(TargetObject), AdditionalFields.["TARGET_OBJECT.DEVICE"], TargetObject)
| where FromGroup in (GroupsToMonitor) or ToGroup in (GroupsToMonitor)
| order by Timestamp
| project-away AdditionalFields
| project-reorder Timestamp, ActionType,Application, FromGroup, ToGroup, TargetObject
In den meisten Fällen sollte das Ergebnis leer sein. Wenn nicht ist jetzt ein guter Zeitpunkt zu prüfen ob diese Änderung legitim war.
Eine Custom Detection erstellen
Um bei zukünftigen Änderungen einen Alarm zu erhalten kannst du eine Custom Detection erstellen. Dazu nach der Ausführung der Abfrage auf den Button “create detection rule” klicken.
Gib dem Alarm einen sprechenden Namen und füge Informationen hinzu was gemacht werden soll wenn dieser auftritt. Wähle eine Severity die für deine Umgebung passend ist.
Als betroffenen Entität muss TargetAccountUpn
ausgewählt werden und der Bereich Action kann übersprungen werden.
Erstelle den Alarm und wechsel zu Custom detection rules.
Um sofort ein Ergebnis zu erhalten kann die Detection manuell gestartet werden.
Alarm
Sollte der Alarm ausgelöst werden ist es sehr einfach zu erkennen welche Benutzer verändert wurde.
In den Alert Details werden auch die Query Results inklusive der betroffenen Gruppe anzeigt. Da FromGroup
und ToGroup
unterschiedliche Felder sind, ist es einfach zu erkennen ob jemand zusätzliche Rechte erhält oder diese verliert.
Mit kleinen Anpassungen könnte somit auch basierend auf diesen Feldern unterschiedliche Alarme ausgelöst werden
- Ein Alarm mit “High Severity” wenn jemand in eine Gruppe aufgenommen wird
- Der zweite mit einer “Information Severity” wenn ein Benutzer entfernt wurde
Fazit
Defender for Identity und Custom Detections sind ein wichtiges Werkzeug um deine Umgebung zu schützen. Die zusätzlichen Informationen die abgefragt und genutzt werden können sind ein Schatz um Änderungen an der on-Prem Umgebung festzustellen.
Ich kann nur jedem empfehlen sich mit Advanced Hunting auseinander zu setzen und zu spielen. Da alle Daten schreibgeschützt sind kann man dabei auch nichts kaputt machen und Kusto als Sprache ist intelligent genug um z.B. auch meine nicht optimierten Abfragen sehr schnell auszuführen.
Nutze wenn möglich | limit 10
um initial nur wenig Daten abzufragen und so schneller Ergebnisse zu prüfen.
Wenn dir dieser Blogeintrag gefallen hat solltest du dir meinen Blogpost Automatisch C2 traffic auf Endgeräten erkennen anschauen.