A hiba
2008. május 13-án a Debian projekt bejelentette, hogy Luciano Bello egy érdekes hibát talált az általuk terjesztett OpenSSL csomagban. A kérdéses hibát a következő kódrészlet eltávolítása okozta az md_rand.c-ből
MD_Update(&m,buf,j);
[ .. ]
MD_Update(&m,buf,j); /* purify complains */
Ezek a sorok azért kerültek eltávolításra, mert inicializálatlan adat használatára vonatkozó figyelmeztetéseket generáltak a Valgrind és Purify eszközökben bármilyen OpenSSL-lel kapcsolatos kóddal kapcsolatban. Egy erről szóló visszajelzés az OpenSSL csapat felé olvasható itt. Ennek a kódnak az eltávolítása az OpenSSL-ben használt Pszeudo-Véletlenszámgenerátor (PRNG) seeding folyamatának teljes tönkretételéhez vezetett. A véletlen adat kiinduló seedhez keverése helyett az egyetlen "véletlen" adat ami felhasználásra került, az aktuális folyamat azonosítója lett. Linux platformon alapértelmezetten a maximális folyamatazonosító 32.768, ami nagyon alacsony számú kiindulási értéket eredményez a PRNG műveletek számára.
A hatás
Az összes 2006 Szeptember és 2008 Május 13. között Debain alapú rendszereken (Ubuntu, Kubuntu, stb.) generált SSL és SSH kulcs érintett lehet. SSL kulcsok esetében az összes tanúsítványt újra kell generálni és el kell küldeni a hitelesítő hatóságnak aláírásra. Az összes Debian-alapú rendszeren generált CA kulcsot vissza kell vonni és újra kell generálni. Minden rendszeradminisztrátornak, aki megengedi felhasználóinak, hogy azok SSH-n keresztül nyilvános kulcson alapuló autentikációval férjenek hozzá a szerverekhez, meg kell vizsgálni a használt kulcsokat, hogy kiderüljön ha valamelyiket sebezhető rendszeren generálták. Minden eszköz, ami felhasználta az OpenSSL PRNG-jét az adatok biztonságos továbbítására, sebezhető lehet egy offline támadássals szemben. Minden SSH szerver, ami érintett rendszer által generált hoszt kulcsot használ célpontja lehet egy felhasználók számára észrevehetetlen man-in-the-middle támadásnak, de akár a forgalom is megfejthető lehet.
A probléma azért is nagyon csúnya, mert olyan rendszereket is felül kell vizsgálni vele kapcsolatban, amelyek nem használják a Debian szoftvereit, csak a kulcsait generálták ilyen rendszeren. A Debian és az Ubuntu projekt több eszközt is kiadott a sebezhető kulcsok azonosítására. Ezeket megtalálod [itt].
A játékok
A Debian és Ubuntu által kiadott feketelisták jól mutatják, hogy milyen kicsiny is a kulcstér valójában. Egy új OpenSSH kulcs generálásakor összesen 32767 lehetséges kimenetel létezik adott architektúránál, kulcsméretnél és kulcstípusnál. Ez azért van, mert ez egyetlen "véletlen" adat, amit a PRNG használ, a folyamatazonosító. Az előforduló kulcsok generálásához egy olyan rendszerre van szükségünk, ami tartalmazza megfelelő binárisokat a célplatformra és egy módot arra, hogy adott processz azonosítóval generálhassunk kulcsokat. Ez utóbbi megoldására írtam egy kis megosztott könyvtárat, amit betöltve a getpid() libc hívás egy felhasználó által specifikált értéket ad vissza.
A következő lépés, hogy létrehozzunk egy chrootolt környezetet, ami tartalmazza a szükséges binárisokat és a sebezhető rendszerek könyvtárait. Csináltam egy snapshotot egy Ubuntu rendszerről a helyi hálózaton. Az egész chroot környetetet megtalálod itt. Amegfelelő típusú, hosszúságú és folyamat azonosítójú OpenSSH kulcs generálásához írtam egy shell szkriptet, ami a chroot környezetben futtatható. Ezt megtalálod itt. Helyezd a kibontott Ubuntu környezet gyökerébe! Kulcs generálásához futtasd a következő parancsot:
Az érdekesség ezekkel a kulcsokkal kapcsolatban az, hogy mennyire a PID-hez kötöttek. Mivel a Debian-alapú rendszerek egymás utáni processz azonosítókat alkalmaznak, a kulcshoz tartozó PID-ből következtethetünk arra, hogy a gépe elindítását követően mikor generálták a kulcsot. Ha ezt megfordítjuk, egy nyers erőn alapuló támadásnál megválaszthatjuk az először kipróbálandó kulcsokat.
Ha egy boothoz közel generált kulcsot próbálunk megtalálni (mint pl. egy SSH hoszt kulcs), a 200-asnál kisebb PID-del rendelkező kulcsokat érdemes választani egy brute-force-hoz. Ha felhasználó által generált kulcsot támadunk, 500 és 10000 közti PID-ekkel számolhatunk. Ez a fajta optimalizáció jelentősen meg tud gyorsítani egy távoli felhasználói fiók elleni nyers erőn alapuló támadást SSH-n keresztül.
[Ez a rész a kiadott kulcsok és eszközök használatával foglalkozik, aki kíváncsi a részletekre az lépjen az eredeti oldalra]
Gyakra Ismételt Kérdések
K: Mennyi időbe tellt legenerálni a kulcsokat?
V: 31 db 2.33 GHz-en ketyegő Xeon magot használtam. Két órát vett igénybe legenerálni az 1024 bites DSA és 2048 bites RSA kulcsokat. A 4096 bites RSA kulcsok hat órát vettek igénybe. A 8192 bites RSA kulcs generálás kb. 100 órába tellne ezen a sebességen, és valószínűleg meg lenne állítva a vége előtt.
K: Meg fogod osztani a több processzorra kiterjesztett kulcsgenerálási kódodat?
V: Nyem. A kód erre a spéci klaszterre van írva és túl gagyi módon van megírva hogy megérje kicsinosítani.
K: Mennyi időbe telik megtörni egy SSH fiókot ezekkel a kulcsokkal?
V: Ez a hálózat sebességétől és az SSH szerver konfigurációjától függ. Elvileg mind a 32767 DSA-1024 és RSA-2048 kulcs kipróbálása meglenne néhány óra alatt,d e vigyázzni kell a szerver-oldali anti-brute-force szkriptekkel.
K: 16384 bites RSA kulcsokat használok, ezek megtörhetők?
V: Igen, ez csak idő, és számítási teljesítmény kérdése. A 8196 bites RSA kulcshalmaz mind a 32767 tagjának generálása 3100 CPU órát igényelne (100 óra az én 31 processzoros klaszteremen). Úgy képzelem, hogy a 16384 bites RSA kulcshalmaz közel lenne a 100.000 CPU órához. Egy dolgot viszont észben kell tartani, nevezetesen, hogy a legtöbb kulcs a processz ID mag miatt sokkal kisebb térből kerül ki, és nem kell az egész kulcsteret nem kell végignézni, hogy a legtöbb felhasználói kulcsot lefedjük (a legtöbb kulcs az első 3000 PID-nél van).
A hatás
Az összes 2006 Szeptember és 2008 Május 13. között Debain alapú rendszereken (Ubuntu, Kubuntu, stb.) generált SSL és SSH kulcs érintett lehet. SSL kulcsok esetében az összes tanúsítványt újra kell generálni és el kell küldeni a hitelesítő hatóságnak aláírásra. Az összes Debian-alapú rendszeren generált CA kulcsot vissza kell vonni és újra kell generálni. Minden rendszeradminisztrátornak, aki megengedi felhasználóinak, hogy azok SSH-n keresztül nyilvános kulcson alapuló autentikációval férjenek hozzá a szerverekhez, meg kell vizsgálni a használt kulcsokat, hogy kiderüljön ha valamelyiket sebezhető rendszeren generálták. Minden eszköz, ami felhasználta az OpenSSL PRNG-jét az adatok biztonságos továbbítására, sebezhető lehet egy offline támadássals szemben. Minden SSH szerver, ami érintett rendszer által generált hoszt kulcsot használ célpontja lehet egy felhasználók számára észrevehetetlen man-in-the-middle támadásnak, de akár a forgalom is megfejthető lehet.
A probléma azért is nagyon csúnya, mert olyan rendszereket is felül kell vizsgálni vele kapcsolatban, amelyek nem használják a Debian szoftvereit, csak a kulcsait generálták ilyen rendszeren. A Debian és az Ubuntu projekt több eszközt is kiadott a sebezhető kulcsok azonosítására. Ezeket megtalálod [itt].
A játékok
A Debian és Ubuntu által kiadott feketelisták jól mutatják, hogy milyen kicsiny is a kulcstér valójában. Egy új OpenSSH kulcs generálásakor összesen 32767 lehetséges kimenetel létezik adott architektúránál, kulcsméretnél és kulcstípusnál. Ez azért van, mert ez egyetlen "véletlen" adat, amit a PRNG használ, a folyamatazonosító. Az előforduló kulcsok generálásához egy olyan rendszerre van szükségünk, ami tartalmazza megfelelő binárisokat a célplatformra és egy módot arra, hogy adott processz azonosítóval generálhassunk kulcsokat. Ez utóbbi megoldására írtam egy kis megosztott könyvtárat, amit betöltve a getpid() libc hívás egy felhasználó által specifikált értéket ad vissza.
A következő lépés, hogy létrehozzunk egy chrootolt környezetet, ami tartalmazza a szükséges binárisokat és a sebezhető rendszerek könyvtárait. Csináltam egy snapshotot egy Ubuntu rendszerről a helyi hálózaton. Az egész chroot környetetet megtalálod itt. Amegfelelő típusú, hosszúságú és folyamat azonosítójú OpenSSH kulcs generálásához írtam egy shell szkriptet, ami a chroot környezetben futtatható. Ezt megtalálod itt. Helyezd a kibontott Ubuntu környezet gyökerébe! Kulcs generálásához futtasd a következő parancsot:
# chroot ubunturoot /dokeygen.sh 1 -t dsa -b 1024 -f /tmp/dsa_1024_1Ez egy új 1024 bites DSA kulcsot fog generálni, mindig 1-et visszaadó getpid()-del. Meg is van az első előre generált SSH kulcsunk. Ha folytatjuk a dolgot a PID értéket egészen 32767-ig növelve, aztán az egészet megismételjük 2048 bites RSA kulcsokra, megkapjuk az összes lehetséges, x86-os architektúrán, hibás OpenSSL-lel generált kulcsot. Ezzel a készlettel bármelyik olyan rendszert kompromittálhatjuk, melynek authorized_keys fájlja sebezhető kulcsot tartalmaz. Ez a kulcshalmaz alkalmas továbbá egy előzőleg elcsípett SSH munkamenet megfejtésére is, ha az SSh szerver hibás hoszt kulcsot használt. Az előre generált 1024 bites DSA és 2048 bites RSA kulcsok letölthetőek [innen].
Az érdekesség ezekkel a kulcsokkal kapcsolatban az, hogy mennyire a PID-hez kötöttek. Mivel a Debian-alapú rendszerek egymás utáni processz azonosítókat alkalmaznak, a kulcshoz tartozó PID-ből következtethetünk arra, hogy a gépe elindítását követően mikor generálták a kulcsot. Ha ezt megfordítjuk, egy nyers erőn alapuló támadásnál megválaszthatjuk az először kipróbálandó kulcsokat.
Ha egy boothoz közel generált kulcsot próbálunk megtalálni (mint pl. egy SSH hoszt kulcs), a 200-asnál kisebb PID-del rendelkező kulcsokat érdemes választani egy brute-force-hoz. Ha felhasználó által generált kulcsot támadunk, 500 és 10000 közti PID-ekkel számolhatunk. Ez a fajta optimalizáció jelentősen meg tud gyorsítani egy távoli felhasználói fiók elleni nyers erőn alapuló támadást SSH-n keresztül.
[Ez a rész a kiadott kulcsok és eszközök használatával foglalkozik, aki kíváncsi a részletekre az lépjen az eredeti oldalra]
Gyakra Ismételt Kérdések
K: Mennyi időbe tellt legenerálni a kulcsokat?
V: 31 db 2.33 GHz-en ketyegő Xeon magot használtam. Két órát vett igénybe legenerálni az 1024 bites DSA és 2048 bites RSA kulcsokat. A 4096 bites RSA kulcsok hat órát vettek igénybe. A 8192 bites RSA kulcs generálás kb. 100 órába tellne ezen a sebességen, és valószínűleg meg lenne állítva a vége előtt.
K: Meg fogod osztani a több processzorra kiterjesztett kulcsgenerálási kódodat?
V: Nyem. A kód erre a spéci klaszterre van írva és túl gagyi módon van megírva hogy megérje kicsinosítani.
K: Mennyi időbe telik megtörni egy SSH fiókot ezekkel a kulcsokkal?
V: Ez a hálózat sebességétől és az SSH szerver konfigurációjától függ. Elvileg mind a 32767 DSA-1024 és RSA-2048 kulcs kipróbálása meglenne néhány óra alatt,d e vigyázzni kell a szerver-oldali anti-brute-force szkriptekkel.
K: 16384 bites RSA kulcsokat használok, ezek megtörhetők?
V: Igen, ez csak idő, és számítási teljesítmény kérdése. A 8196 bites RSA kulcshalmaz mind a 32767 tagjának generálása 3100 CPU órát igényelne (100 óra az én 31 processzoros klaszteremen). Úgy képzelem, hogy a 16384 bites RSA kulcshalmaz közel lenne a 100.000 CPU órához. Egy dolgot viszont észben kell tartani, nevezetesen, hogy a legtöbb kulcs a processz ID mag miatt sokkal kisebb térből kerül ki, és nem kell az egész kulcsteret nem kell végignézni, hogy a legtöbb felhasználói kulcsot lefedjük (a legtöbb kulcs az első 3000 PID-nél van).