Na tropie błędów. Przewodnik hakerski. Peter Yaworski
Чтение книги онлайн.
Читать онлайн книгу Na tropie błędów. Przewodnik hakerski - Peter Yaworski страница 13
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>