Наши партнеры

UnixForum





Библиотека сайта rus-linux.net

Безопасная эксплуатация Apache, часть 4: атаки на основе межсайтовой трассировки (XST) и межсайтовых манипуляций с историей (XSHM)

Оригинал: Securing Apache, Part 4: Cross-site Tracing (XST) & Cross-site History Manipulation (XSHM)
Автор: Arpit Bajpai
Дата публикации: 1 Декабря 2010 г.
Перевод: А.Панин
Дата перевода: 20 Января 2013 г.

Данная серия статей предназначена для экспертов в области защиты информации, интересующихся безопасностью веб-приложений, системных администраторов, а также для всех тех, кто хочет начать строить карьеру в этой области. На этот раз мы подвергнем подробнейшему рассмотрению аспект безопасности веб-приложений, рассмотрев атаки на основе межсайтовой трассировки (XST) и межсайтовых манипуляций с историей (XSHM) и приведя примеры некоторых методов защиты от данных атак.

В части 2 данной серии статей мы рассматривали XSS-атаки; в качестве одного из методов защиты от них предлагалось использование механизма кук "HttpOnly". Механизм "HttpOnly" служит для защиты сессий, устанавливая запрет на доступ к идентификатору сессии через модель DOM приложения. В случае использования этого механизма, взломщик не может похитить сессию с помощью вредоносных сценариев, так как вызов document.cookie не возвращает какой-либо полезной информации. Механизм "HttpOnly" работает практически во всех современных браузерах. Его достаточно просто использовать:
Set-Cookie: PHPSESSIONID=[token]; HttpOnly

Этот механизм был одним из лучших методов для защиты от XSS-атак с похищением кук до тех пор, пока не было установлено, что веб-сервер позволяет использовать метод HTTP TRACE (о котором мы поговорим ниже), позволяющий обойти механизм защиты "HttpOnly".

Если взломщик, использую XSS-уязвимость, заставляет браузер жертвы атаки отправить TRACE-запрос веб-серверу и в распоряжении браузера находятся куки для данного домена, они будут автоматически добавлены в заголовок запроса и, таким образом, будут возвращены браузеру в составе ответа сервера. После этого доступ к данным из кук из сценариев JavaScript будет возможен, поэтому наконец появится возможность отправить эти данные третьему лицу, даже в том случае, если используется механизм "HttpOnly". Следовательно, XST-атака является ничем иным, как XSS-атакой с использованием запроса TRACE.

Запрос HTTP TRACE и XST-атаки

Запрос HTTP TRACE является методом, спроектированным для диагностики проблем, таких, как ошибки при работе сетевого соединения между серверами. Этот запрос определен наряду с такими известными запросами, как GET, PUT, DELETE, и.т.д.

Когда клиент отправляет запрос TRACE к поддерживающему его серверу, сервер отвечает на него, отправляя заголовок, присланный клиентом. Взломщик может использовать эту особенность для захвата кук, защищенных методом "HttpOnly", просто внедрив код, который использует XMLHttpRequest и отправляет асинхронно запросы TRACE, получая куки из сообщения, отправленного сервером в ответ на запрос.

Давайте рассмотрим простой сценарий осуществления атаки для лучшего понимания:

Сценарий атаки

Давайте продолжим рассмотрение примера, который был приведен в части 2 данной серии статей (в нем рассматривалась отраженная XSS-атака). В данном примере взломщик находит XSS-уязвимость в веб-приложении, заключающуюся в выводе сценарием приложения строки запроса, использующейся для поиска на сайте и содержащейся в составе строки URL, при выводе результатов поиска. Например, строка URL браузера для вызова страницы результатов поиска со строкой запроса "products" должна выглядеть следующим образом: http://www.example.com/search.php?query=products. Теперь рассмотрим следующие случаи:

Метод "HttpOnly" не используется для защиты кук и есть возможность осуществлять запросы TRACE

