CZ 
06.10.2024 Hanuš VÍTEJTE V MÉM SVĚTĚ

An English translation is available for this article. Pro tento článek je dostupný anglický překlad.
Kerberos disabling RC4 part 2 - moving from RC4 to AES

Kerberos deaktivace RC4 část 2 - přechod z RC4 na AES

| Petr Bouška - Samuraj |
V první části jsme se věnovali teorii fungování Kerberos protokolu a volbě typu šifrování. Dnes navážeme praktickými příklady. Jak detekovat tickety s RC4. Jak hledat účty, které nemají povolen AES nebo nemají vystaveny AES klíče. Jaké informace a chyby můžeme nalézt mezi událostmi v logu na doménovém řadiči. Kde mohou být problémy, pokud používáme Keytab soubory. Pro většinu věcí budeme využívat PowerShell. Na závěr si uvedeme jak vynutit použití AES a zablokovat RC4.
zobrazeno: 2 185x (1 822 CZ, 363 EN) | Komentáře [0]

Zablokování RC4 v Kerberos protokolu a přechod na AES

Již řadu let se doporučuje přestat používat (zablokovat) šifru RC4 a kompletně přejít na AES. Aktualizace 11/2022 udělala malý krok tímto směrem. Teorii jsme si popsali v minulém článku Kerberos deaktivace RC4 část 1 - princip protokolu a typy šifrování. Pro pochopení praktických dopadů a speciálních situací je dobré se s ní seznámit.

Samozřejmě nesmíme mít v síti systémy, které AES nepodporují. To je například Windows Server 2003, Windows XP či nějaké staré non-Microsoft systémy. Problém může být i se síťovými zařízeními, třeba staré diskové pole, které se využívá jako souborový server. Vypadá to, že je problém s podporou i na samostatném ESXi (vCenter AES podporuje a ESXi pro jiná použití než Kerberos také).

Identifikace ticketů šifrovaných pomocí RC4

Než budeme měnit nastavení (blokovat RC4), tak je dobré zjistit, kde se RC4 používá. Optimální postup je následně testovat změnu pro určité systémy. Některé situace vyžadují provést konfigurační změny.

Detekce ticketů vystavených s RC4

Pokud máme zapnuté auditování Audit Kerberos Service Ticket Operations (Auditování bezpečnostních událostí Windows v doméně), tak v Security logu na doménovém řadiči (DC) nalezneme informace o vystavených ticketech. Mezi informacemi je také uvedeno použité šifrování (Ticket Encryption Type).

Kódy hlavních typů šifrování jsou

  • 0x3 (3) - DES-CBC-MD5
  • 0x11 (17) - AES128-CTS-HMAC-SHA1-96
  • 0x12 (18) - AES256-CTS-HMAC-SHA1-96
  • 0x17 (23) - RC4-HMAC
  • 0x18 (24) - RC4-HMAC-EXP

Jedná se o událost Event ID 4769 pro Service Ticket a Event ID 4768 pro TGT. Obsah vypadá následně

A Kerberos service ticket was requested.

Account Information:
	Account Name:     bouska@FIRMA.LOCAL
	Account Domain:   FIRMA.LOCAL
	Logon GUID:       {dad1327c-bdf9-564f-6a17-d8ce4788d2dc}

Service Information:
	Service Name:     app-sso
	Service ID:       FIRMA\app-sso

Network Information:
	Client Address:   ::ffff:10.0.10.2
	Client Port:      63670

Additional Information:
	Ticket Options:         0x40810000
	Ticket Encryption Type: 0x17
	Failure Code:           0x0
	Transited Services:     -

Pozn.: V některých PowerShell příkladech níže se používá speciální znak ` pro rozdělení řádku (příkazu), aby se lépe zobrazilo na webu (běžně může následovat odřádkování po | a ,).

Pokud máme centrální logování, tak můžeme prohledat logy v našem nástroji. Nebo musíme procházet jednotlivé DC pomocí Event Viewer. V článku HOWTO: Detect Kerberos tickets that are encrypted using RC4 je uveden pěkný PowerShell skript, který nám toto hledání zjednoduší. Musíme jej spustit na každém DC. Zobrazí údaje o Service Ticket vystavených s RC4 šifrováním.

$Events = Get-WinEvent -Logname security `
 -FilterXPath "Event[System[(EventID=4769)]]and Event[EventData[Data[@Name='TicketEncryptionType']='0x17']]or Event[EventData[Data[@Name='TicketEncryptionType']='0x18']]" |
 Select-Object `
 @{Label='Time';Expression={$_.TimeCreated.ToString('g')}}, 
 @{Label='UserName';Expression={$_.Properties[0].Value}},
 @{Label='IPAddress';Expression={$_.Properties[6].Value}},
 @{Label="ServiceName";Expression={$_.properties[2].value}},
 @{Label="EncryptionType";Expression={$_.properties[5].value}}
$Events | Out-Gridview

Případně jej můžeme spustit centrálně, kdy se vzdáleně volá pro všechny doménové řadiče. Pro informace o TGT změníme Event ID na 4768.

$dcs = Get-ADDomainController -Filter * | Select Name -ExpandProperty Name
$Events = ForEach ($dc in $dcs) {
  Get-WinEvent -ComputerName $dc -Logname security `
    -FilterXPath "Event[System[(EventID=4769)]]and Event[EventData[Data[@Name='TicketEncryptionType']='0x17']]or Event[EventData[Data[@Name='TicketEncryptionType']='0x18']]" |
    Select-Object `
    @{Label='Time';Expression={$_.TimeCreated.ToString('g')}},
    @{Label='UserName';Expression={$_.Properties[0].Value}},
    @{Label='IPAddress';Expression={$_.Properties[6].Value}},
    @{Label="ServiceName";Expression={$_.properties[2].value}},
    @{Label="EncryptionType";Expression={$_.properties[5].value}},
    MachineName
}
$Events | Sort-Object TimeCreated -Descending | Out-Gridview

V seznamu uvidíme Service Ticket šifrované pomocí RC4, tedy aktivně využívané služby. Jde o to, jak máme dlouhou historii, některé méně využívané služby se zde nemusí objevit. V praxi zde často uvidíme servisní účty, ke kterým je vystaven Keytab soubor.

Pozn.: V události 4768 můžeme vidět, že bylo použito RC4 pro TGT. Ale často jde o šifrování Session Key (a ne ticketu). Pokud klient podporuje pouze RC4, tak během pre-authentication je Session Key pro TGT šifrován pomocí RC4, ale vlastní TGT je šifrován pomocí AES.

Ověření ticketů na klientovi

Druhá možnost je zobrazit vystavené tickety na klientovi. Můžeme pracovat s so nejvíce informačními systémy (službami) a následně si zobrazit tickety pomocí příkazu klist. Více informací v minulém článku Informace o získaných Kerberos Service Ticket na klientovi.

Kontrola účtů v Active Directory

Pomocí PowerShellu můžeme nalézt mnoho informací o účtech v AD a vypsat si účty s určitými hodnotami. Využít můžeme cmdlety Get-ADUser, Get-ADComputer, Get-ADServiceAccount či Get-ADObject. Některé atributy můžeme číst jako běžný uživatel, ale pro řadu musíme mít dostatečná oprávnění (Domain Admin).

Na internetu nalezneme různé skripty, které provádí hromadné kontroly. Zajímavý je 11Bchecker, i když je zaměřen na problémy s updatem 11/2022. Další skript QuickChecks (popis How Do I Know If My AD Environment Is Impacted By The November 8th 2022 Patch?), z kterého můžeme čerpat informace. Zaměřuje se na zobrazení informací, kde není povoleno RC4, ale můžeme upravit. Je zde definována funkce Get-ETypeDefinition, která nám ve výstupech může zobrazit typy šifrování místo kódů atributu msDS-SupportedEncryptionTypes.

Minule jsme si uvedli Hodnoty atributu msDS-SupportedEncryptionTypes.

Uživatelské (servisní) účty (bez AES)

Zajímavé jsou uživatelské účty, které mají nastaven Service Principal Name (SPN). Ty se využívají jako servisní účty pro určitou službu. Výpis všech těchto účtů.

Get-ADUser -filter 'servicePrincipalName -like "*"' -properties msDS-SupportedEncryptionTypes, servicePrincipalName,
 whenCreated | Select sAMAccountName, servicePrincipalName, msDS-SupportedEncryptionTypes

V některých situacích se může hodit zobrazení kdy byl účet vytvořen a kdy bylo naposledy změněno heslo.

Get-ADUser -filter 'servicePrincipalName -like "*"' -properties msDS-SupportedEncryptionTypes, servicePrincipalName,
 whenCreated, passwordLastSet, LastLogonDate | FT sAMAccountName, servicePrincipalName, msDS-SupportedEncryptionTypes,
 whenCreated, passwordLastSet, LastLogonDate, Enabled

Pozn.: Datum posledního přihlášení v atributu LastLogonDate (lastLogonTimestamp), nemusí obsahovat správný údaj. Pro přesnou hodnotu musíme načíst atribut LastLogon ze všech DC a vzít poslední hodnotu. Níže je příklad zobrazení datumů pro uživatele UZIVATEL.

Get-ADDomaincontroller -Filter * | % {$DC = $_.name ; Get-ADuser UZIVATEL -properties * -Server $_.name |
 Select @{n="LastLogon";e={[datetime]::FromFileTime($_.lastlogon)}},@{n="DC";e={$DC}} }

Můžeme si vypsat pouze ty účty, které nemají vyplněn atribut msDS-SupportedEncryptionTypes, takže se používá defaultní hodnota.

Get-ADUser -filter 'servicePrincipalName -like "*" -and (msDS-SupportedEncryptionTypes -eq 0 -or `
 msDS-SupportedEncryptionTypes -notlike "*")' -properties msDS-SupportedEncryptionTypes, servicePrincipalName |
 Select sAMAccountName, servicePrincipalName, msDS-SupportedEncryptionTypes

Nebo takové účty, kde je povoleno RC4.

Pozn.: Bitový operátor band (AND) filtruje hodnoty, kde je nastaven daný bit.

Get-ADUser -filter 'servicePrincipalName -like "*" -and msDS-SupportedEncryptionTypes -band 0x4' `
 -properties msDS-SupportedEncryptionTypes, servicePrincipalName | Select sAMAccountName, servicePrincipalName,
 msDS-SupportedEncryptionTypes

Další možnost je vypsat všechny objekty, které mají nastaveno RC4, ale ne AES128 ani AES256. Tedy povolují použít pouze RC4.

Get-ADObject -Filter 'msDS-SupportedEncryptionTypes -bor 0x4 -and -not msDS-SupportedEncryptionTypes -bor 0x18' `
 -properties msDS-SupportedEncryptionTypes | Select Name, objectClass, msDS-SupportedEncryptionTypes

Staré účty, které mají heslo nastaveno před podporou AES, mají vytvořeny pouze DES a RC4 klíče. Je potřeba jim dvakrát změnit heslo (třeba na původní), aby se vytvořily všechny klíče. Můžeme si zobrazit účty, kde bylo heslo změněno dříve než nějaký rok. Více tento problém rozebereme v další kapitole.

Get-ADUser -filter * -properties whenCreated, passwordLastSet | Where-Object {$_.PasswordLastSet -lt (Get-Date -Year 2009)} |
 Sort-Object PasswordLastSet | FT sAMAccountName, distinguishedName, whenCreated, passwordlastset

Asi historická věc. Na uživatelském účtu můžeme nastavit, že je povolen pouze DES. Tím se nastaví bit 0x200000 (UF_USE_DES_KEY_ONLY) atributu UserAccountControl. Kontrola, zda je někde nastaveno.

Get-ADUser -Filter 'UserAccountControl -band 0x200000'

Když řešíme různé účty, tak můžeme hledat, na jakém počítači byl určitý účet použit. Řešení je prohledat Security log na doménovém řadiči. Určitý náznak možností, který by se dal hodně vylepšit, je uveden níže.

Get-WinEvent -FilterHashtable @{logname='security';id=4624;data='USERNAME'} |
 Select-Object -Property timecreated,
 @{label='username';expression={$_.properties[5].value}},
 @{label='computername';expression={$_.properties[11].value}},
 @{label='IP';expression={$_.properties[18].value}}

Počítačové účty (bez AES)

Další oblast jsou počítačové účty. Ty mají (téměř) všechny nastaveno SPN. Většinou mají také nastaven atribut msDS-SupportedEncryptionTypes, ale nemusí to být vždy. Můžeme si vypsat kolik existuje účtů s jakou hodnotou atributu.

Get-ADComputer -Filter * -Properties msDS-SupportedEncryptionTypes | Group-Object msDS-SupportedEncryptionTypes |
 Select Count, Name

Count Name
----- ----
  613 28  
    1 16  
   16 31  
    5     
    1 24  

A pak zobrazit jaké počítače se nachází v určité kategorii. První příklad zobrazí počítače s hodnotou atributu 31 (DES, RC4, AES), druhý s prázdným atributem.

Get-ADComputer -Filter 'msDS-SupportedEncryptionTypes -eq 31' -Properties msDS-SupportedEncryptionTypes |
 Select Name, DNSHostName

