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)
Отримайте перспективу хакера на свої веб-додатки, мережу та хмару
Знайдіть і повідомте про критичні, експлуатовані вразливості з реальним бізнес-імпактом. Використовуйте наші 20+ спеціальних інструментів для картографування атакуючої поверхні, знаходження проблем безпеки, які дозволяють вам підвищити привілеї, і використовуйте автоматизовані експлойти для збору важливих доказів, перетворюючи вашу важку працю на переконливі звіти.
Ця вразливість виникає, коли десинхронізація між фронтальними проксі та бекенд сервером дозволяє зловмиснику надіслати 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
в першому запиті при смугуванні запитів.
При спробі експлуатувати це за допомогою Burp Suite вимкніть Update Content-Length
та Normalize HTTP/1 line endings
в повторювачі, оскільки деякі гаджети зловживають новими рядками, поверненнями каретки та неправильно сформованими content-length.
Атаки на смугування HTTP-запитів створюються шляхом надсилання неоднозначних запитів, які експлуатують розбіжності в тому, як фронтальні та бекенд сервери інтерпретують заголовки 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 на основі граматики, корисний для виявлення дивних розбіжностей у прихованні запитів.
Отримайте перспективу хакера на ваші веб-додатки, мережу та хмару
Знайдіть і повідомте про критичні, експлуатовані вразливості з реальним бізнес-імпактом. Використовуйте наші 20+ спеціальних інструментів для картографування атакуючої поверхні, виявлення проблем безпеки, які дозволяють вам підвищити привілеї, і використовуйте автоматизовані експлойти для збору важливих доказів, перетворюючи вашу важку працю на переконливі звіти.
Вчіться та практикуйте Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE) Вчіться та практикуйте Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)