Zrozumienie ataku Cross Site Request Forgery (CSRF)

Atak Cross Site Request Forgery jest jednym z tych typów ataków, które ciężko rozpoznać na pierwszy rzut oka. Najczęściej jest on wykorzystywany w połączeniu z innymi atakami. Polega on na zmuszeniu użytkownika do wykonania niepożądanej akcji w aplikacji internetowej. W połączeniu z innymi podatnościami, CSRF może skutkować różnymi efektami. Czasem może być to ujawnienie danych wrażliwych, usuwanie, edycja i dodawanie danych bądź nawet przejęcie dostępu do konta użytkownika.

Token

Istnieje kilka możliwości ochrony przed atakami CSRF. Warto wspomnieć, że większość współczesnych framemworków posiada wbudowaną ochronę przed CSRF (na przykład .NET).

Jednym z wielu i jednocześnie najbardziej znanym sposobem na ochronę przed CSRF jest generowanie losowych tokenów, czyli używanie wzorca Synchronizer Token Pattern. Owe tokeny są generowane po stronie serwera raz na sesję użytkownika lub każdorazowo przed kolejnym requestem. Wtedy, po przesłaniu formularza wyglądającego w sposób następująco:

<form action="/checkout" method="post">
  <input type="hidden" name="CSRFToken" value="edc5bb791b41b9d5d25a662dfe0bd11773351bd5c7e87d4c1a32cc66bdbc9694">
  (...)
</form>

Serwer sprawdza, czy wygenerowany wczesniej przez niego CSRFToken jest prawidłowy. Atakujący nie jest w stanie przewidzieć tokena, który zostanie chwilę wcześniej wygenerowany.

Przykład na żywej aplikacji

Cały czas obracamy się w świecie abstrakcji i teoretyzowania. Przejdźmy zatem do praktyki, która zobrazuje problem i atak Cross Site Request Forgery. Na początek zpullujmy lokalnie repozytorium. Następnie zainstalujmy potrzebne biblioteki i uruchomimy aplikację lokalnie. Pod adresem http://localhost:3000/login znajduje się nasza podatna aplikacja. Zalogujmy się używając loginu bob oraz hasła test.

Widzimy przed sobą prosty formularz do przesyłania środków na konta innych użytkowników. Na naszym koncie mamy 500 środków. Przejdźmy teraz na stronę atakującego pod linkiem http://localhost:3001/.

Zajrzyjmy w zakładkę Network w narzędziach developerskich.

Jak widać, zostało przesłanych kilka requestów na podatną stronę. Ponadto, kiedy wejdziemy na nią, zobaczymy, że nasze saldo uległo zmianie.

Jak to się stało, że balans naszego konta zmniejszył się o 13? Sprawdźmy dokładniej requesty ze strony atakującego.

GET /transfer?to=alice&amount=4 HTTP/1.1
Host: localhost:3000
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0
Accept: image/webp,*/*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
DNT: 1
Connection: keep-alive
Referer: http://localhost:3001/
Cookie: connect.sid=s%3AIIXi7mXyaq2sXJuCSaiBEUtkwrYzQxFu.CrlsY1pvQRTrS615VWPdhPCna8dimAmdP%2FzMPEW8ZN8
POST /transfer HTTP/1.1
Host: localhost:3000
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 17
Origin: http://localhost:3001
DNT: 1
Connection: keep-alive
Referer: http://localhost:3001/
Cookie: connect.sid=s%3AIIXi7mXyaq2sXJuCSaiBEUtkwrYzQxFu.CrlsY1pvQRTrS615VWPdhPCna8dimAmdP%2FzMPEW8ZN8
Upgrade-Insecure-Requests: 1

to=alice&amount=9

Między requestami znalazły się dwa ze statusem odpowiedzi 302. Jeden z nich jest żądaniem GET, w którym to w parametrach definiujemy osobę, do której mamy przesłać nasze środki (alice) i ich ilość (4). Drugi request jest już typu POST i w jego ciele znajdujemy te same informacje. Tym razem jednak ilość środków do przesłania ma wartość 9. Łącznie daje nam to 13 środków, czyli dokładnie tyle, ile zniknęło z naszego konta.

Skrypty do wykrywania podatności

Istnieje masa skryptów i narzędzi sprawdzających czy aplikacja poprawnie używa (jeśli w ogóle) tokenów. Jednym z narzędzi jest Bolt. Jego działanie jest banalnie proste.

┌──(bugspace㉿kali)-[~/Desktop/3rdtools/Bolt]
└─$ python3 bolt.py -u http://www.ip:port/ -l 2

     ⚡ BOLT  ⚡
    
(...)
 ⚡ Phase: Crawling [1/6]
[!] Crawled 12 URL(s) and found 12 form(s). 
 ⚡ Phase: Evaluating [2/6]
[+] Insecure form(s) found
 ⚡ Phase: Comparing [3/6]
[-] No CSRF protection to test
                                                                                

Innym przykładem narzędzia jest XSRFProbe.

┌──(bugspace㉿kali)-[~/Desktop/3rdtools/XSRFProbe]
└─$ xsrfprobe -u http://www.ip:port/

     _____       _____       _____      _____       _____                                    
  __|__   |_  __|___  |_  __|___  |_  _|____ |_   _|____ |_  _____   _____  ______  ______  
 \  `  /    ||   ___|   ||  _  _|   ||   ___|  | |   _  |  ||  _ ,' /     \|  _   )|   ___| 
  >   <     | `-.`-.    ||     \    ||   ___|  | |    __|  ||     \ |  -  || |_  { |   ___| 
 /__/__\   _||______|  _||__|\__\  _||___|    _| |___|    _||__|\__\\_____/|______)|______| 
    |_____|     |_____|     |_____|    |_____|     |_____| 


   [---]            XSRFProbe, A Cross Site Request Forgery Audit Toolkit          [---]
   [---]                                                                           [---]
   [---]                       ~  Author : Pinaki Mondal  ~                        [---]
   [---]                      ~  github.com / 0xInfection  ~                       [---]
   [---]                                                                           [---]
   [---]                           ~  Version 2.3.1  ~                             [---]

 [!] Testing site www.evil-page.com status...
 [+] Site seems to be up!
 [!] Testing  endpoint status...
 [+] Endpoint seems to be up!
 [*] Preparing the request...
 [*] Processing the GET Request...
 [!] Trying to parse response...
 [!] Checking endpoint request validation via Referer Checks...

 +--------------------------------------+
 |   Referer Based Request Validation   |
 +--------------------------------------+

 [!] Making request on normal basis...
 [*] Preparing the request...
 [*] Processing the GET Request...
 [*] Setting generic headers...
 [!] Making request with Tampered Referer Header...
 [*] Preparing the request...
 [*] Processing the GET Request...
 [-] Endpoint Referer Validation Not Present!
 [-] Heuristics reveal endpoint might be  VULNERABLE  to Origin Based CSRFs...
 [+] Possible CSRF Vulnerability Detected : http://www.evil-page.com/!
 [+] Possible Vulnerability Type:  No Referer Based Request Validation 
 [!] Confirming the vulnerability...
 [!] Confirming endpoint request validation via Origin Checks...

 +-------------------------------------+
 |   Origin Based Request Validation   |
 +-------------------------------------+

 [!] Making request on normal basis...
 [*] Preparing the request...
 [*] Processing the GET Request...
 [*] Setting generic headers...
 [!] Making request with Tampered Origin Header...
 [*] Preparing the request...
 [*] Processing the GET Request...
 [-] Endpoint Origin Validation Not Present!
 [-] Heuristics reveal endpoint might be  VULNERABLE  to Origin Based CSRFs...
 [+] Possible CSRF Vulnerability Detected : http://www.evil-page.com/!
 [!] Possible Vulnerability Type:  No Origin Based Request Validation 

 [!] Retrieving all forms on http://www.evil-page.com/...

 [+] Scan completed!

Źródła

https://owasp.org/www-community/attacks/csrf
https://github.com/Learn-by-doing/csrf-examples
https://rohitcoder.medium.com/victims-anti-csrf-token-could-be-exposed-to-third-party-applications-installed-on-user-s-device-be8e40d511ba
https://ysamm.com/?p=702
https://nirajmodi51.medium.com/missing-cors-leads-to-complete-account-takeover-1ed4b53bf9f2
https://github.com/s0md3v/Bolt
https://github.com/0xInfection/XSRFProbe

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *