Windows-Angriffe entgegen der Vertrauensstellung

Windows Domänen lassen sich durch Vertrauensstellungen zusammenbringen. Wird der Zugriff nur in eine Richtung benötigt kann man das Vertrauen auch nur einseitig aussprechen – aber sind damit Angriffe in die andere Richtung ausgeschlossen? Leider nicht, denn es gibt Wege um das Vertrauen entgegen der „Direction of Access“ auszunutzen. 

In dem Artikel starten wir erst mit ein paar Grundlagen, um dann den konkreten Angriff vorzustellen. Zum Schluss geben wir noch Tipps für Gegenmaßnahmen und Detektionsmöglichkeiten. 

Vertrauensstellung, was ist das? 

Eine der Kernaufgaben des Active Directory (AD) ist es dafür zu sorgen, dass Nutzer sich bei verschiedenen Diensten und Systemen im eigenen Netz anmelden können. Dafür vertrauen alle Domänenmitglieder dem eigenen Domain Controller (DC), dass dieser die Authentizität der Nutzer gut prüft. 

Aber das Vertrauen kann auch über die Grenzen einer Domäne oder eines Forests hinausgehen1. Dazu wird in beiden Domänen eine Vertrauensstellung (Trust) eingerichtet. Im einfachsten Fall ist sie beidseitig, dann können Nutzer aus beiden Domänen Ressourcen in der jeweils anderen Domäne nutzen. Aber man kann auch nur eine einseitige Vertrauensstellung (One-Way Trust) einrichten, dann können Nutzer der einen Domäne Ressourcen der anderen Domäne nutzen aber nicht umgekehrt. Hier kommt man leicht mit den Richtungen und Begriffen durcheinander, daher findet sich in jeder guten AD-Anleitung ein Bild wie dieses: 

Für unser Beispiel würde dies also so aussehen: 

Ein Angreifer, der in der vertrauten Domäne (hier PARTNER.local) ein Konto oder gar die ganze Domäne übernommen hat, kann natürlich über die Vertrauensbeziehung auch Ressourcen in der anderen Domäne nutzen (entlang der “direction of access”). Bei der beidseitigen Vertrauensstellung gilt das logischerweise in beide Richtungen, aber auch bei der einseitigen Vertrauensstellung gibt es einen Grenzfall wie ein Angreifer, der bereits den Domain Controller übernommen hat, sich entgegen der “direction of access” weiterbewegen kann: 

Kerberos über Grenzen hinweg, die Theorie 

Für die verteilte Anmeldung nutzt Active Directory das Kerberos-Protokoll, das ursprünglich aus der akademischen Welt kommt und ganz im Sinne der akademischen Zusammenarbeit auch bereits alles für die hochschulübergreifende Zusammenarbeit mitbringt. Das Konzept hinter der Vertrauensstellung heißt bei Kerberos Cross-Realm-Authentifizierung.  

Innerhalb eines Realms (oder Domäne in AD-Terminologie) meldet sich der Nutzer initial beim Authentisierungsserver (AS) an und erhält ein Sitzungsticket (Ticket Granting Ticket, TGT). Mit diesem Ticket kann der Nutzer dann beim Ticket-Granting-Server (TGS) Service-Tickets beantragen und sich dann mit diesen bei den Systemen und Services ausweisen, die er nutzen möchte. 

Für die Cross-Realm-Authentifizierung wird dann einfach der fremde TGS wie ein Dienstserver im eigenen Realm betrachtet. Der Nutzer fragt also seinen Heimat-TGS nach einem Ticket für den Fremd-TGS. Dieses Ticket funktioniert dann analog zu einem TGT im anderen Realm. Der Nutzer beantragt mit diesem dann ein Service-Ticket beim Fremd-TGS für den eigentlichen Service, den er nutzen möchte. In beiden Schritten werden die gleichen Befehle ausgetauscht. 

In der Praxis sind der TGS und der AS keine getrennten Server, sondern zwei Funktionen des Key Distribution Centers (KDC), die beide über den UDP-Port 88 erreicht werden. In der Windows-Welt ist das ein Service auf dem Domain Controller.  

Um den Angriff gleich verstehen zu können, müssen wir noch einen Schritt tiefer gehen. Die Tickets, die bei Kerberos immer wieder ausgetauscht werden, sind Datenstrukturen, die mit einem symmetrischen Schlüssel verschlüsselt sind. Diese Schlüssel werden für Nutzer, Services und auch die Zwischenschritte am TGS in Principals gespeichert. Die Schlüssel für die Sitzungstickets (TGT) sind beispielsweise im Principal “krbtgt” gespeichert. 

Für den ersten Schritt, die initiale Anmeldung am AS, basiert der Schlüssel auf dem Nutzerpasswort. Für die anderen Fälle sind auch andere Wege möglich, aber in Windows wird für die Fälle, in denen kein Nutzer involviert ist, einfach ein zufälliges Passwort generiert und daraus der Schlüssel abgeleitet. 

Innerhalb einer Domäne bzw. eines Realms ist das auch einfach, da wir hier ja über eine zentral verwaltete Principal- bzw. Benutzer-Datenbank reden. Wenn wir jetzt aber die Grenzen überschreiten wollen, muss es in beiden Datenbanken einen gleichartigen Eintrag mit dem gleichen Schlüssel (also dem gleichen Passwort) geben. Auf der einen Seite der Grenze, um das Ticket verschlüsseln zu können, und auf der anderen Seite, um es wieder entschlüsseln zu können.  

Die Umsetzung im AD 

Jetzt wollen wir uns anschauen, was bei einer Vertrauensstellung in einem Windows Active Directory (AD) passiert. 

Das Trusted Domain Object (TDO) 

Um sich zu merken, mit welchen anderen Domänen oder Forests eine Vertrauensstellung existiert, wird pro Vertrauensstellung im “System”-Container der dazugehörigen Domänen (bzw. den Root-Domänen bei Forest-Trusts) jeweils ein Objekt angelegt – ein sogenanntes Trusted Domain Object (TDO). Auch bei einseitigen Vertrauensstellungen wird an beiden Enden ein TDO angelegt (einmal als eingehende, einmal als ausgehende Vertrauensstellung).  

In den Attributen des Objekts werden alle Einstellungen für die Vertrauensstellung gespeichert. In dem Objekt wird zudem ein Passwort für das TDO gespeichert. Und zwar zum einen wie man es sonst von Benutzern und Computern kennt als Hash bzw. abgeleiteter Schlüssel und in diesem Fall zusätzlich auch im Klartext. Das Passwort wird automatisch alle 30 Tage geändert und – um Störungen beim Passwortwechsel vorzubeugen – wird jeweils das aktuelle sowie das vorherige Kennwort im TDO gespeichert. Das Passwort, und das ist wichtig, ist für beide Objekte gleich. 

Das Objekt kann man in der MMC unter “Active Directory-Benutzer und -Computer” sehen, wenn man zuvor unter “Ansicht” die “Erweiterten Features” aktiviert hat. Dort findet es sich dann unter dem vollen Namen der jeweils anderen Domäne. 

Der versteckte User 

Das es auf beiden Seiten einen gleichartigen Eintrag mit dem gleichen Schlüssel geben muss, hatten wir schon bei der Kerberos-Theorie gesehen. In der Windows-Welt sind die beiden TDO aber nicht die einzigen Repräsentanten der Vertrauensstellung. 

Schaut man sich die Nutzerliste auf der Seite der vertraueten Domäne (bei uns PARTNER.local) z. B. im ADSI-Editor etwas genauer an, findet sich dort ein User dessen Namen an die vertrauenden Domäne erinnert – in unserem Fall finden wir einen Benutzer HISOCORP$

ADSI-Editor auf dem PARTNER-DC.

In vielen anderen Ansichten wie der MMC wird der Nutzer ausgeblendet. Praktischerweise hat dieser versteckte Benutzer das gleiche Passwort, das auch in beiden TDO-Objekten im Klartext gespeichert wird. 

Der Angriff entgegen der Vertrauensrichtung 

Nach so viel Theorie und Grundlagen wollen wir jetzt endlich schauen, wie wir das Vertrauen gegen den Strom ausnutzen können. Noch einmal zur Erinnerung: Wir wollen gegen die erlaubte “Direction of Access” arbeiten. 

Der Trick ist jetzt, dass der versteckte Nutzer in der vertrauten Domäne ein fast normaler Nutzer ist, und wir sein Passwort kennen. 

Dann besteht der Angriff aus diesen Schritten: 

  1. Die vertrauende Domäne kompromittieren (in unserem Beispiel HISOCORP.local) 
  2. Auf dem kompromittierten DC das Passwort aus dem Trusted Domain Object (TDO) auslesen
  3. Mit dem bekannten Nutzernamen und dem ausgelesenen Passwort bei der vertrauenden Domäne (in unserem Beispiel PARTNER.local) anmelden. Also ein TGT beziehen.
  4. Mit dem bekannten Nutzernamen und dem ausgelesenen Passwort bei der vertreuten Domäne (in unserem Beispiel PARTNER.local) anmelden. Also ein TGT beziehen. 
  5. Mit dem TGT können jetzt Dienst-Tickets bezogen werden und ggf. Dienste genutzt werden. 

Auf Schritt 1 gehen wir nicht näher ein. Für die folgenden Schritte nehmen wir an, es ist bereits gelungen die Domäne zu kompromittieren und Zugriff auf einen Domain Controller (DC) zu erlangen. Das ist keine kleine Annahme und damit haben wir bereits vollen Zugriff auf alle Ressourcen auf dieser Seite der Vertrauensstellung. 

Auf dem DC können wir jetzt für Schritt 2 das bekannte Tool Mimikatz nutzen. Für das Auslesen des TDO gibt es einen eigenen Befehl: lsadump::trust /patch 

Im TDO ist das gemeinsame Passwort im Klartext gespeichert – in der Ausgabe oben jedes Zeichen als eine Hexadezimalzahl nach dem Stichwort „CLEAR“ – sowie verschiedene Hashwerte vom Passwort.  

Den NT-Hash (rc4_hmac_nt) können wir direkt für Schritt 3 nutzen. Die beiden anderen Hashes/Schlüssel wurden mit einem anderen Salt erzeugt und entsprechen daher nicht den Hashes, die bei der vertrauten Domain im versteckten Nutzer gespeichert sind. Aber wir kennen jetzt ja das Klartextpasswort und die Berechnungsformel für die Nutzer-Schlüssel, können also diese beiden Werte auch selbst berechnen. 

Wir nehmen in Schritt 3 den einfachsten Weg und melden uns direkt mit dem erbeuteten NT-Hash an. Dafür bietet sich beispielsweise die impacket-Suite an. Damit können wir direkt ein TGT beziehen: 

Das TGT können wir in Schritt 4 dann zum Beispiel für einen Zugriff auf eine Dateifreigabe per SMB nutzen: 

Im Beispiel wird auf die SYSVOL-Freigabe des fremden DC zugegriffen. Das geht, weil diese Freigabe grundsätzlich von allen Nutzern (Gruppe „Domänenbenutzer“) gelesen werden kann.

Da der Nutzer in der normalen Administration nicht sichtbar ist, ist er weder Mitglied in anderen Gruppen noch wurde der User selbst für Dienste oder Zugriffe explizit berechtigt. In einem realen Netz finden sich aber auch häufig weitere Freigaben und Dienste, die alle gemeinsam nutzen und die für die allgemeine Gruppe der Domänenbenutzer freigegeben sind. 

Bei der Bewertung von Sicherheitslücken wird immer unterschieden, ob sie auch ohne Login oder nur nach erfolgreicher Authentifizierung möglich sind. Und genau diesen Sprung zum authentifizierten Angreifer konnten wir jetzt machen, unabhängig davon wie wenig Rechte dem versteckten Nutzer eingeräumt wurden.  

Ein Beispiel sind Kerberoasting-Angriffe, die darauf abzielen, Service-Konten zu übernehmen, die nicht mit einem zufällig automatisch generierten Passwort, sondern mit einem menschlich erdachten Passwort gesichert sind. Einzige Voraussetzung für diesen Angriff ist der Zugriff auf ein funktionierendes Nutzerkonto in der Domäne. Dieser Nutzer muss gar keine Zugriffsrechte für den zu knackenden Dienst haben, daher funktioniert der Angriff auch mit dem versteckten Nutzer: 

Im Anschluss haben wir Zugriff auf ein Nutzerkonto mit mehr Zugriffsrechten, meist sogar einigen administrativen Rechten und können uns so immer weiter in der Partner-Domäne ausbreiten. 

Mögliche Detektions- und Gegenmaßnahmen 

In den nächsten Abschnitten wollen wir uns anschauen, wie man sich gegen diese Art von Angriffen wappnen kann und auch kurz Maßnahmen besprechen, die zwar naheliegend klingen, aber nicht wirken.  

All diese Maßnahmen zielen auf die Sicherheit der vertrauten Domäne (in unserem Beispiel PARTNER.local). Für die vertrauende Domäne (in unserem Beispiel HISOCORP.local) gibt es unabhängig von dem hier geschilderten Problem auch einiges zu beachten, um nicht durch die Vertrauensstellung Probleme zu bekommen. Da dies aber der geplante Zugriffsweg ist, gibt es dazu bereits passende Anleitungen

