12:50
22/2/2014

Kiedy przedwczoraj informowaliśmy o dziurze dotyczącej 70% użytkowników Androida, niektórzy z Was przewidywali, że niebawem pojawi się równie krytyczny i powszechny błąd w urządzeniach Apple. Prorocy… Oto wykrakana przez Was dziura — dotyczy ona obsługi połączeń szyfrowanych (SSL) na wszystkich urządzeń z jabłuszkiem, telefonach, tabletach i komputerach.

Na czym polega błąd? Na podwójnym failu

O błędzie informuje Apple i robi to w dość enigmatycznych słowach. Dowiadujemy się, że

Dziura dotyczy metody weryfikacji poprawności certyfikatów. Atakujący posiadający uprzywilejowaną pozycję w sieci może przechwycić lub zmodyfikować dane w szyfrowanych SSL/TLS połączeniach.

Mówiąc wprost, jest to klasyczny atak Man in the middle. Jeśli atakujący znajdzie się na drodze pomiędzy waszym urządzeniem z jabłuszkiem a serwerem docelowym, to będzie mógł niepostrzeżenie rozszyfrować połączenia typu HTTPS, co pozwoli mu zapoznać się np. z przesyłanymi hasłami.

Atakującym może być każdy, kto znajduje się w tej samej sieci co ofiara, bądź kontroluje jakieś serwery operatorów (dostawców internetu), nie tylko NSA ;-) Wystarczy wykonać zwykły arp spoofing np. w firmowej sieci ethernetowej lub otwartej sieci Wi-Fi w McDonaldzie i zamiast — jak do tej pory, wykorzystywać sslstripa, który posiada pewne ograniczenia — zmodyfikować sesję ofiary tak, aby wykorzystać dziurę o której poinformowało Apple. To pozwoli atakującemu na podszycie się pod serwer, z którym chce się połączyć ofiara. Pocieszające jest jednak to, że na razie nie są znane żadne publiczne narzędzia służące do wykorzystywania tego błędu — ale community jest już na tropie przyczyny błędu.

Warto wspomnieć, że na atak podatne są także …mechanizmy aktualizacji (zestawiają one sesję po SSL). Jest więc możliwe, że nastąpi kuriozalna sytuacja, w której atakujący przy pomocy tej dziury uniemożliwi ofierze ściągnięcie aktualizacji, która dziurę tę ma wyeliminować…

GOTO FAIL x 2

Oto fragment kodu w którym odkryto błąd (jest nim podwójne użycie instrukcji “goto fail“):

static OSStatus
SSLVerifySignedServerKeyExchange(SSLContext *ctx, bool isRsa, SSLBuffer signedParams,
uint8_t *signature, UInt16 signatureLen)
{
OSStatus err;
...
if ((err = SSLHashSHA1.update(&hashCtx, &serverRandom)) != 0)
goto fail;
if ((err = SSLHashSHA1.update(&hashCtx, &signedParams)) != 0)
goto fail;
goto fail;
if ((err = SSLHashSHA1.final(&hashCtx, &hashOut)) != 0)
goto fail;
...
fail:
SSLFreeBuffer(&signedHashes);
SSLFreeBuffer(&hashCtx);
return err;
}

Drugie, niepotrzebne użycie instrukcji goto fail powoduje, że nie jest ona przypięta do warunku if, ale przechwytuje bieg programu i zawsze prowadzi do “faila” co oznacza, że weryfikacja sygnatury zawsze będzie poprawna.

Mam iPhone/iPada/Mac OS X – co robić jak żyć?

Rozwiązaniem problemu w przypadku urządzeń mobilnych (iPhone, iPad, AppleTV) jest aktualizacja do iOS 7.0.6. (lub 6.1.6 dla starszych urządzeń jak np. iPhone 3GS). Instrukcję aktualizacji krok-po-kroku znajdziecie tutaj. (Niektórzy wspominają, że aktualizacja usuwa także dziurę pozwalającą na jailbreak — ale nie jest to prawda — dalej jailbreak jest możliwy.)

Aby sprawdzić, czy jesteś podatny, kliknij tutaj. Co ciekawe, chociaż Mac OS X jest podatny (i test wykonany na Safari pokazuje, że atak się powiódł) to na Google Chrome na Mac OS X atak nie zadziałał.