В данном случае, как уже упоминалось в части 2 серии, взломщик может предоставить модифицированную ссылку, аналогичную данной: http://www.example.com/search.php?query=<script>alert(document.cookie)</script>.

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

Метод "HttpOnly" используется для защиты кук, а также есть возможность осуществлять запросы TRACE

В данном случае ясно, что метод, представленный выше не будет работать, так как при использовании метода защиты "HttpOnly" данные кук не будут переданы сценарию JavaScript при использовании document.cookie. Поэтому взломщик, зная о том, что использование запроса TRACE разрешено на веб-сервере (он может установить это, используя методики, описанные в разделе ниже), может использовать код, аналогичный приведенному ниже (назовем его mal.js):
<script type="text/javascript">
var x = new ActiveXObject("Microsoft.XMLHTTP");
// var x = new XMLHttpRequest();
x.open("TRACE", "http://example.com",false);
x.send();
//x.send("");
cookie=x.responseText;
alert(cookie);
</script>

(Код выше может использоваться в браузере Internet Explorer; для использования его в браузере Mozilla следует произвести модификации, представленные в форме комментариев).

Данный код выводит сообщение с данными из кук жертвы атаки даже в том случае, когда используется метод защиты "HttpOnly". Помните о том, что взломщик может сократить длину данного вредоносного кода, воспользовавшись техниками сокращения длины URL (описанными в части 2 данной серии статей). Взломщик может также похитить данные из кук и другие идентификационные данные, воспользовавшись приведенным выше кодом. Схематичное представление данной атаки приведено на Рисунке 1.

Атака возможна в случае разрешения TRACE-запросов
Рисунок 1. Атака возможна в случае разрешения TRACE-запросов

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

Что происходит негласно?

Приведенный выше код, используя объект ActiveX с названием XMLHTTP, должен отправить TRACE-запрос указанному веб-серверу. Если веб-сервер обрабатывает TRACE-запросы, он отправит клиенту информацию из его HTTP-запроса. Теперь в том случае, если браузер жертвы атаки имеет в распоряжении куки от удаленного сервера или получен доступ к серверу с использованием механизмов неявной аутентификации, данные из кук будут выведены в окне предупреждения.

А что если отключить обработку запросов TRACE?

Многие эксперты в области безопасности советуют в самом начале настройки веб-сервера отключать обработку TRACE-запросов, так как это повышает безопасность сервера (Рисунок 2).

Атака невозможна при отключении TRACE-запросов
Рисунок 2: Атака невозможна при отключении TRACE-запросов

Тем не менее, в том случае, когда соединение с сервером осуществляется через промежуточный прокси-сервер, существует возможность принуждения прокси-сервера к ответу на TRACE-запрос. Для этого взломщик может просто включить параметр Max-Forward: 0 в заголовок HTTP-запроса. Первый прокси-сервер цепочки при обнаружении данного параметра должен ответить на TRACE-запрос вместо того, чтобы передавать запрос веб-серверу. Следовательно, сценарий должен быть усовершенствован следующим образом:
<script type="text/javascript">
var x = new ActiveXObject("Microsoft.XMLHTTP");
// var x = new XMLHttpRequest();
x.open("TRACE", "http://example.com",false);
x.setRequestHeader("Max-Forwards", "0");
x.send();
//x.send("");
c=x.responseText;
alert(c);
</script>

(И снова код, приведенный выше, предназначен для использования в браузере Internet Explorer, модификации для браузера Mozilla закомментированы).

Компания Microsoft, пытаясь повысить безопасность работы браузера Internet Explorer, провела работу по удалению поддержки любых методов с названиями, начинающимися с "TRACE" объектом XmlHttp. Как бы то ни было, эта мера безопасности была также преодолена, когда было обнаружено, что вместо использования "TRACE" взломщик может использовать просто "rnTRACE". Следовательно, строка x.open("TRACE", "http://example.com",false) из сценария выше должна быть преобразована в строку x.open("rnTRACE","http://example.com",false).

