Scroll Top

Become an invisible admin

Martin Handel

Bei mir “um die Ecke” haben die “bösen Jungs”, bei einem Batteriehersteller, großflächig die Server verschlüsselt.

Daher nehme ich den Ball auf um einen der vielen Steine im Mosaik mit dem Namen “AD-Security” zu zeigen. Namentlich geht es um den List Object Mode (LOM), welcher schon etwas älter* ist.

*ich meine seit AD 2003, muss aber noch mal recherchieren**

**Ja, mindestens seit 2003 R2 / 2003 SP1 (zur Erinnerung, das war im Jahr 2005).

LOM-2003R2

List Object Mode und Security

Was hat das Ganze “List Object Mode”-Zeug mit On-Premises AD-Security zu tun?

Relativ einfach erklärt: nicht aufklärbar sein (siehe Punkt 4).

Von außen, z. B. als Domänen-Benutzer, sollte nicht erkennbar sein, wer ein hochprivilegiertes Konto ist. Um ein hochprivilegiertes Konto zu erkennen kann der Domänen-Benutzer, sofern versiert, eine PowerShell- oder LDAP-Abfrage machen. Wir haben es bei Active Directory mit einem “read many”-Verzeichnis zu tun.

Hierüber bekomme ich schnell eine Übersicht, wer administrativ unterwegs ist.

Administrative Konten sind für eine angreifende Partei mit Sicherheit attraktiver als unprivilegierte Konten.

Per (Windows) PowerShell:

Get-ADGroupMember -Identity Administrators -Recursive
List-Admins

Update zum Webinar-Termin, 25.04.2024

Discovery per ADSI

Für die Gruppe der “Built-in Administratoren”

$DN = ([adsisearcher]"(&(objectClass=group)(objectsid=S-1-5-32-544))").FindAll().properties.distinguishedname
([adsisearcher]"(&(memberOf:1.2.840.113556.1.4.1941:=$DN)(objectclass=user))").FindAll().properties.samaccountname

Für die Gruppe der “Domain Admins”

$DomainSID = (New-Object System.Security.Principal.SecurityIdentifier([byte[]](([adsi]"LDAP://cloud-hybrid.de").Properties."objectSID")[0],0)).toString()
$DomAdminRid = '-512'
$DomAdminObjectSID = $DomainSID + $DomAdminRid
$DN = ([adsisearcher]"(&(objectClass=group)(objectsid=$DomAdminObjectSID))").FindAll().properties.distinguishedname
([adsisearcher]"(&(memberOf:1.2.840.113556.1.4.1941:=$DN)(objectclass=user))").FindAll().properties.samaccountname
Discovery per PowerShell-Modul ActiveDirectory

Für die Gruppe der “Built-in Administratoren”

$AdminGroupSID = 'S-1-5-32-544'
$AdminGroup = Get-ADObject -Filter { objectSid -eq $AdminGroupSID }
(Get-ADGroupMember -Identity $AdminGroup.DistinguishedName -Recursive).sAMAccountName

Für die Gruppe der “Domain Admins”

$DomAdminGroupRID = '-512'
$DomainSID = (Get-ADDomain).DomainSID
$DomainAdminSID = $DomainSID.Value + $DomAdminGroupRID
$DomAdminGroup = Get-ADObject -Filter { objectSid -eq $DomainAdminSID }
(Get-ADGroupMember -Identity $DomAdminGroup.DistinguishedName -Recursive).sAMAccountName

List Object Mode (LOM)

Der List Object Mode, oder später hier mit “LOM” abgekürzt, ist ein Feature des Active Directory, welches die Sichtbarkeit von Objekten steuert.

Active Directory läuft “out of the box” im “list contents mode”. Das bedeutet, salopp formuliert, dass man sich schwer tut Objekte zu verstecken. Möchte ich beispielsweise die User in der OU OU=Users,OU=ADDS,OU=Tier0,OU=ESAE,DC=CLOUD-HYBRID,DC=DE verstecken, könnte man auf das Recht “List contents / Read all properties / Read permissions” mit “Deny” setzen.

Für ein Mitglied von Tier2-Allow sieht das dann aber komisch aus, Verstecken geht anders.

Deny Permission
Tier2-Allow unknown object
Well...

Was waren denn bisher die Strategien bezüglich administrativer Konten? Wie wurde bisher die Aufklärung dieser Konten verhindert?

Die drei bisherigen Strategien:

How not to be seen

Nix machen!

How not to be seen - I
How not to be seen - I - result

Hält von 12 Uhr bis Mittag.

Umbenennen!

How not to be seen - II
How not to be seen - II - result

Rekursives durchsuchen der Gruppen regelt.

rename + Honey pot!

How not to be seen - III
How not to be seen - III - result

Netter Versuch, aber rekursives Durchsuchen der Gruppen regelt.

Um richtig zu verstecken brauchen wir den LOM. Ich empfehle den LOM seit 2013 um sensible AD-Objekte vor neugierigen Blicken zu schützen.

DSHeuristics!

Über die dSHeuristics wird der LOM aktiviert.

Die dSHeuristics ist ein Attribut, welches sich in der Configuration im Objekt Directory Services findet (CN=Directory Service,CN=Windows NT,CN=Services,CN=Configuration,DC=<domain-name>,DC=<tld>).

Dieses Attribut, dSHeuristics, steht normaler Weise auf “<not set>”, zumindest “out of the box”.

Setzt man dSHeuristics auf “001”, wird der LOM aktiviert. Kein Neustart von DCs, Memberservern, Clients oder Diensten ist hier notwendig. Setzen, fertig.

dSHeuristics default
dSHeuristics 001
dSHeuristics

Vorsicht!

Die dSHeuristics ist ein Attribut mit der Syntax “Big Endian” und durch den Speicherort, Configuration, gilt eine solche Änderung im gesamten Forest!

Was bringt jetzt der LOM?

Eine neue Berechtigung!

“List object”

Daher auch der Name: List object mode.

LOM

Der LOM schaltet also “List object” frei.

Das alleine reicht nicht.

“List object” muss immer am Eltern-Objekt mit “List contents” kombiniert werden.

Möchte ich verhindern, dass jemand ein Objekt sieht, muss am Elternobjekt das Recht “List contents” entzogen werden und am eigentlichen Objekt das Recht “List object” entzogen werden.

Die Gruppe “Authenticated Users” hat immer “Read” für “List contents”. Da ich nichts davon halte die vordefinierten Berechtigungen zu kürzen, füge ich lieber hinzu. Wenn auch, wie hier, mit der Notwendigkeit eines “Deny”.

Deny-List-Contents
Deny-List-Object

Violà: weg ist er!

Der eine User.

Weg.

Der andere User:

Da.

Hm…

Weg issa!

SDProp / admincount=1

Der Fluch wird jetzt ein Segen!

Was habe ich nicht schon gestöhnt über den SDPropagator / SDProp, welcher in Verbindung mit dem PDCE die “geschützten Objekte” schützt.

Nun jedoch wird der Fluch zum Segen: SDProp hilft uns den Schutz voll automatisch auszurollen! Noch drei ACL-Änderungen und wir sind fertig mit der Arbeit, die Admins versteckt und der Angreifer schaut hier mit den Ofenrohr ins Gebirge.

Wir müssen noch editieren:

  1. CN=Users,DC=CLOUD-HYBRID,DC=DE
  2. CN=Builtin,DC=CLOUD-HYBRID,DC=DE
  3. CN=AdminSDHolder,CN=System,DC=CLOUD-HYBRID,DC=DE

Bitte selbständig folgende Transferleistung erbringen: DC=CLOUD-HYBRID,DC=DE in den jeweils eigenen, passenden DN übersetzen, vielen Dank.

CN=Users,DC=CLOUD-HYBRID,DC=DE

Users-Permissions-LOM

CN=Builtin,DC=CLOUD-HYBRID,DC=DE

Builtin-Permissions-LOM

CN=AdminSDHolder,CN=System,DC=CLOUD-HYBRID,DC=DE

AdminSDHolder-Permissions-LOM

W wie weg

Nach spätestens 1 Stunde galloppiert der PDCE los und propagiert die neue ACL auf alle geschützten Objekte.

Das Ergebnis überzeugt:

Sicht des eines Administrators:

Sicht eines Tier2-Allow-Users:

LOM-Result-2
LOM-Result-3
LOM-Result-4

“This demonstrates the value of not being seen.”

Security by obscurity kann nicht alleine die Lösung sein, schon klar.

Vielmehr sollte man man die Unsichtbarkeit vom Tier0, wie bereits oben genannt, als ein Stein im Mosaik “AD-Security” betrachten.

So mal unter uns Gebetsschwestern: was sind denn da noch für Steine im Mosaik?

  1. Tiering implementieren: einem nackten Mann greift man nicht in die Tasche.
  2. krbtgt-Passwortänderungen durchführen: alle 12 Stunden
  3. Passwortänderungen der DC beschleunigen: jeden Tag muss geändert werden
  4. RC4 bei Kerberos V5 abschalten: siehe Blogartikel “Kerberoasting
  5. Windows LAPS einführen: DSRM-Passwörter ändern lassen
  6. kürzere Kerberos-Ticketlaufzeiten implementieren
  7. nutzen der Gruppe Protected Users: siehe Blogartikel “Protected Users
  8. Default Domain und Default Domain Controllers Policy anpassen: Stichworte Tiering und der Klassiker “Add workstations to domain”

Webinar zum dem Thema am 25.04.2024 ab 16:00 Uhr (UTC +2) – Dauer ca. 30 Minuten

Ich biete zu dem Thema ein kurzes, kostenfreies Webinar an:

Nachtrag zum Webinartermin, 25.04.2024 – 16:00 Uhr

Im Webinar kam die Frage auf (vielen Dank dafür), wie man diesen “Sichtschutz” für das Tier1 implementieren kann. Hier gibt es, meine Auffassung nach, zwei praktikable Möglichkeiten, die sich im logistischen Aufwand unterscheiden:

Lösung A: Tier1-Gruppen manuell mit admincount=1 markieren

Die Tier1-Gruppen werden manuell mit dem Attributwert “1” beim Attribut “admincount” versehen. Die Berechtigungen werden dann durch den PDC-E wie bei den Tier0-Konten propagiert. Die Berechtigungsvergabe erfolgt analog zu dem Schutz von Tier0, jedoch: die Tier1-Gruppen müssen bei den Berechtigungen in der OU-Struktur berücksichtigt werden.

Lösung B: Tier1-Gruppen manuell schützen

Wie Lösung A, zusätzlich muss die ACL bei jeder Tier1-Gruppe und bei jedem Tier1-User manuell gepflegt werden. Hierzu kann, beispielsweise, eine geplante Aufgabe / scheduled task herangezogen werden. Ein möglicher, überschaubarer Ansatz wäre es, über eine AD-Abfrage mit Namen, welche mit “T1” beginnen, die ACL schreiben zu lassen.

Egal wie, ein Blick in die Bildergallerie sollte es verdeutlichen.

Letzte Anmerkung:

Will man das Tier0 vor dem Tier1 und Tier2 verbergen, so ist anstelle von Tier2-Allow die Gruppe Tier0-Deny geeignet.

Related Posts