Get-ADComputer -Filter 'msDS-SupportedEncryptionTypes -notlike "*"' -Properties msDS-SupportedEncryptionTypes |
 Select Name, DNSHostName

Můžeme vypsat počítače v určitém AD kontejneru, spolu s hodnotou atributu msDS-SupportedEncryptionTypes.

Get-ADComputer -Filter * -SearchBase "OU=Počítače,DC=firma,DC=local" -Properties msDS-SupportedEncryptionTypes |
 Select Name, DNSHostName, msDS-SupportedEncryptionTypes

Některá zařízení připojená do domény (jako třeba Synology NAS, VMware vCenter) či speciální účty (AZUREADSSOACC) nemusí mít vyplněn atribut msDS-SupportedEncryptionTypes, takže defaultně používají RC4. Nebo (některé) Linuxové systémy mají povoleny všechny šifry 0x1F (31).

Účty bez (použitelných) AES klíčů

V minulém díle jsme si popsali princip Kerberos protokolu. Z toho plyne potřeba, mít u účtu vystavené odpovídající klíče, aby se mohl použít určitý typ šifrování.

Přihlášení uživatele (TGT)

Při přihlášení (vystavení TGT) použije uživatel svůj klíč pro zašifrování Authenticator a DC pomocí něj zašifruje odpověď se Session Key. Pokud u uživatelova účtu v AD existuje pouze RC4 klíč, tak se šifruje pomocí RC4. Ale pokud klient (počítač) i DC podporuje AES, tak se TGT i Session Key vystaví s AES (příklady Kerberos paketů jsou v první části Volba typu šifrování pro TGT).Nikde v logu ani ve výpisu ticketů neuvidíme, že má uživatel pouze RC4 klíč. Podpora RC4 šifrování je nutná, aby se uživatel přihlásil, i když se použije pouze pro šifrování prvotní komunikace.

Až když zablokujeme RC4 na DC nebo klientově počítači (pomocí politiky), tak klient nezíská TGT (DC má pouze RC4 klíč, ale tato šifra není povolena). Na požadavek AS-REQ se vratí chyba KRB5KDC_ERR_ETYPE_NOSUPP.

Kerberos komunikace, když není k dispozici podporovaný klíč

Pozn.: Nutno dodat, že standardně, když se uživateli nepovede přihlásit pomocí Kerberos, tak dojde k přepadu na NTLM a uživatel se přihlásí (ale Kerberos samozřejmě nefunguje). Ale již si nemůže změnit heslo (standardně na tomto počítači), protože se využívá Keberos služba. Zobrazí se chyba The encryption type requested is not supported by the KDC. Pokud zablokujeme RC4 na Exchange serveru, tak se nepovede nastavit heslo ani přes OWA. Ač opět přihlášení do OWA nebo třeba ActiveSync funguje (do System logu na DC se zapisuje událost ID 14 ... did not have a suitable key for generating a Kerberos ticket ).

Přihlášení ke službě (Service Ticket)

Při přihlášení ke službě (vystavení Service Ticket) použije DC klíč služby pro zašifrování Service Ticket. Pokud u účtu služby existuje pouze RC4 klíč, tak se použije RC4. Jedině když zablokujeme RC4 na DC, tak se Service Ticket nevystaví. Měl by se uplatnit atribut msDS-SupportedEncryptionTypes u účtu služby, ale i když zde nastavíme pouze AES, tak se budou vystavovat Service Ticket s RC4. Uvedli jsme si, že RC4 se přidává automaticky z důvodu kompatibility. Informaci, že byl ticket vystaven s RC4, nalezneme v logu DC.

Když zablokujeme RC4, a účet nemá dostupné AES klíče, tak by se měla logovat událost na doménovém řadiči do systémového logu (zdroj Microsoft-Windows-Kerberos-Key-Distribution-Center), že nelze vystavit Kerberos ticket. Při testech se někdy zpráva neobjevila, pouze v Security logu událost ID 4771 Kerberos pre-authentication failed.

ID 14 ... did not have a suitable key for generating a Kerberos ticket (the missing key has an
 ID of 1). The requested etypes : 18 17 3. The accounts available etypes : 23.

A proč nemá některý účet vystaveny AES klíče?

Nejčastěji proto, že byl vytvořen dříve, než byla do naší domény přidána podpora AES (která přišla s Windows Server 2008, funkční stupeň domény 2008). A následně nedošlo ke dvěma novým nastavením/změnám hesla. Existuje rada, jak poznat, kdy byla v doméně přidána podpora AES. Jde o datum vytvoření skupiny Read-only Domain Controllers. Můžeme jej zobrazit

(Get-ADGroup -filter * -properties SID,WhenCreated | where-object {$_.SID -like '*-521'}).WhenCreated

úterý 19. ledna 2010 16:58:14

Pokud měl účet naposledy změněné heslo před tímto datem, tak určitě nemá AES klíče. Příklad vyhledání různých typů objektů.

$AESdate = (Get-ADGroup -filter * -properties SID,WhenCreated | where-object {$_.SID -like '*-521'}).WhenCreated

Get-ADObject -filter * -properties whenCreated, pwdlastset | Where-Object {$_.pwdlastset -gt 0 -and $_.pwdlastset -lt `
 $AESdate.ToFileTime()} | Sort-Object pwdlastset | FT Name, ObjectClass, distinguishedName, whenCreated,
 @{Label='passwordlastset';Expression={[DateTime]::FromFiletime([Int64]::Parse($_.pwdlastset))}}

Jednodušeji se pracuje pouze s uživatelskými účty (což nám často může stačit).

Get-ADUser -filter * -properties whenCreated, passwordLastSet, LastLogonDate | Where-Object {$_.PasswordLastSet -gt 0 `
 -and $_.PasswordLastSet -lt $AESdate} | Sort-Object PasswordLastSet | FT sAMAccountName, distinguishedName, whenCreated,
 passwordlastset, LastLogonDate, Enabled

Dvojí nastavení hesla - vytvoření klíčů

Na těchto účtech musíme nově nastavit heslo, aby se vytvořily AES klíče. Když se následně podíváme cmdletem Get-ADReplAccount, tak uvidíme v části KerberosNew vzniklé Credentials AES a DES (předtím byla sekce prázdná). Vypadá to úplně stejně, jako když vytvoříme nový účet (heslo se mu nastaví při vytvoření).

Ale AES nefunguje a pokud zablokujeme RC4, tak se účet Kerberosem nepřihlásí. V Kerberos odpovědi, kde je vyžadována Pre-Authentication, se nabízí pouze RC4. Až když podruhé nastavíme heslo, vidíme Credentials a OldCredentials, tak začne AES korektně fungovat.

Týká se to (pravděpodobně) pouze starých účtů, které byly vytvořeny bez podpory AES. U nich se musí dvakrát nastavit heslo. Když nyní vytvoříme nový účet, a heslo nastavíme pouze při vytvoření, tak AES funguje korektně.

Proto bychom potřebovali nalézt účty, které vznikly před podporou AES a od té doby měli pouze jednou změněné heslo. To je ovšem problém. Můžeme vypsat účty vytvořené před daným datem (případně omezit změnu hesla v nějaké poslední době). Pro jednotlivé účty si můžeme zobrazit dostupné klíče cmdletem Get-ADReplAccount.

Get-ADUser -filter * -properties whenCreated, passwordLastSet, LastLogonDate | Where-Object {$_.whenCreated -lt $AESdate} |
 Sort-Object PasswordLastSet | FT sAMAccountName, distinguishedName, whenCreated, passwordlastset, LastLogonDate, Enabled

Get-ADUser -filter * -properties whenCreated, passwordLastSet, LastLogonDate |
 Where-Object {$_.whenCreated -lt $AESdate -and $_.PasswordLastSet -lt (Get-Date -Year 2022)} | Sort-Object PasswordLastSet |
 FT sAMAccountName, distinguishedName, whenCreated, passwordlastset, LastLogonDate, Enabled

Nastavení používání AES

Vhodné je postupně měnit nastavení účtů, které nyní používají RC4, a testovat, zda vše korektně funguje. Nakonec můžeme zablokovat RC4 na doménovém řadiči, takže není možno použít RC4 v komunikaci s DC.

Servisní účet a Keytab soubor

Častý případ, kde se objevuje RC4, jsou servisní účty pro nějakou webovou aplikaci, které zařizují SSO přihlašování. V praxi se vytváří jako uživatelský účet a následně se k nim vystaví Keytab (key table) soubor. Uživatelský účet standardně nemá nastaven atribut msDS-SupportedEncryptionTypes a používá se defaultní šifrování. To chceme změnit.

Důležité je, zda jsme při vytváření keytabu pomocí ktpass určili, parametrem crypto, jaké klíče (typy šifrování) se mají vystavit do souboru. Často se doporučuje vytvářet všechny podporované typy šifrování. Pokud jsme neurčili, tak v souboru nejsou AES klíče a musíme jej vystavit znovu.

Jednoduše můžeme říci, pokud na účtu povolíme pouze AES a přestane nám fungovat SSO do aplikace, tak je potřeba vystavit nový Keytab soubor. Ve výjimečných případech může být i problém, že server (aplikace) nepodporuje AES a je potřeba řešit zde.

Keytab soubor - AES klíče a sůl

Jak jsme si uvedli v minulém díle v kapitole Šifrovací klíče (Encryption Keys). Pro AES klíče se přidává sůl, která obsahuje Realm (doménu) a uživatelské jméno. RC4 klíče se vytváří pouze z hesla (takže je jedno jaké je jméno a může se měnit). To může způsobit problémy v některých situacích.

Narazil jsem na článek Lessons in Disabling RC4 in Active Directory (případně další On Adding AES Support to Kerberos.NET). Z něho mi přijde, že se jako uživatelské jméno používá sAMAccountName a při změně UPN sufix účtů (domény v User Principal Name) se mění sůl, a tedy AES klíče (při změně hesla). Ale moje testy (výpisy příkazem Get-ADReplAccount a zachytávání Kerberos komunikace) ukazují, že se pro sůl používá doména (nikoliv UPN sufix, ten můžeme libovolně měnit) a uživatelské jméno se bere z User Principal Name (UPN), formátuje se část před zavináčem.

Může se ovšem objevit jiný problém. Když nastavujeme heslo účtu, tak se (pro AES) vezme zadané heslo, doména a jméno z UPN účtu a pomocí toho se vytvoří klíče. Když vytváříme Keytab soubor pomocí příkazu ktpass (můžeme použít i jiný nástroj, který nemá žádnou komunikaci s doménou, třeba v Linuxu ktutil), tak se (patrně) vezmou zadané parametry a z nich se vytvoří klíče v souboru (nic se nenačítá z účtu v AD). Použije se parametr Principal Name (princ), z kterého se bere uživatelské jméno a doména, a Password (pass) heslo.

Problém je, že princ také představuje Service Principal Name (SPN), podle kterého se hledá služba. Aby byly klíče v Keytabu a AD stejné, tak musíme změnit UPN účtu. To defaultně příkaz ktpass dělá, ale nesmíme použít parametr -setUpn (což jsem dříve využíval). Určité informace jsou ve staré diskusi Enabling AES-encrypted single sign-on to Apache in a Win2008 domain.

Pokud chceme zachovat UPN účtu, tak můžeme, při vytváření Keytab souboru příkazem ktpass, použít parametr -rawsalt FIRMA.LOCALusername. Zde zadáme sůl, která se použije při vytváření klíčů v Keytabu (zadáme hodnotu soli z AD).

ktpass -out mujweb.keytab -princ HTTP/mujweb.firma.local@FIRMA.LOCAL -mapUser firma\mujweb-sso -mapOp set -pass heslo
 -ptype KRB5_NT_PRINCIPAL -kvno 0 -crypto AES256-SHA1 -rawsalt FIRMA.LOCALmujweb-sso -setupn 

Entra Seamless SSO

Pokud používáme Seamless SSOEntra ID (dříve Azure AD), tak pravděpodobně uvidíme, že vystavené Service Ticket používají RC4.

#2>     Client: bouska @ FIRMA.LOCAL
        Server: HTTP/autologon.microsoftazuread-sso.com @ FIRMA.LOCAL
        KerbTicket Encryption Type: RSADSI RC4-HMAC(NT)
        Ticket Flags 0x40810000 -> forwardable renewable name_canonicalize
        Start Time: 1/11/2024 13:18:08 (local)
        End Time:   1/11/2024 22:18:12 (local)
        Renew Time: 1/18/2024 12:18:12 (local)
        Session Key Type: AES-256-CTS-HMAC-SHA1-96
        Cache Flags: 0
        Kdc Called: dc.firma.local

Doporučeno je nastavit hodnotu atributu msDS-SupportedEncryptionTypes účtu AZUREADSSOACC na 0x10 (AES256). Následně je potřeba vystavit nové Kerberos klíče pro tento účet. Oficiální informace Microsoft Entra seamless single sign-on: Technical deep dive, další popis Secure Active Directory + Azure AD SSO and disable RC4-HMAC.

