Na tropie błędów. Przewodnik hakerski. Peter Yaworski

Чтение книги онлайн.

Читать онлайн книгу Na tropie błędów. Przewodnik hakerski - Peter Yaworski страница 13

Na tropie błędów. Przewodnik hakerski - Peter Yaworski

Скачать книгу

ma atrybutów httponly i secure, może zostać odczytany przez potencjalnie groźne źródła. Plik cookie bez atrybutu secure może zostać wysłany do strony internetowej innej niż HTTPS; podobnie plik bez atrybutu httponly może być odczytany przez JavaScript.

      Atrybuty expires i max-age określają, kiedy plik cookie powinien wygasnąć i przeglądarka ma go zniszczyć. Atrybut expires określa konkretną datę, kiedy plik cookie ma zostać zniszczony. Na przykład cookie może ustawić atrybut expires=Wed, 18 Dec 2019 12:00:00 UTC. Dla odróżnienia, max-age określa liczbę sekund, po których cookie wygasa (max-age=300).

      Podsumowując, jeśli strona bankowa Boba używa plików cookies, przechowa ona jego autoryzację w następujący sposób. Kiedy tylko Bob odwiedzi stronę i zaloguje się, bank wyśle odpowiedź http, która będzie zawierać plik cookie identyfikujący Boba. Z kolei przeglądarka Boba zacznie automatycznie wysyłać ten plik wraz ze wszystkimi innymi żądaniami HTTP do strony internetowej banku.

      Po zakończeniu bankowości Bob opuszcza stronę banku, nie wylogowując się. Jest to istotny szczegół, ponieważ kiedy wylogowujesz się ze strony, ta wysyła odpowiedź http, która wygasza Twój plik cookie. W rezultacie po ponownym wejściu na stronę będziesz znowu musiał się zalogować.

      Po sprawdzeniu wiadomości Bob klika w link do złośliwej strony.  Ta następnie przeprowadza atak CSRF przez wysłanie żądania do strony bankowej z odpowiednimi plikami cookies.

      CSRF przez żądanie GET

      Sposób, w jaki złośliwa strona wykorzystuje stronę bankową Boba, zależy od tego, czy bank akceptuje przelewy przez żądania GET, czy POST. Jeśli strona bankowa Boba akceptuje przelewy przez żądanie GET, złośliwa strona wyśle żądanie HTTP z ukrytym formularzem, bądź znacznikiem <img>. Zarówno metoda GET, jak i POST opierają się na tym, aby dzięki odpowiedniemu kodowi HTML przeglądarka wysłała wymagane żądanie HTTP, oraz obie metody mogą użyć techniki ukrytego formularza, lecz tylko z metodą GET można użyć techniki tagów <img>. W tej części przyjrzymy się działaniu ataku, który korzysta ze sposobu tagu <img> przez żądanie GET, natomiast techniką z użyciem ukrytego formularza zajmiemy się w kolejnej części, „CSRF przez żądanie POST”.

      Atakujący musi umieścić pliki cookies Boba w każdym żądaniu HTTP do strony bankowej. Ponieważ jednak nie ma żadnego sposobu na odczytanie plików Boba, atakujący nie może po prostu stworzyć żądania HTTP i wysłać go na stronę. Zamiast tego może on użyć tagu <img> do utworzenia żądania GET, które będzie już mieć wymagane pliki cookies Boba. Tag <img> wyświetla zdjęcia na stronie internetowej i zawiera atrybut src, który określa lokalizację plików ze zdjęciami. Kiedy przeglądarka wyrenderuje tag <img>, wykona ona żądanie HTTP GET na adres opisany w atrybucie src oraz umieści w tym żądaniu wszystkie istniejące pliki cookies. Powiedzmy zatem, że złośliwa strona w celu wykonania przelewu 500 $ od Boba do Joe wykorzystuje poniższy URL:

      https://www.bank.com/transfer?from=bob&to=joe&amount=500

      Tag <img> użyje tego adresu jako wartość atrybutu src, tak jak poniżej:

      <img src="https://www.bank.com/transfer?from=bob&to=joe&amount=500">

      W wyniku tego, gdy Bob odwiedza stronę atakującego, w swojej odpowiedzi HTTP będzie ona zawierać złośliwy tag <img>, a zatem przeglądarka wykona żądanie GET do banku. Przeglądarka wysyła pliki uwierzytelniające w celu otrzymania tego, co uważa za obraz. W rzeczywistości jednak bank otrzymuje żądanie, przetwarza URL zawarty w atrybucie src i wykonuje żądanie przelewu.

      By uniknąć tej podatności, deweloperzy nigdy nie powinni korzystać z żądań GET w celu wykonania jakichkolwiek żądań modyfikujących dane, takich jak przelewanie pieniędzy. Jednak jakiekolwiek żądanie, które służy jedynie do odczytu, powinno być bezpieczne. Wiele popularnych frameworków używanych w budowie stron internetowych, takich jak Ruby on Rails, Django i tak dalej, odgórnie oczekuje od programistów przestrzegania tej zasady, zatem automatycznie dodają one zabezpieczenia CSRF do żądań POST, ale nie do żądań GET.

      CSRF przez żądanie POST

      Jeżeli bank wykonuje przelewy przez żądania POST, do wykonania ataku CSRF będziesz musiał podejść w inny sposób. Atakujący nie mógłby użyć znacznika <img>, ponieważ <img> nie może wywołać żądania POST. Zamiast tego strategia atakującego będzie zależeć od zawartości żądania POST.

      Najprostszy scenariusz obejmuje żądanie POST z nagłówkiem content-type application/x-www-form-urlencoded lub text/plain. Nagłówek content-type jest często dodawany przez przeglądarki przy wysyłaniu żądań HTTP. Podpowiada on odbiorcy, jak zakodowana jest treść żądania HTTP. Oto przykład żądania content-type text/plain:

      POST / HTTP/1.1

      Host: www.google.ca

      User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:50.0) Gecko/20100101  Firefox/50.0

      Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

      Content-Length: 5

      

Content-Type: text/plain;charset=UTF-8

      DNT: 1

      Connection: close

      hello

      Content-type

jest oznaczony, a jego rodzaj wymieniony wraz ze sposobem kodowania znaków w żądaniu. Nagłówek ten jest istotny, ponieważ przeglądarki mogą traktować różne rodzaje zawartości w odmienny sposób (do czego przejdę za moment).

      W tej sytuacji złośliwa strona jest w stanie utworzyć ukryty formularz HTML i wysłać go do podatnej witryny bez wiedzy ofiary. Formularz może wysłać żądanie POST lub GET na dany adres URL, a nawet przesłać wartości parametrów. Poniżej zobaczysz przykład szkodliwego kodu na stronie, do której podejrzany link mógł przekierować Boba:

      

<iframe style="display:none" name="csrf-frame"></iframe>

      

<form method='POST' action='http://bank.com/transfer' target= "csrf-frame" id="csrf-form">

      

<input type='hidden' name='from' value='Bob'>

      <input type='hidden' name='to' value='Joe'>

      <input type='hidden' name='amount' value='500'>

      <input type='submit' value='submit'>

      </form>

      

<script>document.getElementById("csrf-form").submit()</script>

      W tym przykładzie wykonujemy żądanie POST

do banku Boba razem z formularzem (oznaczonym atrybutem action w tagu <form>). Ponieważ atakujący nie chce, żeby Bob widział formularz, dlatego każdy z elementów <input>

Скачать книгу