Jakiś czas temu Google udostępniło możliwość logowania się do swoich usług za pomocą uwierzytelnienia dwuskładnikowego. Jedną z możliwości jest wykorzystanie kodów jednorazowych generowanych przez aplikację Google Authenticator (źródła tego projektu można znaleźć tutaj: google-authenticator). Aplikacja ta jest niczym innym, jak programowym tokenem generującym hasła jednorazowe w oparciu o czas lub licznik (więcej szczegółów: HOTP: An HMAC-Based One-Time Password Algorithm).
O Google Authenticator
Jakiś czas temu miało miejsce włamanie do RSA, w trakcie którego wykradziono "bliżej niesprecyzowane dane" związane z tokenami SecureID. Od początku przypuszczano, że te "bliżej niesprecyzowane dane" to seedy (np.: Co skradziono z RSA?). Ostatecznie RSA podjęła decyzję o wymianie wszystkich tokenów: Open Letter to RSA SecurID Customers), co w zasadzie potwierdziło wcześniejsze domysły.
Wróćmy do Google Authenticator. Jeśli ktoś przeanalizuje wspomniany wcześniej RFC, bez trudu zauważy, że kod jest generowany na podstawie klucza (seed) oraz jakichś dodatkowych danych (wskazanie czasowe, licznik, challenge). Jedynym sekretem w tym przypadku jest właśnie klucz, który należałoby chronić. Ujawnienie klucza pozwoli atakującemu generować hasła jednorazowe bez dodatkowych problemów w przypadku haseł opartych na czasie i z drobnym problemem w przypadku licznika, bo poza kluczem potrzebny jest jeszcze jego właściwy stan.
Tokeny "sprzętowe" są specjalizowanymi urządzeniami, które służą tylko do generowania kodów i niczego więcej. Nie ma prostej możliwości wyciągnięcia wartości seed z takiego urządzenia (są w pewnym stopniu tamper-resistant). Na takim urządzeniu nie można zainstalować również "obcego", w szczególności złośliwego kodu. Nie można ich również niepostrzeżenie "zwielokrotnić" (no chyba, że posiada się seed), gdy token zmienia właściciela jego prawowity właściciel ma szansę dość szybko zorientować się, że go nie ma. Zupełnie inaczej przedstawia się sytuacja w przypadku tokenów programowych. Obecnie telefon staje się urządzeniem ogólnego przeznaczenia, na którym można zainstalować praktycznie cokolwiek. Ich odporność na ingerencję z zewnątrz jest niższa, niż w przypadku tokenu, odporność na takie ataki nie jest kluczową cechą telefonu (jeszcze?). Informacja przechowywana na telefonie może zostać niepostrzeżenie skopiowana, a jej właściciel może pozostać w błogim przekonaniu, że nadal jest jedynym jej posiadaczem.
Jak wygląda bezpieczeństwo klucza w przypadku Google Authenticator? No niestety, nie wygląda:
# cd /data/data/com.google.android.apps.authenticator/databases cd /data/data/com.google.android.apps.authenticator/databases # sqlite3 databases sqlite3 databases SQLite version 3.6.22 Enter ".help" for instructions Enter SQL statements terminated with a ";" sqlite> select * from accounts; select * from accounts; 1|test1|I234567I234567I234567|0|0 2|test2|I234567I234567I234567|2|1 sqlite> .schema accounts .schema accounts CREATE TABLE accounts (_id INTEGER PRIMARY KEY, email TEXT NOT NULL, secret TEXT NOT NULL, counter INTEGER DEFAULT 0, type INTEGER);
Tak, w kolumnie secret przechowywane jest to, czego potrzeba, by "sklonować" token (klucz w postaci Base32). Nie ma żadnego dodatkowego wejścia (danych pochodzących od użytkownika), wystarczy zawartość tej bazy. Co prawda sama baza danych jest chroniona mechanizmami dostępnymi w systemie (odpowiednie ACL), ale może to być niewystarczające choćby w przypadku, gdy:
- na urządzeniu działa malware, który uzyskał prawa użytkownika root,
- atakujący ma pełny dostęp do urządzenia,
Pisałem już o tym, że zabezpieczenie (szyfrowanie) danych na urządzeniach mobilnych jest trudnym zadaniem. Akurat w przypadku aplikacji typu Google Authenticator sprawa jest dużo łatwiejsza. Aplikacja generuje kod, który przesyłany jest do serwera w celu weryfikacji (w procesie uwierzytelnienia). O ile atakujący może mieć pełną kontrolę nad aplikacją i telefonem, na którym ta aplikacja działa, serwera już nie kontroluje. Serwer po swojej stronie może zablokować konto/token użytkownika jeśli stwierdzi, że ilość błędnych prób była zbyt duża. Atakujący nie ma żadnego innego sposobu, by przekonać się, że wygenerowany kod był prawidłowy, jak wysłać go do serwera (no dobrze, nie jest to do końca prawdą, może sprawdzać poprawność kodów offline pod warunkiem, że dysponuje kilkoma wcześniejszymi kodami wygenerowanymi przez użytkownika).
Jak można zabezpieczyć klucz? Cóż, w tym wypadku odpowiedź jest prosta - szyfrować klucz (sekret) za pomocą klucza generowanego na podstawie hasła (kodu PIN) wpisywanego przez użytkownika przy uruchomieniu aplikacji lub po dłuższej bezczynności. Token powinien generować kody dla każdego podanego przez użytkownika/atakującego kodu PIN (operacja rozszyfrowania sekretu powinna zakończyć się sukcesem). Atakujący musi użyć wygenerowanego kodu, by sprawdzić, czy jest prawidłowy (czyli pośrednio - czy podany PIN jest prawidłowy). Pomijając wspomniany przypadek specjalny, gdy atakujący dysponuje kilkoma wcześniej wygenerowanymi kodami, w celu takiej weryfikacji kod musi zostać przesłany do serwera, a serwer po określonej ilości nieprawidłowych kodów blokuje użytkownika/token. W rezultacie atakujący ma tylko kilka prób, by odgadnąć prawidłowy PIN.
Temat ten był rozważany w ramach projektu: Issue 5: Encrypt key on mobile devcies. Szczególnie interesujący jest komentarz #5, pozwolę sobie zacytować ważniejsze fragmenty:
This all really depends on your threat model. For the threat model of a remote attack on your phone, I don't believe encrypting the secret key on the phone actually improves security.
(...)
Or you believe that the phone's security is already compromised, in which case rogue applications can just as easily read the user's pin as they can read the secret key.
No właśnie, kluczowy tutaj jest threat model. Dobrze jest wiedzieć jakie zagrożenia (threats) zostały uwzględnione przy projektowaniu danego rozwiązania i nie oczekiwać, że zrobi ono coś więcej, niż to, do czego zostało zaprojektowane. W tym kontekście, że będzie się bronić przed czymś, przed czym bronić się nie może (tu konkretnie: malware). Można też zastanowić się, czy w modelu uwzględnić również drugi przypadek, o którym pisałem, czyli nieograniczony dostęp fizyczny do telefonu. Moim zdaniem - tak, a przynajmniej decyzja o wyłączeniu tego scenariusza spod rozważań powinna być uzasadniona. Z drugiej strony ta decyzja w szerszym kontekście nie jest specjalnie istotna i nie warto się upierać przy stosowaniu opisanego wcześniej zabezpieczenia. Temat pozostawię w zawieszeniu, każdy może mieć swoje zdanie, natomiast bardzo jestem ciekawy jak będziecie je (ewentualnie) uzasadniać.
A teraz przećwiczmy mały disaster recovery.
Załóżmy, że utraciłeś telefon. Jakie działania podejmiesz?
W tym wypadku nie chodzi o budżet, ale o uświadomienie sobie jakie konfitury są teraz na telefonie. I w jak wielu miejscach telefon jest "zaufany".
Wszystko jest oczywiście kwestią kosztów i/lub umiejętności atakującego. Przecież nie w każdym przypadku utracone urządzenie trafia do osoby zdeterminowanej by wyciągnąć z niego dane
Oczywiście nie porównuję bezpieczeństwa tokenu i telefonu, bo ten drugi można atakować na wiele innych sposobów. Z pewnością trudniej jest też sklonować token niż telefon.
Hipotetycznie - mogę zaszyfrować urządzenie, klucz (mocny, prawdziwie losowy) trzymać w TPM, chronić go przy pomocy kodu PIN i niszczyć (klucz) w przypadku n nieudanych prób. Praktycznie będzie to tożsame ze zniszczeniem danych w urządzeniu. Będą zaszyfrowane, ale klucz zostanie utracony.
I może być drugi przypadek - klucz trzymany w pamięci urządzenia (lub generowany na podstawie wejścia użytkownika). Klucz lub zaszyfrowane dane są usuwane po n nieudanych próbach, co kontroluje samo urządzenie. Tylko urządzenie można wyłączyć a dane skopiować i próbować sobie spokojnie na boku.
Telefon to (jako całość) nie jest TPM i przed bezpośrednim dostępem do pamięci (flash, karta) nie broni nawet w części tak wymyślnie, jak TPM przed dostępem do siebie. Fakt, były udane ataki również na TPM, ale stopień skomplikowania jest jednak nieco większy.
Jak napisałem, nie porównuję bezpieczeństwa telefonu z bezpieczeństwem tokenu, chodzi mi tylko o ten konkretny przypadek.
"Załóżmy, że utraciłeś telefon. Jakie działania podejmiesz?"
Telefon zaczyna być urządzeniem typu "general purpose device". Służy nie tylko do telefonowania czy wysyłania SMS, ale całej masy różnych rzeczy, w tym może służyć do generowania haseł jednorazowych (aplikacja na nim). W innych aplikacjach możesz mieć pozapisywane hasła do poczty, (...).
Co w rezultacie trzeba zrobić? Zablokowanie karty SIM nie wystarczy, szczęśliwy nowy posiadacz telefonu nie będzie mógł dzwonić, ale... może skorzystać z zapisanych na telefonie danych/zainstalowanych aplikacji. No i nagle się okazuje, że poza zablokowaniem karty SIM powinno się jeszcze zablokować token w banku, zmienić hasło do poczty, (...). Ta lista staje się coraz dłuższa, a mam wrażenie, że konieczność wykonania tych działań wcale nie jest tak oczywista dla sporej części populacji użytkowników telefonów.
Przykładowy token bardziej kojarzy się z bankiem (bo TYLKO do tego służy), niż telefon służący MIĘDZY INNYMI do dostępu do banku, ale również do 1000 innych rzeczy, z których jakaś inna może być (subiektywnie) ważniejsza...
Wybierając softwarowy token w telefonie powinno się być świadomym tego, że nie zapewnia on takiego bezpieczeństwa jak sprzętowy. Inna sprawa że faktycznie z taką świadomością może być kiepsko.
Tutaj rozwiązaniem jest już tylko bezpieczne zaszyfrowanie telefonu, więc wracamy do poprzedniego tematu - o to akurat trudno.
Poza tym użytkownik musi myśleć. Jeśli jego super-bezpieczny klucz do banku nie jest już tylko jego, to nie jest już bezpieczny. To tak samo jak z kluczami do domu - skoro ktoś ma kopię mojego klucza, to dom nie jest już tylko mój tj. nie tylko ja mam dostęp. I nic nie zwalnia od myślenia, a tym bardziej zapewnienia dostawcy zabezpieczenia, którego głównym interesem jest nie bezpieczeństwo użytkownika a sprzedanie mu zabezpieczenia.
Poza tym użytkowników można uświadamiać, natomiast nie ma co liczyć, że dostawca zabezpieczenia powie całą prawdę na temat jego słabości.
W temacie: Reproducing Keys from Photographs (http://www.schneier.com/blog/archives/2009/10/reproducing_key.html).
Jak zareaguje "użytkownik" w takich przypadkach:
- zgubił klucz do mieszkania,
- jakaś obca osoba oddaje mu klucze mówiąc (bo rzekomo je upuścił),
- ktoś robi zdjęcie, gdy trzyma klucz w ręce,
Przypuszczam, że nawet pierwsze zdarzenie nie zawsze skończy się wymianą zamka
I dochodzi jeszcze inna kwestia: wszyscy (?) korzystają z kluczy i zamków w domach. Ale wybierając token programowy w telefonie użytkownik powinien być świadomy wad takiego rozwiązania i o wiele bardziej uczulony.
Z kluczem do drzwi przykład jest o tyle dobry, że prawie każdy go ma i z niego korzysta, ale ilość osób potrafiących w sposób prawidłowy ocenić ryzyko związane z chwilową lub trwałą utratą kontroli nad kluczem (że o "side channel" w postaci zdjęć nie wspomnę) jest niewielka. Po prostu z kluczy korzystamy, a nie doktoryzujemy się na ich temat. Podobnie jest z otwieraniem zamków - prezentacje z lock pickingu to magia.
Moim zdaniem analogiczna sytuacja jest z telefonem, jest to przedmiot użytkowy, gadżet, narzędzie lansu. Dla niewielkiej części osób z niego korzystających interesujące są jego internalsy. To trochę tak, jak z usuwaniem danych. Niby każdy wie, że skasowane dane da się odzyskać, ale jak przyjdzie co do czego, to nośniki i tak okazują się wcale nie tak bardzo wyczyszczone.
Co do "świadomości". Powinien (w teorii), zgadzam się. Przypuszczam, że w w praktyce nie jest. Bo i sam wybór takiego rozwiązania nie jest świadomy. Doradca klienta dostanie zadanie "wciskać klientom token GSM, bo wtedy nam koszty spadną o 1,21%". Gdy czasami zadam sobie trud i przeczytam informacje, które otrzymuje klient, to informacje merytoryczne są przykryte marketingowym blablingiem, czasami również odbiegają od rzeczywistości (no, przyjmijmy, że stanowią twórczą interpretację wyjątkowego przypadku).
Co do papki marketingowej: dokładnie o tym mówiłem. Celem dostawcy zabezpieczenia jest zarobek a nie bezpieczeństwo klienta.
Tak naprawdę chodzi o to samo: samo to, że zabezpieczenie "jest" powoduje, że klient usypia swoją czujność. Przypomina mi to zdjęcia z sieci "Ten samochód jest chroniony przez naklejkę antykradzieżową".
Tak więc, żadne zabezpieczenie nie zastąpi myślenia. Nie można usypiać czujności ani z kluczem do zamka, tokenem sprzętowym czy software-tokenem w komórce.
To że user nie zna internalsów - nie musi. Ale musi logicznie myśleć. Ktoś może mieć mój klucz = potencjalne kłopoty. A to, czy klucz jest do domu, banku, czy jest kawałkiem metalu, urządzeniem czy programem nie ma znaczenia.
Skoro user nie zadba o swoje bezpieczeństwo, bo nie umie myśleć, to nikt za niego myśleć nie będzie.
Czyli dostajemy dodatkową warstwę ochronną, która jest token, a w razie utraty telefonu po prostu dodatkowa warstwa znika, ale zostaje zwykłe hasło do konta Google. Czyli lepiej mieć token niż nie mieć, nic nie tracimy ale zyskujemy, bo ktoś musi nam nie tylko zhackowac kompa ale również telefon.
Ale jeśli dobrze rozumiem to w przypadku korzystania z autoryzacji dwuetapowej w Google statyczne hasło nie jest używane do logowania z Androida. Do aplikacji niewspierających tokena np. Thunderbird, Picassa, Android(chyba) itd. wykorzystywane są "hasła aplikacji", które możemy sobie dla takiej aplikacji wygenerować tylko i wyłączenie poprzez zalogowanie do konta Google w przeglądarce.
żródło: http://www.google.com/support/accounts/bin/static.py?page=guide.cs&guide=1056283&topic=1056286
W każdym razie nawet jeśli hasło mamy w telefonie to i tak bezpieczniej skorzystać z dodatkowej weryfikacji niż tego nie zrobić. Choćby dla ochrony przed zwykłym keyloggerem na nieznanym komputerze. Sam z tego jeszcze nie korzystam, bo po prostu mi się nie chcę, ale uważam, że w miarę znacząco podnosi to bezpieczeństwo konta. Zresztą zdecydowana większość osób z tego nie korzysta - więc może mało komu będzie się chciało to łamać
Druga sprawa - zdarzenie "malware na stacji" i "malware na telefonie" nie są zdarzeniami rozdzielnymi. Atakujący dysponując malware na stacji może skłonić użytkownika do zainstalowania sobie malware również na telefonie (socjotechnika). Dokładnie w ten sposób przecież działał malware atakujący banki - w większości przypadków użytkownik sam go sobie instalował na swoim telefonie zachęcony do tego przez komunikat wyświetlony na komputerze przez malware (np. w trakcie logowania do banku).
Jeśli chodzi o bezpieczeństwo sprzętu, to bardziej sensownym podejściem wydaje mi się ubezpieczenie telefonu. U części operatorów można coś takiego dokupić przy podpisywaniu umowy. Ale zdaję sobie sprawę, że znaczna część telefonów nie pochodzi (bezpośrednio) od operatora i takiej opcji nie ma.