Druhý speciální počítačový účet související s Entra ID, který můžeme mít v doméně, je AzureADKerberos. Používá se pro přihlášení pomocí FIDO2 bezpečnostního klíče, případně Windows Hello for Business. Tento účet nemá nastavené SPN a má prázdný atribut msDS-SupportedEncryptionTypes. Možná nemá jeho nastavení žádný vliv, ale zkusil jsem nastavit na hodnotu 0x10 (AES256) a vše funguje.

Speciální počítačové účty

Účty počítačů, které se používají pro vystavování ticketů. A které nemají nastaven atribut msDS-SupportedEncryptionTypes nebo mají povoleny šifry, které chceme blokovat. Můžeme zkusit přenastavit a testovat funkčnost. V mém případě jsem narazil na problém pouze u starého testovacího ESXi 6.0, které patrně AES pro Kerberos nepodporuje (pro jiné použití ano).

Pokud potřebujeme změnit hromadně, tak můžeme celou skupinu přenastavit PowerShellem.

Get-ADComputer -Filter 'msDS-SupportedEncryptionTypes -eq 31' -Properties msDS-SupportedEncryptionTypes |
 Set-ADComputer -KerberosEncryptionType AES128,AES256

Get-ADComputer -Filter * -SearchBase "OU=Počítače,DC=firma,DC=local" | Set-ADComputer -KerberosEncryptionType AES128,AES256

Nastavení povolených šifrovacích typů na počítačích pomocí Group Policy

V minulém díle jsme zmiňovali politiku Group Policy - Configure encryption types allowed for Kerberos, kterou můžeme nastavit na počítačové účty a povolit pouze AES. Z těchto počítačů je pak pro Kerberos možno použít pouze zadané šifrovací typy.

Toto nastavení politiky na klientech (počítačích) neovlivní typ šifrování pro Service Ticket, který klient získá. Pouze v případě nastavení na server, kde běží služba, a pro službu se využívá účet počítače.

Zablokování RC4 v doméně

Když nastavíme politiku Network security: Configure encryption types allowed for Kerberos na doménové řadiče, a povolíme pouze AES, tak bychom měli účinně zablokovat použití RC4 v doméně. Jak jsme si uvedli, doménový řadič volí typ šifrování pro Session Key i Service Ticket a musí to být takový, který má povolený.

Pozn.: Narazil jsem na diskusi, kde někdo uvádí, že dělal testy s různými OS pro DC a omezení fungovalo až od Windows Sever 2019. Já jsem starší OS nezkoušel, ale přijde mi, že to z principu fungovat musí všude.

Registry DefaultDomainSupportedEncTypes

Na doménových řadičích můžeme nastavit Default Domain Supported Encryption Types. Vytvoříme klíč DefaultDomainSupportedEncTypes v registrech v cestě HKEY_LOCAL_MACHINE\System\CurrentControlSet\services\KDC. A nastavíme (třeba) hodnotu 24 (AES128, AES256). Možná to není potřeba, když nastavíme politiku na DC, kde povolíme pouze AES. Uváděl jsem svůj praktický test, že se AES používá i při defaultní hodnotě.

Zvláštní chování - vystavení RC4 Service Ticket

V praxi jsem narazil na různé chování, které mi přišlo podivné či špatné. Postupně jsem asi vše pochopil, když jsem pronikl do detailních principů Kerberosu. Jeden příklad je zde.

Existuje uživatelský účet, pod kterým běží služba na Windows Serveru. Když se klient pomocí aplikace ke službě přihlásil, tak získal Service TicketRC4 a Session KeyAES256. To by bylo normální. Ale po nastavení atributu msDS-SupportedEncryptionTypes uživatelského účtu na hodnotu 24 (AES128, AES256) nebyl žádný rozdíl (ve všech ostatních případech toto nastavení fungovalo). Později jsem se dočetl, že se RC4 přidává automaticky mezi podporované. Proto, když se nepovedlo použít AES, tak se použilo RC4.

Příčinu problému jsem nalezl až po nastavení politiky na DC, která povolila pouze AES. V tuto chvíli se ticket nevystavil a logovala se událost Kerberos-Key-Distribution-Center ID 16 s textem

The requested etypes were 18  17  23  3  1. The accounts available etypes were 23.

Po kontrole účtu se ukázalo, že je opravdu velmi starý a má vytvořené pouze DES a RC4 klíče. Po dvojí změně hesla vše začalo fungovat a vystavoval se Service TicketAES256.

Kontroly chyb po vynucení AES

Do systémového logu Windows na DC se zapisují události ze zdroje Microsoft-Windows-Kerberos-Key-Distribution-Center (ve filtru v Event Viewer najdeme jako Kerberos-Key-Distribution-Center). Můžeme procházet všechny chyby a varování. Nejčastější problém může být vidět v událostech:

Text události je ve všech případech velmi podobný. Význam je, že se nepovedlo nalézt použitelný typ šifrování.

While processing an [AS/TGS] request for target service %1, the account %2 did not have a suitable key for generating a
 Kerberos ticket (the missing key has an ID of %3). The requested etypes were %4. The accounts available etypes were %5.
 [Changing or resetting the password of %6 will generate a proper key.] 

V některých případech dává chyba jasné informace, ale často ne. Zobrazuje, jaké typy šifrování se nacházely v požadavku a jaké klíče má dostupné účet. Chybí zde informace, jaké má účet povolené typy a co je nastaveno na DC. Různé příklady jsou uvedeny v článku What happened to Kerberos Authentication after installing the November 2022/OOB updates?.

Například, když klient podporuje (a požaduje) pouze AES, účet má klíče RC4 a AES, ale nastaven atribut msDS-SupportedEncryptionTypes na 4 (RC4). Tak se ticket nevystaví a zaloguje chyba.

ID 16 ... Kerberos ticket (the missing key has an ID of 8). The requested etypes were 18  17. The accounts available
 etypes were 23  18  17.

Další příklad, kde klient podporuje RC4 a AES, účet má klíče pouze RC4, na DC je povoleno pouze AES.

ID 16 ... Kerberos ticket (the missing key has an ID of 9). The requested etypes were 18  17  23  3  1. The accounts
 available etypes were 23.

Počítačový účet pro samostatný ESXi server připojený do domény, který nepodporuje AES. Když se zakáže RC4 na doméně, tak nedostane TGT.

ID 26 ... Kerberos ticket (the missing key has an ID of 3). The requested etypes were 23. The accounts available
 etypes were 23  18  17.

Pokud uživatelský účet nemá (použitelné) AES klíče a na počítači se povolí pouze AES, tak nedostane TGT.

ID 14 ... Kerberos ticket (the missing key has an ID of 1). The requested etypes : 18 17 3. The accounts available
 etypes : 23.

Důležité informace se skrývají v textu the missing key has an ID of %3, kde ID neidentifikuje klíč, ale operaci s klíčem (Key Operation). Bohužel Microsoft význam těchto identifikátorů tají. Nějaké informace jsem nalezl v článku Kerberos Event ID 27. Podle nich ID 9 znamená Service Ticket Encryption a ID 8 chybějící AES klíč (klíč asi může existovat, ale účet má nastaveno pouze RC4, takže se AES nemůže použít).

Události z logu můžeme vypsat PowerShellem ze všech DC.

$dcs = Get-ADDomainController -Filter * | Select Name -ExpandProperty Name
$Events = ForEach ($dc in $dcs) {
  Get-WinEvent -ComputerName $dc -FilterHashtable @{LogName='System'; Id=14,16,26,27} |
   Where-Object {$_.ProviderName -eq "Microsoft-Windows-Kerberos-Key-Distribution-Center" } |
   Select-Object TimeCreated, MachineName, Id, Message
}
$Events | Sort-Object TimeCreated -Descending | Out-Gridview

Související články:

Kerberos protokol se zaměřením na SSO v AD DS

Nový seriál, který se podrobně věnuje protokolu Kerberos V5, hlavně v prostředí Microsoft Active Directory. Popisuje i řadu souvisejících věcí, které jsou potřeba pro pochopení fungování Kerberos Single Sign-On (SSO).

Active Directory a protokol LDAP

Správa firemní počítačové sítě využívající Microsoft OS většinou znamená správu Active Directory Domain Services (AD DS). Jedná se o velice rozsáhlou skupinu technologií, protokolů a služeb. Základem jsou adresářové služby, autentizace a komunikační protokol LDAP.

Pokud se chcete vyjádřit k tomuto článku, využijte komentáře níže.

Komentáře

Zatím zde nejsou žádné komentáře.

Přidat komentář

Vložit tag: strong em link

Vložit smajlík: :-) ;-) :-( :-O

Nápověda:
  • maximální délka komentáře je 2000 znaků
  • HTML tagy nejsou povoleny (budou odstraněny), použít se mohou pouze speciální tagy (jsou uvedeny nad vstupním polem)
  • nový řádek (ENTER) ukončí odstavec a začne nový
  • pokud odpovídáte na jiný komentář, vložte na začátek odstavce (řádku) číslo komentáře v hranatých závorkách