Rozwiązania dla komputerów (Maców i Macbooków) jeszcze nie ma. Apple w zasadzie oficjalnie nie potwierdziło, że błąd dotyczy Mac OS X, ale potwierdzili to niezależni badacze, którzy zreversowali patche wypuszczone przez Apple. Trzeba więc czekać na patch i w miarę możliwości nie korzystać z Safari, a Gogole Chrome (które nie jest podatne na ten atak, z racji posiadania własnych bibliotek do obsługi SSL)

Czy to celowy błąd?

Pewnie za chwilę pojawią się sugestie, że taki błąd to celowe działanie programisty, aby wbudować taką tylną furtkę w system operacyjny, która ułatwi pracę służbom. Wspomnijmy tu, że są specjalne konkursy tzw. niewinnego programowania, które ma na celu, w razie odkrycia błędu, uniemożliwić udowodnienie, że było to celowe działanie programisty.

Przypomnijmy, że podobne pogłoski krążyły wokół Linuksa po wypowiedzi Linusa, IPSec w OpenBSD, TPM-a w Windowsie 8, a backdoory w oprogramowaniu znanych firm to jak przyznają sami programiści — często celowe zagranie.. Przywołajmy chociażby drukarki Samsunga, macierze HP, loadbalancery F5, routery D-Linka czy TP-Linka, a nawet sterowniki ładowarek do paluszków.


Przeczytaj także:





49 komentarzy

Dodaj komentarz
  1. Ciekawe, czy pojawi się teraz wysyp ataków wykorzystujących tę podatność? Plotki mówiące choćby o łatce jb wskazują, że komuś zależy na tym, by te aktualizacje nie były instalowane. Z drugiej jednak strony mając jailbreak evasi0n nie ma się co martwić o problemy z SSL, bo to najmniejszy pikuś ;)

  2. A jak ktoś ma starszego iPhone?

    • To jest biedakiem, nie jest fajny i nie stać go na update.

    • Jest też iOS 6.1.6 dla 3GS :)

    • Przy okazji kpin ze starszej wersji IOS-a czy ktoś z kolegów wie jak mając 5 zainstalować poprawki tylko w linii IOS6 bez wchodzenia na IOS7?

    • @Paweł: mhm.

      .Install ios6_updates_only / no ios7_please; thanks.

      Emacsem. Nie zawsze działa; w razie problemów napisz ponownie, poprawię kod.

  3. W MacOS samo podszycie się pod serwer update to połowa sukcesu. Każdy update jest podpisany cyfrowo certyfikatem developera. W przypadku update systemowego musi to być ‘podpis’ Apple. Trzeba byłoby wiec podpisać właściwym kluczem spreparowany update i sfałszować certyfikat Apple zainstalowany na kompie. Kolejny myk do pokonania jest już banalny, nawet jak update ma właściwy podpis i tak jest jeszcze weryfikowany z serwerem. Nie mniej, dla chcącego nic trudnego :)

    • Co nie zmienia faktu, że nawet jak nie uda się wrzucić własnej fake-poprawki, to można uniemożliwić sciągnięcie patcha poprawiającego SSL ;)

    • Tutaj jest mowa nie o tym, żeby podmienić update, ale żeby uniemożliwić pobranie, chociażby przez podpisanie złym certyfikatem. Nie zainstaluje się, więc dziura ciągle jest.

    • Nie trzeba fałszować samej paczki – można po prostu do niej nie dopuszczać ;)

  4. Dla starszych urządzeń jest dostępny up 6.1.6

  5. Zaraz zaraz. Czy błąd dotyczy tylko Mac OS X czy OS X też jest podatny? Autorowi chyba chodziło o wszystkie systemy desktopowe Apple, czyli ML i Mavericks też?

  6. Czy iphone będzie wodoodporny?

  7. Czy powyższa sprawa dotyczy również iPoda Touch? Jest tam również OS X podobnie jak w iPhone….

  8. @Krzysztof
    IPhone wodoodporny??
    Nigdy nie byl i nie bedzie.

    • Tu chodzi o to, że po aktualizacji do iOS 7 użytkownicy uwierzyli, że będzie on wodoodporny :)
      http://news.sky.com/story/1145439/waterproof-iphone-advert-owners-fooled

    • jednak mozna zakupic obudowy odpowiednie? To taki model biznesowy kiedy telefon jest do wielu zastosowan, nie na odwrot kiedy do zastosowania kupuje sie telefon.

  9. Swoje i-zabawki można sprawdzić na stronie o znamiennej nazwie:
    http://gotofail.com

    Opis błędu jest tam:
    https://www.imperialviolet.org/2014/02/22/applebug.html

  10. ZAWSZE używać bracketów przy instrukcjach if, ZAWSZE i WSZĘDZIE!

    • Bo co? Tupniesz nóżką?
      Nawiasy klamrowe często jeszcze bardziej zaciemniają kod.

    • Serio?

      int f9_memory(int cipher,
      const unsigned char *key, unsigned long keylen,
      const unsigned char *in, unsigned long inlen,
      unsigned char *out, unsigned long *outlen)
      {
      f9_state *f9;
      int err;

      /* is the cipher valid? */
      if ((err = cipher_is_valid(cipher)) != CRYPT_OK) {
      return err;
      }

      /* Use accelerator if found */
      if (cipher_descriptor[cipher].f9_memory != NULL) {
      return cipher_descriptor[cipher].f9_memory(key, keylen, in, inlen, out, outlen);
      }

      f9 = XCALLOC(1, sizeof(*f9));
      if (f9 == NULL) {
      return CRYPT_MEM;
      }

      if ((err = f9_init(f9, cipher, key, keylen)) != CRYPT_OK) {
      goto done;
      }

      if ((err = f9_process(f9, in, inlen)) != CRYPT_OK) {
      goto done;
      }

      err = f9_done(f9, out, outlen);
      done:
      XFREE(f9);
      return err;
      }

    • Jest zdumiewające jakie tumany piszą teraz kod krytyczny dla bezpieczeństwa. Podwójne linie kodu wykrywają programy typu LINT od lat 90-tych, zaś o konwencji z bracketami jest w książce Kernighana z lat 80-tych, automatyczne formatowanie pokazujące tego typu błędy jak darmowe astyle w wersjach komercyjnych było już ok roku 2000. Wniosek: w korporacjach managerowie od IT są w dzisiejszych czasach debilami.

  11. A mówi się, że jeżeli musiałeś użyć etykiet i goto w C/C++, to znaczy, że coś źle zaprojektowałeś…

    • Ta. Czarne jest czarne, białe jest białe i nie ma absolutnie żadnej sytuacji w której GOTO byłoby potrzebne ;) Takie wspaniałe prawdy się młodzieży mówi w szkole, tak samo jak to, że “alkohol* szkodzi” albo “człowiek musi spać 8h* dziennie” ;P

      *hello, biphasic sleep, którym ludzi spali dopóki nie wynaleźliśmy elektryczności

  12. Błąd wygląda na klasyczny problem podczas megowania kodu.
    W całym tym fail’u najgorsze widoczne niskie standardy kodowania: nie należy używać goto, oraz taki prosty błąd powinien być bezproblemowo wykrywany przez testy jednostkowe.
    To wskazuje na to, że Apple nie ma testów jednostkowych, na dodatek dla tak porstego i krytycznego dla bezpieczeństwa fragmentu kodu, więc spodziewam się, że takich kwiatków w kodzie mają na pewno dużo więcej.
    Na dodatek jestem pewien, że kompilator nie ostrzegał o martwym kodzie. To wskazuje na kolejne naruszenie standardów kodowania, bo w tak poważnych projektach flaga -Wall powinna być obowiązkowa.

    • Na studiach Ci powiedzieli, że nie należy używać “goto”? Są przypadki, że usilne unikanie “goto” prowadzi do stworzenia kodu, który mocno traci na czytelności, co prowadzi prosto do kolejnych błędów. Tutaj nie jest winą samo użycie “goto”, bo podobny błąd można popełnić na tysiąc innych sposobów bez użycia tej konstrukcji. Zgrabnie stworzony kod potrafi wykorzystać wszelkie walory tej instrukcji. Tutaj zabrakło standardów, takich chociażby, jak umieszczanie bloków w bracketach, o czym wcześniej ktoś wspominał.

      Odnośnie testów jednostkowych przyznaję rację. Ale widząc obecną tendencję do robienia wszystkiego na wczoraj, podejrzewam, że programista został postawiony pod ścianą i przez naciskanie na szybkie wypuszczenie kodu, pominął testy jednostkowe.

      Niemniej jednak, kod Apple’a znany jest z tego, że nie jest najlepszej jakości. Ale to i tak jest pewnie o niebo lepiej niż to co się tworzy w wielu polskich firmach…

  13. Pytanie – jaki test znalazłby taki błąd?

    • > Pytanie – jaki test znalazłby taki błąd?

      W tym konkretnym przypadku:

      Jeśli zamieszczony fragment kodu jest w miarę pełny, tzn. OSStatus err nie jest nigdzie inicjowane poza if((err = …) != 0) , to kompilator powinien zwrócić ostrzeżenie, że istnieje możliwość zwrócenia niezainicjowanej zmiennej.

      Często warning z kompilatora może wskazywać na błąd logiczny.

      PS. Oczywiście można to poprawić na:

      OSStatus err = 0;

      na początku funkcji i wtedy nie mamy ostrzeżenia z kompilatora. ;)

    • Czyli robimy jeszcze gorzej, bo zwracamy brak błędu przy niewykonaniu żadnej operacji sprawdzającej certyfikat… Poza tym, tam w każdym warunku jest przypisanie wartości ‘err’, zatem nie ma szans, żeby kompilator wywalił ostrzeżenie, chyba że bez warunku poleci już pierwsze goto. Inaczej nie ma możliwości zwrócenia niezainicjowanej zmiennej. ‘err’ przypisuje niezależnie od wyników zwróconych przez funkcje.

    • Kamil pisze:
      > Poza tym, tam w każdym warunku jest przypisanie wartości ‘err’, zatem nie ma szans,
      > żeby kompilator wywalił ostrzeżenie

      Niezła skucha z mojej strony, oczywiście masz rację – err zawsze jest przypisany (przynajmniej w załączonym fragmencie kodu).

  14. Kod Appla nie jest jakiś wcale super w kwestii quality. Wystarczy analiza statyczna dobrym narzędziem i apple rozkłada nogi…

  15. Kiedy patrzę na kod, w którym zidentyfikowano błąd, to jestem pod ‘wielkim wrażeniem’ sposobu obsługi błędów. Tragedia!

  16. Wygląda na to, że Apple nie stosuje ani reguł analizy kodu (np. sonara), ani nie mają dobrych testów jednostkowych, ani nie wykonują review code, do tego nie stosują się do dobrych praktyk kodowania (brak klamer w instrukcji if, użycie goto). Zbyt dużo tych niedociągnięć jak na taką firmę. Mógłbym nawet pokusić się o stwierdzenie, że już w mojej są lepsze standardy programowania :p

  17. Podobnie jak z MSem, czyli ktos niepowolany zaczal uzywac tego rozwiazania, a przeciez wiadomo, ze tylko Wujek Sam ma do tego prawo?

  18. Ten test z http://gotofail.com powiedzial ze Safari (4.1.3) na moim Maczku jest “szczelne”.

    • to już nie jest twój maczek…

    • @zeN0n
      Mozesz jasniej napisac o co Ci chodzi?

  19. Mija weekend i nadal brak aktualizacji dla OS X.

  20. Dziękuję i szacuneczek safari wywala błąd … dobrze że istniejecie ;)

  21. Update dla OS X

  22. Przez chwilę się zastanowiłem nad tym błędem, jak to, jak drugie “goto” ma się wykonać. I nagle zrozumiałem. Na codzień programuję w Pythonie. Tam nie ma szansy na tego typu problem :-)

    • … i dodam, że bardziej niż o brak “goto” chodziło mi o sposób formatowania programu.

  23. Ostatni raz goto używałem w BASICu na ATARII.

    • A potem odnalazłeś się w sztuce kulinarnej?

    • W sztuce kulinarnej też, skąd wiedziałeś?

  24. 10.6,8 z Safari 5.1.10 (6534.59.10) nietykalny!!! Nie zawsze starsze, znaczy gorsze :-)

  25. Jest już update dla OS X Mavericks >> http://support.apple.com/kb/HT6150 i http://support.apple.com/kb/HT6114

  26. […] koniec przypomnijmy, że kilka tygodni temu krytyczny błąd w bibliotece obsługującej SSL/TLS dotknął oprogramowanie Apple …a i GnuTLS miało niedawno swoje […]

  27. […] się w czarne pasmo ujawnionych w tym roku poważnych błędów w innych stosach TLS-owych (por. Apple’owski goto fail i Linuksowy […]

Twój komentarz

Zamieszczając komentarz akceptujesz regulamin dodawania komentarzy. Przez moderację nie przejdą: wycieczki osobiste, komentarze nie na temat, wulgaryzmy.

RSS dla komentarzy: