CA+MD5=FAIL!

Ludzie zajmujący się komputerowym bezpieczeństwem żyją w ciekawych czasach. Tak, to klasyczna już chińska klątwa. Najpierw okazało się, że udało się obejść WPA, teraz zaś na placu boju poległ algorytm MD5 a konkretniej – poległ pomysł jego wykorzystania przy tworzeniu skrótów e-certyfikatów.

Krótkie wprowadzenie do tematu for dummies: certyfikat elektroniczny to nic innego jak zestaw danych, który posiada ściśle określoną strukturę i cyfrową kłódkę. Ta kłódka to podpis utworzony z wykorzystaniem klucza kryptograficznego. Po co potrzebny jest certyfikat? Dokładnie po to, po co dowód osobisty – potwierdza tożsamość. Po co potwierdzać tożsamość w Internecie? Ano po to, żeby być pewnym, że na przykład strona, na której się logujemy (czyli wysyłamy do niej poufne informacje – nasz login i hasło) jest dokładnie tą stroną, której ufamy. Powiecie „jest adres w pasku przeglądarki, adres się zgadza!”. Problem polega na tym, że adres w obecnych czasach niewiele znaczy – istnieje sporo technik, które pozwalają na przekierowanie połączeń w sposób niezauważalny dla użytkownika. Adres się niby zgadza, ale serwer, na który wskazuje, to zupełnie inna maszyna. Konsekwencje wysłania jej loginu i hasła na przykład do konta bankowego powinny być oczywiste dla każdego.

Niezawodną metodą na potwierdzenie tożsamości serwera, z którym się łączymy są właśnie certyfikaty. Każda przeglądarka posiada wbudowaną listę autoryzowanych urzędów certyfikacji, którym bezgranicznie ufa. Ta lista to tak naprawdę zestaw kluczy publicznych wydanych przez tych wystawców. Urząd certyfikacji (CA) posiada parę kluczy – klucz prywatny i klucz publiczny. Klucz prywatny CA jest potwornie, potwornie wielką tajemnicą, klucz publiczny zaś może pobrać każdy – przeglądarki, jak już wspomniałem, mają wbudowaną listę kluczy publicznych od najważniejszych CA. Klucz publiczny służy do potwierdzenia, że certyfikat został podpisany kluczem prywatnym tego samego urzędu. Twoja przeglądarka przy łączeniu się ze serwerem z użyciem protokołu HTTPS sprawdza najpierw certyfikat wysłany przez ten serwer – pobiera z niego podpis wykonany kluczem prywatnym CA (któremu ufa, pamiętamy), po czym przy użyciu klucza publicznego (który ma na wbudowanej liście, pamiętamy) potwierdza, że podpis powstał przy użyciu klucza prywatnego wystawcy. W szczegóły wchodzić nie będę.

Wielkie pytanie brzmi: jak powstaje taki podpis? Uzyskuje się go przez zaszyfrowanie kluczem prywatnym certyfikatu – ale nie całego. Ze względów praktycznych z certyfikatu tworzy się tzw. „skrót” (hash) i dopiero ten skrót się szyfruje. Algorytmy odpowiedzialne za tworzenie tego skrótu powinny zapewniać, że niemożliwe jest utworzenie takich samych skrótów z różnych zestawów danych. Na przykładzie naszego certyfikatu – wystarczy zmienić w nim jedną literę a zmieni się cały skrót. Teoretycznie to zapewniają. Teoretycznie.

W praktyce jest tak, że zdarzają się w tych algorytmach tzw. „kolizje”, kiedy dzieje się to, co dziać się nie powinno – powstają identyczne skróty dla różnych zestawów danych (kłania się paradoks dnia urodzin). W jednym z najpopularniejszych takich algorytmów – MD5 – właśnie znaleziono taką lukę. Dlaczego jest groźna? Dlatego, że przy jej wykorzystaniu można wygenerować kolejne certyfikaty, już bez wiedzy CA. W naszym bankowym przykładzie – uzyskując niewinny certyfikat dla zupełnie innej strony, można wygenerować w pełni poprawny certyfikat uroczyście stwierdzający, że jesteśmy PKO BP, czy innym ING Bankiem Śląskim. Teraz wystarczy rozesłać maile, zawierające sfałszowane linki do naszego serwera udającego witrynę banku, na które kliknie jakiś tam procent odbiorców – przeglądarka ofiary nawiąże łączność, sprawdzi podpis CA na otrzymanym certyfikacie i radośnie zamelduje użytkownikowi, że wszystko jest w jak najlepszym porządku. Użytkownik zaloguje się i BUM! – mamy jego login i hasło.

