подделка заголовков HTTP-запроса с помощью Flash ActionScript

Flash Player – популярное дополнение к браузеру от компании Adobe (изначально Flash был разработан Macromedia, которую позже купил Adobe). В этой статье рассматриваются Flash 7-й и 8-й версии, которые установлены более чем на 94% рабочих станций, имеющих выход в Интернет (согласно опросу NPD Online Survey в апреле 2006 года). Flash анимация поставляется в виде файлов SWF (ShockWave File).

Adobe также разработал язык ActionScript, напоминающий Javascript, который используется внутри Flash роликов. ActionScript позволяет посылать произвольные HTTP-запросы к произвольным сайтам через веб-браузер, проигрывающий флеш-ролик. В результате можно сформировать запрос к сайту, который нельзя выполнить через обычный Javascript-код. Также в запросе можно задать произвольные HTTP.

посылаем произвольный HTTP-заголовок через Flash

Следующий синтаксис в ActionScript 2.0 позволяет послать GET-запрос (в нашем примере на сайт http://www.vuln.site/some/page.cgi?p1=v1&p2=v2) с произвольным HTTP-заголовком (Foo: Bar). Этот код работает с Flash 7 и 8 версии (возможно, работает и в 6-й версии):

var req:LoadVars=new LoadVars();
req.addRequestHeader("Foo","Bar");
req.send("http://www.vuln.site/some/page.cgi?p1=v1&p2=v2", "_blank","GET");


Похожий синтаксис используется для отправки POST-запросов (с тем же самым заголовком, с телом запроса a=b&c=d):

var req:LoadVars=new LoadVars();
req.addRequestHeader("Foo","Bar");
req.decode("a=b&c=d");
req.send("http://www.vuln.site/some/page.cgi?p1=v1&p2=v2", "_blank","POST");


Примечание: метод LoadVars.decode() был добавлен в Flash 7.

Запрос посылается из браузера, выполняющего Flash-объект. Любые куки, которые обычно отправляет браузер, будут также посланы в этом случае. Посылается также User-Agent браузера и все стандартные заголовки браузера. Также поддерживаются HTTPS-запросы.

Эти примеры проверены и работают с Microsoft IE 6.0, Microsoft IE 6.0 SP2 и FireFox 1.5.0.4, с установленными плагинами Flash 8.0.22.0 и Flash 7.0.19.0.

В IE также существует возможность переписать “нормальные” заголовки браузера, добавляя addRequestHeader с новым значением заголовка, в том числе заголовки Referer и User-Agent. В FireFox 1.5.0.4, при использовании addRequestHeader(), заголовки будут добавлены к HTTP-запросу.

// Один User-Agent в IE 6.0 SP2, 2 User-Agent в FF 1.5.0.4
req.addRequestHeader("User-Agent","Hacker/1.0");

// Один Referer в IE 6.0 SP2, два Referers в FF 1.5.0.4
req.addRequestHeader("Referer","http://somewhere/");


В IE также можно переписать некоторые важные заголовки (например Host и Content-Length), добавляя двоеточие к имени заголовка:

req.addRequestHeader("Host:","foobar.site");

Этот метод не работает в FireFox 1.5.0.4.

влияние на безопасность

Способность атакующего заставить браузер жертвы послать произвольные HTTP-запросы к произвольным сайтам с произвольными HTTP-заголовками влияет на наше понимание безопасности веб-приложений – как на оценку связанных с безопасностью явлений, так и на обоснованность некоторых механизмов безопасности.

Важно понять, что этот тип нападения по сути не является обычной XSS-атакой, так как не воздействует на межсайтовое доверие внутри Flash-объекта или на доверие между Flash объектом и внедренной HTML-страницей. Нападение лишь основывается на возможности послать запросы из Flash-объекта к произвольному URL с произвольными HTTP-заголовками. Такая возможность сама по себе является проблемой, так как позволяет атакующему посылать ссылку (к HTML-странице с внедренным Flash-объектом или непосредственно к Flash-объекту, расположенному на веб-сайте атакующего), которая выполнит этот объект в браузере жертвы. В свою очередь Flash-объект пошлет HTTP-запрос (с HTTP-заголовками по выбору атакующего) к целевому сайту, и это, возможно, поставит под угрозу безопасность браузера жертвы (впрочем, атака может быть проведена и против самого целевого сайта). Другими словами, неявное предположение, сделанное многими разработчиками ПО (и вероятно также многими экспертами безопасности), что большинство HTTP-заголовков не может быть изменено атакующим, который манипулирует данными в браузере жертвы, является ошибочным.

пример 1. заголовок Expect

Ранее была обнаружена уязвимость в Apache 1.3.34, 2.0.57 и 2.2.1, позволяющая внедрить HTML-данные (включая произвольный Javascript-код) через Expect-заголовок. Однако производитель посчитал, что уязвимость невозможно поэксплуатировать, потому что не существует способа заставить браузер послать измененный Expect-заголовок к целевому сайту. Однако, используя Flash-объект, атакующий может заставить браузер послать такой запрос, заставив жертву кликнуть на ссылку с флешкой. Flash-объект запустит следующий ActionScript-код:

var req:LoadVars=new LoadVars();
req.addRequestHeader("Expect", "<script>alert('gotcha!')</script>");
req.send("http://www.target.site/","_blank","GET");


Этот ActionScript пошлет запрос из браузера жертвы к целевому сайту с Expect заголовком, содержащим произвольный HTML (Javascript) код. Если целевой сайт работает на уязвимой версии Apache, то в результате будет возможно осуществить атаку межсайтового скриптинга. XSS-атака возможна против Apache 1.3.34, 2.0.57 и 2.2.1, если браузер клиента - IE или Firefox, поддерживающие Flash 6/7+). В случае Apache 2.0/2.2, XSS-ответ будет возвращен только после истечения времени ожидания (обычно несколько минут). Уязвимость устранена в последних версиях Apache – 1.3.35, 2.0.58 и 2.2.2 соответственно).

пример 2. CSRF и Referer

CSRF (Cross Site Request Forgery) атака позволяет атакующему заставить браузер жертвы выполнять различные действия (посылать HTTP-запросы) на целевой сайт. Это редкий вид нападения, который всплывал несколько раз - впервые в списке рассылки Zope ("Client Side Trojans") и несколько раз в BugTraq под именем CSRF. Обе ссылки советуют, кроме других методов, доверять HTTP-заголовку Referer, как очевидности того, что браузер посылает этот заголовок от ссылки, которая расположена на веб-сайте. Действительно, используя возможности HTML+Javascript, почти невозможно подменить Referer (единственный способ описан в http://www.securityfocus.com/archive/1/411585, однако он работает в ограниченном подмножестве сценариев, и не работает, если используется HTTPS). Однако, как было показано выше, можно обойти эти ограничения, используя Flash, в том числе и для изменения заголовка Referer в HTTPS-ресурсах, используя браузер, который посылает куки сайта вместе с запросом. В результате могут быть посланы GET-запросы (с произвольным хостом и частью запроса) и POST запросы (с произвольным хостом, частью запроса и телом в стандартном Content- Type формате "application/x-www-form-urlencoded").

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

Очевидно, что может быть подделан любой заголовок. В случае IE, заголовок, представленный браузером, может быть подменен атакующем (например, заголовок Referrer).

В случае браузера Firefox, заголовок Referer подменить не получится, так как Firefox добавляет заголовок последним в HTTP-запросе. Однако некоторые веб-приложения могут использовать последние значения заголовка и также могут быть уязвимыми к этому способу атаки.

В результате становится возможным эксплуатация любой рефлективной атаки межсайтового скриптинга, которая использует заголовки HTTP-запроса (например Referer, User-Agent, Expect, Host, Content-Type).

Flash 9

Flash 9 появился в 28 июня 2006 года. В Flash 9 методика, описанная выше (для класса LoadVars), не работает для любого заголовка,
представленного браузером (например, User-Agent, Host и Referrer), и, скорее всего, для других защищенных заголовков типа Content-Length. Однако все равно могут быть посланы заголовки типа Expect, так что некоторые нападения (как в первом примере) все равно работают в Flash 9.
ограничения методики

URL и часть тела запроса должны быть всегда URL-кодированы. Таким образом, невозможно вставить SP, HT, CR и LF (и множество других символов) в URL и тело запроса.

Могут использоваться только GET- и POST-методы.

В IE может быть послан только один вариант каждого заголовка.

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

частичное решение

Первое ограничение этой методики – невозможность послать CR и LF в теле запроса - означает, что методика не может использоваться для отправки POST-запросов с content-type "multipart/form-data" (этот формат использует сырые CR и LF чтобы отметить заголовки и границы). Другими словами, POST-запрос, тело которого содержит поток multipart/form-data, не может быть послан из Flash-плеера. Авторы веб-приложения могут использовать HTML-формы со свойством ENCTYPE, установленным в "multipart/form-data", и предписывать, что POST-запрос содержит тело multipart/form-data. Если используются эти механизмы, то невозможно осуществить нападения описанные выше.

Это решение конечно слишком навязчиво – должны быть изменены HTML страница и получаемый сценарий, чтобы использовать multipart/form-data. Во многих средствах разработки веб-приложений это просто реализовать, но в некоторых нет.



Amit Klein


Сетевые решения. Статья была опубликована в номере 07 за 2006 год в рубрике save ass…

©1999-2024 Сетевые решения