Błędy w protokołach kryptograficznych

Kryptografia towarzyszy nam obecnie praktycznie wszędzie, chociaż niekoniecznie musimy sobie z tego zdawać sprawę. Wykorzystujemy ją podczas logowania się do swojego serwera po pocztę, robienia zakupów w Internecie, korzystania z telefonu komórkowego i każdej innej formy komunikacji, która wymaga zapewnienia poufności lub potwierdzenia tożsamości rozmówców.

W ciągu ostatnich lat kryptografia, jako nauka, posuwa się do przodu niesłychanie szybko musząc sprostać nowym wymaganiom wynikających z nieznanych wcześniej oczekiwań wobec sieci komputerowych. Tak na przykład narodził się algorytm AES (Advanced Encryption Standard), którego założenia zostały wyznaczone właśnie pod kątem zastosowania w Internecie -- miał być szybki, wydajny w implementacjach programowych i wreszcie bezpieczny. Równocześnie jednak okazało się, że nie wystarczy samo zastosowanie silnego szyfru, należy go jeszcze stosować w bezpieczny sposób. Dochodzimy więc do problemu projektowania protokołów kryptograficznych, czyli budowania konkretnego systemu, mającego działać niezawodnie i bezpiecznie w oparciu o sprawdzone algorytmy.

Nie jest to wbrew pozorom sprawa prosta -- jak pokazują liczne przykłady (część przedstawiliśmy poniżej), niesłychanie łatwo jest popełnić brzemienny w skutkach błąd, niweczący całe zabezpieczenie nawet, jeśli skorzystano z silnych algorytmów szyfrujących.

Przez stosunkowo niedługi okres czasu, jaki upłynął od cywilnego upowszechnienia kryptografii udało się -- metodą prób i błędów -- dojść do pewnego ogólnego schematu mówiącego jak powinien wyglądać protokół służący do bezpiecznej komunikacji. Dotyczy to zarówno doboru odpowiednich algorytmów zapewniających poufność oraz integralność przekazu, ale także metod projektowania i późniejszego testowania danego protokołu. W przypadku protokołów stosowanych obecnie w Internecie standardem stał się otwarty model rozwoju, to znaczy projekt stworzony przez grupę ekspertów jest następnie przedstawiany do publicznego wglądu oraz oceny. Na tym etapie wychodzą najczęściej poważniejsze słabości projektu, które są następnie poprawiane. W ten sposób powstały właśnie dwa najszerzej zapewne stosowane obecnie protokoły kryptograficzne, to jest SSL w wersji 3-ciej (wersja 2-ga posiadała pewne słabości) oraz IPSec, używany do budowania sieci VPN.

Praktyka dowiodła, że paradoksalnie otwartość procesu projektowania takich algorytmów dodatnio wpływa na ich bezpieczeństwo, podczas gdy zamknięcie tego etapu przez publiczną oceną i utrzymywanie protokołu w tajemnicy skutkuje prawie zawsze jego złamaniem później, kiedy jest on już szeroko wdrożony i kiedy naprawienie błędów kosztuje znacznie więcej. Znamiennym przykładem może być tutaj zestaw protokołół stosowanych w telefonii GSM, które w ciągu kilku ostatnich lat zostały najpierw ujawnione za pomocą reverse-engineeringu [1], a następnie wykazano w nich liczne słabości.

Wydawać by się mogło, że jest jeśli jest jakaś grupa instytucji cywilnych, w których podobne wpadki nie mają prawa się zdarzyć, to wśród nich na pewno znajdą się banki. Niestety, praktyka wskazuje że nie zawsze tak jest i banki, czy też właściwie firmy piszące dla nich oprogramowanie, podatne są na niekompetencję w zakresie kryptograficznej ochrony danych. Znamienne, że ze względów bezpieczeństwa stosowane protokoły komunikacyjne są przeważnie tajne i nigdy nie podlegają publicznej krytyce. Problemy z ich bezpieczeństwem wychodzą dopiero podczas audytów lub testów penetracyjnych konkretnych aplikacji, przy czym i to nie zawsze, jeśli zespół testujący nie posiada odpowiednich kompetencji (o czym za chwilę).

Bank #1

Z pierwszym takim przypadkiem zetkęliśmy się przypadkiem, podczas zwykłej oceny przydatności pewnej aplikacji bankowej dla klienta, który rozważał jej wykorzystanie w firmie. Była to aplikacja służaca do prostego home-bankingu i komunikująca się z centralą przez modem. Generowane przez program zlecenia były zapisywane do zaszyfrowanych plików, a następnie przesyłane do banku.

Pierwszy rzut oka na pliki wynikowe i występujące w nich identyczne sekwencje, odpowiadające długim ciągom spacji, pozwalał jednak sądzić, że wykorzystano jakiś prosty algorytm szyfrujący domowej roboty, którego zasadę działania ustalono później eksperymentalnie. Każdy bajt wiadomości był szyfrowany przez dodawanie modulo bajtu klucza, którego długość była łatwo widoczna w zaszyfrowanym pakiecie i wynosiła 25 znaków.

Wiedząc to nie trzeba było się nawet silić na odkrywanie dalszych szczegółów algorytmu, na przykład skąd bierze się klucz i gdzie jest przechowywany. Program łamiący skutecznie zaszyfrowane wiadomości działał bardzo prosto, a mianowicie próbował wykonywać operację szyfrowania każdym możliwym kluczem tak długo, aż otrzymany wynik składał się w całości ze znaków drukowalnych. Ta metoda, niekoniecznie poprawna w ogólnym przypadku, dawała tutaj stuprocentowe powodzenie w odszyfrowywaniu wiadomości ze względu na typową budowę oraz zawartość takich pakietów. Co ciekawe, aplikacja ta była wcześniej audytowana przez inną firmę, która nie stwierdziła żadnych nieprawidłowości. W chwili obecnej jednak bank ten korzysta z nowej wersji programu, stworzonej praktycznie od zera przez jeszcze inną polską firmę, specjalizującą się w tworzeniu oprogramowania kryptograficznego.

Bank #2

W innym przypadku do komunikacji pomiędzy oddziałami a centralnym komputerem wykorzystywane były protokoły komunikacyjne rzekomo wyposażone w ,,jakieś'' szyfrowanie. W chwilę po przechwyceniu pierwszych pakietów z takiej sesji okazało się, że nie jest to nawet prymitywny szyfr a tylko typowe dla systemów IBM kodowanie EBCDIC [2] Sprawiedliwie dodajmy, że aplikacja do home-bankingu oferowana przez ten bank dla odmiany stosowała silne szyfrowanie do wymiany pakietów z centralnym serwerem, a w chwili obecnej cały ruch do oddziałów jest szyfrowany protokołem IPSec.

Płatnik Teletransmisja

Jak widać, ukrywanie kodu odpowiedzialnego za bezpieczeństwo transmisji rzadko się opłaca, a w większości przypadków opóźnia jedynie (ale nie uniemożliwia) odkrycie błędów wprowadzonych na etapie projektowania lub implementacji. Mimo tego, świadomość ta z trudem przenika do świadomości osób odpowiedzialnych za tworzenie oprogramowania wykorzystywanego przez administrację państwową. Przykładem może tutaj być casus stworzonego przez firmę Prokom na zamówienie ZUS programu Płatnik Teletransmisja. Sprawa ta wywołała sporo dyskusji kiedy okazało się, że stworzony za publiczne pieniądze program korzysta z niejawnych formatów i struktur danych. A ściślej, format stosowany przez Program Płatnika, czyli główny element systemu jest dobrze udokumentowany i jawny, ale ten używany przez Płatnik Teletransmisja do eksportowania zaszyfrowanych paczek -- już nie. Dlaczego tak jest, trudno zgadnąć -- pojawiały się sugestie że ujawnienie formatu Teletransmisji naraziłoby bezpieczeństwo danych płatników na szwank. Argument jest absurdalny i gdyby tak było w istocie -- to znaczy, że podstawą bezpieczeństwa systemu jest tajność formatu przez niego stosowanego -- to producent nie wystawiłby sobie tym samym najlepszego świadectwa.

