HTTP Request Smuggling / HTTP Desync Attack
Qu'est-ce que c'est
Cette vulnérabilité se produit lorsqu'une désynchronisation entre les proxys frontaux et le serveur back-end permet à un attaquant d'envoyer une requête HTTP qui sera interprétée comme une seule requête par les proxys frontaux (équilibrage de charge/proxy inverse) et comme 2 requêtes par le serveur back-end. Cela permet à un utilisateur de modifier la prochaine requête 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 du corps de l'entité, en octets, envoyé au destinataire.
Transfer-Encoding: chunked
L'en-tête Transfer-Encoding spécifie la forme de codage utilisée pour transférer en toute sécurité le corps de la charge utile à l'utilisateur. Chunked signifie que de grandes données sont envoyées sous forme de séries de morceaux.
Réalité
Le Front-End (un équilibreur de charge / Proxy Inverse) traite 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 pourrait être très critique car un attaquant pourra envoyer une requête au proxy inverse 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 venait 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 par le 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 prochain chunk. 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 Smuggling de Requête.
Exemples de Base
Lorsque vous essayez d'exploiter cela avec Burp Suite, désactivez Mettre à jour la longueur du contenu
et Normaliser les fins de ligne HTTP/1
dans le répéteur car certains gadgets abusent des sauts de ligne, des retours chariot et des longueurs de contenu mal formées.
Les attaques de Smuggling de Requête HTTP sont élaborées en envoyant des requêtes ambiguës qui exploitent les divergences dans la façon dont les serveurs frontaux 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 comme CL.TE, TE.CL et TE.TE. Chaque type représente une combinaison unique de la priorisation de ces en-têtes par les serveurs frontaux et back-end. Les vulnérabilités découlent du traitement de la même requête par les serveurs de différentes manières, entraînant des résultats inattendus et potentiellement malveillants.
Exemples de Types de Vulnérabilités de Base
![](https://book.hacktricks.xyz/~gitbook/image?url=https%3A%2F%2F2088318145-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252Frq9WIQinJaxpWMvakjIQ%252Fuploads%252Fgit-blob-24c786eb7fc7afff983199ae45a26b18629c65da%252FEKi5edAUUAAIPIK.jpg%3Falt%3Dmedia&width=768&dpr=4&quality=100&sign=1caed2fb&sv=1)
Vulnérabilité CL.TE (Content-Length utilisé par le Front-End, Transfer-Encoding utilisé par le Back-End)
Front-End (CL) : Traite la requête en fonction de l'en-tête
Content-Length
.Back-End (TE) : Traite la requête en fonction de 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 serveur front-end transmet la requête entière au serveur back-end, en fonction de la valeur de
Content-Length
.Le serveur back-end traite la requête en morceaux en raison de l'en-tête
Transfer-Encoding: chunked
, interprétant les données restantes comme une requête distincte et ultérieure.Exemple :
Vulnérabilité TE.CL (Transfer-Encoding utilisé par le Front-End, Content-Length utilisé par le Back-End)
Front-End (TE) : Traite la requête en fonction de l'en-tête
Transfer-Encoding
.Back-End (CL) : Traite la requête en fonction de l'en-tête
Content-Length
.Scénario d'attaque :
L'attaquant envoie une requête en morceaux où la taille du morceau (
7b
) et la longueur réelle du contenu (Content-Length: 4
) ne correspondent pas.Le serveur front-end, respectant
Transfer-Encoding
, transmet la requête entière au serveur back-end.Le serveur back-end, respectant
Content-Length
, traite uniquement la partie initiale de la requête (7b
octets), laissant le reste comme partie d'une requête ultérieure non intentionnelle.Exemple :
Vulnérabilité TE.TE (Transfer-Encoding utilisé par les deux, avec obfuscation)
Serveurs : Les deux prennent en charge
Transfer-Encoding
, mais l'un peut être trompé pour l'ignorer via l'obfuscation.Scénario d'attaque :
L'attaquant envoie une requête avec des en-têtes
Transfer-Encoding
obfusqués.Selon le serveur (frontal ou arrière) qui ne parvient pas à reconnaître 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 une partie d'une requête ultérieure, conduisant à un trafic illicite.
Exemple :
Scénario CL.CL (Content-Length utilisé par à la fois le Front-End et le Back-End) :
Les deux serveurs traitent la requête uniquement en fonction de l'en-tête
Content-Length
.Ce scénario ne conduit généralement pas à un trafic illicite, car il y a une concordance dans la façon dont les deux serveurs interprètent la longueur de la requête.
Exemple :
Scénario CL != 0 :
Fait référence 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.Il est crucial de comprendre et de concevoir des attaques de trafic illicite, car cela influence la façon dont les serveurs déterminent la fin d'une requête.
Exemple :
Forcer via les en-têtes hop-by-hop
En abusant des en-têtes hop-by-hop, vous pourriez indiquer au proxy de supprimer l'en-tête Content-Length ou Transfer-Encoding afin de permettre un trafic illicite dans une requête HTTP.
Pour plus d'informations sur les en-têtes hop-by-hop, visitez :
hop-by-hop headersIdentification de la faille de requête HTTP Smuggling
L'identification des vulnérabilités de requête HTTP smuggling peut souvent être réalisée en utilisant des techniques de synchronisation, qui reposent sur l'observation du temps nécessaire au serveur pour répondre aux requêtes manipulées. Ces techniques sont particulièrement utiles pour détecter les vulnérabilités CL.TE et TE.CL. Outre ces méthodes, il existe d'autres stratégies et outils qui peuvent être utilisés pour trouver de telles vulnérabilités :
Recherche de vulnérabilités CL.TE en utilisant des techniques de synchronisation
Méthode :
Envoyer une requête qui, si l'application est vulnérable, amènera le serveur back-end à attendre des données supplémentaires.
Exemple :
Observation :
Le serveur frontal traite la requête en fonction de
Content-Length
et coupe le message prématurément.Le serveur back-end, s'attendant à un message chunked, attend le prochain chunk qui n'arrive jamais, provoquant un retard.
Indicateurs :
Délais d'attente ou longs retards dans la réponse.
Réception d'une erreur 400 Bad Request du serveur back-end, parfois avec des informations détaillées sur le serveur.
Recherche de vulnérabilités TE.CL en utilisant des techniques de synchronisation
Méthode :
Envoyer une requête qui, si l'application est vulnérable, amènera le serveur back-end à attendre des données supplémentaires.
Exemple :
Observation :
Le serveur frontal traite la requête en fonction de
Transfer-Encoding
et transmet l'ensemble du message.Le serveur back-end, s'attendant à un message basé sur
Content-Length
, attend des données supplémentaires qui n'arrivent jamais, provoquant un retard.
Autres méthodes pour trouver des vulnérabilités
Analyse de réponse différentielle :
Envoyer des versions légèrement variées d'une requête et observer si les réponses du serveur diffèrent de manière inattendue, indiquant 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 ambiguës et en analysant les réponses.
Tests de variance de Content-Length :
Envoyer des requêtes avec des valeurs de
Content-Length
variables qui ne correspondent pas à la longueur réelle du contenu et observer comment le serveur gère de telles incohérences.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 les serveurs frontal et back-end réagissent différemment à de telles manipulations.
Test de vulnérabilité de la requête HTTP Smuggling
Après avoir confirmé l'efficacité des techniques de synchronisation, il est crucial de vérifier si les requêtes des clients peuvent être manipulées. Une méthode simple consiste à tenter de falsifier vos requêtes, par exemple, en faisant en sorte qu'une requête vers /
renvoie une réponse 404. Les exemples CL.TE
et TE.CL
discutés précédemment dans Exemples de base montrent comment falsifier une requête d'un client pour obtenir une réponse 404, malgré le fait que le client cherche à accéder à une ressource différente.
Considérations clés
Lors du test des vulnérabilités de la requête smuggling en interférant avec d'autres requêtes, gardez à l'esprit :
Connexions réseau distinctes : Les requêtes "d'attaque" et "normales" doivent être envoyées sur des connexions réseau distinctes. Utiliser la même connexion pour les deux ne valide pas la présence de la vulnérabilité.
URL et paramètres cohérents : Essayez d'utiliser des URL et des noms de paramètres identiques pour les deux requêtes. Les applications modernes routent souvent les requêtes vers des serveurs back-end spécifiques en fonction de l'URL et des paramètres. En les faisant correspondre, vous augmentez la probabilité que les deux requêtes soient traitées par le même serveur, une condition préalable à une attaque réussie.
Synchronisation et conditions de course : La requête "normale", destinée à détecter l'interférence de la requête "d'attaque", entre en concurrence avec d'autres requêtes d'application concurrentes. Par conséquent, envoyez la requête "normale" immédiatement après la requête "d'attaque". Les applications chargées peuvent nécessiter plusieurs essais pour confirmer de manière concluante la vulnérabilité.
Défis de l'équilibrage de charge : Les serveurs frontal agissant comme équilibreurs de charge peuvent distribuer les requêtes sur divers systèmes back-end. Si les requêtes "d'attaque" et "normales" se retrouvent sur des systèmes différents, l'attaque échouera. Cet aspect de l'équilibrage de charge peut nécessiter plusieurs tentatives pour confirmer une vulnérabilité.
Impact utilisateur non intentionnel : Si votre attaque affecte involontairement une autre requête utilisateur (pas 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 continus pourraient perturber d'autres utilisateurs, exigeant une approche prudente.
Abus de la requête HTTP Smuggling
Contournement de la sécurité frontale via la requête HTTP Smuggling
Parfois, les proxies frontaux appliquent des mesures de sécurité, scrutant les requêtes entrantes. Cependant, ces mesures peuvent être contournées en exploitant la requête HTTP Smuggling, permettant un accès non autorisé aux points de terminaison restreints. Par exemple, l'accès à /admin
peut être interdit de l'extérieur, le proxy frontal bloquant activement de telles tentatives. Néanmoins, ce proxy peut négliger d'inspecter les requêtes intégrées dans une requête HTTP smugglée, laissant une faille pour contourner ces restrictions.
Considérez les exemples suivants illustrant comment la requête HTTP Smuggling peut être utilisée pour contourner les contrôles de sécurité frontaux, ciblant spécifiquement le chemin /admin
qui est généralement protégé par le proxy frontal :
Exemple CL.TE
Dans l'attaque CL.TE, l'en-tête Content-Length
est exploité pour la requête initiale, tandis que la requête intégrée ultérieure utilise l'en-tête Transfer-Encoding: chunked
. Le proxy frontal traite la requête POST
initiale mais ne parvient pas à inspecter la requête GET /admin
intégrée, permettant un accès non autorisé au chemin /admin
.
Exemple TE.CL
Inversement, dans l'attaque TE.CL, la requête POST
initiale utilise Transfer-Encoding: chunked
, et la requête imbriquée ultérieure est traitée en fonction de l'en-tête Content-Length
. Tout comme l'attaque CL.TE, le proxy frontal ignore la requête GET /admin
dissimulée, accordant involontairement l'accès au chemin /admin
restreint.
Révéler la réécriture de la requête frontale
Les applications utilisent souvent un serveur frontal pour modifier les requêtes entrantes avant de les transmettre au serveur back-end. Une modification typique implique l'ajout d'en-têtes, tels que X-Forwarded-For: <IP du client>
, pour transmettre l'IP du client au serveur back-end. Comprendre ces modifications peut être crucial, car cela pourrait révéler des moyens de contourner les protections ou de découvrir des informations ou des points d'accès dissimulés.
Pour enquêter sur la manière dont un proxy modifie une requête, localisez un paramètre POST que le back-end renvoie dans la réponse. Ensuite, créez une requête, en utilisant ce paramètre en dernier, similaire à ce qui suit:
Dans cette structure, les composants de la requête suivante sont ajoutés après search=
, qui est le paramètre reflété dans la réponse. Cette réflexion exposera les en-têtes de la requête suivante.
Il est important d'aligner l'en-tête Content-Length
de la requête imbriquée avec la longueur réelle du contenu. Il est conseillé de commencer par une petite valeur et d'augmenter progressivement, car une valeur trop basse 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
. Peu importe les caractères de saut de ligne, les valeurs seront ajoutées au paramètre de recherche.
Cette méthode sert principalement à comprendre les modifications de la requête effectuées par le proxy frontal, réalisant essentiellement une enquête auto-dirigée.
Capture des requêtes d'autres utilisateurs
Il est possible de capturer les requêtes de l'utilisateur suivant en ajoutant une requête spécifique en tant que valeur d'un paramètre lors d'une opération POST. Voici comment cela peut être réalisé :
En ajoutant la requête suivante en tant que valeur d'un paramètre, vous pouvez enregistrer la requête du client suivant :
Dans ce scénario, le paramètre de commentaire est destiné à stocker le contenu dans la section commentaire d'un article sur une page publiquement accessible. Par conséquent, le contenu de la requête suivante apparaîtra comme un commentaire.
Cependant, cette technique présente des limitations. En général, elle ne capture que les données jusqu'au délimiteur de paramètre utilisé dans la requête trafiquée. Pour les soumissions de formulaires 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 chaîne de requête.
De plus, il convient de noter que cette approche est également viable avec une vulnérabilité TE.CL. Dans de tels cas, la requête devrait se terminer par search=\r\n0
. Peu importe les caractères de saut de ligne, les valeurs seront ajoutées au paramètre de recherche.
Utilisation du trafic de requêtes HTTP pour exploiter les XSS réfléchis
Le trafic de requêtes HTTP peut être utilisé pour exploiter les pages web vulnérables aux XSS réfléchis, offrant des avantages significatifs :
L'interaction avec les utilisateurs cibles n'est pas nécessaire.
Permet l'exploitation de XSS dans des parties de la requête normalement inaccessibles, comme les en-têtes de requête HTTP.
Dans les scénarios où un site web est vulnérable aux XSS réfléchis via l'en-tête User-Agent, la charge utile suivante démontre comment exploiter cette vulnérabilité :
Ce payload est structuré pour exploiter la vulnérabilité en :
Initiating une requête
POST
, apparemment typique, avec un en-têteTransfer-Encoding: chunked
pour indiquer le début du smuggling.Enchaînant avec un
0
, marquant la fin du corps du message chunked.Ensuite, une requête
GET
smugglée 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 l'en-tête User-Agent
à travers le smuggling, le payload contourne les contraintes normales de la requête, exploitant ainsi la vulnérabilité XSS réfléchie d'une manière non standard mais efficace.
Exploiter les redirections sur site avec le Smuggling de Requêtes HTTP
Les applications redirigent souvent d'une URL à une autre en utilisant le nom d'hôte de l'en-tête Host
dans l'URL de redirection. C'est courant avec des serveurs web comme Apache et IIS. Par exemple, demander un dossier sans barre oblique finale entraîne une redirection pour inclure la barre oblique :
Résultats en :
Bien que semblant inoffensif, ce comportement peut être manipulé en utilisant le trafic d'HTTP pour rediriger les utilisateurs vers un site externe. Par exemple:
Cette requête dissimulée pourrait entraîner la redirection de la prochaine requête utilisateur traitée vers un site web contrôlé par un attaquant :
Résultats :
Dans ce scénario, la demande d'un utilisateur pour un fichier JavaScript est détournée. L'attaquant peut potentiellement compromettre l'utilisateur en lui servant du JavaScript malveillant en réponse.
Exploitation de l'empoisonnement du cache Web via le détournement de requête HTTP
L'empoisonnement du cache Web peut être exécuté si un composant de l'infrastructure frontale met en cache le contenu, généralement pour améliorer les performances. En manipulant la réponse du serveur, il est possible de contaminer le cache.
Précédemment, nous avons observé comment les réponses du serveur pouvaient être modifiées pour renvoyer une erreur 404 (voir Exemples de base). De la même manière, il est possible de tromper le serveur pour qu'il renvoie le contenu de /index.html
en réponse à une demande de /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 potentiellement entraîner un déni de service (DoS).
Cette technique devient particulièrement puissante si une vulnérabilité de redirection ouverte est découverte ou s'il y a une redirection sur site vers une redirection ouverte. De telles vulnérabilités peuvent être exploitées pour remplacer le contenu mis en cache de /static/include.js
par un script sous le contrôle de l'attaquant, permettant essentiellement une attaque généralisée de Cross-Site Scripting (XSS) contre tous les clients demandant le /static/include.js
mis à jour.
Voici une illustration de l'exploitation de l'empoisonnement du cache combiné à une redirection sur site vers une redirection ouverte. L'objectif est de modifier le contenu mis en cache de /static/include.js
pour servir du code JavaScript contrôlé par l'attaquant:
Notez la requête intégrée ciblant /post/next?postId=3
. Cette requête sera redirigée vers /post?postId=4
, en utilisant la valeur de l'en-tête Host pour déterminer le domaine. En modifiant l'en-tête Host, l'attaquant peut rediriger la requête vers son domaine (redirection sur site vers une redirection ouverte).
Après un empoisonnement de socket réussi, une requête GET pour /static/include.js
doit être initiée. Cette requête sera contaminée par la précédente requête de redirection sur site vers une redirection ouverte 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 efficacement une vaste attaque XSS.
Utilisation du détournement de requête HTTP pour effectuer une tromperie de cache web
Quelle est la différence entre l'empoisonnement de cache web et la tromperie de cache web ?
Dans l'empoisonnement de cache web, l'attaquant amène l'application à stocker un contenu malveillant dans le cache, et ce contenu est servi à partir du cache à d'autres utilisateurs de l'application.
Dans la tromperie de cache web, l'attaquant amène l'application à stocker un contenu sensible appartenant à un autre utilisateur dans le cache, puis l'attaquant récupère ce contenu à partir du cache.
L'attaquant crée une requête dissimulée qui récupère un contenu sensible spécifique à l'utilisateur. Considérez l'exemple suivant:
Si cette requête dissimulée empoisonne une entrée de cache destinée à un contenu statique (par exemple, /someimage.png
), les données sensibles de la victime provenant de /private/messages
pourraient être mises en cache sous l'entrée de cache du contenu statique. Par conséquent, l'attaquant pourrait potentiellement récupérer ces données sensibles mises en cache.
Abus de TRACE via HTTP Request Smuggling
Dans cet article, il est suggéré que si le serveur a la méthode TRACE activée, il pourrait être possible de l'exploiter avec une HTTP Request Smuggling. Cela est dû au fait que cette méthode reflétera tout en-tête envoyé au serveur en tant que partie du corps de la réponse. Par exemple:
Enverra une réponse telle que :
Un exemple de l'abus de ce comportement serait de faire passer d'abord une requête HEAD. Cette requête recevra uniquement les en-têtes d'une requête GET (Content-Type
parmi eux). Et faire passer immédiatement après le HEAD une requête TRACE, qui va refléter les données envoyées.
Comme la réponse HEAD contiendra un en-tête Content-Length
, la réponse de la requête TRACE sera traitée comme le corps de la réponse HEAD, reflétant ainsi des données arbitraires dans la réponse.
Cette réponse sera envoyée à la prochaine requête sur la connexion, ce qui pourrait être utilisé dans un fichier JS mis en cache par exemple pour injecter du code JS arbitraire.
Abus de TRACE via le fractionnement de la réponse HTTP
Continuer à suivre cet article suggère une autre façon d'abuser de la méthode TRACE. Comme commenté, en faisant passer une requête HEAD et une requête TRACE, il est possible de contrôler certaines données réfléchies 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.
Par conséquent, la nouvelle idée serait que, en 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 du Content-Length, permettant à un attaquant de contrôler complètement la requête vers la prochaine réponse (qui pourrait être utilisée pour effectuer un empoisonnement de cache).
Exemple:
Générera ces réponses (notez comment la réponse HEAD a une longueur de contenu faisant du TRACE une partie du corps HEAD et une fois que la longueur de contenu HEAD se termine, une réponse HTTP valide est contrebandée):
Armes HTTP Request Smuggling avec désynchronisation des réponses HTTP
Avez-vous trouvé une vulnérabilité de HTTP Request Smuggling et vous ne savez pas comment l'exploiter ? Essayez cette autre méthode d'exploitation :
HTTP Response Smuggling / DesyncAutres techniques de HTTP Request Smuggling
HTTP Request Smuggling du navigateur (côté client)
Smuggling de requêtes dans les downgrades HTTP/2
Scripts Turbo Intruder
CL.TE
Depuis https://hipotermia.pw/bb/http-desync-idor
TE.CL
De : https://hipotermia.pw/bb/http-desync-account-takeover
Outils
https://github.com/bahruzjabiyev/t-reqs-http-fuzzer: Cet outil est un Fuzzer HTTP basé sur la grammaire utile pour trouver des incohérences étranges dans le trafic HTTP.
Références
Last updated