Атаки на основе межсайтовой трассировки (XST) являются одной из самых незаметно распространяющихся угроз безопасности в Интернет на сегодняшний день. Тем не менее, следующие меры повышения безопасности могут помочь вам нейтрализовать их.

Меры повышения безопасности

  1. Первой и самой важной мерой по повышению безопасности является блокировка обработки TRACE-запросов (за исключением тех случаев, когда эти запросы используются) на ваших веб-серверах.
  2. Более того, разработчикам веб-серверов следует блокировать обработку TRACE-запросов в настройках, заданных по умолчанию при установке.
  3. Прокси-сервера также должны устанавливаться с заблокированной возможностью обработки TRACE-запросов в настройках, заданных по умолчанию.
  4. Следует также отключить TRACE-запросы на уровне объекта XmlHttpRequest вашего браузера. Для этого следует обратиться к страницам поддержки разработчика вашего браузера.
  5. Для всех пользователей браузера Internet Explorer: если вам необходимо продолжать использование Inernet Explorer, следует обновиться до версии 7 или 8, так как для них, скорее всего, существуют исправления, препятствующие осуществлению данной атаки. Тем не менее, лучшим вариантом, который я бы порекомендовал, является использование последних версий браузера Mozilla Firefox (>3.2) вместо него.

Как отключить обработку TRACE-запросов в Apache?

Отключение обработки TRACE-запросов в Apache осуществляется достаточно просто. Единственным требованием является установка модуля Apache mod_rewrite, после чего выполняются следующие действия:
  1. Активируется модуль mod_rewrite путем добавления в файл httpd.conf данной строки:
    LoadModule rewrite_module modules/mod_rewrite.so
    	
  2. В файл httpd.conf добавляются следующие строки для отключения обработки TRACE-запросов:
    RewriteEngine On
    RewriteCond %{REQUEST_METHOD} ^TRACE
    RewriteRule .* - [F]
    	
  3. После этого следует осуществить перезапуск веб-сервера Apache.
После того, как обработка TRACE-запросов была отключена в соответствии с приведенными инструкциями, на любые входящие TRACE-запросы последуют ответы с кодами статуса HTTP 403 или 405. Вы также можете проверить работу сервера, подключившись к нему с помощью telnet, так, как показано ниже:
server@attacker~$ telnet www.victim.com 80
OPTIONS / HTTP/1.1
Host: www.victim.com
HTTP/1.1 200 OK
Server: Apache-httpd/2.2.1
Date: Tue, 31 Oct 2006 08:00:29 GMT
Connection: close
Allow: GET, HEAD, POST, PUT, DELETE, OPTIONS
Content-Length: 0

Как мы видим в примере, в строке, начинающейся со слова Allow приведен список всех методов HTTP, поддерживаемых веб-сервером. В данном случае очевидно, что разрешены все методы за исключением метода TRACE.

Теперь давайте перейдем к рассмотрению другого типа атак на веб-приложения: атак межсайтовых манипуляций с историей (XSHM).

Межсайтовые манипуляции с историей (XSHM)

Этому типу атаки, получившему известность в последнее время и использующему историю посещений пользователя, подвержены браузеры Mozilla Firefox, Google Chrome и Internet Explorer. Манипулируя историей посещений браузера, возможно обойти технологию защиты браузера "same-origin policy (SOP)" и, таким образом, вмешаться в частную жизнь пользователя.

Следует напомнить, что в части 3 данной серии статей мы кратко обсудили технологию SOP и упомянули о том, что при использовании этой технологии веб-страницы разного происхождения не могут взаимодействовать друг с другом (под взаимодействием в данном случае понимается то, что страница одного происхождения может только отправлять HTTP-запрос странице другого происхождения; при этом ей не разрешается чтение ответа от страницы другого происхождения).

Следовательно, при осуществлении CSRF-атаки взломщик может только отправлять вредоносные HTTP-запросы к веб-сайту банка, но но или она не может получать HTTP-ответы от этого сайта. Тем не менее, не так давно обнаружено, что даже эти ограничения действий взломщика технологией SOP могут быть преодолены с помощью манипуляций с объектами истории браузера.