Dokonana przez autora tego artykułu pobieżna analiza formatu paczek Teletransmisji (nie wiążąca się z analizą działania samego programu) wskazuje jednak, że projektanci albo skorzystali z dobrego wzoru, albo przynajmniej mniej więcej wiedzieli co robią -- paczki wykorzystują silne algorytmy kryptograficzne, zadbano także o ich integralność, a autentyczność jest zapewniana przez podpisy wykonywane kluczami RSA. Sprawa z pewnością nie budziłaby jednak tylu podejrzeń, gdyby specyfikacja tego formatu była po prostu jawna.

PPTP

Jawność specyfikacji od początku istnienia protokołu nie zapewnia jednak -- sama w sobie -- jego bezpieczeństwa. Do tego potrzebne są jeszcze niezależne analizy, najlepiej dokonane przed produkcyjnym wdrożeniem. Ten etap pominęła firma Microsoft tworząc w 1996 roku własną wersję PPTP (Point to Point Tunelling Protocol), czyli protokołu tunelowania PPP po TCP wyposażonego w mechanizmy uwierzytelnienia i szyfrowania. W dwa lata później został opublikowany artykuł Bruce Schneiera z firmy Counterpane i Mudge'a z L0pht Heavy Industries opisujący słabości PPTP w implementacji Microsoftu. PPTP jest przykładem, jak nie należy projektować protokołów -- poza licznymi słabościami PPTP wykonuje szereg operacji, które są po prostu niepotrzebne. Nie zapewniając faktycznego zwiększenia poziomu bezpieczeństwa, komplikują tylko proces uwierzytelniania i utrudniają analizę protokołu.

PPTP do uwierzytelniania użytkownika wykorzystuje mechanizm MS-CHAP [3], który pozwala na stwierdzenie tożsamości klienta bez przesyłania hasła otwartym tekstem przez sieć. Jest to typowy protokół typu challenge-response, w którym serwer przedstawia losową liczbę (challenge) klientowi, który po zaszyfrowaniu jej swoim hasłem odsyła ją do serwera. Ten przeprowadza tę samą operację przy pomocy hasła przechowywanego w lokalnej bazie, identyczny wynik traktując jako potwierdzenie poprawności hasła klienta. W przypadku MS-CHAP procedura ta jest jeszcze bardziej skomplikowana i przebiega następująco:

  1. Klient prosi serwer o przesłanie wyzwania (challenge)
  2. Serwer zwraca wyzwanie w postaci liczby losowej o długości 8-miu bajtów
  3. Klient oblicza skrót swojego hasła za pomocą funkcji LMHASH [4] oraz drugi, przy pomocy alternatywnej funkcji NTHASH [5]
  4. Z każdego skrótu tworzone są trzy klucze DES, którymi szyfrowane jest wyzwanie odsyłane później do serwera w postaci 24-ro bajtowej odpowiedzi
  5. Serwer tworzy analogiczne klucze na podstawie skrótów przechowywanych w swojej bazie haseł i deszyfruje nimi odpowiedź klienta
  6. Jeśli wynik jest identyczny jak wyzwanie wysłane do klienta, to jest on uwierzytelniany pomyślnie

Model ten ma kilka problemów implementacyjnych. Po pierwsze, zarówno funkcja LMHASH jak i NTHASH są funkcjami skrótu słabymi z kryptograficznego punktu widzenia. Na przykład, identyczne hasła dają w wyniku zawsze identyczne skróty, co znacząco zmniejsza ilość możliwych kombinacji koniecznych do sprawdzenia podczas zgadywania haseł metodą brute-force [6] (na przykład w analogicznej uniksowej funkcji crypt każde hasło może być zaszyfrowane na 4096 sposobów).

Rezultatem jest zwiększenie podatności haseł PPTP na ataki tego typu do poziomu, kwalifikującego je do praktycznego wykorzystania. Otóż w przypadku MS-CHAPv1 czas potrzebny do złamania podsłuchanych haseł wynosi 26-250 godzin [7], a w przypadku MS-CHAPv2 od 16 do 290 godzin [8], przy czym górne granice dotyczą najgorszych możliwych przypadków, kiedy w haśle wykorzystano wszystkie znaki drukowalne (a nie tylko litery i cyfry).

Po ukazaniu się artykułów analizujących błędy w PPTP, a następnie programu L0phtCrack [9] Microsoft opublikował zmodyfikowaną, drugą wersję protokołu w której wprowadzono kilka zmian, m.in. zrezygnowano z przesyłania słabszego LMHASH razem z NTHASH i wprowadzono mechanizm uwierzytelnienia serwera wobec klienta. Jednak część ze zmian ma faktycznie znaczenie tylko kosmetyczne -- dodatkowe przekształcenia podczas liczenia skrótów faktycznie nie mają żadnego wpływu na zwiększenie bezpieczeństwa hasła, a jedynie komplikują cały algorytm. Dodatkowo dla zachowania wstecznej kompatybliności Microsoft zdecydował się pozostawić domyślne ustawienia tak, by wykorzystywany był stary protokół co powodowało że większość sieci nadal przez długi czas korzystała ze słabszej jego wersji.

Kolejny, wręcz podręcznikowy, błąd w pierwszej wersji PPTP dotyczył szyfrowania, które było zapewniane przez podprotokół MPPE [10]. Wykorzystywał on szyfr strumieniowy RC4 z kluczem wynegocjowanym na etapie uwierzytelnienia przez MS-CHAP. Problem był bardzo prosty -- otóż RC4, jako szyfr strumieniowy, jest faktycznie generatorem pseudolosowym produkujących ciąg bajtów klucza ($K$). Każdy z nich służy następnie do zaszyfrowania kolejnego bajtu danych ($P$) przez dodawanie ich modulo czyli XOR ($\oplus$). Wynikiem jest ciąg bajtów kryptogramu ($C$):

$K \oplus P = C$

Operacja XOR jest odwracalna, dzięki czemu wystarczy dodać do każdego bajtu kryptogramu kolejne bajty klucza, by otrzymać z powrotem otwarty tekst:

$C \oplus K = P$

Problem polegał jednak na tym, że dokładnie ten sam klucz był wykorzystywany do szyfrowania danych płynących zarówno od serwera do klienta ($P_{1}$), jak i od klienta do serwera ($P_{2}$).

$K \oplus P_{1} = C_{1}$
$K \oplus P_{2} = C_{2}$

Mając możliwość podsłuchiwania obu strumieni atakujący mógł w łatwy sposób zniweczyć szyfrowanie wykorzystując przemienność dodawania modulo. Polegało to po prostu na dodaniu do siebie obu strumieni zaszyfrowanych danych:

$C_{1} \oplus C_{2} = (P_{1} \oplus K) \oplus (K \oplus P_{2}) = P_{1} \oplus P_{2}$

Jako wynik otrzymujemy więc sumę obu strumieni tekstów jawnych, która, pomimoże bezpośrednio nie jest czytelna pozwala na łatwe przeprowadzenie kolejnych ataków kryptograficznych, na przykład analizy statystycznej. Usunięty bowiem został element losowy w postaci strumienia klucza.

Problem ten został usunięty w drugiej wersji PPTP, która wykorzystywała różne klucze do szyfrowania w każdym z kierunków, ale z perspektywy czasu nie można uznać zastosowanej metody szyfrowania za bezpieczną. W ciągu ostatnich lat pojawiło się bowiem kilka nowych ataków na algorytm RC4, które pozwalają na skuteczne obliczanie klucza jeśli tylko dysponować będziemy odpowiednią ilością przechwyconych kryptogramów.

Secure Shell, wersja 1

Kolejnym przykładem osłabienia protokołu przez zły dobór algorytmów kryptograficznych jest pierwsza wersja protokołu SSH, stworzonego przez Fina Tatu Ylonena szyfrowanego odpowiednika popularnego w środowisku uniksowym programu rsh, służącego do pracy na zdalnych maszynach. Oryginał był podatny na większość znanych obecnie ataków sieciowych, z podsłuchem, przejmowaniem sesji i spoofingiem na czele. Pojawienie się pierwszych wersji SSH w połowie lat 90-tych zostało przyjęte z entuzjazmem i program ten szybko stał się standardem de facto w zakresie szyfrowanych zdalnych sesji terminalowych. Kilka metod uwierzytelnienia (m.in. przez klucz RSA lub przesyłane w zaszyfrowanej postaci hasło) oraz kilka negocjowalnych algorytmów kryptograficznych (DES, 3DES, Blowfish i inne) czyniło z niego narzędzie bezpieczne i funkcjonalne. W ciągu kilku lat istnienia zrezygnowano na przykład ze słabego algorytmu RC4 i wprowadzono kilka udoskonaleń, jednak w 1998 roku zespół CORE SDI z Argentyny opublikował informację [11] o poważnej dziurze w samym protokole SSH (nie był to więc błąd implementacyjny).

SSHv1 przesyłało dane w postaci pakietów o zmiennej długości z nagłówkiem zawierającym następujące dane:

  • Długość -- długość danego pakietu z pominięciem samego
    pola Długość oraz wypełnienia
  • Wypełnienie -- od 1 do 8 losowych bajtów, ich ilość była
    wyznaczana według wzoru 8 -- Długość mod 8, pole to miało
    utrudniać ataki na klucz szyfrujący ze znanym tekstem jawnym
  • Typ -- rodzaj pakietu według specyfikacji SSH
  • Dane -- zmienna ilość bajtów danych użytkownika
  • CRC-32 -- suma kontrolna pola Dane

Suma CRC-32 była obliczana przed zaszyfrowaniem pakietu, temu ostatniemu podlegały wszystkie pola oprócz pierwszego, czyli Długości. Zauważmy, że jedynym sposobem stwierdzenia intergralności pakietu było rozszyfrowanie go i obliczenie sumy kontrolnej pola danych. Wydawałoby się, że pole to jest bezpieczne, ponieważ przez sieć jest ono przesyłane w postaci zaszyfrowanej. Okaząło się że tak nie jest -- możliwe było bowiem skonstruowanie takiego pakietu, który po rozszyfrowaniu dałby taki wynik, by po pierwsze wpasować w pole danych (oraz typu) dowolny ciąg znaków, a po drugie umieścić w polu sumy kontrolnej jego poprawną wartość. Było to możliwe dzięki temu, że przed polem z danymi znajdował się ciąg bajtów nie mających znaczenia i nie sprawdzanych przez serwer, a także dzięki temu że szyfrowanie następowało w trybie CBC [12], przez co pierwsze bloki miały wpływ na wynik deszyfrowania kolejnych.

Pozwalało to na przykład na przejęcie sesji użytkownika korzystającego z SSH w taki sposób, by wykonać na serwerze dowolne polecenie z jego uprawnieniami. Konsekwencje są w tym wypadku oczywiste, a bezpośrednią przyczyną było zastosowanie słabego algorytmu kontroli integralności. CRC-32 nie zostało opracowane z myślą o bezpieczeństwie -- łatwo jest przygotować dane tak, by dawały pożądaną sumę kontrolną CRC.

Protokołu SSH nie dało się naprawić bez jego całkowitej przebudowy (co nastąpiło wkrótce w postaci nowej, drugiej wersji SSH), dodano więc specyficzne obejście tego problemu -- serwer SSH posiadał mechanizm, wykrywający tego rodzaju ataki i odrzucający podejrzane pakiety. Niestety, autorzy mieli w tym wypadku sporego pecha, bo co prawda zabezpieczenie działało skutecznie, ale w kilka miesięcy później w tym fragmencie kodu wykryto błąd przepełnienia bufora, co umożliwiało zdalne uzyskanie praw administratora na serwerze. Kolejnym problemem było rozpowszechnienie protokołu SSHv1, o który oparto tak wiele specyficznych rozwiązań że przechodzenie na nową wersję SSHv2 następowało z oporami. Doszło więc do sytuacji identycznej jak w przypadku PPTP -- pomimo istnienia nowej, poprawionej wersji protokołu duża część użytkowników nadal stosowała starą.

Jak zepsuć protokół?

Wiedzą to twórcy specyfikacji protokołu WTLS, stosowanego do bezpiecznej komunikacji przez telefony komórkowe w standardzie WAP, oraz Markku Juhani-Saarinen, który przedstawił kryptoanalizę WTLS [13]. Protokół ten powstał jako odpowiednik SSL i TLS [14] przeznaczony do wykorzystania w sieciach komórkowych. Jego twórcy od początku w bardzo dużym stopniu bazowali na specyfikacji TLSv1, który jest uznawany za protokół sprawdzony i bezpieczny, jednak specyficzne warunki transmisji w telefonii bezprzewodowej zmusiły ich do wprowadzenia szeregu zmian. Okazały się one niestety szkodliwe z punktu widzenia bezpieczeństwa wynikowego protokołu WTLS.

Podstawowymi różnicami w stosunku do TCP/IP jakie musieli uwzględnić były:

  • wolniejsza transmisja w sieciach bezprzewodowych, konieczność liczenia się z dużymi czasami wędrówki pakietów
  • konieczność uwzględnienia zarówno transportu połączeniowego jak i opartego o datagramy
  • niska moc obliczeniowa oraz niewielka pamięć większości aparatów korzystających z WTLS
  • konieczność liczenia się z ograniczeniami eksportowymi kryptografii

Każde z tych założeń przyczyniło się w jakimś stopniu do zredukowania bezpieczeństwa WTLS, czy też wręcz stworzenia konkretnych słabości w tym protokole. Na przykład konieczność przesyłania datagramów wymusiła stosowanie wektorów inicjalizujących (IV) trybu CBC możliwych do odtworzenia dla każdego otrzymanego przez klienta pakietu, niezależnie od tego czy wcześniejsze pakiety zostały zgubione czy też przyszły w innej kolejności. Problem ten można rozwiązać na dwa sposoby -- albo za pomocą tzw. explicit IV, czyli wektora dołączonego do każdego przesyłanego pakietu (takie rozwiązanie zastosowano w IPSec), albo wektorów liniowych (linear IV), czyli możliwych do wyliczenia podczas odbierania pakietu. Konieczność redukowania wielkości pakietów spowodowała, że zdecydowano się na to drugie rozwiązanie -- jako wektor jest wykorzystywany po prostu numer sekwencyjny pakietu, zawarty w jego nagłówku. Ponieważ numer ten jest całkowicie przewidywalny, atakujący ma możliwość zgadywania jakie znaki były akurat przesyłane wewnątrz szyfrowanego tunelu wysyłając pakiety zawierające odgadywany znak i opatrzone mającym dopiero wystąpić numerem sekwencyjnym zsumowanym modulo z numerem poprzednim. Zgodność wynikowych kryptogramów świadczy o poprawnym trafieniu i dysponując taką "wyrocznią" można odgadnąć całe hasło w kilkuset próbach.

Kolejnym problemem jest znaczne osłabienie klucza szyfrującego algorytmu DES, który według specyfikacji powinien mieć 5 bajtów co teoretycznie daje 40 bitów klucza. Niemniej jednak DES rezerwuje jeden bit każdego bajtu na kontrolę parzystości, co daje efektywną długość 35 bitów -- podczas łamania klucza zmniejsza to ilość prób 32 razy.

Słabości tego typu jest więcej i pomimo że żadna w bezpośredni sposób nie kompromituje bezpieczeństwa WTLS, o tyle zsumowane dają one dość znaczne -- w stosunku do deklarowanego -- osłabienie tego protokołu.

Problemy z uwierzytelnieniem

Istnieją ataki, wobec których nawet sprawdzone i uznawane za bezpieczne protokoły (takie jak SSL czy SSHv2) mogą być bezsilne. Są to ataki typu man-in-the-middle, czyli w wolnym tłumaczeniu ataki prowadzone przez pośrednika. Ich idea jest prosta -- gdzieś pomiędzy klientem a serwerem lokuje się ktoś, kto wobec każdej ze stron udaje tę drugą, w rzeczywistości przechwytując i według potrzeb modyfikując wszystkie dane.

Praktyczna implementacja takiego ataku (gdyby nie jedna drobna przeszkoda, o której za chwilę) mogłaby na przykład wyglądać tak:

  1. Atakujący lokuje się w segmencie sieci, z którego ofiara łączy się przez SSL z serwerem bankowym i za pomocą ARP spoofingu zapewnia sobie pośrednictwo w przekazywaniu pakietów pomiędzy klientem a lokalnym routerem (a więc i oczywiście serwerem bankowym). Następnie uruchamia na swoim hoście aplikację udającą serwer SSL banku
  2. Klient łączy się z bankiem, jednak jego połączenie trafia faktycznie na serwer atakującego
  3. Ten rozszyfrowuje pakiety klienta rejestrując interesujące go dane po czym bezzwłocznie nawiązuje faktyczne połączenie z bankiem, udając przeglądarkę klienta
  4. Takie pośrednictwo trwa do zakończenia transakcji i pozostaje niezauważone przez klienta

Konsekwencje są oczywiste -- atakujący zapewnia sobie, niskim kosztem, możliwość przejęcia i śledzenia sesji klienta, w tym także jej modyfikacji. Klient , jeśli nie będzie dość ostrożny, to niczego nie zauważy. Problem oczywiście wynika z trudności w uwierzytelnieniu serwera w stosunku do banku, bo w drugą stronę stosuje się hasła jednorazowe, tokeny i inne zaawansowane rozwiązania. Tymczasem pewność że dany serwer jest naprawdę bankowym klient zyskuje głównie na podstawie tego, że widzi znajomy interfejs użytkownika oraz -- co jest chyba najistotniejsze -- na podstawie certyfikatu SSL serwera.

Zauważmy jednak, że certyfikat opiewający na Pierwszy Bezpieczny Bank Internetowy S.A. może w praktyce wystawić sobie każdy. Problem w tym momencie jednak polega na tym że aby przeglądarka klienta zaakceptowała dany certyfikat bez ostrzegawczych komunikatów konieczne jest jeszcze by był on podpisany przez zaufany urząd certyfikujący (CA). Zaufany w tym wypadku oznacza, że certyfikat nadrzędny (root certificate) danego wystawcy musi znajdować się w bazie przeglądarki, tworzonej przez jej producenta. Rolą wystawcy w tym momencie jest zweryfikowanie praw danego podmiotu do posługiwania się wyżej wymienioną nazwą firmy, domeny i innymi charakterystycznymi znakami. Wystawca w tym momencie zapewnia przeniesienie zaufania z marki danej firmy na nazwę domenową oraz jej certyfikat -- klient ma podstawy by uznać, że skoro urząd zaufał tożsamości firmy (i tylko tożsamości, CA nie zajmują się oczywiście stwierdzaniem wiarygodności handlowej), to i on może.

Czy taki model jest skuteczny? Jak na razie tak i nie wygląda na to by wkrótce miał się pojawić lepszy, pomimo że urzędom certyfikującym również zdarzają się wpadki, tak jak przypadek wystawienia certyfikatu dla domeny www.microsoft.com nieznanym bliżej osobnikom, którzy wyłudzili go od firmy VeriSign na podstawie fałszywych dokumentów. Należy to jednak uznać za przypadek odosobniony i można mieć nadzieję, że wystawcy będą bardziej uczuleni na próby takich nadużyć.

Czego można się nauczyć?

Na podstawie powyżej przedstawionych przykładów, stanowiących zresztą zbiór wybranych, najciekawszych przypadków z historii ochrony danych w sieciach można wyciągnąć kilka wniosków:

  • Opieranie bezpieczeństwa protokołów na ich niejawności jest w większości wypadków nieporozumieniem, szczególnie jeśli ich implementacje programowe są później dostępne publicznie. Analiza kodu programów jest wykonalna stosunkowo niskim kosztem, późniejsze straty na wizerunku producenta lub bezpieczeństwie klientów kosztują znacznie więcej [15].
  • Nie opłaca się tworzyć własnych protokołów i algorytmów kryptograficznych, taniej i bezpieczeniej jest korzystać z istniejących standardów. Przed skorzystaniem z nich należy zbadać dostępną literaturę tematu, aby poznać znane słabości danych algorytmów, o których niekoniecznie musi wspominać producent.
  • Należy w miarę możliwości modularyzować protokoły bezpieczeństwa i nie wiązać ich zbyt ściśle z samą aplikacją tak, aby maksymalnie ułatwić bezproblemową wymianę modułu na nowszy w celu naprawienia znalezionych błędów. W ten sposób unikamy sytuacji, w której wszyscy używają starej wersji bo tak jest wygodniej.

Podsumowanie

Projektowanie aplikacji kryptograficznych jest zadaniem trudnym i wymagającym ogromnej wiedzy teoretycznej oraz praktycznej. Jak pokazują przedstawione powyżej przykłady, nie ma ataków zbyt skomplikowanych by je odkryć i przeprowadzić. Autor ma nadzieję, że prezentacja najciekawszych błędów w tej dziedzinie z kilku ostatnich lat przybliży Czytelnikowi metody ich odkrywania i wykorzystywania oraz, tym bardziej, pozwoli mu uniknąć powtarzania cudzych błędów w tej dziedzinie.

Przypisy

  1. Reverse-engineering jest procesem wspomaganego za pomocą odpowiednich narzędzi (debuggerów, deasemblerów) analizowania binarnego kodu programu, bez dostępu do jego kodu źródłowego. Jest to proces czasochłonny, ale w 100% skuteczny ze względu na możliwość obserwacji pracy programu na dokładnie takim samym poziomie, z jakiego jest on widziany przez wykonujący go procesor. Dodajmy, że deasemblacja i analiza działania programów komputerowych jest zgodnie z prawem autorskim nielegalna, poza przypadkiem kiedy służy ona zapewnieniu kompatybilności.
  2. EBCDIC (Extended Binary Coded Decimal Interchange Code) kodowanie znaków wprowadzone przez IBM w latach 60-tych i używane do dziś na niektórych systemach tej firmy. W uproszczeniu jest to odpowiedni kodu ASCII o innym ułożeniu znaków, w związku z czym plik ze znakami zakodowanymi w EBCDIC wygląda jak "krzaki". Narzędzia do konwersji pomiędzy obu kodami są jednak powszechnie dostępne.
  3. MS-CHAP -- Microsoft Challenge Authentication Protocol
  4. LMHASH, LAN Manager Hash, funkcja skrótu stworzona oryginalnie przez Microsoft dla Windows for Workgroups, oparta o algorytm DES
  5. NTHASH, Windows NT Hash, funkcja skrótu stworzona przez Microsoft dla systemów Windows NT, oparta o algorytm MD4
  6. Brute-force, czyli przeszukiwanie wyczerpujące polega na generowaniu każdej możliwej kombinacji znaków i obliczania jej skrótu. Jeśli będzie on taki sam jak łamane hasło, to znaczy że albo właśnie go odgadliśmy, albo że znaleźliśmy inne, dające identyczny skrót. Rezultat jest jednak ten sam -- kompromitacja hasła. Ataki tego typu gwarantują sukces, jedna często bywają niepraktyczne ze względu na czas potrzebny do sprawdzenia wszystkich kombinacji.
  7. Bruce Schneier, Mudge, ,,Cryptanalysis of MS PPTP'', 1998, http://www.counterpane.com/pptp-paper.html
  8. Jochen Eisinger, ,,Exploiting Known Security Holes in PPTP MS-CHAPv2'', 2001, http://mopo.informatik.uni-freiburg.de/pptp_mschapv2/pptp_mschapv2.html
  9. L0phtCrack, narzędzie automatyzujące proces podsłuchiwania i łamania haseł Windows, http://www.atstake.com/research/lc3/download.html
  10. MPPE, Microsoft Point to Point Encryption Protocol
  11. CORE SDI, ,,SSH Insertion Attack", http://www.core-sdi.com/soft/ssh/ssh-advisory.txt
  12. CBC, Cipher Block Chaining, tryb szyfrów blokowaych w których każdy wynikowy kryptogram jest wiązany (przez dodawanie modulo) z następującym po nim blokiem tekstu jawnego.
  13. Markku Juhani-Saarinen, ,,Attacks agains WAP WTLS protocol", http://online.securityfocus.com/library/3328
  14. Protokół TLSv1 jest sygnowanym przez IETF następcą protokołu SSLv3, opracowanego przez Netscape. Różnice pomiędzy nimi są faktycznie minimalne.
  15. Niejawność kodu może być dodatkowym zabezpieczeniem jeśli dostępne są wyłącznie implementacje sprzętowe lub produkt jest rozprowadzany w wąskim gronie. Przykładem może być polski Narodowy Algorytm Szyfrujący (NASZ), oparty faktycznie o 3DES z dodatkowymi przekształceniami, które prawdopodobnie mają uniemożliwić wykorzystanie do jego łamania seryjnie dostępnych układów elektronicznych. Nie ma, o ile mi wiadomo, publicznie dostępnych implementacji programowych tego algorytmu, jest on natomiast wykorzystywany w produkowanych przez Comp S.A. szyfratorach sprzętowych.

Comments

Comment viewing options

CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.
Select your preferred way to display the comments and click "Save settings" to activate your changes.

bardzo dobry artykuł.