Architektura ověřování v systémech Windows (a rizika z toho plynoucí)

Operační systémy Windows a jejich služby, již od verze Windows 2000, nabízejí v podstatě tři metody ověřování uživatelských účtů:

  • heslem - jak interaktivně na obrazovku (Ctrl-Alt-Del), tak i přes síť
  • čipovou kartou - interaktivně na obrazovku i do sítě pomocí Kerberos PKINIT technologie
  • certifikátem - jen do sítě přes TLS/SSL client authentication

V případě ověřování čipovou kartou (smart card logon) se jedná také vlastně o ověření identity pomocí digitálního podpisu soukromým klíčem certifikátu. Ale uvádím to tu samostatně, protože Windows vyžadují čipovou kartu. Nelze použít jen tak certifikát v souboru. Zatímco v případě TLS client authentication může být certifikát i privátní klíč tak zvaně softwarový. Ale i v případě TLS client authenticationje možné mít ho uložený v čipové kartě.

Cílem celé technologie je poskytnout uživatel single-sign-on (SSO), tak jak požaduje norma ISO/IEC 2700x. Budeme se tedy snažit, aby uživatel nemusel zadávat heslo (nebo obecně jiné tajné informace, třeba PIN) vícekrát, než je nezbytně nutné. Obvykle jen jednou.

Výhody čipových karet oproti heslům a softwarovým certifikátům jsou jasné:

  • multifaktorovost - to znamená, že uživatel musí znát PIN a současně musí mít kartu. Karty nelze kopírovat (pokud je to správně nastaveno :-)). Narozdíl od hesla, když vám někdo kartu ukradne, relativně rychle to poznáte. Není také tak jednoduché ukrást fyzicky kartu, jako je mnohdy jednoduché ukrást heslo softwarově.
  • kvalita cryptografie - privátní klíče se generují náhodně a kryptografie nezávisí na kvalitě PINu. I když budete mít jen třeba pětiznakový PIN, bezpečnost přenosů tím nijak netrpí. Zatímco při použití hesla, abychom se kvalitou vyrovnali alespoň SHA-1 (a to je dnes jen 80-bitová bezpečnost), museli bychom mít hesla dvanácti a vice znaková, komplexní.

Přenos přihlašovacích údajů po síti Windowspodporují pomocí následujících protokolů:

  • basic - zde budu nazývat "basic" cokoliv, co přenáší hesla v plain-text formě. Jsou to třeba HTTP basic authentication, nebo LDAP simple bind, nebo Telnet, nebo SMTP a POP3 a IMAP4 apod. Jedna z velmi obvyklých "basic" autentizací je také RDP. I zde se posílá do vzdáleného serveru plno-textové heslo. V poslední době se rozšiřuje i PowerShell remoting při ověření technologií CredSSP.
  • LM, NTLM a NTLMv2 - zde budu tuto rodinu tří protokolů nazývat jen zkráceně "NTLM". Není pro nás podstatná kryptografická kvalita jejich starších odrůd, protože ty se dají již od Windows 2000 vypnout a můžeme vynutit jen NTLMv2. Jde mi hlavně o principiální chování této rodiny. NTLM ověřuje vždy jen "heslem"
  • Kerberos - je možné použít pouze pro Active Directory doménové účty. Kerberos je ten, kdo umí ověřovat buď "heslem", nebo certifikátem
  • Schannel neboli TLS/SSL client certificate authentication - budu tuto metodu zde nazývat "schannel", protože tak se jmenuje autentizační balíček (dll knihovna), která ověřování realizuje.

Důležitá poznámka k basic ověřování : V dalším textu nebudu vůbec řešit zabezpečení přenosů při různých formách basic ověření. Počítám, že se to dá vždy zabezpečit pomocí nějaké jiné kryptografie, například TLS/SSL, nebo třeba pomocí IPSeca podobně.

Ještě poznámka k pojmu "heslo" : Pokud budu v obecném textu používat výraz "heslo", nemusí to znamenat přímo plain-textové heslo. Pokud bych chtěl explicitně vyjádřit použití takového clear-text hesla, tak řeknu "basic". Pokud říkám "heslo", myslím tím fakt, že uživatel někde zadává heslo, které má v hlavě. V případě NTLM a Kerberosse z tohoto hesla samozřejmě vytvoří nějaké heše (hash) a teprve s těmi se potom dál šifruje.

Architektura ověřování klient-server

Na následujících dvou obrázcích můžete vidět zjednodušenou architekturu ověřování při přístupu do sítě na nějakou vzdálenou službu:

Z klientského počítače (Client) se snažíte přistupovat na síťovou službu na serveru (Server). Jakoukoliv službu, jako jsou SMB sdílené soubory, SQL server, IIS web server, Exchange, Lync, RDP server nebo cokoliv jiného, co běží na Windowsoperačních systémech.

