Привет, Хабр! Вчера вечером жена пожаловалась, что не может зайти на сайт детской одежды, потому что с него перебрасывает на совершенно посторонний ресурс. Проверяю сам — действительно, во время загрузки главной страницы (или любой другой, если успеть перейти по ссылке с загружающейся страницы) внезапно перебрасывает на другой домен.
На улице сентябрь и холодает, поэтому решил не отступать перед проблемой и выбрать-таки ребёнку демисезонный костюм, попутно разобравшись в чём же дело!
Первое и очевидное, что приходит в голову — поискать явный редирект на странице. Открываю исходный код страницы в попытке найти что-нибудь такое:
Безрезультатно, к тому же это было бы слишком просто. Раз нет стандартного редиректа, следовательно он реализован средствами JS. Проверяем гипотезу отключением JS в браузере — страница загрузилась, никуда не перекидывает. При этом window.location на странице нигде не используется, подменяющего URL тоже нет. Глянем, какие ресурсы закачивает браузер:
Сразу бросается в глаза подозрительный URL, по запросу к которому возвращается HTTP код 301: is.gd/J87Pzs
По этому URL быстро находим строчку в исходниках страницы:
Отмечу, что эта строчка присутствует на всех страницах, где смотрел.
Хм, необходимо разобраться, что же такое происходит по этой ссылке: is.gd/J87Pzs.
is.gd — это типичный «ссылкоукорачиватель». За данным URL стоит следующий: home-income-business.com/sfi/i/qwe
GET-запрос на него возвращает такой контент:
Дело уже можно было бы закрывать, как в этот момент я переключаюсь на другую точку доступа к Интернет, а проблема (внезапно) исчезает: HTTP-запрос по последнему URL в цепочке начинает возвращать пустой контент! Что за?! Переключаемся опять на другую точку доступа — зловредный код снова отдаётся. А это уже интереснее! Выходит, в зависимости от ip-адреса отдаётся разное содержимое. Как такое может быть? Например, в nginx есть специальный модуль geo, с использованием которого можно настроить подобное поведение. Содержимое HTTP-ответа косвенно подтверждает вышесказанное:
Зачем делать атаку с редиректом на другой сайт? Причин может быть множество, в том числе меркантильных, например, для осуществления нечестной конкуренции или привлечения трафика на сайт.
При этом владелец сайта-жертвы может даже не догадываться, что находится под атакой, поскольку с его ip-адресов сайт будет прекрасно открываться и работать, а с других… Пользователи, зайдя на такой сайт, вероятно просто уйдут и не будут заморачиваться.
Я заморочился. И написал на e-mail, указанный в контактах. А уже на следующий день, то есть сегодня, со мной связался администратор сайта, которому я подробно изложил проблему. И, пока я писал этот пост и готовил картинки, проблему уже исправили, удалив зловредный скрипт со страниц сайта!
Вероятно, вам интересно узнать, как же зловредный код оказался на страницах сайта: администратор высказал предположение, что это его предшественник оставил «подарок».
P.S. Посчитал неуместным указывать подвергшийся атаке сайт.
На улице сентябрь и холодает, поэтому решил не отступать перед проблемой и выбрать-таки ребёнку демисезонный костюм, попутно разобравшись в чём же дело!
Первое и очевидное, что приходит в голову — поискать явный редирект на странице. Открываю исходный код страницы в попытке найти что-нибудь такое:
<meta http-equiv="refresh" content="3;url=http://подозрительный-сайт-точка-ру/">
Безрезультатно, к тому же это было бы слишком просто. Раз нет стандартного редиректа, следовательно он реализован средствами JS. Проверяем гипотезу отключением JS в браузере — страница загрузилась, никуда не перекидывает. При этом window.location на странице нигде не используется, подменяющего URL тоже нет. Глянем, какие ресурсы закачивает браузер:
Сразу бросается в глаза подозрительный URL, по запросу к которому возвращается HTTP код 301: is.gd/J87Pzs
По этому URL быстро находим строчку в исходниках страницы:
Отмечу, что эта строчка присутствует на всех страницах, где смотрел.
Хм, необходимо разобраться, что же такое происходит по этой ссылке: is.gd/J87Pzs.
is.gd — это типичный «ссылкоукорачиватель». За данным URL стоит следующий: home-income-business.com/sfi/i/qwe
GET-запрос на него возвращает такой контент:
function process(){ window.location = "http://подозрительный-сайт-точка-ру/"; } window.onerror = process; process()
Дело уже можно было бы закрывать, как в этот момент я переключаюсь на другую точку доступа к Интернет, а проблема (внезапно) исчезает: HTTP-запрос по последнему URL в цепочке начинает возвращать пустой контент! Что за?! Переключаемся опять на другую точку доступа — зловредный код снова отдаётся. А это уже интереснее! Выходит, в зависимости от ip-адреса отдаётся разное содержимое. Как такое может быть? Например, в nginx есть специальный модуль geo, с использованием которого можно настроить подобное поведение. Содержимое HTTP-ответа косвенно подтверждает вышесказанное:
Зачем делать атаку с редиректом на другой сайт? Причин может быть множество, в том числе меркантильных, например, для осуществления нечестной конкуренции или привлечения трафика на сайт.
При этом владелец сайта-жертвы может даже не догадываться, что находится под атакой, поскольку с его ip-адресов сайт будет прекрасно открываться и работать, а с других… Пользователи, зайдя на такой сайт, вероятно просто уйдут и не будут заморачиваться.
Я заморочился. И написал на e-mail, указанный в контактах. А уже на следующий день, то есть сегодня, со мной связался администратор сайта, которому я подробно изложил проблему. И, пока я писал этот пост и готовил картинки, проблему уже исправили, удалив зловредный скрипт со страниц сайта!
Вероятно, вам интересно узнать, как же зловредный код оказался на страницах сайта: администратор высказал предположение, что это его предшественник оставил «подарок».
Выводы:
- Самый эффективный способ предупреждения внедрения таких скриптов — не использовать подгружаемые со сторонних сайтов ресурсы;
- Для исключения их выполнения также можно применять Content Security Policy, используя HTTP-заголовок Content-Security-Policy (X-WebKit-CSP для старых версий Chrome и X-Content-Security-Policy для старых версий Firefox и IE 10-11), который в силу своей относительной молодости и статуса Candidate Recomendation не поддерживается в старых браузерах;
- И по возможности отправлять баг-репорты, так мы сможем сделать Интернет чище.
P.S. Посчитал неуместным указывать подвергшийся атаке сайт.
Поделиться с друзьями
Комментарии (8)
x893
20.09.2016 13:30+2Это только подтверждает давнюю дискуссию об использовании сторонних ресурсов на своем сайте. Если бы администратор посмотрел, что при загрузке используются хрен поймешь какие ресурсы, то проблемы и не было.
almassar
20.09.2016 16:26+1Чем то напоминает официанта, который плюет тебе в тарелку. В судить такого админа нужна.
PS: В Яндекс метрике должны же ведь указаны переходы на другой сайт?
Andrey_Volk
Ну, я бы не назвал это XSS-атакой. Я бы назвал это подлянкой от предшественника.
Klepus
Не факт, что от предшественника, я бы поискал шелл на сайте. С вероятностью 90% сайт взломали, залили шелл и добавили свой скрипт в исходники
gnkoshelev
Если скрипт был добавлен предшественником — согласен, XSS-атакой это называть неуместно.
Основной поинт в проблеме выявления организованной подобным образом XSS-атаки, когда зловредный код отдаётся в зависимости от ip-адреса или других доступных данных, например User-Agent.
Единственный способ обезопасить себя — не использовать сторонние ресурсы, тогда выявить подгрузку будет проще простого.
jazzl0ver
Или на уровне сервера настроить Content Security Policy
gnkoshelev
Да, спасибо. Добавил эту информацию в конец.
pansa
1. Это как ни крути не имеет отношения к XSS.
XSS подразумевает исполнение вредоносного JS в контексте открытой страницы (Origin). В данном конкретном случае плохие парни тоже влепили .js, но, очевидно, тут был взлом сайта (99% на wordpress и сломали через шаблоны) и редирект сделали давно проверенным способом.
2. Такое поведение ( появление кода в зависимости от окружения клиента ) элементарно реализуется на php или что там в бэкэнде было, что с 99.99% и было сделано, доступ к конфигам nginx не нужен.
3. Условным вредоносным редиректам ( UserAgent, гео, версии плагинов, мобильные сети) — уже лет 5 как. С разморозкой. =)