/Разборы задач
5 ноября 2026
Райтап на задачу «Слепая инъекция»
Пишем скрипт для слепой SQL-инъекции по ответам true/false и разбираем альтернативу с sqlmap.26
10

Web
Задача «Приоритетный канал»
В этой задаче нам нужно узнать, что же это за такой альтернативный способ передачи URL-адресов, чтоб можно было изменять URL-адреса на лету относительно поданного, соответственно, в адресной строке.
Для начала зайдём в Burp Suite и посмотрим, что в целом у нас есть:
Итак, перед нами веб-приложение для просмотра файлов. Думаю, несложно догадаться, что нужно посмотреть какие-то файлы, доступ к которым скрыт, — системные.
Пробуем обратиться для прочтения access.log — получаем файл, пробуем flag.txt — получаем File not found or is a directory!
Однако, по логике задания, должен быть какой-то путь, обратившись на который стандартным образом нам должен быть выдан запрет на просмотр.
Попробуем стандарт: /etc/passwd (это такой файлик в Linux, где хранится всякая информация по пользователям, если кратко):
Опа! Получили 403 Forbidden. 3-й вариант ответа от сайта выбит. Теперь нужно придумать, как обойти эту защиту.
Погуглим в соответствии с условием: «...приложение будет работать за сложной системой балансировки нагрузки или веб-прокси, которая будет изменять URL-адреса на лету?» Надо узнать, как это реализуется в веб-приложениях: Напишем такой запрос в Google:
Rewrite URL 403Переходим, например, на этот сайт и видим, что пользователь обошёл контроль доступа при помощи некого HTTP-заголовка X-Rewrite-URL.
Гуглим:
X-Rewrite-URL header что делаетЗдесь узнаём, что этот хедер выполняет буквально описанную в условии функцию — подменяет URL.
Идём обратно к нашему сайту и пробуем применить найденную штуку — подменяем и отправляем request:
Ура! Нам удалось обойти защиту сервера! Однако ничего похожего на флаг в /etc/passwd нет. В таком случае нам остаётся перебирать пути, по которым может лежать исходный код приложения.
Системные пути можно найти на родном PayloadsAllTheThings, а конкретно в статье по Path Traversal.
Вот самое интересное, что удалось найти: Пробуем /etc/hosts:
Теперь мы знаем название приложения и, следовательно, папку, где оно находится.
Пробуем /proc/self/environ: В ответ получаем запрос на скачивание файла — скачиваем файл logs.
Идём в терминал и читаем файл через утилиту strings:
strings logsИнтересно, в выводе мы видим информацию о Python и значения переменных TASK_FLAG_35, FLAG, CTF_FLAG, напоминающие реальный флаг. Однако их префикс отличается от искомого. Попробуем заменить префикс флага на BugCTF{} и сдать — зашло! Получается, что таска решена таким интересным образом.
Однако, возможно, это не самое эталонное решение, поскольку найденный в логе флаг по своему префиксу не является верным. Покопаем ещё чуть-чуть.
Мы знаем, что приложение называется app и написано оно на Python. Тогда попробуем прочитать исходный код по пути /app/app.py:
А вот тут у нас уже оригинальный флаг с правильным префиксом!
Итак, флаг найден двумя способами!
Уязвимость реализована в следующей части кода:
filename = request.args.get('file', 'access.log')
if '..' in filename or filename.startswith('/'):
abort(403)
if request.headers.get('X-Rewrite-URL'):
filename = request.headers.get('X-Rewrite-URL')Логика тут такая:
.., либо путь начинается с /. Если есть, то возвращаем 403.X-Rewrite-URL, то перезаписываем filename в передаваемое в этом хедере значение.Таким образом, перед нами нарушена защита, потому что, по сути, существующая проверка бесполезна, так как она идёт до извлечения данных из X-Rewrite-URL.
Допустим, вам необходимо создать подобный сервис, но без данной уязвимости (кстати, называется она URL Rewrite Vulnerability), тогда самым очевидным решением будет исправить логику обработки пути следующим образом:
filename = request.args.get('file', 'access.log')
if request.headers.get('X-Rewrite-URL'):
filename = request.headers.get('X-Rewrite-URL')
if '..' in filename or filename.startswith('/'):
abort(403)По-хорошему ещё стоит подправить саму проверку путей. Потому что, например, вместо .. злоумышленник может прописать URL-кодированный %2e%2e%2f. В целом, в рамках этой задачи достаточно исправления логики, но в вашем собственном приложении лучше перестраховаться, исправив и проверку пути, например, так:
filename = request.args.get('file', 'access.log')
if request.headers.get('X-Rewrite-URL'):
filename = request.headers.get('X-Rewrite-URL')
log_dir = os.path.realpath(os.path.join(os.path.dirname(__file__), 'logs'))
full_path = os.path.realpath(os.path.join(log_dir, filename))
if os.path.commonpath([log_dir, full_path]) != log_dir:
abort(403)