Для начала давайте рассмотрим архитектуру объекта истории браузера.

Объект истории браузера

История браузера представляет собой глобальный список страниц, которые пользователь посещал ранее и по которому он может перемещаться, нажимая кнопки браузера "Назад" и "Вперед". Некоторые особенности данного списка:
  1. Если строка URL использовалась несколько раз, в список истории добавляется только одна запись.
  2. Если пользователь открывает страницу B, которая автоматически перенаправляет пользователя на страницу A (при помощи веб-сервера), в список истории добавляется только строка URL для страницы A.
  3. Возможно открыть URL без добавления записи в список истории. Используя метод location.replace, мы можем открывать различные URL один за одним, заменяя текущую запись списка истории.
  4. Технология SOP предотвращает только доступ из сценариев JavaScript к URL из списка истории; она не предотвращает доступ к свойству history.length (количество элементов в глобальном списке истории). Также имеется возможность загрузить страницу для заданной строки URL из списка истории с помощью метода history.go(URL).
Основные направления XSHM-атаки, в ходе которой производятся манипуляции с объектом истории браузера, представлены ниже:
  • Межсайтовое раскрытие условий
  • Межсайтовое отслеживание действий пользователя
  • Межсайтовые манипуляции со строками URL и другими параметрами

Рассмотрим эти направления по очереди.

Межсайтовое раскрытие условий

Предположим, что сценарий веб-сайта содержит следующее логическое условие:
Page A: If(Condition)
        Redirect(Page B)
В данном случае взломщик может осуществить CSRF-атаку для получения указания на значение логической переменной Condition (истинно ли значение или оно ложно) в ответе. Данная атака проводится с сайта взломщика с использованием следующих шагов в процессе:
  1. Взломщик создает элемент iframe, параметр src которого указывает на адрес страницы B.
  2. Код сохраняет текущее значение свойства history.length в переменной.
  3. После этого код меняет значение параметра src элемента iframe на адрес страницы A.
  4. Сравнивается значение переменной, в которой была сохранена длина списка истории со значением свойства history.length и если эти значения равны, то значение переменной Condition истинно.

Принцип работы приведенного выше алгоритма базируется на второй особенности поведения объекта истории из списка выше.

Поэтому значение history.length будет оставаться неизменным при открытии страницы A, что указывает на истинность значения логической переменной Condition. Если бы значение переменной Condition было ложным, то добавление страницы A в список истории браузер увеличило бы его длину на единицу. Так как взломщик может открыть оба URL с этой страницы в элементе iframe и доступ к значению history.length со страницы на сайте взломщика открыт, этот случай является примером межсайтового раскрытия условий и, следовательно, примером обхода технологии защиты SOP.

После получения указания на значение переменной Condition взломщик может начать планировать двухстороннюю CSRF-атаку (под двухсторонней CSRF-атакой понимается CSRF-атака, при которой взломщик получает ответ от сервера). Давайте рассмотрим простой сценарий такой атаки.

Сценарий атаки

Предположим, что банковское приложение позволяет переводить средства с одного счета на другой. При этом сценарий веб-сайта может использовать следующий код:
If (Money_Transfer())
        Redirect("Transaction_done.php");
Приведенный код выполняет перевод средств и, в случае успешного завершения, пользовательский браузер перенаправляется на страницу Transaction_done. В данном случае взломщик может не только осуществить CSRF-атаку и выполнить перевод средств, но и получить ответ об успешном завершении операции перевода, используя следующую последовательность действий в процессе:
  1. Взломщик создает элемент iframe со свойством src='Transaction_done.php' и получает значение history.length.
  2. В итоге в распоряжении взломщика имеется информация о текущем значении свойства history.length для браузера жертвы атаки.
  3. После этого значение свойства src элемента iframe меняется на Money_transfer.php.
  4. Если значение свойства history.length остается неизменным, операция была завершена успешно.

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

