Adsisearcher – Gruppen rekursiv auflösen

Zunächst ist es wichtig zu verstehen, warum Gruppen und Gruppenzugehörigkeiten relevant sind.

In Active Directory werden Gruppen verwendet, um Benutzerkonten und Computerkonten in Einheiten zu gruppieren, die dann einfacher verwaltet werden können. Es gibt 2 Arten von Gruppen: Verteilergruppen, die nur mit E-Mail-Anwendungen zum Erstellen von E-Mail-Verteilerlisten verwendet werden können und Sicherheitsgruppen, mittels derer das Zuweisen von Berechtigungen zu freigegebenen Ressourcen erledigt werden kann. Zudem unterscheiden sich Gruppen noch nach dem Geltungsbereich (englisch: Scope), der angibt, in welchem Umfang die Gruppe in der Domänenstruktur oder im Forest angewendet wird. Der Geltungsbereich definiert, wo der Gruppe beziehungsweise deren Mitgliedern Berechtigungen erteilt werden können. In Active Directory gibt es folgende drei Bereiche:

  • Universal: kann Berechtigungen in jeder Domain im selben Forest oder in vertrauenswürdigen Forests erteilen
  • Global: kann Berechtigungen in jeder Domain im selben Forest oder in vertrauenswürdigen Domains oder Forests erteilen
  • Domain Lokal: kann Berechtigungen innerhalb derselben Domäne erteilen[1]

Optionen beim Erstellen einer Gruppe

Von besonderem Interesse sind die Sicherheitsgruppen, da mit den hierüber zugewiesenen Benutzerrechten bestimmt werden kann, was Mitglieder dieser Gruppe im Bereich einer Domain oder Gesamtstruktur (Forest) tun können. Bei der Installation von Active Directory werden automatisch einigen Sicherheitsgruppen Benutzerrechte zugewiesen. Dies ermöglicht es zum Beispiel die Administratorrolle einer Person in der Domäne zu definieren. User, die der Gruppen Domain Admins hinzugefügt werden, erhalten administrative Rechte in der Domain. Der Gruppe Domain Admins werden standardmäßig die Benutzerrechte für administrative Aktivitäten zugewiesen und Mitglieder der Gruppe erben diese Rechte. Wenn eine andere Gruppe Mitglied der Domain Admins Gruppe wird, erhalten auch alle Mitglieder dieser anderen Gruppe administrative Rechte. Es ist also wichtig nicht nur direkte Gruppenmitglieder auslesen zu können, sondern Gruppen auch rekursiv auflösen zu können, um wirklich jedes effektive Mitglied erfassen zu können.

Direkte Gruppenmitgliedschaft

Eine direkte Gruppenmitgliedschaft ist direkt in den Attributen der jeweiligen Gruppe hinterlegt. Direkte Mitgliedschaft bedeutet, dass ein User direkt in einer Gruppe Mitglied ist und nicht etwa in einer Gruppe, Mitglied der Gruppe ist. Grundsätzlich ist es erstmal sinnvoll, zu wissen, wie man nach allen Gruppen suchen kann. Dies kann man, wie auch schon bei User- oder Computer-Suchen, mit dem Attribut objectClass im Suchfilter erledigen:

Wenn einer Gruppe Mitglieder zugewiesen werden, hat diese das Attribut member – in diesem Attribut werden alle direkten Mitglieder der Gruppe mit ihrem jeweiligen Distinguished Name aufgelistet. Man kann daher sowohl alle Gruppen, die Member haben, suchen:

als auch alle Gruppen, die keine Member haben:

Möchte man alle direkten Mitglieder einer Gruppe abfragen, kann man dies einfach tun, indem man z.B. nach dem distinguishedName oder dem sAMAccountName einer Gruppe filtert und sich dann mit .properties.member den Inhalt des Attributs member ausgeben lässt:

Es ist auch möglich für einen bestimmten User zu prüfen, welchen Gruppen er direkt angehört, indem man das Attribut memberof des Users abfragt:

Admin oder nicht?

Es ist grundsätzlich immer von Vorteil, wenn man weiß – oder weiß, wie man herausfindet – wer administrative Rechte in einem Active Directory hat. Das kann man natürlich mit den richtigen Suchfiltern via adsisearcher bewerkstelligen. Sucht man im Internet nach einer einfachen Lösung, werden häufig relativ einfache Suchen wie die nach der direkten Gruppenmitgliedschaft vorgeschlagen, diese erfasst, aber – wie bereits erwähnt – nur direkte Mitglieder. Ein weiterer Ansatz, auf den man stößt, ist der, an Hand des adminCount Attributs festzumachen, ob jemand Administrator ist. Eine Suche danach sieht wie folgt aus:

AdminCount gibt an, ob ein Account ein sogenanntes Protected Object ist. Ist dies der Fall, ist das Attribut mit dem Wert 1 vorhanden.

Beispiel:

Bei Protected Objects handelt es sich um hoch privilegierte administrative Gruppen (z.B. Domain Admins, Schema Admins, etc.) und deren Mitglieder. Hier sind auch indirekte Mitglieder Protected Objects. Protected Objects sind insofern besonders geschützt, dass Ihre Berechtigungen nicht ohne weiteres geändert werden können. Ein Hintergrundprozess schützt sie, indem er in regelmäßigen Abständen nach einem bestimmten Sicherheitsdeskriptor – dieser befindet sich auf dem Objekt AdminSDHolder – sucht und diesen anwendet. Der Deskriptor enthält Sicherheitsinformationen zu dem Protected Object und bei unbefugten Änderungen am Objekt überschreibt der Prozess die Einstellungen mit denen im Deskriptor enthaltenen Informationen. Möchte man Berechtigungen für ein Protected Object ändern, muss man den Sicherheitsdeskriptor für das AdminSDHolder-Objekt ändern, damit dieser dann konsistent angewendet wird.

An dieser Stelle ist Vorsicht geboten. Die Suche nach adminCount kann ein Ergebnis ausgeben, dass nicht die Accounts enthält, die man eigentlich sucht, beziehungsweise erwartet. Das hängt damit zusammen, dass adminCount nicht nur den momentanen Status eines Accounts angibt, sondern auch den der Vergangenheit. Wenn einem Account administrative Privilegien zugewiesen werden (z.B. durch Zufügen zu der Gruppe Domain Admins), so wird dem Account das Attribut adminCount=1 zugeordnet – der Account ist jetzt ein Protected Object. Werden diese Privilegien wieder entzogen (z.B. Account wird aus Gruppe entfernt), ist das Attribut trotzdem weiterhin im Account vorhanden.

Wenn man alle Administratoren suchen möchte, eignet sich statt der Suche mit dem Filter adminCount eine rekursive Suche der Gruppenmitgliedschaften besser. Hierzu muss man wissen, nach welcher Gruppe gesucht werden soll. An dieser Stelle sollen Accounts gesucht werden, die administrative Privilegien in der Domain haben. Prinzipiell von Interesse sind daher die Gruppen Administrators, Domain Admins und Enterprise Admins. Die Gruppen unterscheiden sich in einigen Punkten und sind zum Teil auch miteinander verschachtelt. Um alle Mitglieder zu finden, muss man eine rekursive Abfrage durchführen.

Gruppenmitgliedschaften rekursiv auflösen

Um herauszufinden, welche User Mitglieder von Gruppen sind, die wiederum in anderen Gruppen enthalten sind, könnte man ein Skript schreiben, das direkte Mitglieder von Gruppen abfragt, prüft, welche davon ihrerseits wieder Gruppen sind und dann wieder die direkten Mitglieder abrufen usw., bis man auch die letzte Untergruppe abgefragt hat. Zum Glück ist dies nicht nötig, da es in LDAP sogenannte OID (Object Identifier) Matching Rules gibt. In LDAP sind 3 verschiedene OID Matching Rules implementiert, die man der folgenden Tabelle entnehmen kann:

Matching rule OID String identifier (von Ntldap.h) Beschreibung
1.2.840.113556.1.4.803 LDAP_MATCHING_RULE_BIT_AND Eine Übereinstimmung wird gefunden, wenn alle Bits aus dem Attribut mit dem Wert übereinstimmen. Diese Regel ist äquivalent zu einem bitweisen AND-Operator.
1.2.840.113556.1.4.804 LDAP_MATCHING_RULE_BIT_OR Eine Übereinstimmung wird gefunden, wenn irgendwelche Bits des Attributs mit dem Wert übereinstimmen. Diese Regel ist äquivalent zu einem bitweisen OR-Operator.
1.2.840.113556.1.4.1941 LDAP_MATCHING_RULE_IN_CHAIN Diese Regel ist auf Filter beschränkt, die sich auf den DN (Distinguished Name) beziehen. Es handelt sich um einen speziellen “erweiterten” Übereinstimmungsoperator, der die Abstammungskette in Objekten bis zum Stamm durchläuft, bis er eine Übereinstimmung findet.

Für eine rekursive Abfrage der Gruppenmitgliedschaft, nutzt man die Matching Rule IN CHAIN und benötigt dazu den Distinguished Name der Gruppe. Eine übersichtliche Liste der Common Names und dazugehörigen Distinguished Names aller Gruppen mit Membern kann man sich einfach über folgenden Befehl ausgeben lassen:

Beispieloutput:

Die Matching Rule verwendet man wie folgt im Suchfilter:

Es gilt zu bedenken, dass man als Ergebnis User-Objekte haben möchte. Das bedeutet, dass man hier wieder nach dem sAMAccountType=805306368 sucht und erfahren möchte, ob dieser ein Mitglied einer Gruppe ist. Die Matching Rule wird also auf das Attribut memberOf angewendet. Eine Suche nach den Mitgliedern der Gruppe Domain Admins aus dem Beispieloutput würde wie folgt aussehen:

Wenn man es sich etwas einfacher machen möchte, kann man den Wert des Attributes distinguishedname auch in einer Variable speichern und dies dann im Suchfilter aufrufen:

Das gleiche Prinzip kann man auch anwenden, um aufzulösen, in welchen Gruppen ein spezifischer User ist. Man benötigt den Distinguished Name des Users und verwendet die OID Matching Rule IN CHAIN mit dem Attribut member. Bei einem angenommenen Beispiel-User John Doe würde man folgende Abfrage tätigen:

Die beschriebenen Suchen zeigen, dass die Verwendung von Matching Rules im Suchfilter enorm nützlich sind, wenn man weißt, wie und mit welchen Attributen sie zu verwenden sind. Man kann die Matching Rules auch benutzen, um Informationen in Bitmasken abzufragen, aber das soll im nächsten Blogpost zum Thema adsisearcher behandelt werden.

Serienübersicht

 

[1] Active Directory Security Groups, Microsoft Documentation, https://docs.microsoft.com/en-gb/windows/security/identity-protection/access-control/active-directory-security-groups

Beitrag teilen auf:

XING
Twitter
LinkedIn

Nina Fasel • Autor

Cyber Defense Analyst

Nina begeistert sich für anspruchsvolle Security-Projekte. Nachdem sie zunächst als Pentesterin auf der Angreifer-Seite in die IT-Security Branche eingestiegen ist, setzt sie ihr erlerntes Wissen jetzt in der Erkennung, Analyse und Abwehr von Cyber-Angriffen ein.

> alle Artikel
Cookie Consent mit Real Cookie Banner