HTTP Request Smuggling / HTTP Desync Attack
Last updated
Last updated
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Ця вразливість виникає, коли десинхронізація між фронтальними проксі та бекенд сервером дозволяє зловмиснику надіслати HTTP запит, який буде інтерпретований як один запит фронтальними проксі (балансування навантаження/реверс-проксі) та як 2 запити бекенд сервером. Це дозволяє користувачу модифікувати наступний запит, який надходить до бекенд сервера після його.
Якщо повідомлення отримано з обома заголовками Transfer-Encoding та Content-Length, останній ПОВИНЕН бути проігнорований.
Content-Length
Заголовок Content-Length вказує на розмір тіла сутності в байтах, надісланих отримувачу.
Transfer-Encoding: chunked
Заголовок Transfer-Encoding вказує на форму кодування, що використовується для безпечної передачі тіла навантаження користувачу. Chunked означає, що великі дані надсилаються серією частин.
Фронтальний (балансування навантаження / Реверс-проксі) обробляє content-length або transfer-encoding заголовок, а бекенд сервер обробляє інший, викликаючи десинхронізацію між 2 системами. Це може бути дуже критично, оскільки зловмисник зможе надіслати один запит до реверс-проксі, який буде інтерпретований бекенд сервером як 2 різні запити. Небезпека цієї техніки полягає в тому, що бекенд сервер інтерпретує 2-й запит, що інжектується, як якщо б він надійшов від наступного клієнта, а реальний запит цього клієнта буде частиною інжектованого запиту.
Пам'ятайте, що в HTTP символ нового рядка складається з 2 байтів:
Content-Length: Цей заголовок використовує десяткове число для вказівки кількості байтів тіла запиту. Тіло, як очікується, закінчується останнім символом, новий рядок не потрібен в кінці запиту.
Transfer-Encoding: Цей заголовок використовує в тілі шістнадцяткове число для вказівки кількості байтів наступного шматка. Частина повинна закінчуватися новим рядком, але цей новий рядок не враховується індикатором довжини. Цей метод передачі повинен закінчуватися шматком розміром 0, за яким слідують 2 нові рядки: 0
Connection: Згідно з моїм досвідом, рекомендується використовувати Connection: keep-alive
в першому запиті при використанні HTTP Request Smuggling.
Коли ви намагаєтеся експлуатувати це за допомогою Burp Suite вимкніть Update Content-Length
та Normalize HTTP/1 line endings
в повторювачі, оскільки деякі гаджети зловживають новими рядками, поверненнями каретки та неправильно сформованими content-length.
HTTP request smuggling атаки створюються шляхом надсилання неоднозначних запитів, які експлуатують розбіжності в тому, як фронтальні та бекенд сервери інтерпретують заголовки Content-Length
(CL) та Transfer-Encoding
(TE). Ці атаки можуть проявлятися в різних формах, головним чином як CL.TE, TE.CL та TE.TE. Кожен тип представляє унікальну комбінацію того, як фронтальні та бекенд сервери пріоритизують ці заголовки. Вразливості виникають через те, що сервери обробляють один і той же запит по-різному, що призводить до несподіваних і потенційно шкідливих наслідків.
До попередньої таблиці слід додати техніку TE.0, як техніку CL.0, але з використанням Transfer Encoding.
Фронтальний (CL): Обробляє запит на основі заголовка Content-Length
.
Бекенд (TE): Обробляє запит на основі заголовка Transfer-Encoding
.
Сценарій атаки:
Зловмисник надсилає запит, де значення заголовка Content-Length
не відповідає фактичній довжині вмісту.
Фронтальний сервер пересилає весь запит до бекенду на основі значення Content-Length
.
Бекенд сервер обробляє запит як частковий через заголовок Transfer-Encoding: chunked
, інтерпретуючи залишкові дані як окремий, наступний запит.
Приклад:
Фронтальний (TE): Обробляє запит на основі заголовка Transfer-Encoding
.
Бекенд (CL): Обробляє запит на основі заголовка Content-Length
.
Сценарій атаки:
Зловмисник надсилає частковий запит, де розмір частини (7b
) та фактична довжина вмісту (Content-Length: 4
) не збігаються.
Фронтальний сервер, поважаючи Transfer-Encoding
, пересилає весь запит до бекенду.
Бекенд сервер, поважаючи Content-Length
, обробляє лише початкову частину запиту (7b
байтів), залишаючи решту частиною ненавмисного наступного запиту.
Приклад:
Сервери: Обидва підтримують Transfer-Encoding
, але один може бути обманутий, щоб ігнорувати його через обфускацію.
Сценарій атаки:
Зловмисник надсилає запит з обфускованими заголовками Transfer-Encoding
.
В залежності від того, який сервер (фронтальний або бекенд) не розпізнає обфускацію, може бути експлуатована вразливість CL.TE або TE.CL.
Непроцесована частина запиту, як видно з одного з серверів, стає частиною наступного запиту, що призводить до смуглінгу.
Приклад:
Обидва сервери обробляють запит виключно на основі заголовка Content-Length
.
Цей сценарій зазвичай не призводить до смуглінгу, оскільки є узгодженість у тому, як обидва сервери інтерпретують довжину запиту.
Приклад:
Відноситься до сценаріїв, де заголовок Content-Length
присутній і має значення, відмінне від нуля, що вказує на те, що тіло запиту має вміст. Бекенд ігнорує заголовок Content-Length
(який розглядається як 0), але фронтальний його обробляє.
Це важливо для розуміння та створення атак смуглінгу, оскільки це впливає на те, як сервери визначають кінець запиту.
Приклад:
Як попередній, але з використанням TE
Техніка повідомлена тут
Приклад:
Ця техніка також корисна в сценаріях, де можливо зламати веб-сервер під час читання початкових HTTP-даних, але без закриття з'єднання. Таким чином, тіло HTTP-запиту буде вважатися наступним HTTP-запитом.
Наприклад, як пояснюється в цьому описі, у Werkzeug було можливо надіслати деякі Unicode символи, і це призведе до зламу сервера. Однак, якщо HTTP-з'єднання було створено з заголовком Connection: keep-alive
, тіло запиту не буде прочитано, і з'єднання залишиться відкритим, тому тіло запиту буде розглядатися як наступний HTTP-запит.
Зловживаючи заголовками hop-by-hop, ви можете вказати проксі видалити заголовок Content-Length або Transfer-Encoding, щоб зловживання HTTP-запитом стало можливим.
Для додаткової інформації про заголовки hop-by-hop відвідайте:
hop-by-hop headersВиявлення вразливостей HTTP request smuggling часто можна досягти за допомогою технік таймінгу, які базуються на спостереженні за тим, скільки часу потрібно серверу для відповіді на маніпульовані запити. Ці техніки особливо корисні для виявлення вразливостей CL.TE та TE.CL. Окрім цих методів, існують інші стратегії та інструменти, які можна використовувати для знаходження таких вразливостей:
Метод:
Надішліть запит, який, якщо додаток вразливий, змусить сервер на задньому плані чекати на додаткові дані.
Приклад:
Спостереження:
Сервер на передньому плані обробляє запит на основі Content-Length
і передчасно обриває повідомлення.
Сервер на задньому плані, очікуючи на частину повідомлення, чекає на наступну частину, яка ніколи не приходить, що викликає затримку.
Індикатори:
Тайм-аути або тривалі затримки у відповіді.
Отримання помилки 400 Bad Request від сервера на задньому плані, іноді з детальною інформацією про сервер.
Метод:
Надішліть запит, який, якщо додаток вразливий, змусить сервер на задньому плані чекати на додаткові дані.
Приклад:
Спостереження:
Сервер на передньому плані обробляє запит на основі Transfer-Encoding
і пересилає все повідомлення.
Сервер на задньому плані, очікуючи на повідомлення на основі Content-Length
, чекає на додаткові дані, які ніколи не приходять, що викликає затримку.
Аналіз диференційних відповідей:
Надішліть трохи змінені версії запиту та спостерігайте, чи відповіді сервера відрізняються несподіваним чином, що вказує на розбіжність у парсингу.
Використання автоматизованих інструментів:
Інструменти, такі як розширення 'HTTP Request Smuggler' Burp Suite, можуть автоматично перевіряти ці вразливості, надсилаючи різні форми неоднозначних запитів і аналізуючи відповіді.
Тести на варіацію Content-Length:
Надсилайте запити з різними значеннями Content-Length
, які не відповідають фактичній довжині вмісту, і спостерігайте, як сервер обробляє такі невідповідності.
Тести на варіацію Transfer-Encoding:
Надсилайте запити з обфусцированими або неправильно сформованими заголовками Transfer-Encoding
і спостерігайте, як по-різному реагують сервери на передньому та задньому плані на такі маніпуляції.
Після підтвердження ефективності технік таймінгу важливо перевірити, чи можна маніпулювати запитами клієнта. Простий метод - спробувати отруїти свої запити, наприклад, зробивши запит до /
, щоб отримати відповідь 404. Приклади CL.TE
та TE.CL
, обговорені раніше в Основних прикладах, демонструють, як отруїти запит клієнта, щоб викликати відповідь 404, незважаючи на те, що клієнт намагається отримати доступ до іншого ресурсу.
Ключові міркування
При тестуванні на вразливості request smuggling, втручаючись в інші запити, пам'ятайте:
Відокремлені мережеві з'єднання: "атака" та "нормальні" запити повинні надсилатися через окремі мережеві з'єднання. Використання одного й того ж з'єднання для обох не підтверджує наявність вразливості.
Послідовні URL та параметри: Намагайтеся використовувати однакові URL та імена параметрів для обох запитів. Сучасні додатки часто маршрутизують запити до конкретних серверів на задньому плані на основі URL та параметрів. Відповідність цим підвищує ймовірність того, що обидва запити обробляються одним і тим же сервером, що є передумовою для успішної атаки.
Таймінг та умови гонки: "нормальний" запит, призначений для виявлення втручання з боку "атаки", конкурує з іншими одночасними запитами додатка. Тому надсилайте "нормальний" запит відразу після "атаки". Завантажені додатки можуть вимагати кількох спроб для підтвердження вразливості.
Виклики балансування навантаження: Сервери на передньому плані, які виконують функції балансування навантаження, можуть розподіляти запити між різними системами на задньому плані. Якщо "атака" та "нормальні" запити потрапляють на різні системи, атака не вдасться. Цей аспект балансування навантаження може вимагати кількох спроб для підтвердження вразливості.
Непередбачений вплив на користувачів: Якщо ваша атака ненавмисно впливає на запит іншого користувача (не "нормальний" запит, який ви надіслали для виявлення), це вказує на те, що ваша атака вплинула на іншого користувача додатка. Постійне тестування може порушити роботу інших користувачів, що вимагає обережного підходу.
Іноді проксі-сервери на передньому плані впроваджують заходи безпеки, перевіряючи вхідні запити. Однак ці заходи можна обійти, експлуатуючи HTTP Request Smuggling, що дозволяє несанкціонований доступ до обмежених кінцевих точок. Наприклад, доступ до /admin
може бути заборонений зовні, а проксі на передньому плані активно блокує такі спроби. Проте цей проксі може не перевіряти вбудовані запити в межах прихованого HTTP запиту, залишаючи лазівку для обходу цих обмежень.
Розгляньте наступні приклади, які ілюструють, як HTTP Request Smuggling може бути використано для обходу заходів безпеки на передньому плані, зокрема націлюючись на шлях /admin
, який зазвичай охороняється проксі на передньому плані:
Приклад CL.TE
У атаці CL.TE заголовок Content-Length
використовується для початкового запиту, тоді як наступний вбудований запит використовує заголовок Transfer-Encoding: chunked
. Проксі на фронтенді обробляє початковий POST
запит, але не перевіряє вбудований запит GET /admin
, що дозволяє несанкціонований доступ до шляху /admin
.
TE.CL Приклад
Навпаки, в атаці TE.CL початковий POST
запит використовує Transfer-Encoding: chunked
, а наступний вбудований запит обробляється на основі заголовка Content-Length
. Подібно до атаки CL.TE, фронтальний проксі ігнорує контрабандний запит GET /admin
, ненавмисно надаючи доступ до обмеженого шляху /admin
.
Додатки часто використовують фронтальний сервер для модифікації вхідних запитів перед їх передачею на бекенд-сервер. Типова модифікація включає додавання заголовків, таких як X-Forwarded-For: <IP клієнта>
, для передачі IP клієнта на бекенд. Розуміння цих модифікацій може бути вирішальним, оскільки це може виявити способи обійти захист або виявити приховану інформацію або кінцеві точки.
Щоб дослідити, як проксі змінює запит, знайдіть параметр POST, який бекенд відображає у відповіді. Потім створіть запит, використовуючи цей параметр останнім, подібно до наступного:
У цій структурі наступні компоненти запиту додаються після search=
, що є параметром, відображеним у відповіді. Це відображення виявить заголовки наступного запиту.
Важливо узгодити заголовок Content-Length
вкладеного запиту з фактичною довжиною вмісту. Рекомендується починати з невеликого значення і поступово збільшувати, оскільки занадто низьке значення обрізає відображені дані, а занадто високе значення може призвести до помилки запиту.
Ця техніка також застосовна в контексті вразливості TE.CL, але запит повинен закінчуватися search=\r\n0
. Незалежно від символів нового рядка, значення будуть додаватися до параметра пошуку.
Цей метод в основному служить для розуміння модифікацій запиту, зроблених проксі-сервером фронтенду, фактично виконуючи самостійне розслідування.
Цілком можливо захопити запити наступного користувача, додавши конкретний запит як значення параметра під час операції POST. Ось як це можна здійснити:
Додавши наступний запит як значення параметра, ви можете зберегти запит наступного клієнта:
У цьому сценарії параметр коментаря призначений для зберігання вмісту в секції коментарів поста на публічно доступній сторінці. Відповідно, вміст наступного запиту з'явиться як коментар.
Однак у цієї техніки є обмеження. Як правило, вона захоплює дані лише до роздільника параметра, використаного в контрабандному запиті. Для URL-кодованих формулярів цей роздільник - символ &
. Це означає, що захоплений вміст з запиту жертви зупиниться на першому &
, який може бути навіть частиною рядка запиту.
Крім того, варто зазначити, що цей підхід також є життєздатним з вразливістю TE.CL. У таких випадках запит має закінчуватися search=\r\n0
. Незалежно від символів нового рядка, значення будуть додані до параметра пошуку.
HTTP Request Smuggling можна використовувати для експлуатації веб-сторінок, вразливих до Reflected XSS, що пропонує значні переваги:
Взаємодія з цільовими користувачами не потрібна.
Дозволяє експлуатувати XSS у частинах запиту, які зазвичай недоступні, таких як заголовки HTTP-запиту.
У сценаріях, коли веб-сайт вразливий до Reflected XSS через заголовок User-Agent, наступний payload демонструє, як експлуатувати цю вразливість:
Цей payload структурований для експлуатації вразливості шляхом:
Ініціювання POST
запиту, що виглядає типовим, з заголовком Transfer-Encoding: chunked
, щоб вказати на початок контрабанди.
Наступним є 0
, що позначає кінець тіла повідомлення з частинами.
Потім вводиться контрабандний GET
запит, де заголовок User-Agent
інжектується зі скриптом, <script>alert(1)</script>
, що викликає XSS, коли сервер обробляє цей наступний запит.
Маніпулюючи User-Agent
через контрабанду, payload обходить звичайні обмеження запитів, таким чином експлуатуючи вразливість Reflected XSS нестандартним, але ефективним способом.
У разі, якщо вміст користувача відображається у відповіді з Content-type
таким як text/plain
, що запобігає виконанню XSS. Якщо сервер підтримує HTTP/0.9, це може дозволити обійти це!
Версія HTTP/0.9 була раніше 1.0 і використовує лише GET дієслова та не відповідає з заголовками, лише тілом.
У цьому описі це було зловжито з контрабандою запиту та вразливим кінцевим пунктом, який відповість з вхідними даними користувача для контрабанди запиту з HTTP/0.9. Параметр, який буде відображено у відповіді, містив фальшиву HTTP/1.1 відповідь (з заголовками та тілом), тому відповідь міститиме дійсний виконуваний JS код з Content-Type
text/html
.
Застосунки часто перенаправляють з одного URL на інший, використовуючи ім'я хоста з заголовка Host
у URL перенаправлення. Це поширено на веб-серверах, таких як Apache та IIS. Наприклад, запит на папку без слешу в кінці призводить до перенаправлення, щоб включити слеш:
Результати в:
Хоча це виглядає безпечним, цю поведінку можна маніпулювати за допомогою HTTP request smuggling, щоб перенаправити користувачів на зовнішній сайт. Наприклад:
Цей підроблений запит може призвести до того, що наступний оброблений запит користувача буде перенаправлено на веб-сайт, контрольований зловмисником:
Результати в:
У цьому сценарії запит користувача на файл JavaScript перехоплюється. Зловмисник може потенційно скомпрометувати користувача, надаючи шкідливий JavaScript у відповідь.
Отруєння веб-кешу може бути виконано, якщо будь-який компонент інфраструктури фронтенду кешує контент, зазвичай для покращення продуктивності. Маніпулюючи відповіддю сервера, можна отруїти кеш.
Раніше ми спостерігали, як відповіді сервера можуть бути змінені, щоб повернути помилку 404 (див. Основні приклади). Аналогічно, можливо обманути сервер, щоб він надав контент /index.html
у відповідь на запит /static/include.js
. В результаті, контент /static/include.js
замінюється в кеші на контент /index.html
, що робить /static/include.js
недоступним для користувачів, потенційно призводячи до відмови в обслуговуванні (DoS).
Ця техніка стає особливо потужною, якщо виявлено вразливість Open Redirect або якщо є перенаправлення на сайті до відкритого перенаправлення. Такі вразливості можуть бути використані для заміни кешованого контенту /static/include.js
на скрипт під контролем зловмисника, що фактично дозволяє здійснити широкомасштабну атаку Cross-Site Scripting (XSS) проти всіх клієнтів, які запитують оновлений /static/include.js
.
Нижче наведено ілюстрацію використання отруєння кешу в поєднанні з перенаправленням на сайті до відкритого перенаправлення. Мета полягає в тому, щоб змінити кешований контент /static/include.js
, щоб надати JavaScript-код, контрольований зловмисником:
Зверніть увагу на вбудований запит, що націлений на /post/next?postId=3
. Цей запит буде перенаправлений на /post?postId=4
, використовуючи значення заголовка Host для визначення домену. Змінюючи заголовок Host, зловмисник може перенаправити запит на свій домен (внутрішнє перенаправлення на відкритий редирект).
Після успішного отруєння сокета слід ініціювати GET запит на /static/include.js
. Цей запит буде забруднений попереднім запитом внутрішнього перенаправлення на відкритий редирект і отримає вміст скрипта, контрольованого зловмисником.
В подальшому будь-який запит на /static/include.js
буде обслуговувати кешований вміст скрипта зловмисника, ефективно запускаючи широкий XSS-атаку.
У чому різниця між отруєнням веб-кешу та обманом веб-кешу?
У отруєнні веб-кешу зловмисник змушує додаток зберігати деякий шкідливий вміст у кеші, і цей вміст обслуговується з кешу іншим користувачам додатка.
У обмані веб-кешу зловмисник змушує додаток зберігати деякий чутливий вміст, що належить іншому користувачу, у кеші, а потім зловмисник отримує цей вміст з кешу.
Зловмисник створює контрабандний запит, який отримує чутливий вміст, специфічний для користувача. Розгляньте наступний приклад:
Якщо цей підроблений запит отруює кеш-енцію, призначену для статичного контенту (наприклад, /someimage.png
), чутливі дані жертви з /private/messages
можуть бути кешовані під кеш-енцією статичного контенту. Внаслідок цього, зловмисник потенційно може отримати ці кешовані чутливі дані.
У цьому пості пропонується, що якщо сервер має метод TRACE увімкненим, це може дозволити зловживання ним за допомогою HTTP Request Smuggling. Це пов'язано з тим, що цей метод відображатиме будь-який заголовок, надісланий на сервер, як частину тіла відповіді. Наприклад:
Відправить відповідь, таку як:
Прикладом зловживання цією поведінкою буде переправка спочатку запиту HEAD. На цей запит буде відповідано лише заголовками запиту GET (Content-Type
серед них). І переправити одразу після HEAD запит TRACE, який буде відображати надіслані дані.
Оскільки відповідь на HEAD міститиме заголовок Content-Length
, відповідь на запит TRACE буде розглядатися як тіло відповіді HEAD, отже, відображаючи довільні дані у відповіді.
Ця відповідь буде надіслана до наступного запиту через з'єднання, тому це може бути використано в кешованому JS файлі, наприклад, для впровадження довільного JS коду.
Продовжуючи слідкувати за цим постом, пропонується інший спосіб зловживання методом TRACE. Як зазначено, переправка запиту HEAD і запиту TRACE дозволяє контролювати деякі відображені дані у відповіді на запит HEAD. Довжина тіла запиту HEAD в основному вказується в заголовку Content-Length і формується відповіддю на запит TRACE.
Отже, нова ідея полягає в тому, що, знаючи цей Content-Length і дані, надані у відповіді TRACE, можна зробити так, щоб відповідь TRACE містила дійсну HTTP-відповідь після останнього байта Content-Length, що дозволяє зловмиснику повністю контролювати запит до наступної відповіді (що може бути використано для виконання отруєння кешу).
Приклад:
Згенерує ці ці responses (зверніть увагу, що у відповіді HEAD є Content-Length, що робить відповідь TRACE частиною тіла HEAD, і як тільки закінчується Content-Length HEAD, дійсна HTTP відповідь прихована):
Ви знайшли вразливість HTTP Request Smuggling і не знаєте, як її експлуатувати. Спробуйте ці інші методи експлуатації:
HTTP Response Smuggling / DesyncHTTP Request Smuggling у браузері (Клієнтська сторона)
Request Smuggling у зниженні версії HTTP/2
З https://hipotermia.pw/bb/http-desync-idor
Від: https://hipotermia.pw/bb/http-desync-account-takeover
https://github.com/bahruzjabiyev/t-reqs-http-fuzzer: Цей інструмент є граматичним HTTP Fuzzer, корисним для виявлення дивних розбіжностей у запитах на контрабанду.
Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)