Отравление очереди ответов

Response queue poisoning — это мощная форма атаки контрабанды запросов, из-за которой фронтенд-сервер начинает сопоставлять ответы от бэкэнда не тем запросам. На практике это означает, что всем пользователям, использующим одно и то же соединение фронтенд/бэкэнд, постоянно выдаются ответы, предназначенные для кого-то другого.

Этого добиваются, провозя полный запрос, тем самым вынуждая бэкэнд отдать два ответа там, где фронтенд ожидает получить только один.

Каков эффект отравления очереди ответов?

Эффект отравления очереди ответов обычно катастрофический. Как только очередь отравлена, атакующий может перехватывать ответы других пользователей, просто отправляя произвольные последующие запросы. Эти ответы могут содержать конфиденциальные персональные или бизнес данные, а также сессионные токены и т.п., что фактически даёт злоумышленнику полный доступ к аккаунту жертвы.

Отравление очереди ответов также вызывает значительный побочный ущерб, по сути ломая сайт для любых других пользователей, чей трафик идёт на бэкэнд по тому же TCP-соединению. Пытаясь просматривать сайт как обычно, пользователи будут получать, казалось бы, случайные ответы сервера, из-за чего большинство функций перестанут работать корректно.

Как построить атаку отравления очереди ответов

Для успешной атаки отравления очереди ответов должны выполняться следующие критерии:

  • TCP-соединение между фронтендом и бэкэндом используется повторно для нескольких циклов запросов и ответов.

  • Злоумышленник способен провезти полный, автономный запрос, который получит свой собственный отдельный ответ от бэкэнда.

  • Атака не приводит к закрытию TCP-соединения ни на одном из серверов. Серверы, как правило, закрывают входящие соединения при получении некорректного запроса, поскольку не могут определить, где запрос должен завершаться.

Понимание последствий контрабанды запросов

Атаки контрабанды обычно подразумевают провоз неполного запроса, который сервер добавляет как префикс к началу следующего запроса на соединении. Важно отметить, что содержимое контрабандного запроса влияет на то, что произойдёт с соединением после первоначальной атаки.

Если вы просто провозите строку запроса с некоторыми заголовками, при условии, что вскоре по тому же соединению отправится ещё один запрос, бэкэнд в конечном счёте всё равно увидит два полных запроса.

smuggling-http-request-to-back-end-server 1.svg

Если вместо этого вы провозите запрос, который также содержит тело, следующий запрос в соединении будет присоединён к телу контрабандного запроса. Это часто имеет побочный эффект в виде усечения финального запроса на основании видимого Content-Length. В результате бэкэнд фактически видит три запроса, где третий запрос — это просто серия оставшихся байтов:

Front-end (CL)

Фронтэнд видит два запроса:

Back-end (TE)

А бэкэнд три:

Поскольку эти оставшиеся байты не образуют корректный запрос, обычно это приводит к ошибке и сервер закрывает соединение.

Провоз полного запроса

С небольшой аккуратностью можно провезти полный запрос вместо одного лишь префикса. Пока вы отправляете ровно два запроса в одном, любые последующие запросы по соединению останутся неизменными:

Front-end (CL)
Back-end (TE)

Обратите внимание: на бэкэнд не попадают некорректные запросы, поэтому соединение должно оставаться открытым после атаки.

Десинхронизация очереди ответов

Когда вы провозите полный запрос, фронтенд по-прежнему считает, что переслал только один запрос. Бэкэнд же видит два отдельных запроса и соответственно отправляет два ответа:

response-queue-poisoning.jpg

Фронтенд корректно сопоставляет первый ответ с исходным обёрточным запросом и пересылает его клиенту. Поскольку дальнейших запросов, ожидающих ответ, нет, неожиданный второй ответ сохраняется в очереди на соединении между фронтендом и бэкэндом.

Когда фронтенд получает ещё один запрос, он как обычно пересылает его на бэкэнд. Однако при выдаче ответа он отправит первый в очереди, то есть «залежавшийся» ответ на контрабандный запрос.

Корректный ответ бэкэнда остаётся без соответствующего запроса. Этот цикл повторяется каждый раз, когда по тому же соединению на бэкэнд пересылается новый запрос.

Кража ответов других пользователей

Как только очередь ответов отравлена, злоумышленник может просто отправлять произвольные запросы, чтобы перехватывать ответы других пользователей.

stealing-other-users-responses.jpg

Он не контролирует, какие именно ответы получит: ему всегда придёт следующий ответ в очереди, то есть ответ на предыдущий пользовательский запрос. В некоторых случаях это малоинтересно. Однако с помощью инструментов вроде Burp Intruder злоумышленник легко автоматизирует повторные запросы. Так он быстро соберёт подборку ответов, предназначенных разным пользователям, среди которых, вероятно, окажутся полезные данные.

Атакующий может продолжать красть ответы таким образом, пока соединение фронтенд/бэкэнд остаётся открытым. Точный момент закрытия соединения зависит от сервера. По умолчанию он разрывает соединение после обработки 100 запросов. Так же тривиально заново отравить новое соединение после закрытия текущего.

Tip

Чтобы легче отличать похищенные ответы от ответов на ваши собственные запросы, используйте несуществующий путь в обоих отправляемых вами запросах. Тогда на ваши запросы стабильно будет приходить, например, 404-й ответ.

Note

Эта атака возможна как через классическую контрабанду запросов HTTP/1, так и путём эксплуатации понижения версии HTTP/2.

Last updated