K tomu, abyste tento přístup mohli uskutečnit, se musíte ověřit pomocí účtu uloženého na řadiči domény Active Diretory (domain controller, DC). V případě Kerberos bude s DC komunikovat Client v každém případě. Server jen za určitých okolností (PAC validation, což je mimo tento článek).

Naopak v případě NTLM a basic ověřování sám Client se svým DC nekomunikuje vůbec a pošle svoje přihlašovací údaje přímo do Server, který si je sám přepošle na svoje DC k ověření. V takovém případě se to nazývá pass-through authentication.

Další podstatný koncept je tak zvaný double-hop, neboli delegace (delegation). Je možné, že prostřední Server a jeho služba chce přistupovat ještě dále do sítě, na nějakou zadní službu běžící na Back-end Server počítači. Mnohdy se požaduje opět ověření uživatelových přihlašovacích údajů stejného uživatele, jako přistupuje na službu na předním Server počítači. Důvod je jednoduchý. Back-end Server je zabezpečen normálním Windowszabezpečením, které máte uděláno per uživatel a chcete to tak nechat.

Představte si například SQL server reporting services (to je v podstatě webová aplikace, běžící na prostředním Server). Back-end Server by v takovém případě byla databáze nějakého jiného informačního systému. Tento informační systém obsahuje data všech firemních uživatelů a sám si řídí přístup podle jejich identit. Uživatelé se normálně přes vlastní GUI aplikaci toho informačního systému připojují přímo do Back-end Server. A vidí jen ta data, na která mají oprávnění. Jenže časem chceme přeřadit Reporting Services a generovat nějaké BIstatistiky a vytvářet z toho reporty.

Máme dvě možnosti - Reporting Services mohou používat nějaký svůj jeden vyhrazený účet pro přístup do zadních business dat na Back-end Server. Jenže to pak budou generovat report pro uživatele i z dat, která by ten uživatel sám přímo možná neviděl. Proto zavedeme raději delegaci (delegation). Reporting Services chce pak jen použít přímo identitu svého klienta, kterou by delegoval do zadního databázového business systému na Back-end Server.

Jenže to není tak jednoduché.

Rizika, kterým se snaží ověřovací protokoly bránit

Na následujících dvou obrázcích jsou vidět dvě základní rizika, kterým se snaží ověřovací technologie zabránit, nebo je alespoň minimalizovat. Znovu připomínám, že bezpečnost přenosu samotného nás zde netrápí a neřešíme ji.

Prvním je vykrádání přihlašovacích údajů na straně klienta Client. Musíme zajistit, aby zlý program (malware), který běží klientovi, nemohl jen tak dostat přihlašovací údaje uživatele v plné formě (pass-the-password útoky). Nejlépe ani ve formě heše (pass-the-hash útoky). Pokud by si uživatel stáhl nechtěně malware(webový prohlížeč, outlook apod.), tento útok by jistě rád získal jeho heslo a odeslal ho svému pánovi do internetu, aniž by to uživatel věděl.

Druhý problém je méně známý. Vykrádání přihlašovacích údajů na straně síťové služby Server. Je zdrojový kód služby opravdu důvěryhodný? Kdo ho dodává? Jste si jistí, že vývojáři dané webové aplikace neudělají někde chybu a nepůjde to heknout? Jste si jistí, že oni sami nejsou zlí a nedodají vám záměrně malware přímo do aplikace, kterou si od nich kupujete?

Mohli by zkusit získat přihlašovací údaje vašich uživatelů přicházejích na váš vlastní Server, do kterého dodali kód své aplikace. Uvědomte si, že přihlašovací údaje v nějaké formě, chodí přímo do síťového rozhraní aplikace běžící na Server. Pokud bude obsahovat zlý kód, bude mít k údajům přístup.

Musíme zajistit, aby tyto údaje byly v bezpečí i proti malware uvnitř Serveraplikace/služby.

Zabezpečený přenos ověřovacích údajů Local Security Authority

Na následujícím obrázku vidíte technologii LSA:

LSA je local security authority, tedy zabezpečený proces lsass.exe běžící na všech Windows operačních systémech. Běží pod účtem SYSTEM. Tento proces ve skutečnosti realizuje všechno spojené s ověřováním. To je proces, který dostane váš login a heslo po Ctrl-Alt-Del přihlášení. Poté ho má celou dobu uloženo v paměti až do okamžiku vašeho odhlášení. To je tento proces, který si pamatuje v paměti PINk vaší čipové kartě, pokud jste se pomocí ní přihlašovali.

Tento proces se snaží vaše přihlašovací údaje chránit. Samozřejmě, pokud jste členem skupiny Administrators tak je moc ochránit nedokáže. Ale jejich vykradení není tak jednoduché - útočník by musel přečíst celou paměť procesu LSA a údaje dešifrovat. Jsou na to prográmky jako je wce například. Od Windows 8.1 je dokonce možno je ještě lépe zabezpečit, pokud je počítač postaven na UEFI firmware a v registrech to nastavíte pomoci klíče RunAsPpl. Opět detaily mimo rozsah článku.

Právě proto, že jen skupina Administrators je schopna z LSA tyto údaje násilím dostat, je vhodné mít zapnutu ochranu UAC (user account control, neboli řízení uživatelských účtů). Tím se zabrání náhodným malware v tom, aby se spouštěly jen tak pod skupinou Administrators.

LSA má přihlašovací údaje jen u sebe v paměti a normálně je nevydává nikomu přímo. Je z nich ochotné pouze generovat NTLM, nebo Kerberosověřovací "balíčky".

Představte si klient server aplikaci typu Internet Explorer vs. IIS web server. Tihle dva se spojují pomocí HTTP. Sami dva nemusí vůbec rozumět ověřování. Jiné takové služby jsou SMB, SQL, cokoliv. Vývojáři se nemusí sami zabývat protokolem Kerberos, nebo NTLM. Prostě jen použijí LSA APIknihovnu. V okamžiku, kdy serverová strana chce klienta ověřovat, požádá ho o to ve svém protokolu.

Klient pouze řekne svému lokálnímu LSA o "ověřovací balíček". LSA mu něco vydá. Client balíčku nemusí vůbec rozumět. Navíc si ho ani nepřečte, právě protože je cílem, aby byl "šifrovaný". Vezme balíček tak jak je a pošle ho na Server. Na serverové straně služba balíček přijme. Ani ona by neměla být schopna do balíčku vidět. Prostě ho jen předá do LSA na straně Server.

A LSA na straně serveru se postará o ověření, kontaktuje si DC, pokud to potřebuje. A vydá výsledný access token, což je paměťová struktura, která reprezentuje identitu uživatele na vzdáleném počítači. A služba na Serveruž ho potom jen používá.

Máte tedy vlastně Client LSA a Server LSA, což je vlastně klient-server technologie. Jenom nemají svůj vlastní transportní protokol a spoléhají na to, že "ověřovací balíčky" se přenesou v konkrétním aplikačním protokolu.

Jak funguje "basic" ověření za pomoci LSA

Velmi omezeně. Na straně Client služba LSA odmítá vydávat plain-textová hesla vůbec komukoliv. Znamená to, že Internet Explorer si bude muset sám říct uživateli o heslo. Stejně jako třeba RDP klient. Ano, heslo si můžete obvykle uložit, ale to je na straně Client pouze záležitostí dané aplikace. Protože se klient vždy zeptá, neexistuje tu SSO (single-sign-on).

Na straně Server toto clear-textové heslo přijme nejprve služba serveru. Takže ho může ukrást. Následně ho vloží do LSA pomocí API a od toho okamžiku ho chrání serverové LSA. Ale až potom, co si ho mohla ukrást služba serveru. Nebo její správce.

Heslo přišlo na Server v plain-textu, takže je v paměti LSA i nadále uloženo v plné formě. V případě IIS existuje dokonce keš, která to heslo tam udrží ještě 15 minut potom, co se odpojí uživatelovo TCPspojení.

Uvědomte si, že úplně stejně se chová RDP spojení. Komunikace může být zašifrována, ale na RDP server se přenáší heslo v plné formě a je potom udržováno v paměti LSASSaž do odhlášení uživatele.

Jak funguje "NTLM" ověření za pomoci LSA

Nebudeme se zabývat detaily protokolu. Pro nás je zajímavý infrastrukturní princip. Poznámka k obrázku - v paměti na straně klienta je pwd hash MD4(ta mřízka to naznačuje), nikoliv plné heslo.

Na straně Client může automaticky LSA vytvořit bezpečný "ověřovací balíček" z toho, co má v paměti. V případě NTLMv2 ho vytvoří jako MD5-HMAC podpis náhodného čísla (challenge) pomocí MD4heše uživatelova hesla.

Plyne z toho, že klientská aplikace (jako třeba Internet Explorer, nebo SQL klienti apod.) nedostanou do ruky nic, než zašifrovaný produkt uživatelova hesla. Jediné, co by s ním mohli dělat, je zkusit na něho brute-force, neboli útok hrubou silou a mohli by zkusit heslo kreknout.

