A probléma
Ez gyakorlatilag azt jelenti, hogy összes kulcsod (RSA, DSA, akármi), amit ezeken a rendszereken generáltál ezen időszak alatt, komprommitált. És az összes DSA kulcsod is komprommitáltnak tekintendő, függetlenül attól, hogy hol és mikor generáltad, ha egy rossz rendszeren aláírtál vagy autentikáltál vele. Lásd a Wikipedia DSA szócikkét: ha k ismert, akkor x (a titkos kulcs) kiszámítható s-ből.
Kurt azért csinálta ezt mert gonosz?
Nem, nem hiszem hogy az lenne. Egyszerűen nincs képesítése arra, hogy kripto kódot készítsen, javítson vagy foltozzon, főleg nem egy olyan széles körűen használt project esetében, mint az OpenSSL. Nem érti a C-t, a ki- és bemeneti paramétereket, az előfeldolgozást, az ifdefeket és a memóramenedzsment problémáit.
Valószínűleg soha nem hagyták volna, hogy hozzányúljon az OpenSSL-hez. Csak azért tehette meg ezt, mert Debian karbantartó, így közvetlenül a Debianban "javíthat ki" dolgokat. Ezért van az, hogy ez egy kizárólag Debiant érintő hiba, Kurt csak feltöltötte a változtatását a Debianba, aztán elfelejtette megpróbálni betolni őket a főágba. Egyszer azért próbálkozott ilyennel, de ez a változás nem lett elfogadva, és ő soha sem gondolkozott el rajta, hogy miért.
A gonosz emberek azt fogják mondani, hogy Kurt egyszerűen az NSA-nek dolgozik. Ez nem igaz, ők nem alkalmaznak gügyéket.
De amit meg akart javítani az OpenSSL-ben, az tényleg hibás volt?
Nem, nem volt az. Kurt semmit nem tud a memória menedzsmenttel kapcsolatos dolgokról, ezért úgy gondolta, hogy hibát talált az OpenSSL-ben, de nem volt igaza. Szembe került egy inicializálatlan memória problémával, amit a valgrind - ez az egyébként nagyon hasznos programozói eszköz - mutatott meg neki. Például:
#include <stdio.h>
/tmp/a% cat valgrind-test.c
int main() {
char buf[1];
printf("%d\n", buf[0]);
return 1;
}
/tmp/a% gcc -Wall -g -o valgrind-test valgrind-test.c
/tmp/a% ./valgrind-test
-73
/tmp/a% valgrind ./valgrind-test
...
==11175== Use of uninitialised value of size 4
==11175== at 0x4080C0B: (within /lib/libc-2.7.so)
==11175== by 0x40827D0: vfprintf (in /lib/libc-2.7.so)
==11175== by 0x408A7E2: printf (in /lib/libc-2.7.so)
==11175== by 0x804839B: main (valgrind-test.c:6)
...
/tmp/a%
... (néhány előszámítás elvégzése, pl. a PID elhashelése)
#ifndef PURIFY
#if 0 /* Ne adjuk hozzá az inicializálatlan adatot. */ (Kurt féle BARBÁRKODÁS)
MD_Update(&m,buf,j); /* purify panaszkodik */
#endif (Kurt féle BARBÁRKODÁS)
#endif
... (csináljunk véletlenszámot és tegyük a buf-ba, return)
A Purify hasonló a valgridhez, csak kicsi öregebb. Amint látható, Kurt soha nem vette észre, hogy a PURIFY konstans definiálásával egyszerűen "purify támogatással" is buildelhetné az OpenSSL-t, ehelyett mindenféle komment nélkül (pl. XY féle Debianos változtatás) beszúrt egy #if 0-t. De békéljünk meg ezzel a lépéssel, semmi baj nincs vele, bár a dupla #if egy kissé furcsa, de a módszer hatékony, biztosak lehetünk benne, hogy a kódrészlet nem fordul be a binárisba.
De Kurt az ssleax_add_rand(const void *buf, int num, double add) függvényt is megváltoztatta, amit általában a RAND_add-on vagy RAND_seed-en keresztül érünk el, ahol buf egy bemeneti buffer, amivel a PRNG-t seedeljük.
... (some precomp)
/*
* Don't add uninitialised data.
MD_Update(&m,buf,j);
*/
... (some postcomp)
RAND_add() mixes the num bytes at buf into the PRNG state. Thus, if theEzt senki nem vette észre?
data at buf are unpredictable to an adversary, this increases the
uncertainty about the state and makes the PRNG output less predictable.
Suitable input comes from user interaction (random key presses, mouse
movements) and certain hardware events. The entropy argument is (the
lower bound of) an estimate of how much randomness is contained in buf,
measured in bytes. Details about sources of randomness and how to
estimate their entropy can be found in the literature, e.g. RFC 1750.
RAND_add() may be called with sensitive data such as user entered
passwords. The seed values cannot be recovered from the PRNG output.
Nem tudom, de senki nem szólt egészen addig, amíg Luciano Bello végre megtalálta.
A Karl által létrehozott Changelog bejegyzések nem sok segítséget nyújtanak:
openssl (0.9.8b-1) unstable; urgency=low
...
* Don't add uninitialised data to the random number generator. This stop
valgrind from giving error messages in unrelated code.
(Closes: #363516)
...
-- Kurt Roeckx <kurt@roeckx.be> Thu, 4 May 2006 20:40:03 +0200
openssl (0.9.8c-1) unstable; urgency=low
...
* Move the modified rand/md_rand.c file to the right place,
really fixing #363516.
...
-- Kurt Roeckx <kurt@roeckx.be> Sun, 17 Sep 2006 14:47:59 +0000
openssl (0.9.8g-9) unstable; urgency=high
...
[ Kurt Roeckx ]
* ssleay_rand_add() really needs to call MD_Update() for buf.
-- Kurt Roeckx <kurt@roeckx.be> Wed, 07 May 2008 20:32:12 +0200
Ahogy a naplóban látszik, 2006 május negyedikén próbálta a lyukat ütni, de nem sikerült neki, rossz helyre töltötte fel az md_rand.c-t, de ezt a botlást szeptemberben "kijavította".
Nem használ semmilyen dpatch-hez hasonló eszközt, így elég nehéz gyorsan rájönni, hogy mit is csinált, miután hagyott egy rejtélyes changelog sort. A Debian több mint 100 sornyi változtatást ad az OpenSSL-hez, de ezeket nem különíti el a csomagolási részletektől a .diff.gz-jeiben.
Korrekt és nyílt nyilvánosságrahozatal Kurt és az egész Debian projekt részéről
Ha azt mondod, mindenki követhet el hibákat, most adok neked egy végső lökést. Mikor rájött, hogy mi történt, Kurt csendben frissítette a csomagot az unstable ágban május 7-én. Minden feltöltés az unstable-be changelog és forráskód szinten széles nyilvánosság számára elérhető.
Az összes gép közvetlen veszélynek volt kitéve ettől a pillanattól kezdve a Debian 1751 -s biztonsági jelentésének május 13-i kiadásáig.
A Debian (néhány hosszú, fájdalmas óra elteltével) kiadott néhány eszközt és tanácsot a rossz kulcsok lecserélésére. De soha nem hoztak nyilvánosságra információt azzal kapcsolatban, hogy hogyan készítették a szoftvereket. Az eszköz tartalmaz egy hatalmas (~5MB) bináris hash szekvenciát, de senki nem tudja, hogy ezt hogyan generálták. Ezek ugyanazok a srácok, akik sírnak, amikor egy gyártó olyan driver ad ki, ami csak egy 1kbyte-os bináris firmware-t tartalmaz.
A Debian Projekt tanulni fog ebből...
Nehezen hiszem el. Ugyanezt megcsinálták a cronnal pontosan hét évvel ezelőtt. Abban az időben házon belül megpróbáltak javítani egy biztonsági hibát, de elfelejtették időben eldobni a jogosultságokat egy rendkívül fontos helyen.
A biztonsági probléma amit orvosolni akartak elég kellemetlen volt, de korántsem volt olyan komoly, mint az, amit a javítás eredményezett. Annyit kellett tenned, hogy megnyitottad a crontabot szerkesztésre 'crontab -e'-vel, vétettél valamilyen hibát, mentettél, majd kiléptél (:wq), tudomásul vetted, hogy hibát követtél el, újraszerkesztést kértél, majd az új szerkesztőben kértél egy shellt (:!/bin/bash). Voila, kész is a root shell!
Kérlek ne oldj meg problémát anélkül, hogy az upstreammel egyeztetnél!
Mit tehetek, hogy biztonságban tudjam gépeimet?
Tekintsd komprommitáltnak őket. Rakd újra a rendszert a javított OpenSSL-lel és generálj új kulcsokat. Az újrainstall után ne használj semmilyen jelszót mégegyszer! Igen, ez rengeteg meló. PITA! Köszönjük Kurt! Ne engedd meg a felhasználóidnak, hogy rossz kulcsokat használjanak autentikációra. Még egyszer ne használj Kurt Roeckx által karbantartott csomagot! Inkább forgass forrásból, az ilyen kiadókban nem szabad megbízni!
És keress egy olyan disztrót, ahol szorosan együtt dolgoznak az upstreammel, okos karbantartói vannak, és nem javítanak ki bajt okozva olyan problémákat, amelyek nem is léteznek. Ha találsz egyet, keress meg!
Linkek, további olvasnivaló
[Riskó Gergely oldalán]
Hatalmas hurrá, a nagyszerű, okos és hozzáértő Debian karbantartóknak!
abacs 2008.05.18. 00:38:48
buherator · http://buhera.blog.hu 2008.05.18. 09:30:12