
На недавнем CTF-турнире задание выглядело элементарным: форма логина, два поля, кнопка «Войти». Автоматический сканер прошёл все эндпоинты и вернул ноль findings. Ноль. Я открыл Burp Repeater, отправил запрос авторизации и увидел в заголовке Set-Cookie значение role=dXNlcg==. Скопировал в Decoder, декодировал base64 — получилось user. Закодировал admin обратно, подставил в следующий запрос — флаг пришёл в ответе через четыре секунды. Вся «сложная» задача свелась к замене одного значения в куке. Сканер молчал, а ответ лежал в одном заголовке. Такие уязвимости сессий в web CTF встречаются на каждом втором турнире, и единственный надёжный способ их обнаружить — ручной анализ аутентификации через Burp Repeater.
Прежде чем что-то ломать, стоит разобраться, что именно авторы задач закладывают как уязвимость. В CTF на веб ошибки аутентификации и управления сессиями — один из самых частых векторов. Они попадают в категорию A01:2021 — Broken Access Control по классификации OWASP, где 94% протестированных приложений содержали ту или иную форму нарушения контроля доступа. Подробнее — в нашем подробном разборе создание ctf заданий.
Для тех кто в танке — коротко про основы. Когда вы вводите логин и пароль, сервер создаёт сессию — запись о том, что конкретный пользователь прошёл проверку. Чтобы не запрашивать пароль при каждом клике, сервер выдаёт токен — уникальную строку, подтверждающую личность. Токен чаще всего живёт в куке (cookie) — фрагменте данных, который браузер автоматически прикрепляет к каждому запросу на тот же домен.
В терминах MITRE ATT&CK кража или подделка этого токена описывается несколькими техниками: - Steal Web Session Cookie (T1539, Credential Access) — перехват существующей куки сессии - Forge Web Credentials: Web Cookies (T1606.001, Credential Access) — создание поддельного токена - Web Session Cookie (T1550.004, Lateral Movement) — использование украденной куки для доступа к другим ресурсам - Browser Session Hijacking (T1185, Collection) — перехват активной сессии браузера
Авторы CTF-заданий намеренно закладывают в механизмы аутентификации типичные ошибки:
session=1, session=2 вместо криптографически стойкой строкиrole=user или role=dXNlcg== (base64)secret или алгоритмом noneЗадача — найти ту точку, где доверие к клиентским данным превышает разумное. Burp Repeater позволяет это сделать методично, без угадывания.
Repeater — вкладка в Burp Suite, где можно вручную отправлять HTTP-запросы, менять любые параметры и сразу видеть ответ сервера. В отличие от Proxy (который перехватывает запросы «на лету»), Repeater позволяет гонять один запрос десятки раз, каждый раз меняя одну переменную. Для анализа HTTP-заголовков в Burp Repeater это и есть ключевое преимущество: изолируете одно изменение и наблюдаете за реакцией.
Правая панель Repeater показывает ответ сервера. Для CTF-задач на аутентификацию фокусируйтесь на двух местах:
В заголовках ответа ищите Set-Cookie с токеном сессии, заголовки безопасности (X-Frame-Options, Content-Security-Policy), нестандартные заголовки. Иногда флаг прячется в кастомном заголовке вроде X-Flag — да, бывает настолько прямолинейно.
В теле ответа — HTML с подсказками в комментариях, JSON с полями прав доступа, redirect на /admin или /dashboard.
Нюанс, на котором спотыкаются новички: пока Intercept включён, каждый запрос из браузера ждёт нажатия Forward. Перешли к работе в Repeater — выключите Intercept, иначе браузер зависнет. Repeater работает независимо.
Подмена значений cookie — самый распространённый тип уязвимости аутентификации в CTF-задачах начального и среднего уровня. Сервер хранит информацию о правах пользователя прямо в куке, а единственная «защита» — кодирование (не шифрование!). Такое кодирование разворачивается за секунды.
Увидев в ответе Set-Cookie: session=eyJ1c2VyIjoiZ3Vlc3QifQ==, первым делом определите формат:
+, /, один или два = на конце. Декодируется во вкладке Decoder: вставляете строку, жмёте Decode as → Base64%20, %3D вместо пробелов и спецсимволов61646d696e (это admin)xxxxx.yyyyy.zzzzz (разбирается отдельно)Можно не гадать: вставьте строку в Decoder и нажмите Smart decode — Burp сам попробует определить формат и покажет результат.
После логина сервер выставил куку role=dXNlcg==. Порядок действий:
dXNlcg== → Decoder → Decode as Base64 → результат: useradmin → Encode as Base64 → результат: YWRtaW4=Cookie: role=dXNlcg==Cookie: role=YWRtaW4=Если ответ изменился — появилась админ-панель, другой контент, флаг — уязвимость подтверждена. Сервер декодирует base64 и доверяет результату, не проверяя целостность. Классический Broken Access Control (OWASP A01:2021) и Forge Web Credentials: Web Cookies (T1606.001) по MITRE ATT&CK.
Не ограничивайтесь одной подменой. Пробуйте разные значения: admin, administrator, root, superuser, числовые ID (0, 1, -1). Авторы CTF-заданий иногда закладывают нестандартные роли — мне попадалось god и debug.
Заголовок Set-Cookie содержит не только значение, но и атрибуты безопасности. В CTF их отсутствие — часто подсказка:
Если нет HttpOnly — куку можно прочитать через JavaScript. Автор задания намекает: ищите XSS, крадите сессию через document.cookie. Нет Secure — кука передаётся по HTTP без шифрования, на реальном пентесте это перехват через MitM. SameSite = None или отсутствует — возможны CSRF-атаки.
Видите Set-Cookie: session=abc123; Path=/ без единого флага безопасности? Перед вами сразу несколько потенциальных векторов. Красный ковёр, по сути.
JWT (JSON Web Token) — формат токена из трёх частей, разделённых точками: заголовок (header), полезная нагрузка (payload) и подпись (signature). Каждая часть закодирована в base64url. Взлом JWT в CTF заданиях — одна из популярных категорий, потому что ошибки в реализации встречаются повсеместно.
Токен eyJhbGciOiJIUzI1NiJ9.eyJ1c2VyIjoiZ3Vlc3QifQ.XXXXX разбирается по частям. Берёте первую часть до точки, декодируете в Decoder как Base64:
# Заголовок (первая часть после base64url decode):
{"alg":"HS256"}
# Payload (вторая часть после base64url decode):
{"user":"guest","role":"viewer"}
Заголовок указывает алгоритм подписи. Payload содержит данные пользователя — именно их вы хотите изменить. Третья часть — подпись, которая «гарантирует» целостность. Гарантия работает только при корректной реализации. А вот с этим в CTF-задачах (да и в продакшене, чего уж) бывает плохо.
Часть JWT-библиотек поддерживает алгоритм none — токен без подписи. Если серверная сторона не ограничивает допустимые алгоритмы белым списком, атака выглядит так:
"alg":"HS256" на "alg":"none""user":"guest" → "user":"admin"+ на -, / на _, уберите =)новый_заголовок.новый_payload. — третья часть пустая, но точка остаётсяCookie: token=... или Authorization: Bearer ...), нажмите SendСервер вернул данные администратора? Уязвимость подтверждена. Это Cryptographic Failures (OWASP A02:2021): сервер не валидирует алгоритм подписи.
Когда алгоритм HS256 и атака none не сработала, попробуйте другой вектор: слабый секретный ключ. Подпись HMAC вычисляется с секретом, и если ключ словарный (secret, password, 123456, changeme), его можно подобрать оффлайн. Берёте токен, прогоняете список распространённых паролей, проверяете совпадение подписи. Но первый шаг всегда один — через Repeater обнаружить, что сервер использует JWT, и разобрать его структуру.
В CTF нередко встречается подсказка прямо в исходном коде страницы или в нестандартном заголовке ответа — секрет или его часть. Проверяйте HTML-комментарии (<!-- secret: ... -->) и все заголовки ответа. Авторы задач любят прятать ключи на видном месте.
Не все уязвимости прячутся в куках. Иногда сервер принимает решение об авторизации на основе HTTP-заголовков, которые клиент полностью контролирует. Поиск уязвимостей в HTTP-заголовках — отдельное направление, которое русскоязычные ресурсы почти не покрывают.
Веб-приложение за обратным прокси определяет IP клиента по заголовку X-Forwarded-For. Если приложение доверяет этому заголовку без проверки — ну, тут всё просто:
GET /admin HTTP/1.1
Host: target.ctf
X-Forwarded-For: 127.0.0.1
Cookie: session=ваш_токен
Если админ-панель доступна только с 127.0.0.1 и сервер берёт IP из заголовка — вы внутри. Это связка Exploit Public-Facing Application (T1190, Initial Access) с Broken Access Control. Пробуйте не только 127.0.0.1, но и 10.0.0.1, 192.168.1.1, ::1 (IPv6 loopback). На одном CTF сработал именно IPv6.
Некоторые фреймворки поддерживают заголовки X-Original-URL или X-Rewrite-URL, которые переопределяют путь запроса на бэкенде. Типичный сценарий: фронт-сервер блокирует /admin по правилу URL, но бэкенд читает путь из заголовка. Отправляете GET / с заголовком X-Original-URL: /admin — фронт пропускает, бэкенд обрабатывает как запрос к защищённому ресурсу.
В Repeater это проверяется за секунды: добавили заголовок, нажали Send, сравнили ответ с предыдущим.
Редко, но в CTF попадается: сервер проверяет заголовок Referer, чтобы убедиться, что запрос пришёл с «правильной» страницы. Если эндпоинт /admin/delete-user проверяет, что Referer содержит /admin/dashboard — добавьте этот заголовок в Repeater, и ограничение снято.
Общий принцип для всех трёх случаев: отправляете оригинальный запрос, получаете отказ (403 Forbidden), добавляете или меняете один заголовок, отправляете снова, сравниваете ответы. Систематический перебор известных заголовков через Repeater — метод, который закрывает целый класс задач.
Session fixation — атака, при которой злоумышленник заранее фиксирует идентификатор сессии. После того как жертва логинится с этим идентификатором, он становится валидным — и атакующий использует его для доступа.
В CTF-задачах проверка выглядит так:
1. Перехватите ответ сервера до аутентификации — обратите внимание на Set-Cookie: session=abc123
2. Выполните логин, отправьте запрос через Repeater
3. Проверьте, изменилось ли значение session в Set-Cookie после успешного входа
4. Если значение осталось abc123 — session fixation подтверждена
Корректная реализация: после успешной аутентификации сервер обязан сгенерировать новый идентификатор сессии и инвалидировать старый. Если этого не происходит, любой, кто знал старый токен, получает доступ к аутентифицированной сессии. Просто и больно.
Методика через Repeater (описана в документации PortSwigger по тестированию привилегий):
admin:admin или учётные данные из подсказки), пройдитесь по админскому функционалу — все запросы попадут в Proxy → HTTP Historysession=...)/admin/users, /admin/panel), отправьте его в RepeaterСервер вернул 200 OK с содержимым админ-панели вместо 401 или 403? Контроль доступа сломан. Сервер проверяет валидность сессии, но не проверяет привилегии пользователя для конкретного эндпоинта.
Для автоматизации на большом количестве эндпоинтов подходит расширение Autorize из BApp Store — оно дублирует каждый запрос с cookie другого пользователя и подсвечивает расхождения. Но начинать стоит руками через Repeater, чтобы понять механику до подключения автоматизации. Сначала руками — потом автоматика.
Вот алгоритм, который я применяю к каждой CTF-задаче на аутентификацию. Порядок действий одинаковый для задач любого уровня — различается глубина анализа на каждом шаге.
Делай раз: перехвати и прочитай. Включите Proxy Intercept, откройте целевое приложение во встроенном браузере Burp. Зарегистрируйтесь (если есть форма регистрации), залогиньтесь. Перейдите в Proxy → HTTP History, найдите запрос логина (обычно POST на /login или /auth). Отправьте его в Repeater. Прочитайте каждый заголовок ответа: Set-Cookie, X-Powered-By, Server, любые нестандартные заголовки. Декодируйте все значения cookie через Decoder — пробуйте base64, URL decode, hex. Если значение содержит точки и похоже на xxx.yyy.zzz — это JWT, разбирайте по частям.
Делай два: модифицируй и сравни. Измените одно значение в куке: user → admin, id=5 → id=1, role=0 → role=1. Нажмите Send. Сравните ответы: изменился ли статус-код? Тело? Длина? Появились ли новые заголовки? Если изменений нет — пробуйте другие значения. Если токен JWT — попробуйте атаку algorithm none и модификацию payload. Добавьте заголовки: X-Forwarded-For: 127.0.0.1, X-Original-URL: /admin, Referer: /admin. Каждый раз меняйте только одну вещь — иначе не поймёте, что именно сработало.
Делай три: подтверди и зафиксируй. Если ответ изменился — повторите запрос два-три раза для подтверждения стабильности. Определите, какое именно изменение привело к результату. В CTF ищите флаг в теле ответа, заголовках или значениях cookie. На реальном пентесте документируйте: эндпоинт, параметр, значение до и после, классификацию по OWASP и MITRE ATT&CK.
Этот workflow закрывает большинство задач уровня Easy и Medium на CTF-платформах. Суть: не сканер нашёл уязвимость, а вы руками через Burp Repeater изменили один параметр и увидели разницу в поведении сервера.
«Меняю куку, но ничего не происходит» — проверьте, что отправляете запрос к защищённому эндпоинту. Подмена cookie в запросе к главной странице может не дать видимого результата. Отправляйте к /admin, /dashboard, /api/users — туда, где разница в правах проявляется.
«JWT не принимается после модификации» — если изменили payload, но оставили старую подпись с алгоритмом HS256, сервер отклонит токен. Убедитесь, что поменяли алгоритм на none и убрали подпись, либо подобрали секретный ключ. Частая ошибка: забыть убрать символы = из base64url (в URL-safe base64 паддинг не используется).
«Не вижу cookie в Repeater» — cookie выставляется через Set-Cookie в ответе сервера (правая панель), а передаётся через Cookie в запросе (левая панель). Новички путают направление. В Repeater вы модифицируете запрос слева и читаете результат справа.
«Пробовал всё — ничего не работает» — расширьте поиск за пределы cookie. Иногда токен передаётся в URL (?token=), в скрытом поле формы (<input type="hidden">), в заголовке Authorization: Bearer ... или даже в теле POST-запроса как JSON. Repeater позволяет модифицировать любой из этих вариантов одинаково.
«Burp показывает HTTPS-ошибку» — для перехвата HTTPS-трафика браузер должен доверять сертификату Burp. Откройте http://burpsuite во встроенном браузере, скачайте CA-сертификат и установите его. Без этого Burp не сможет проксировать зашифрованные запросы, а большинство CTF-платформ работают по HTTPS.
Отдельный момент, который упускают даже опытные участники: проверяйте все запросы, а не только POST к /login. Иногда уязвимость прячется в GET-запросе к API, в WebSocket-соединении или в запросе на загрузку «статического» ресурса, который на самом деле динамический. Burp Repeater для пентеста веб-приложений хорош именно тем, что вы контролируете каждый байт запроса.
Большинство новичков в CTF тратят первые месяцы на освоение автоматических инструментов — sqlmap, nikto, dirsearch — и упускают главное: навык ручного чтения HTTP-трафика. Автоматика обнаружит SQL-инъекцию в GET-параметре, но не заметит, что role=dXNlcg== в куке — это base64 от user. Восемь из десяти CTF-задач на аутентификацию решаются не эксплойтом, а внимательностью в Repeater: прочитал заголовки, декодировал значение, подменил один байт, отправил — флаг.
Сканер — мультипликатор навыка. Если навык ручного анализа нулевой, мультипликатор тоже нулевой. Начинайте с ручной работы, поймите, почему конкретная подмена сработала, — и только после этого подключайте автоматизацию.
Прогноз: через год-два CTF-задачи на аутентификацию усложнятся. Чистых base64-кук станет меньше, зато вырастет доля задач с многослойными токенами, race conditions в сессиях, OAuth-потоками с некорректным state-параметром. Фундамент останется прежним: Repeater, внимание к заголовкам, понимание того, что именно сервер проверяет — а что нет. Если хочешь не прыгать между разрозненными writeup'ами, а пройти базу от сетей до веб-уязвимостей системно — на codeby.school есть IB Basics, который закрывает этот фундамент за пару месяцев.
🚀 Хочешь закрепить на практике? Реши задачи по теме на HackerLab — категория «web».
0 комментариев
Пожалуйста, войдите, чтобы оставить комментарий.
Загрузка комментариев...