Detektion 

Das versteckte Nutzerkonto für die Vertrauensstellung wird nie als Nutzer im eigentlichen Sinn verwendet. Daher sind jegliche Aktivitäten mit der Nutzerkennung (Muster <Domänenkürzel>$) wie das Ausstellen eines TGT (Windows Event 4768), eines Service Tickets (Anfordern Windows Event 4769, Erneuern Windows Event 4770, Fehler Windows Event 4773) oder eine Anmeldung ein eindeutiges Zeichen für eine Ausnutzung.  

Gegenmaßnahmen 

Auf verschiedenen Wegen kann die Anmeldung mit dem versteckten Nutzerkonto verhindert werden. 

Die Systeme der beiden Domänen befinden sich meist auch in unterschiedlichen Netzen, daher kann per Firewall der Zugriff auf Port 88 zum Domain Controller der vertrauten Domäne (in unserem Beispiel PARTNER.local) vom Netz der vertrauenden Domäne (HISOCORP.local) gesperrt werden. In die umgekehrte Richtung ist der Zugriff nötig, damit Nutzer sich Service Tickets für freigegebene Dienste der vertrauenden Domäne ziehen können, in dieser Richtung jedoch nicht. Damit wird der Angriff verhindert, wenn der Angreifer aus dem anderen Netz agiert. Hat der Angreifer unabhängig von der Kompromittierung der vertrauten Domäne auch bereits Netzwerkzugriff auf Systeme der vertrauten Domäne, hilft die Firewallregel nicht. 

Die Nutzung des versteckten Kontos kann auch per GPO unterbunden werden. Dafür muss die Regel „Zugriff vom Netzwerk auf diesen Computer verweigern“ erstellt werden und dort dann manuell das Konto (in unserem Beispiel HISOCPRP$) eintragen werden. Der Kontoname muss händisch eingegeben werden, da bei der „Durchsuchen“-Funktion das Konto auch ausgeblendet ist. Wenn die GPO wirksam ist, kann zwar weiterhin ein TGT für dieses Konto bezogen werden, aber keine Servicetickets. Damit geht auch kein Zugriff auf Dienste (wie Dateifreigaben) oder der oben geschilderte Kerberoasting-Angriff. 

Als weitere Verteidigungsschicht können die Zugriffsrechte für den Nutzer eingeschränkt werden. Der Nutzer ist automatisch Mitglied in der Gruppe „Domänenbenutzer“ und gehört auch zur Gruppe „Benutzer“. Dienste und Dateien sollten nicht für eine der beiden Gruppen freigegeben werden, auch wenn sie von allen genutzt werden sollen. Stattdessen bieten sich für solche Freigaben eine zusätzlich gepflegte Gruppe mit allen aktiven Nutzern an. 

Maßnahmen, die nicht wirken 

Es gibt einige Gegenmaßnahmen, die sehr naheliegend klingen, aber tatsächlich nicht umsetzbar oder hilfreich sind.  

So kann der versteckte Nutzer nicht einfach deaktiviert oder gelöscht werden, entsprechende Versuche führen direkt zu Fehlermeldungen.  

Der Nutzer hat als primäre Gruppe die Gruppe „Domänenbenutzer“. Das ist eine automatische Gruppenzuordnung, das heißt man kann zwar eine andere primäre Gruppe eintragen aber der Nutzer wird dennoch immer Mitglied der „Domänenbenutzer“ bleiben. 

Fazit 

Aus einer einseitigen Vertrauensstellung zwischen Domänen kann sich damit auch ein Risiko entgegen der „Direction of Access“ ergeben. Wird die eine Domäne kompromittiert erhält der Angreifer auch das Passwort für einen versteckten Nutzer in der anderen Domäne. Der hat zwar kaum Zugriffsrechte, aber kann als erster „Fuß in der Tür“ für weiterführende Angriffe genutzt werden. 

Da Risiko lässt sich aber durch Firewallregeln, GPOs und gutes Rechtemanagement adressieren. Ein erfolgreicher Angriff lässt sich auch eindeutig in den Windows Events identifizieren. 


  1. Im Folgenden werden wir der Einfachheit halber immer von einer Domäne sprechen, da sich ganze Forests in diesem Fall wie eine Domäne verhalten ↩︎