Межсайтовое отслеживание действий пользователя

При использовании элемента iframe взломщик сталкивается с рядом ограничений: он не может знать о том, как жертва атаки взаимодействует с элементом iframe и также, в соответствии со стандартом, элемент iframe не может взаимодействовать с родительской страницей. Но при помощи XSHM-атаки взломщик может обойти и эти ограничения и в ряде случаев отследить действия пользователя внутри элемента iframe.

Для отслеживания действий жертвы атаки на странице внутри элемента iframe взломщик создает список строк URL, указывающих на содержащиеся на странице элементы и страницы, на которые могут быть отправлены данные из форм. После этого в любой момент, когда жертва атаки переходит по ссылке внутри элемента iframe, значение свойства history.length ее браузера остается неизменным. Строка URL для данной ссылки должна всегда находиться на вершине списка истории; в данном случае взломщик может использовать метод location.replace для проверки различных строк URL из списка без добавления их на его вершину.

Процесс осуществления типичной атаки данного типа описан ниже:
  1. Взломщик создает элемент iframe со свойством src, указывающим на сайт жертвы атаки и механизмом для получения значения свойства history.length.
  2. При каждом событии загрузки элемента iframe взломщик сохраняет текущее значение свойства history.length для браузера жертвы и затем меняет значение свойства src элемента iframe на URL, который доступен для родительской страницы.
  3. Проведение двух вышеуказанных действий для каждой строки URL, доступной для родительской страницы, вплоть до того момента, пока значение свойства history.length перестает возрастать, позволяет взломщику узнать, по какой ссылке и когда был осуществлен переход.

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

Межсайтовые манипуляции со строками URL и другими параметрами

Это еще одно направление XSHM-атаки, при которой взломщик может также получить список строк URL для ранее посещенных пользователем ресурсов. Процесс осуществления атаки данного типа достаточно прост:
  1. Взломщик создает массив строк URL для проверки (давайте назовем его URL[]).
  2. После этого взломщик использует метод history.go(URL[x]) для каждой строки URL из списка.
  3. Если наступает событие document.unload, взломщик получает доказательство того, что пользователь посещал URL[x] в рамках данной сессии.

Единственным ограничением данного процесса является то, что перед началом атаки взломщику необходимо создать массив строк URL[x], содержащий строки URL, факт перехода пользователем по которым должен быть установлен.

Межсайтовые манипуляции с историей (XSHM) являются новым направлением атак, с помощью которых может быть скомпрометирована технология защиты "Same Origin Policy (SOP)" и осуществлено вмешательство в личную жизнь пользователя. XSHM-атаки расширяют возможности CSRF-атак, делая их двухсторонними. Тем не менее, следующие меры повышения безопасности могут помочь вам нейтрализовать их.

Меры повышения безопасности

Если ваше приложение использует условные перенаправления, оно может быть уязвимо для XSHM-атак. Тем не менее, для следующего кода эти атаки не опасны:
if (url != "")
        Response.Redirect(url);
Данный код безопасен потому, что условие if(url != "") специфично и не может принимать только логические значения.
  1. Для успешного предотвращения атак на основе межсайтовых манипуляций с историей, обе строки URL: и страницы, с на которой было осуществлено перенаправление, и страницы, на которую оно было осуществлено, должны содержать случайные идентификаторы, как показано ниже:
    if ( !isAuthenticated)
    	Redirect('Login.aspx?r=' + Random())
    	
  2. Для предотвращения получения списка строк URL и параметров все строки URL на сайте должны содержать случайные идентификаторы.

Для получения большего количества информации о данных атаках не забудьте рассмотреть список дополнительных ресурсов ниже. Мы поговорим о других опасных атаках на веб-приложения и Apache в следующей статье.

Всегда помните: нужно знать все о взломе, но не заниматься им.

Дополнительные ресурсы

Продолжение серии: "Безопасная эксплуатация Apache, часть 5: использование уязвимостей архитектуры сообщений HTTP"