Как это выглядит?

Посмотреть, как устроена клиентская часть веб-приложения (та, которая отображается в браузере), очень просто: для этого на любой странице можно нажать «Просмотр кода страницы» и получить ее полный исходник (HTML/CSS/JS-код). Но попробуй в Chrome’е открыть ссылку kurlak.com/john/source.html и посмотреть ее сорец. Когда на странице четко отображается вопрос «Can you view my source from Chrome?», то при запросе исходника отображается издевательская фраза «You can, but not that easily...». Что за дела? Исследователю Джону Курлаку удалось проспуфить исходник веб-страницы! Это может показаться невинной шалостью, но на самом деле представляет собой довольно изящный хак. Ведь если кто-то подозревает, что на его страницу был каким-то образом внедрен посторонний зловредный код, то, открыв вот так в браузере ее исходник, он увидит ровно то, что захочет показать ему злоумышленник!

Исходный код страницы source.html, реализующей спуфинг
Исходный код страницы source.html, реализующей спуфинг

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

В основе хака лежит новая фича JavaScript — функция history.replaceState(). Она позволяет разработчику изменить URL страницы без перезагрузки последней. К примеру, можно использовать данную функцию, чтобы поменять URL страницы с  www.xakep.ru/example.html на www.xakep.ru/example2.html. При этом в целях безопасности имя сервера изменить, естественно, нельзя — только страницы.

Описание history.replaceState() от Mozilla
Описание history.replaceState() от Mozilla

Джон Курлак, экспериментируя с этой функцией, заметил, что если изменить URL страницы и посмотреть ее исходник, то браузер пытается показать сорцы новой страницы. Соответственно, если изменить адрес страницы так, чтобы никто не заметил, мы можем подсунуть что угодно в качестве ее исходника! Главное, чтобы имя страницы выглядело точно так же. И здесь вспомнился старый добрый трюк, использующий Unicode-символ, который переворачивает текст наоборот. Он называется «left to right» (LRO) и переставляет символы слева направо. Фишка в том, что если разместить его после текста, уже ориентированного слева направо, то никаких преобразований не происходит. Соответственно, мы можем переадресовать пользователя на другую страницу, которая пользователю будет отображаться точно так же (например, source.html). Символ LRO можно представить в виде десятичного кода 8237. Получаем простой код страницы source.html:

<!DOCTYPE html>
<html>
    <head>
        <title>Source</title>
        <meta charset="UTF-8">
        <script type="text/javascript">
        history.replaceState(null, null, 
           'source.html' + String.fromCharCode(8237));
        </script>
    </head>
    <body>
        <p>Can you view my source from Chrome?</p>
    </body>
</html>

Когда пользователь открывает страницу source.html, то браузер автоматически меняет адрес страницы на source.html + [LRO] — и в адресной строке по-прежнему отображается нужный нам index.html. Если же посмотреть исходный код страницы, то браузер пытается отобразить исходник страницы source.html†(†— это представление hex-кода символа LRO в ASCII). При этом никакие спецсимволы нигде не отображаются. Что мы делаем? Просто создаем страницу source.html†с нужным нам содержанием, которое будет отображаться пользователю в виде исходника. Бинго! Прочитать авторский пост на тему, скачать исходники и посмотреть демонстрацию ты можешь здесь: goo.gl/itGVr.

 

  • Подпишись на наc в Telegram!

    Только важные новости и лучшие статьи

    Подписаться

  • Подписаться
    Уведомить о
    1 Комментарий
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии