WSTĘP
Ta książka wprowadzi Cię do obszernego świata hackingu etycznego lub inaczej procesu odpowiedzialnego odkrywania podatności bezpieczeństwa i zgłaszania ich do właścicieli aplikacji. Kiedy sam zaczynałem naukę hakowania, nie tylko chciałem wiedzieć, jakie podatności hakerzy znajdują, ale również, jak to robią.
Szukałem wszędzie informacji, lecz zawsze pozostawałem z tymi samymi pytaniami:
- Jakie podatności hakerzy znajdują w aplikacjach?
- Jak hakerzy uczyli się o tych podatnościach?
- Jak hakerzy zaczynają infiltrację strony?
- Jak wygląda samo hakowanie? Wszystko jest zautomatyzowane, czy może robione ręcznie?
- Jak mogę zacząć hakować i znajdować podatności?
W końcu znalazłem się na HackerOne, platformie bug bounty stworzonej do łączenia hakerów etycznych z firmami, które szukają osób do przetestowania ich aplikacji. HackerOne pozwala hakerom i firmom upubliczniać błędy, które zostały znalezione i naprawione.
Czytając te ujawnione zgłoszenia, starałem się zrozumieć, w jaki sposób ludzie znajdują podatności oraz jak je wykorzystują. Często musiałem przeczytać to samo zgłoszenie dwa lub trzy razy, zanim je zrozumiałem. Tak samo jak pozostali początkujący, zdałem sobie sprawę z tego, że mógłbym wynieść o wiele więcej z objaśnień znalezionych podatności, gdyby były napisane prostym językiem.
Na tropie błędów. Przewodnik hakerski jest na to autorską odpowiedzią, która pomoże Ci zrozumieć wiele rodzajów podatności w aplikacjach internetowych. Nauczysz się szukać podatności, zgłaszać je, zarabiać na tym oraz, przy okazji, pisać bezpieczny kod. Książka ta nie omawia jedynie pomyślnych przykładów: znajdziesz w niej również błędy i wyciągnięte wnioski, z których wiele należy do mnie.
Do czasu, gdy skończysz czytanie, postawisz swój pierwszy krok w kierunku zwiększania bezpieczeństwa oraz powinieneś być w stanie zarabiać na tym pieniądze.
Dla kogo jest ta książka?
Ta książka została napisana z myślą o początkujących hakerach. Nie ma znaczenia, czy tworzysz strony internetowe, czy projektujesz je, czy jesteś rodzicem przebywającym w domu, 10-letnim dzieckiem, czy 75-letnim emerytem.
Powiedziawszy to, choć nie jest to warunek konieczny do hakowania, pewne doświadczenie w programowaniu i znajomość z technologiami internetowymi mogą okazać się pomocne. Na przykład nie musisz być programistą internetowym, aby być hakerem, jednak znajomość podstawowego hipertekstowego języka znaczników (HTML), struktury strony internetowej, wyglądu kaskadowych arkuszy stylów (CSS) oraz tego, w jaki sposób JavaScript dynamicznie wchodzi w interakcję z witrynami, pomogą Ci odkrywać podatności i oceniać znaczenie znalezionych błędów.
Umiejętność programowania może pomóc, gdy szukasz podatności dotyczących logiki aplikacji oraz przy domysłach, gdzie programista mógł popełnić błędy. Jeśli potrafisz patrzeć z punktu widzenia programistów, zgadywać, w jaki sposób coś zostało zaimplementowane, bądź czytać ich kod (o ile jest dostępny), będziesz miał większą szansę na powodzenie.
Jeśli chcesz nauczyć się programowania, polecam Ci sprawdzić darmowe kursy na platformach Udacity oraz Coursera. Dodatkowe materiały znajdziesz w załączniku B.
Jak czytać tę książkę?
Każdy rozdział, który omawia określony rodzaj podatności, zbudowany jest w następujący sposób:
1. Opis rodzaju podatności.
2. Przykłady podatności.
3. Podsumowanie wraz z wnioskami.
Każdy przykład podatności zawiera następujące części:
1. Moją ocenę trudności w szukaniu i udowadnianiu tej podatności.
2. Adres URL powiązany z miejscem, w którym dana podatność została znaleziona.
3. Link do oryginalnego zgłoszenia bądź artykułu.
4. Data zgłoszenia podatności.
5. Kwota otrzymana za przesłanie informacji.
6. Przejrzysty opis podatności.
7. Wnioski, które warto zapamiętać.
Nie ma potrzeby czytania tej książki od deski do deski. Jeśli znajdziesz konkretny rozdział, którym jesteś zainteresowany, przeczytaj go najpierw. W niektórych przypadkach odnoszę się do pojęć omawianych w poprzednich rozdziałach, jednak robiąc to, staram się odnotować miejsce, w którym zdefiniowałem ten termin, dzięki czemu łatwiej Ci będzie znaleźć odpowiednią sekcję. Podczas hakowania trzymaj tę książkę otwartą.
Co znajdziesz w tej książce?
Oto przegląd tego, co znajdziesz w każdym z rozdziałów:
Rozdział 1: Podstawy Bug Bounty wyjaśnia, czym są podatności oraz programy bug bounty, oraz tłumaczy różnice między klientem a serwerem. Omawia również, w jaki sposób działa internet, a w tym żądania HTTP, odpowiedzi i metody, oraz co to znaczy, że HTTP jest bezstanowy.
Rozdział 2: Otwarte przekierowanie omawia ataki, które wykorzystują zaufanie użytkowników do określonej domeny w celu przekierowywania ich do innej.
Rozdział 3: HTTP Parameter Pollution omawia sposób, w jaki hakerzy manipulują żądaniami HTTP, wstrzykując dodatkowe parametry, którym dana witryna ufa, prowadząc w ten sposób do nieoczekiwanych rezultatów.
Rozdział 4: Cross-Site Request Forgery wyjaśnia sposób, w jaki atakujący może wykorzystać złośliwą stronę, aby przeglądarka ofiary wykonała żądanie HTTP do innej strony. Strona, która otrzymuje żądanie, postępuje tak, jakby żądanie zostało wysłane umyślnie przez ofiarę.
Rozdział 5: HTML Injection i fałszowanie treści tłumaczy, w jaki sposób złośliwy użytkownik może wstrzykiwać własne elementy HTML na docelowe strony internetowe.
Rozdział 6: Carriage Return Line Feed Injection pokazuje, jak atakujący wstrzykują zakodowane znaki do wiadomości HTTP, aby zmienić to, w jaki sposób interpretują je serwery, proxy i przeglądarki.
Rozdział 7: Cross-Site Scripting wyjaśnia, w jaki sposób atakujący wykorzystują strony, które nie filtrują danych wejściowych użytkownika, w celu wykonywania na nich własnego kodu JavaScript.
Rozdział 8: Template Injection pokazuje, jak atakujący wykorzystują template engine'y w przypadku, gdy strona nie filtruje odpowiednio wejścia użytkownika i używa ich w swoich szablonach. Rozdział pokrywa zarówno przypadki po stronie klienta, jak i serwera.
Rozdział 9: SQL Injection opisuje, jak podatność po stronie aplikacji (serwera) może pozwolić atakującemu na zaatakowanie bazy danych.
Rozdział 10: Server-Side Request Forgery wyjaśnia, w jaki sposób atakujący sprawiają, że serwer wykonuje niezamierzone żądania.
Rozdział 11: XML External Entity pokazuje, jak atakujący wykorzystują sposób, w jaki aplikacja parsuje dane wejściowe XML i przetwarza w nich zewnętrzne encje.
Rozdział 12: Zdalne wykonanie kodu dotyczy wykorzystywania serwera bądź aplikacji do uruchomienia na nich własnego kodu.
Rozdział 13: Podatności w manualnej obsłudze pamięci omawia sposoby, w jakie hakerzy wykorzystują zarządzanie pamięcią aplikacji do powodowania niezamierzonych działań, włączając w to możliwość wykonywania własnych poleceń.
Rozdział 14: Przejęcie subdomeny pokazuje, w jaki sposób atakujący może przejąć kontrolę nad subdomeną w imieniu uprawnionej domeny.
Rozdział 15: Race Condition wyjaśnia, jak atakujący wykorzystują sytuacje, w których zmiana warunku początkowego danego procesu ma wpływ na jego końcowy wynik.
Rozdział 16: Insecure Direct Object Reference omawia wszelkie podatności pojawiające się, gdy atakujący ma dostęp do odniesienia do obiektu, do którego nie powinien mieć dostępu, na przykład pliku, rekordu w bazie danych bądź konta.
Rozdział 17: Podatności OAuth pokazuje błędy w implementacji protokołu stworzonego do uproszczenia i ustandaryzowania bezpiecznego uwierzytelniania w aplikacjach internetowych, mobilnych i desktopowych.
Rozdział 18: Podatności w logice i konfiguracji aplikacji wyjaśnia, w jaki sposób atakujący mogą wykorzystać wadliwą logikę w kodzie lub błąd w konfiguracji do wykonania niezamierzonych działań.
Rozdział 19: Poszukiwanie podatności na własną rękę dostarcza wskazówki, gdzie i jak szukać podatności, bazując na moich doświadczeniach i metodologii. Ten rozdział nie jest jednak poradnikiem krok po kroku do włamywania się na stronę.
Rozdział 20: Zgłaszanie podatności omawia, w jaki sposób pisać wiarygodne i informacyjne zgłoszenia podatności, dzięki czemu programy nie odrzucą twoich raportów.
Załącznik A: Narzędzia omawia popularne narzędzia stworzone do hakowania, włączając w to przechwytywanie ruchu sieciowego, enumerację subdomen, wykonywanie zrzutów ekranu i wiele więcej.
Załącznik B: Źródła stanowi listę dodatkowych materiałów do dalszego rozwoju w dziedzinie hackingu. Znajdziesz tu między innymi ćwiczenia online, popularne platformy bug bounty i polecane blogi.
Zastrzeżenie dotyczące hakowania
Patrząc na upublicznione zgłoszenia podatności, a dokładniej na kwoty pieniędzy, które hakerzy za nie otrzymują, naturalnie może się wydawać, że hacking to łatwa i szybka droga do wzbogacenia się. Tak jednak nie jest. Poszukiwanie błędów potrafi być satysfakcjonujące, jednak mało prawdopodobne jest, że napotkasz wiele historii o porażkach, które zdarzają się po drodze (z wyjątkiem tej książki, gdzie dzielę się kilkoma naprawę kompromitującymi opowieściami). Ponieważ będziesz głównie słyszał o sukcesach hakerów, możesz rozwinąć nierealistyczne oczekiwania wobec swojej hakerskiej przygody.
Sukces może przyjść do Ciebie bardzo szybko. Jednak jeśli masz problemy ze znajdowaniem błędów, nie przestawaj się zagłębiać. Programiści zawsze będą pisać nowy kod, a błędy stanowią nieuniknioną część tego procesu. Im bardziej się starasz, tym więcej błędów będziesz znajdował.
W tej sprawie możesz śmiało do mnie napisać na Twitterze @yaworsk i dać znać, jak sobie radzisz. Nawet jeśli nie odnosisz sukcesów, chciałbym to od Ciebie usłyszeć. Bug hunting potrafi być samotną pracą, szczególnie jeśli sprawia Ci trudności. Jednak wspaniale jest też wspólnie świętować, a może nawet znajdziesz coś, co będę mógł zamieścić w następnym wydaniu tej książki.
Powodzenia i szczęśliwego hakowania.
1. PODSTAWY BUG BOUNTY
Jeżeli jesteś nowy w świecie hackingu, podstawowe zrozumienie tego, jak internet działa i co się dzieje "pod maską", kiedy wpisujesz adres URL w przeglądarce, będzie Ci bardzo pomocne. Nawigacja po stronach internetowych może wydawać się prosta, lecz wbrew pozorom angażuje ona wiele ukrytych procesów, takich jak przygotowanie żądania HTTP, identyfikacja domeny, do której wysłać żądanie, tłumaczenie domeny na adres IP, przesłanie żądania, renderowanie odpowiedzi i tak dalej.
W tym rozdziale poznasz podstawowe koncepcje i terminologię, takie jak podatności, programy bug bounty, klient, serwer, adres IP oraz HTTP. Zrozumiesz, w jaki sposób wykonywanie niezamierzonych akcji i dostarczanie nieoczekiwanego wejścia lub dostępu do prywatnych informacji może skutkować podatnościami bezpieczeństwa. Następnie zobaczymy, co się dzieje, kiedy wpisujesz adres URL w pasku adresu swojej przeglądarki, włączając w to, jak wyglądają żądania i odpowiedzi HTTP, jak i również różne metody HTTP. Zakończymy rozdział ze zrozumieniem tego, co oznacza stwierdzenie, że protokół HTTP jest bezstanowy.
Podatności i Bug Bounty
Podatność jest to słabość aplikacji, która pozwala złośliwej osobie wykonać niedozwolone akcje lub uzyskać dostęp do informacji, których normalnie nie powinna być stanie uzyskać.
Podczas nauki i testowania aplikacji pamiętaj o tym, że podatności mogą skutkować działaniami zamierzonymi lub niezamierzonymi. Dla zobrazowania: zmiana parametru / pola ID identyfikatora rekordu w celu uzyskania informacji, do których nie powinieneś mieć dostępu, jest przykładem niezamierzonej akcji.
Załóżmy, że utworzyłeś profil ze swoją nazwą, e-mailem, datą urodzenia i adresem. Strona zachowałaby te informacje jako prywatne i umożliwiłaby do nich dostęp tylko Twoim znajomym. Jeśli jednak aplikacja internetowa pozwala komukolwiek dodawać Cię jako swojego znajomego bez Twojej zgody, byłaby to podatność bezpieczeństwa. Mimo że strona strzeże Twoich prywatnych danych przed nieznajomymi, pozwalając dowolnej osobie na dodanie Cię do swoich znajomych bez Twojej zgody, jednocześnie umożliwia ona każdemu dostęp do informacji o Tobie. Kiedy testujesz stronę internetową, zawsze rozważaj to, jak ktoś mógłby nadużyć obecnej funkcjonalności.
Bug bounty to nagroda, którą strona lub firma przyznaje każdemu, kto w etyczny sposób znajdzie podatność i zgłosi ją do administracji bądź firmy. Nagrody są zazwyczaj pieniężne i wahają się od dziesiątek, aż po tysiące dolarów. Inne przykłady nagród to między innymi kryptowaluty, mile lotnicze, punkty nagród bądź inne dobra cyfrowe.
Kiedy firma oferuje nagrody za znalezienie podatności, tworzy wyznaczony do tego program - termin, używany w tej książce, by oznaczyć zasady i strukturę ustanowione przez firmy dla ludzi, którzy chcą testować firmy na te podatności. Zwróć uwagę na to, że różni się to od firm, które wykorzystują programy upubliczniania podatności (Vulnerability Disclosure Program - VDP). Programy bug bounty oferują nagrody pieniężne, podczas gdy VDP nie oferuje płatności (aczkolwiek firmy mogą nagradzać rzeczami). VDP to najzwyklejszy sposób dla uczciwych hakerów na zgłaszanie znalezionych podatności, aby dana firma mogła je naprawić. Mimo że nie wszystkie zgłoszenia przedstawione w tej książce zostały nagrodzone, wszystkie pochodzą od hakerów biorących udział w programach bug bounty.
Klient i serwer
Twoja przeglądarka korzysta z internetu, który jest siecią komputerów wysyłających do siebie wiadomości. Wiadomości te nazywamy pakietami. Pakiety zawierają dane, które wysyłasz, i informacje o tym, skąd te dane wychodzą i dokąd zmierzają. Każdy komputer w internecie ma adres do odbierania pakietów. Niektóre komputery akceptują tylko określone typy pakietów, a jeszcze inne akceptują pakiety tylko z ograniczonej listy innych komputerów. Kiedy komputer odbiera pakiet, zależy to tylko od niego, co z nim zrobi i jak odpowie. Na potrzeby tej książki skupimy się tylko na danych zawartych w pakietach (wiadomościach HTTP), a nie na samych pakietach.
Będę się odwoływał do tych komputerów jako do klientów lub serwerów. Komputer inicjujący żądanie jest zazwyczaj nazywany klientem, niezależnie od tego, czy żądanie jest zainicjowane przez przeglądarkę, wiersz poleceń lub coś innego. Nazwa serwery odnosi się do stron i aplikacji internetowych odbierających żądania.
Ponieważ internet może mieć dowolną liczbę rozmawiających ze sobą komputerów, potrzebujemy wytycznych do tego, jak komputery powinny się komunikować przez internet. Przyjmują one formę dokumentów RFC (Request for Comment - prośba o komentarze), które definiują standardy tego, w jaki sposób komputery powinny się zachowywać. Na przykład protokół przesyłania dokumentów hipertekstowych - w skrócie HTTP (Hypertext Transfer Protocol) - określa, jak Twoja przeglądarka internetowa komunikuje się ze zdalnym serwerem przy użyciu protokołu internetowego IP (Internet Protocol). W tym przypadku zarówno klient, jak i serwer muszą się zgodzić na implementację tych samych standardów, dzięki czemu są w stanie zrozumieć wysyłane i odbierane przez siebie pakiety.
Co się dzieje, kiedy odwiedzasz stronę
Ponieważ w tej książce skupiamy się na żądaniach HTTP, ta sekcja dostarczy Ci wysokopoziomowy wgląd na cały proces, który następuje po wpisaniu adresu URL w przeglądarce.
Krok 1: Identyfikacja domeny internetowej
Kiedy wpiszesz http://www.google.com/, Twoja przeglądarka ustala domenę z adresu URL. Domena identyfikuje stronę, którą próbujesz odwiedzić, i musi przy tym przestrzegać określonych zasad zdefiniowanych przez RFC. Na przykład domena może zawierać tylko znaki alfanumeryczne i podkreślenia. Jedyny wyjątek stanowią zinternacjonalizowane domeny, które wychodzą poza zakres tej książki. Jeśli chcesz dowiedzieć się więcej na ten temat, sprawdź dokument RFC 3490, który definiuje ich użycie. W tym przypadku domeną jest www.google.com. Domena służy jako jedna z dróg do znalezienia adresu serwera.
Krok 2: Ustalenie adresu IP
Po ustaleniu domeny, Twoja przeglądarka używa IP do sprawdzenia adresu IP powiązanego z tą stroną. Ten proces jest określany jako ustalanie adresu IP i każda domena w internecie musi zostać przetłumaczona na adres IP, aby działała.
Istnieją dwa rodzaje adresów IP, definiowane przez protokół internetowy w wersji 4 (IPv4) i w wersji 6 (IPv6). Adresy IPv4 są skonstruowane z czterech liczb połączonych kropkami, gdzie każdy numer jest z przedziału od 0 do 255. IPv6 jest najnowszą wersją protokołu internetowego. Został stworzony po to, by rozwiązać problem kończących się adresów IPv4. Adresy IPv6 są stworzone z ośmiu grup czterocyfrowych liczb dziesiętnych, oddzielonych dwukropkami, lecz istnieją metody na ich skrócenie. Na przykład 8.8.8.8 jest adresem IPv4, a 2001:4860:4860::8888 jest skróconym adresem IPv6.
Aby znaleźć adres IP, używając domeny, Twój komputer wysyła żądanie do serwerów DNS (Domain Name System) składających się ze specjalnych serwerów w internecie, które mają rejestr wszystkich domen i odpowiadających im adresów IP. Powyższe adresy IPv4 i IPv6 są serwerami DNS Google.
W tym przypadku serwer DNS, do którego się łączysz, dopasowałby www.google.com do adresu IPv4 216.58.201.228 i wysłałby go z powrotem do Twojego komputera. By dowiedzieć się więcej na temat adresu IP konkretnej strony, możesz użyć komendy dig A site.com w swoim terminalu i zamienić site.com na stronę, którą chcesz sprawdzić.
Krok 3: Nawiązanie połączenia TCP
Następnie komputer próbuje nawiązać połączenie TCP (Transmission Control Protocol - protokół kontroli transmisji) z adresem IP przez port 80, ponieważ odwiedziłeś stronę, używając http://. Szczegóły na temat TCP nie są istotne oprócz tego, że jest to kolejny protokół, który definiuje sposób, w jaki komputery komunikują się ze sobą. TCP zapewnia dwukierunkową komunikację, dzięki czemu odbiorcy wiadomości mogą zweryfikować kompletność przesyłanej informacji podczas transmisji.
Serwer, do którego wysyłasz żądanie, może być w trakcie obsługi wielu usług (traktuj usługę jako program komputerowy), więc używa portów do identyfikacji konkretnych usług, aby odbierać żądania. Możesz je sobie wyobrazić jako drzwi serwera do internetu. Bez portów usługi musiałyby konkurować ze sobą o to, która informacja zostanie wysłana. Oznacza to, że potrzebujemy kolejnego standardu do zdefiniowania tego, jak usługi współpracują ze sobą i upewnić się, że dane dla jednej usługi nie są kradzione przez inne. Na przykład port 80 jest standardowym portem do wysyłania i odbierania żądań HTTP. Innym powszechnym portem jest 443, który jest używany do zaszyfrowanych żądań HTTPS. Mimo że port 80 jest standardem dla HTTP i 443 jest standardem dla HTTPS, komunikacja TCP może następować na dowolnym porcie, zależnie od konfiguracji aplikacji przez administratora.
Możesz nawiązać swoje własne połączenie TCP do strony internetowej przez port 80 przy użyciu terminala, wpisując komendę nc <ADRES IP> 80. Komenda nc używa narzędzia Netcat do utworzenia połączenia sieciowego do odczytywania i pisania wiadomości.
Krok 4: Wysyłanie zapytania HTTP
Kontynuując przykład ze stroną http://www.google.com/, jeśli połączenie w kroku 3 zostało nawiązane pomyślnie, Twoja przeglądarka powinna przygotować i wysłać żądanie HTTP, tak jak w listingu 1.1:
GET / HTTP/1.1
Host: www.google.com
Connection: keep-alive
Accept: application/html, */*
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.109 Safari/537.36
Listing 1.1. Wysyłanie żądania HTTP
Przeglądarka przygotowuje żądanie GET do ścieżki / , która jest główną ścieżką dostępu strony. Zawartość strony jest organizowana ścieżkami, dokładnie tak samo jak foldery i pliki na Twoim komputerze. Gdy wchodzisz w kolejne foldery, ścieżka, którą podążasz, jest oznaczona przez zapisywanie nazw kolejnych folderów i dopisywanie / na ich końcu. Kiedy odwiedzasz pierwszą stronę na witrynie internetowej, dostajesz się do głównej ścieżki dostępu, którą jest po prostu /. Przeglądarka również sygnalizuje, że używa wersji 1.1 protokołu HTTP. Żądanie GET jedynie otrzymuje informacje. Dowiesz się o tym więcej później.
Nagłówek host zawiera dodatkowe informacje, które są wysłane jako część zapytania. HTTP 1.1 potrzebuje ich, by określić, gdzie serwer dla danego adresu IP powinien przesłać żądanie, ponieważ adresy IP mogą hostować kilka domen na raz. Nagłówek connection informuje, żeby utrzymać połączenie otwarte, aby uniknąć potrzeby ciągłego otwierania i zamykania połączeń.
Możesz zobaczyć oczekiwany format odpowiedzi w . W tym przypadku oczekujemy application/html, lecz zaakceptujemy każdy format, co zostało oznaczone symbolem (*/*). Istnieją tysiące możliwych rodzajów zawartości, ale dla naszych potrzeb najczęściej będziesz wykorzystywał: application/html, application/json, application/octet-stream oraz text/plain. W końcu User-Agent określa oprogramowanie odpowiedzialne za wysyłanie żądań.
Krok 5: Odpowiedź serwera
W odpowiedzi na nasze żądanie serwer powinien odpowiedzieć czymś w rodzaju listingu 1.2:
HTTP/1.1 200 OK
Content-Type: text/html
<html>
<head>
<title>Google.com</title>
</head>
<body>
--cięcie--
</body>
</html>
Listing 1.2. Odpowiedź serwera
Tutaj otrzymaliśmy odpowiedź HTTP z kodem statusu 200 . Kod statusu jest istotny, ponieważ mówi o rezultacie odpowiedzi. Co również jest opisane przez RFC, kody te zazwyczaj mają trzycyfrowy numer, który zaczyna się 2, 3, 4 lub 5. Mimo że nie ma wyznaczonych standardów do używania konkretnych kodów, 2xx najczęściej oznacza sukces.
Ponieważ nie istnieje żaden wymóg co do tego, jak serwer implementuje użycie własnych kodów HTTP, możesz czasem zobaczyć odpowiedź z kodem 200, nawet jeśli dalsza odpowiedź HTTP opisuje błąd. Treść wiadomości HTTP jest tekstem powiązanym z żądaniem lub odpowiedzią . W tym przypadku usunęliśmy zawartość i zamieniliśmy ją na -cięcie-- ze względu na wielkość treści wiadomości od Google. Zawartość odpowiedzi to zazwyczaj HTML dla strony internetowej, ale może być również tekstem JSON dla API, zawartością do pobrania i tak dalej.
Nagłówek Content-Type informuje przeglądarkę o rodzaju treści. Rodzaj treści określa, w jaki sposób przeglądarka będzie renderować zawartość. Przeglądarki nie zawsze jednak używają wartości zwróconej przez aplikację; zamiast tego przeglądarka wykonuje tzw. MIME sniffing przez czytanie pierwszych bitów treści wiadomości, aby wykryć jej rodzaj samemu. Aplikacje mogą wyłączyć tę funkcję przez dołączanie nagłówka X-Content-Type-Options:nosniff, który w obecnym przykładzie nie został dołączony.
Kolejny kod statusu, zaczynający się od 3 oznacza przekierowanie, co instruuje Twoją przeglądarkę do wykonania dodatkowego zapytania. Na przykład, jeśli Google chciałby odesłać Cię na stałe z jednego adresu URL na drugi, użyłby odpowiedzi 301. Dla odróżnienia 302 oznacza tymczasowe przekierowanie.
Gdy otrzymujesz odpowiedź 3xx, Twoja przeglądarka powinna wykonać nowe żądanie HTTP na adres URL wskazany w nagłówku Location:
HTTP/1.1 301 Found
Location: https://www.google.com/
Odpowiedzi zaczynające się od 4 najczęściej wskazują na błąd użytkownika, tak jak kod 403, kiedy żądanie nie będzie zawierało odpowiednich danych do wykonania uwierzytelnienia, mimo przesłania prawidłowego żądania HTTP. Odpowiedzi zaczynające się 5 oznaczają błąd po stronie serwera, przykładem może być kod 503, który oznacza, że serwer nie jest w stanie obsłużyć otrzymanego żądania.
Krok 6: Renderowanie odpowiedzi
Ponieważ serwer wysłał odpowiedź z kodem 200 i rodzajem text/html, nasza przeglądarka rozpocznie renderowanie wiadomości, którą otrzymała. Treść odpowiedzi mówi przeglądarce, co powinno zostać wyświetlone użytkownikowi.
Dla naszego przykładu byłby to HTML do budowy strony; kaskadowe arkusze stylów (CSS) do stylizacji i układu; JavaScript do dodatkowej funkcjonalności i mediów, takich jak zdjęć lub filmów. Serwer może również odpowiedzieć inną zawartością, taką jak XML, lecz dla tego przykładu zostaniemy przy podstawach. Rozdział 11 omawia XML w szczegółach.
W przypadku gdy strona internetowa ma zewnętrzną zawartość, taką jak CSS, JavaScript czy media, przeglądarka będzie musiała wykonać dodatkowe żądania HTTP dla wszystkich wymaganych plików przez daną witrynę. W trakcie gdy przeglądarka wysyła wymagane żądania, wciąż będzie analizować odpowiedź i wyświetlać zawartość jako stronę. W tym przypadku wyrenderuje główną stronę Google, www.google.com.
Zauważ, że JavaScript jest językiem skryptowym wspieranym przez każdą przeglądarkę. JavaScript pozwala stronom na posiadanie dynamicznej funkcjonalności, włączając w to możliwość aktualizacji elementów na stronie bez potrzeby odświeżania całej strony, sprawdzanie siły Twojego hasła (w przypadku niektórych stron) i wiele innych. Tak jak inne języki programowania, JavaScript ma wbudowane funkcje, może przechowywać wartości w zmiennych i potrafi uruchamiać kod w odpowiedzi na interakcje na stronie. Ma również dostęp do zróżnicowanych interfejsów programowania (API). Interfejsy te pozwalają językowi JavaScript na interakcję z innymi systemami, z czego jednym z najważniejszych jest obiektowy model dokumentu (DOM - Document Object Model).
DOM umożliwia językowi JavaScript dostęp i manipulację kodem HTML i CSS należącymi do strony. Jest to bardzo istotne, ponieważ jeśli intruz jest w stanie uruchomić własny kod JavaScript, będzie on mógł uzyskać dostęp do DOM-u i wykonać akcje na stronie w imieniu ofiary. Rozdział 7 rozwija to zagadnienie dokładniej.
Żądania HTTP
Zgoda między klientem a serwerem w użyciu wiadomości HTTP włącza definiowanie metod żądań. Metoda określa powód żądania przesyłanego przez klienta oraz to, czego oczekuje jako pozytywny rezultat. Dla zobrazowania w listingu 1.1 wysłaliśmy zapytanie GET do http://google.com/, implikując w ten sposób, że oczekujemy jedynie zawartości http://google.com/ w odpowiedzi, bez wykonywania dodatkowych akcji. Internet jest zaprojektowany jako interfejs między zdalnymi komputerami, z tego względu metody żądań zostały zbudowane i zaimplementowane po to, by rozpoznawać podejmowane akcje.
Standard HTTP definiuje następujące metody: GET, HEAD, POST, PUT, DELETE, TRACE, CONNECT i OPTIONS (PATCH było również rozważane, lecz nie jest wystarczająco często implementowane). W momencie pisania tej książki, przeglądarki wysyłają jedynie żądania GET i POST przy użyciu HTML. Jakiekolwiek żądanie PUT, PATCH lub DELETE może być wywołane jedynie przez JavaScript. Skupimy się na tym później, kiedy będziemy omawiać przykłady podatności aplikacji używających tych metod.
Następna część zawiera zwięzły przegląd rodzajów metod, które znajdziesz w tej książce.
Metody żądań
Metoda GET wyszukuje informacje zidentyfikowane przez URI żądania (Uniform Resource Identifier - ujednolicony identyfikator zasobów). Termin URI jest często synonimicznie używany z URL (Uniform Resource Locator - ujednolicony format adresowania zasobów). Technicznie rzecz biorąc, URL jest jednym z rodzajów URI, który określa zasoby, i zawiera sposób na odnalezienie ich przez lokalizację w sieci. Na przykład http://google.com/<example>/file.txt oraz <example>/file.txt są poprawnymi adresami URI. Jednak tylko http://google.com/<example>/file.txt jest poprawnym URL-em, ponieważ wskazuje, jak odnaleźć zasoby przez domenę http://www.google.com. Pomijając niuanse, kiedy będziemy w tej książce odnosić się do jakichkolwiek identyfikatorów, będziemy używać adresów URL.
Choć nie ma sposobu na wymuszenie tego warunku, żądania GET nie powinny modyfikować danych; powinny jedynie otrzymywać dane z serwera i zwracać je jako zawartość treści HTML. Dla zobrazowania na stronach mediów społecznościowych żądanie GET powinno jedynie zwracać nazwę Twojego profilu, nie aktualizować go. To zachowanie jest krytyczne w przypadku ataków CSRF (Cross-Site Request Forgery) omawianych w rozdziale 4. Odwiedzenie jakiegokolwiek linku bądź adresu URL (o ile nie zostało wykonane przez JavaScript) sprawia, że Twoja przeglądarka wysyła żądanie GET do zamierzonego serwera. Zachowanie to jest bardzo istotne w przypadku podatności na otwarte przekierowania, omawianych w rozdziale 2.
Metoda HEAD jest identyczna z metodą GET z wyjątkiem tego, że serwer nie może przesłać treści wiadomości w odpowiedzi.
Metoda POST uruchamia niektóre funkcje ustalone przez połączony serwer. Innymi słowy, często na stronach podejmujesz pewnego rodzaju backendowe czynności, takie jak utworzenie komentarza, rejestracja użytkownika, usunięcie konta i tak dalej. Reakcja serwera na otrzymane od nas żądanie POST może być różna. Czasem serwer nie podejmie żadnej akcji, na przykład w przypadku, gdy wysłane żądanie POST spowodowało błąd podczas jego przetwarzania. W takiej sytuacji zmiany na serwerze nie zostaną zapisane.
Metoda PUT wywołuje funkcje, które odnoszą się do istniejących już zapisów w zdalnej aplikacji bądź witrynie. Na przykład może być użyta podczas aktualizacji profilu, utworzenia posta na blogu bądź czymkolwiek, co już istnieje. Ponownie podjęte akcje mogą być różne, a czasem nie zostanie podjęta żadna.
Metoda DELETE wysyła żądanie dotyczące usunięcia zdalnego zasobu zidentyfikowanego przez URI.
Metoda TRACE jest kolejną rzadką metodą; jest używana do odesłania wysłanego żądania z powrotem do źródła. Pozwala wykonawcy żądania na zobaczenie tego, co jest odbierane przez serwer i użyć tej informacji do testów bądź zbierania danych diagnostycznych.
Metoda CONNECT jest zarezerwowana do użytku przez proxy, serwer pośredniczący między żądaniami. Ta metoda rozpoczyna dwukierunkową komunikację z żądanym źródłem. Na przykład metoda CONNECT może mieć dostęp do stron, które używają HTTPS przez proxy.
Metoda OPTIONS wysyła żądanie do serwera o informację o dostępnych możliwościach komunikacji. Na przykład, używając OPTIONS, możesz dowiedzieć się, czy serwer akceptuje zapytania GET, POST, PUT, DELETE lub OPTIONS. Ta metoda nie wskaże jednak, czy serwer akceptuje zapytania HEAD lub TRACE. Przeglądarki internetowe automatycznie wysyłają ten rodzaj żądania, gdy zauważą specyficzny rodzaj zawartości, taki jak application/json. Metoda OPTIONS, należąca do mechanizmu preflighted requests, jest omówiona dokładniej w rozdziale 4, gdyż służy jako ochrona przed atakami CSRF.
Protokół HTTP jest bezstanowy
Żądania HTTP są bezstanowe, co oznacza, że każde wysłane żądanie do serwera jest traktowane jako całkowicie nowe. Serwer nie zna historii komunikacji z Twoją przeglądarką, kiedy dobiera żądanie. Dla większości stron jest to problematyczne, ponieważ chcą one pamiętać kim jesteś. Bez tego musiałbyś wpisywać swoją nazwę użytkownika i hasło za każdym razem, kiedy prześlesz żądanie HTTP. Oznacza to również, że wszystkie dane wymagane do wykonania żądania HTTP musiałyby zostać przeładowane z każdym żądaniem, które klient wyśle do serwera.
Do objaśnienia tego mylącego konceptu rozważ następujący przykład: jeśli Ty i ja prowadzilibyśmy bezstanową konwersację, przed wypowiedzeniem jakiegokolwiek zdania musielibyśmy zacząć od "Nazywam się Peter Yaworski; przed chwilą rozmawialiśmy o hakowaniu". Wtedy, musiałbyś przeładować wszystkie informacje dotyczące naszej dyskusji o hakowaniu. Pomyśl tylko co Adam Sandler musiał robić dla Drew Barrymore każdego poranka w 50 Pierwszych Randkach (jeśli nie widziałeś tego filmu, to powinieneś).
W celu uniknięcia konieczności wysyłania swojej nazwy użytkownika razem z hasłem dla każdego żądania HTTP strony internetowe korzystają z plików cookies lub podstawowej autoryzacji, które omówimy szczegółowo w rozdziale 4.
UWAGASpecyfika tego, w jaki sposób dane są kodowane przy użyciu base64, jest poza zakresem tej książki, prawdopodobnie jednak napotkasz zawartość zakodowaną przez base64 podczas hakowania. Jeśli tak, powinieneś ją rozszyfrować. Zapytanie w Google "base64 decode" powinno dostarczyć Ci wystarczającej liczby metod i narzędzi do wykonania tej czynności.
Podsumowanie
Powinieneś teraz już wiedzieć, jak w podstawowy sposób działa komunikacja z serwerami webowymi. Dokładniej mówiąc, dowiedziałeś się tego, co się dzieje, kiedy wpisujesz adres strony w pasek adresu przeglądarki: jak przeglądarka tłumaczy to na domenę, w jaki sposób domena jest kojarzona z adresem IP oraz jak żądanie HTTP jest wysyłane na serwer.
Dowiedziałeś się również, jak Twoja przeglądarka tworzy żądania i renderuje odpowiedzi oraz jak żądania HTTP pozwalają klientom na komunikację z serwerami. Dodatkowo dowiedziałeś się o tym, że podatności wynikają z podejmowania przez kogoś niezamierzonych akcji i otrzymywania informacji w zamyśle niedostępnych dla niego. Poznałeś także programy bug bounty, które wynagradzają hakerów za odkrycia podatności w zabezpieczeniach i zgłaszanie ich do właścicieli stron.