Adsisearcher – Get the Object of Interest: Suchen nach spezifischen Usern und Computern

Wie findet man ein spezifisches “Object of Interest” oder auch mehrere Objekte, die bestimmte Eigenschaften besitzen? Die Antwort hierauf ist so logisch wie einfach: man muss die richtigen Suchfilter kennen und angeben.

Zunächst gilt es zu unterscheiden, ob man nach einer Person oder nach einem Computer sucht. Hierbei bietet es sich an, nach den Attributen objectclass und objectcategory zu suchen. Während objectClass die Einordnung von User-Objekten in der Klassenhierarchie des Active Directory Schemas darstellt, hilft objectCategory als Zusatz zur Information der Objektklasse lediglich bei der Einordnung. objectClass ist hierbei ein Array, dass für User immer wie folgt aussieht:

und für Computer noch den Zusätzlichen Wert computer enthält:

Die im Array zuletzt angegebene Klasse ist die “structural class” (=Hauptklasse) und repräsentiert die eigentliche Objektklasse. Betrachtet man die beiden Attribute, so fällt auf, dass bei einer Suche nach der Objektklasse User wie im Beispiel sowohl Computerobjekte, als auch Userobjekte in der SearchResultCollection (= die Ergebnisse) enthalten sein werden.

Aus diesem Grund nutzt man als zusätzliche Angabe im Suchfilter die objectCategory. Es handelt sich um eine Single Value Eigenschaft, die dem Datentyp des Distinguished Name entspricht. Der Wert ist entweder der Distinguished Name der Klasse, von der das Objekt eine Instanz ist, oder einer ihrer Oberklassen. Wenn ein Objekt erstellt wird, setzt das System seine objectCategory auf den Wert, der in der defaultObjectCategory-Eigenschaft der Objektklasse angegeben ist. Der Wert kann nicht geändert werden. Im Beispiel sieht man die objectCategory eines Users:

Interessant ist an dieser Stelle, dass in der Filter-Syntax direkt der pure Kategoriename als objectCategory Wert verwendet werden kann – also objectCategory=Person statt objectCategory=CN=Person,CN=Schema,CN=Configuration,DC=example,DC=com. Dies ist bei anderen Attributen des Datentyps Distinguished Name nicht möglich. Der richtige Filter, um alle User mittels objectClass und objectCategory zu finden, wäre daher:

Für Computer kann man dem entsprechend diese Suche verwenden:

Die Suche nach Usern mit dem Filter (&(objectClass=user)(objectCategory=person)) wird auch oft vorgeschlagen, wenn man im Internet nach ldap-Suchfiltern sucht. Sie funktioniert, allerdings ist sie ineffizient und verbraucht relativ viel Server-Leistung. Das liegt daran, dass die Filterkriterien “objectClass” und “objectCategory” die technische Suche in der AD-Datenbank für den Server komplexer machen. Je mehr User in einer Domain sind, umso relevanter wird die Sucheffizienz. Alternativ kann man den Filter sAMAccountType=805306368 verwenden. Für das Attribut sAMAccountName gibt es einige Hexadezimalwerte, die jeweils einen Accounttypen ausweisen. Für Objekte des Typs User (SAM_USER_OBJECT) ist dieser Wert 0x30000000.[1] Rechnet man diesen Wert in einen Dezimalwert um, erhält man den Wert 805306368. Bei User Objekten ist der sAMAccountType Wert daher immer 805306368 und ist in der Active Directory Datenbank für schnelle Suchvorgänge indiziert. Mit folgendem Befehl kann man also effektiver nach allen Usern in der Domain suchen:

Oft möchte man jedoch bestimmte User mit spezifischen Eigenschaften suchen. Dazu kann der Zeitraum gehören, in dem ein User zuletzt eingeloggt war, der Zeitraum, in dem ein User erstellt wurde, oder ob ein User ein SPN (Service Principal Name) Account, also ein Service Account ist. Dies kann man mit Abfragen der den Objekten zugeordneten Attributen machen.

Object of Interest: Last Logon

Möchte man wissen, wann sich ein User zuletzt eingeloggt hat, kann man das mit dem Attribut lastLogon ermitteln. Der Wert des Attributs wird als Windows File Time angegeben, z.B.:

Hierbei handelt es sich um einen 64-bit Wert, der die Anzahl an 100-Nanosekundenintervallen angibt, die seit 12:00 Mitternacht, 1. Januar 1601 (UTC) verstrichen sind.[2]

Ist dieser Wert 0, war der User noch nie am DC angemeldet. So kann man ungenutzte Accounts erkennen, bei denen es zu prüfen gilt, ob sie gelöscht werden sollten, um die Angriffsoberfläche möglichst klein zu halten. Um alle User zu finden, die noch nie angemeldet waren, kann man also einfach nach dem Wert lastLogon=0 suchen:

Es kann jedoch auch von Interesse sein, alle User zu finden, die z.B. seit 30 Tagen nicht mehr angemeldet waren. Dazu muss man den Wert des Attributs vergleichen. Hier bietet es sich an den Vergleichswert – eine Zeitangabe, die man man mit Get-Date erhalten kann – in das Windows File Time Format zu konvertieren, was man wiederum mit ToFileTime() erledigen kann. Zunächst muss man den Zeitraum mit (Get-Date).AddDays(-30) angeben. Da Zeiten in LDAP als UTC Zeit gespeichert werden, muss man außerdem noch ToUniversalTime() nutzen. Um den Wert in Windows File Time umzuwandeln, nutzt man dann die Methode ToFileTime(). Mit dem Operator <= werden dann nur Benutzer gesucht, deren lastLogon Wert kleiner ist – also zeitlich vor dem angegebenen Zeitpunkt liegen.

Eine Suche nach allen Usern, die seit mehr als 30 Tagen nicht mehr angemeldet waren, sieht dann wie folgt aus:

Es ist auch möglich, diese Suche nach Stunden und Minuten einzugrenzen, indem man zusätzlich noch AddHours() und AddMinutes() verwendet. Ein Beispiel wären alle User, die seit einem Tag, fünf Stunden und 30 Minuten nicht eingeloggt waren:

Es kann natürlich auch sehr nützlich sein, den letzten Logon eines Users einfach ablesen zu können, was sich bei dem Windows File Time Format für Menschen doch als etwas umständlich darstellen dürfte. Um sich den Wert des lastLogon eines bestimmten Users in einem angenehmen, human-readable Format angeben zulassen kann man den Type Accelerator DateTime wie folgt verwenden:

Beispiel Output:

Object of Interest: Time of Creation

Nicht nur der letzte Logon, auch der Erstellungszeitpunkt eines Users wird als Wert im Attribut whencreated gespeichert und kann mit folgender Abfrage ausgegeben werden:

Im Gegensatz zu lastLogon erhält man das Output hier sogar in einem human-readable Format. Allerdings wird der Wert eigentlich als YMD LDAP-timestamp gespeichert, sodass bei einem Vergleich hier anders vorgegangen werden muss. Die YMD LDAP-timestamps beginnen mit der Jahreszahl und haben das folgende Format: YYYYMMDDHHMMSST. Der Wert T am Ende ist die Zeitzone, die normalerweise Z ist (Zulu Time Zone = UTC/GMT). Um hier einen Vergleichswert zu schaffen, kann man den Format Operator (-f) verwenden, der die folgende Syntax benötigt:

Der String mit Platzhaltern beschreibt hier dann das YMD Format {0:yyyyMMddHHmmss.0Z} und im Array kann mit Get-Date ein bestimmter Zeitwert aufgerufen werden, der dann in das angegebene Format umgewandelt wird. Zum Vergleich können auch hier die Operatoren <= oder >= verwendet werden.

Mit folgender Abfrage kann man alle User finden, die vor 7 Tagen, einer Stunde und fünf Minuten erstellt wurden:

Und mit dieser Abfrage findet man alle User, die nach diesem Zeitpunkt erstellt wurden:

Man kann sogar nach Usern suchen, deren Erstellung in einem bestimmten Zeitraum stattgefunden haben, dazu setzt man einfach zwei Suchfilter. Im folgenden Beispiel gibt die erste whencreated Suche den frühsten und die zweite Suche den spätesten Zeitpunkt des gesuchten Zeitraums an:

Object of Interest: SPN Account

Service Principal Names (SPNs) werden in Active Directory verwendet, um Dienste in die Kerberos-Authentifizierung einzubinden. Über Kerberos können Tickets für die SPNs angefordert werden. Es ist möglich, offline die Verschlüsselung der Tickets zu knacken, was besonders dann nützlich für Angreifer ist, wenn SPNs an Benutzerkonten gebunden sind – dies ist bei Dienstkonten üblich. Man sollte also einen guten Überblick über die SPN Accounts behalten.

Ist ein Account ein SPN Account, besitzt er das Attribut servicePrincipalName, nach welchem man suchen kann. Da gewöhnliche User dieses Property nicht besitzen, kann man in der Suche mit =* einfach prüfen, ob das Attribut bei einem Account existiert, um ihn als SPN Account zu identifizieren. Der Wert von servicePrincipalName enthält außerdem oft Informationen über den Service und kann wie folgt aussehen: smtp/DC1.example.com:145

Eine Suche nach allen SPN Accounts sähe dann wie folgt aus:

Möchte man zusätzlich alle Computeraccounts ausschließen, die typischerweise auf $ enden, kann man diese Suche nutzen:

Ein Augenmerk sollte man auch auf Service Accounts haben, die schon einmal eingeloggt waren und ggf. prüfen, ob dies berechtigte Logins sind:

Object of Interest: Computer

Die in der Domain angebundenen Computer kann man – wie zu Beginn erwähnt – ebenfalls mit einer Suche nach Objektklasse und Objektkategorie Computer finden ((&(objectClass=computer)(objectCategory=computer))). Eine zweite Möglichkeit ist die Suche nach der Primary Group ID. Die Primary Group ID dient der POSIX-Kompatibilität, also für eine mögliche Interaktion mit Unix-Systemen und wird von Windows selbst nicht benötigt. Sie ist jedoch bei jedem Objekt eingetragen. Der POSIX Standard sieht vor, dass jeder Benutzer (genau) einer Gruppe angehört. Dies bildet Windows als “Primary Group” ab. Die Primary Group wird beim Erstellen automatisch direkt im Objekt im Feld “primaryGroupID” gespeichert. Hier wird nicht der Name der Gruppe, sondern die RID (Relative Identifier = der letzte Abschnitt der SID [Security Identifier]) gespeichert.

Für Computer relevant sind folgende Primary Group IDs:

  • 515 = Domain Computer
  • 516 = Domain Controller
  • 521 = read-only Domain Controller

Mit den folgenden Suchen kann man dann spezifisch nach Computern, Domain Controllern oder read-only Domain Controllern in der Domain suchen:

Wenn man Informationen über die Betriebssysteme der in der Domain
angebundenen Computer erlangen möchte, kann man sich z.B. alle Betriebssysteme ausgeben lassen, indem man mit der Methode FindAll() nach (&(objectClass=computer)(objectCategory=computer)) sucht und sich nur die Werte für operatingSystem ausgeben lässt:

Man kann aber auch gezielt nach bestimmten Betriebssystemen suchen:

Es ist auch möglich mittels Wildcard(s) nach Betriebssystemen zu suchen, die einen bestimmten Begriff enthalten:

Mit den aufgeführten Suchen kann man bereits sehr viele Informationen über User zusammentragen, die dazu beitragen können, einen guten Überblick über ein Active Directory zu erlangen, sowie auch “Karteileichen” ausfindig zu machen. Mit adsisearcher kann man aber auch noch mehr herausfinden, wie z.B. Gruppenzugehörigkeiten. Es gilt also neugierig zu bleiben und mehr über adsisearcher zu lernen.

Serienübersicht

[1] 2.223 Attribute sAMAccountType: Microsoft Documentation, https://docs.microsoft.com/en-gb/openspecs/windows_protocols/ms-ada3/7879be50-7109-41e4-9a44-02f5a007b950

[2] File Times: Microsoft Documentation, https://docs.microsoft.com/en-us/windows/win32/sysinfo/file-times

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