Zabrzmiało groźnie? Na szczęście banki używają dodatkowych systemów zabezpieczeń, które chronią użytkownika przed utratą pieniędzy nawet wtedy, gdy ktoś zaloguje się na jego konto. Najczęściej jest to karta kodów jednorazowych, lub elektroniczny token generujący takie kody na poczekaniu – przed dokonaniem jakiegokolwiek przelewu trzeba wprowadzić kod potwierdzający transakcję. Dodatkowo, można zdefiniować dzienny limit kwoty, jaką można wyprowadzić z konta. Ktoś korzysta z usług instytucji, która nie wymaga podawania kodów autoryzujących transakcję? Wiać jak najprędzej, to was właśnie przede wszystkim dotyczy luka, o której tak się rozpisuję. Istnieje oczywiście sporo serwisów, które bankami nie są, ale które dla większości Polaków są bardzo istotne: na przykład Nasza Klasa czy Allegro. Następstwa przechwycenia loginu i hasła do nich mogą również skończyć się dość nieprzyjemnie.

Problem z MD5 dotyka rzecz jasna tylko tych, którzy logują się na strony podmiotów, stosujących certyfikat wygenerowany z użyciem MD5. Na szczęście to nie jest jedyny algorytm, jakiego można używać. Jest jeszcze SHA-1 i SHA-2. SHA-2 jest w tej chwili całkowicie bezpieczny, SHA-1 wydaje się mieć podobne problemy jak MD5, choć na razie nie jest jeszcze znany sposób ich praktycznego wykorzystania. Oficjalnie nie jest znany, dodajmy. Zrobiłem szybką przebieżkę po stronach opatrzonych certyfikatami i większość używa SHA-1. Z MD5 korzysta na przykład Dropbox.

Jest jeszcze jedna kwestia związana z tym atakiem: atakujący musi z góry przewidzieć treść certyfikatu, jeszcze przed jego wydaniem. Jedną z niewiadomych jest numer seryjny – powinien być losowy. CA, którego certyfikaty podrobiono popełnił szkolny błąd, bo używał certyfikatów numerowanych kolejno. Losowa zawartość pola przewidzianego na numer seryjny uniemożliwia w tej chwili jakiekolwiek podróbki.

OK, pora na najważniejsze: jak sprawdzić czy certyfikat, którego używa serwer, na który się logujemy wykorzystuje wadliwy algorytm? Jak sprawdzić czy numer seryjny jest generowany losowo? Przepis dotyczy Firefoksa i wykorzystuje certyfikat wygenerowany dla Naszej-Klasy.

Najpierw zaglądamy na bezpieczną stronę logowania najpopularniejszego serwisu w tym kraju. Klikamy menu Narzędzia → Informacje o stronie → Bezpieczeństwo a potem na przycisk „wyświetl certyfikat” i w nowo wyświetlonym oknie na kartę Szczegóły. Wśród pól certyfikatu wyszukujemy numer seryjny. Widzimy coś w ten deseń:

Okno właściwości certyfikatu: numer seryjny

Pole wyglądające w ten sposób oznacza, że wystawca (w tym przypadku Thawthe, była firma Wiadomo Kogo) używa numerów seryjnych generowanych losowo. Dobrze. Teraz pora na algorytm, jakim generowany jest skrót.

Okno właściwości certyfikatu: algorytm skrótu

Jak widać jest to SHA-1, czyli nie jest najgorzej, szczególnie przy losowym numerze seryjnym. Co zrobić gdy gdzieś zauważymy MD5 i „serial” w rodzaju „76421892″? Cóż, możemy napisać do właściciela serwera. Może pomoże.

Osoby zainteresowane tematem zachęcam do zajrzenia do opracowania autorów ataku na MD5. Osoby niezainteresowane mogą zechcieć zobaczyć jak wygląda blisko 200 sztuk PS3 spiętych siecią (procesory Cell wykorzystano w pierwszej fazie procesu wykrywania kolizji w MD5).