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).
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
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.
Was waren denn bisher die Strategien bezüglich administrativer Konten? Wie wurde bisher die Aufklärung dieser Konten verhindert?
Die drei bisherigen Strategien:
Nix machen!
Hält von 12 Uhr bis Mittag.
Umbenennen!
Rekursives durchsuchen der Gruppen regelt.
rename + Honey pot!
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.
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.
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”.
Violà: weg ist er!
Der eine User.
Weg.
Der andere User:
Da.
Hm…
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:
- CN=Users,DC=CLOUD-HYBRID,DC=DE
- CN=Builtin,DC=CLOUD-HYBRID,DC=DE
- 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
CN=Builtin,DC=CLOUD-HYBRID,DC=DE
CN=AdminSDHolder,CN=System,DC=CLOUD-HYBRID,DC=DE
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:
“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?
- Tiering implementieren: einem nackten Mann greift man nicht in die Tasche.
- krbtgt-Passwortänderungen durchführen: alle 12 Stunden
- Passwortänderungen der DC beschleunigen: jeden Tag muss geändert werden
- RC4 bei Kerberos V5 abschalten: siehe Blogartikel “Kerberoasting“
- Windows LAPS einführen: DSRM-Passwörter ändern lassen
- kürzere Kerberos-Ticketlaufzeiten implementieren
- nutzen der Gruppe Protected Users: siehe Blogartikel “Protected Users“
- 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:
- Wann: 25.04.2024, ab 16:00 Uhr (UTC +2)
- Dauer: ca. 30 Minuten
- Link: https://events.teams.microsoft.com
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.