Takový balíček dorazí na stranu Server, kde si ho převezme serverové LSA. Serverová aplikace je na tom stejně jako klientská strana. Nemá v ruce nic, než zašifrovaný produkt uživatelova hesla.

Server LSA nezná heslo, ani heš uživatele, takže to jenom přepošle na DC k ověření. DC vrátí už jenom stav ověření - tedy něco jako OK, nebo chyba hesla apod. Pokud je to OK, LSA na Server straně si ani teď nemá možnost zapamatovat nic nebezpečného a pouze vytvoří access tokense seznamem uživatelových skupin, který předá zpátky do serverové aplikace k použití.

Možnosti útoku? Jak klientská strana, tak i serverová aplikace může zkusit brute-force vůči zašifrovaným produktům hesla. Nemůže použít rainbow-tables, protože výměna je zasolená (salted) pomocí náhodného čísla, ale může to zkoušet lámat hrubou silou. Co víc, útočník si to může odnést domů a lámat to offline na svých silnějších prostředcích.

Z tohoto pohledu NTLMv2 bezpečnost stojí na kvalitě uživatelova hesla. Krátká hesla půjdou rychle prolomit. Pokud bude heslo osm znaků, na třech 3Dgrafických kartách to útočník zvládne v řádu desítek dnů.

Starší LM a NTLM protokoly jsou ještě horší. LM šifruje pomocí DES a rozděluje heslo na dvě poloviny dlouhé 7 znaků. Kreknutí libovolně dlouhého hesla pak trvá v řádu maximálně hodin i jen s jednou 3Dkartou.

NTLMv1 šifruje také pomocí DES, ale už používá plnou MD4 hashhesla, takže je o něco robustnější.

Jak funguje Kerberos ověření za pomoci LSA

Obrázek je stejný jako v předchozím případě. Jen technologie je podstatně jiná. Kerberos klient v LSA na straně Client si generuje Kerberos tikety. Generuje si je sám se svým DC. To v obrázku ani není vidět. Kerberos ticket je pouze digitálně podepsaný samotným DC, pomocí jeho totálně náhodného symetrického šifrovacího klíče. Neobsahuje vůbec žádný produkt uživatelova hesla.

Kerberos šifruje tikety buď pomocí RC4 a MD4 heše klíče, nebo nově pomocí AES a SHA-1 heše klíče. AES je k dispozici až od Windows 2008. Velmi zjednodušeně řečeno. Detaily by vydaly na samostatný článek.

Ani aplikace na klientovi, ani aplikace na serveru tedy nedostává vlastně nic. Prochází přes ně jen Kerberos service ticket (TGS). Ten je zašifrován něčím, co nemá smysl lámat. Zaprvé je to dokonale náhodné a za druhé by ani výsledek skoro k ničemu nebyl.

Když takový Kerberos TGS ticket dorazí na Server stranu, tamní LSAtomu buď rovnou věří, protože je ticket podepsaný. Nebo si jeho signaturu nechá ověřit na svém DC, za určitých speciálních okolností. Samozřejmě nemá ani co by si nechal v paměti.

Jak funguje TLS client certificate authentication přes LSA technologii (schannel)

To je vlastně něco od NTLM a něco od Kerberos. Privátním klíčem uživatele se podepíše náhodné číslo (challenge, salt) v případě RSA key exchange. Pokud to TLS provádí DH výměnu, podepisují se DHklíče. Tento podepsaný výsledke sice prochází přes aplikace klienta a serveru, ale privátní klíč je tak kvalitní náhodné číslo, že není čeho se bát.

Podepsané výsledky dorazí na Server a místní LSA si signaturu a certifikát nechá ověřit na svém DC. Opět nemá, co by si zapamatovalo a není tedy ani co ukrást.

Závěr

Jak vidíte, basic autentizace (RDP je také "basic", pozor) je tragicky nebezpečná. Ani ne tak z důvodu toho, že by chodilo heslo po síti v otevřené formě. Ale proto, že ho nedůvěryhodné aplikace na Client a Server mohou ukrást. Navíc zůstává v paměti na Server straně, odkud ho dále může vykrást místní člen skupiny Administrators.

O něco bezpečnější je NTLMv2. Sice šifruje, ale pořád se jedná jen o přímé produkty uživatelova slabého hesla. Je možné ho tedy zkusit, dokonce offline, lámat hrubou silou (offline brute-force). O kvalitě NTLM a LMani nehovoříme.

Zato Kerberos a TLS/SSL client certificate authenication nabízí tu pravou bezpečnost. Kerberospoužívá dokonale náhodná hesla, která nemají nic společného s uživatelovým heslem. TLS sice podepisuje privátním klíčem uživatele, ale ten je krásně náhodný.

Ondřej Ševeček, MVP