Главная / Блог / Как написать write-up для CTF: чеклист

12 мин.00

Как написать write-up для CTF: чеклист

Как написать write-up для CTF: чеклист

Три месяца назад на CTFtime я нашёл write-up к web-задаче, которую не осилил на соревновании. Восемьсот слов, шесть скриншотов без подписей, финальный payload в последней строке без контекста. Полтора часа я реверсил чужой ход мысли — при том что автор, судя по таймлайну, решил таск за пятнадцать минут. На следующий день нашёлся второй write-up к той же задаче: автор описал три тупиковых подхода, объяснил переключение на четвёртый — и через двадцать минут я не только воспроизвёл решение, но и узнал этот класс уязвимости на другом CTF неделю спустя. Разница между двумя текстами — не талант и не стаж, а методология оформления разбора CTF-таска. Ниже — полный гайд по CTF write-up: готовый шаблон, таблица «хороший vs плохой», чеклист перед публикацией и набор инструментов для документирования.

Зачем документировать решение CTF-таска

Write-up — не отчёт для галочки. У него три функции, и каждая окупает тридцать минут на оформление. Подробнее — в нашем руководстве по создание ctf заданий.

Закрепление навыка. Когда описываешь решение текстом, мозг переводит интуитивное ковыряние в осознанный алгоритм. Через месяц без записи от решения остаётся смутное «я что-то делал с JWT». С записью — открываешь свой write-up и вспоминаешь конкретную атаку: подмена alg в заголовке, крафт токена, эскалация до admin. По данным USENIX, участники, работавшие с writeup-сообществами и разборами после соревнований, показывали измеримо более быстрое развитие навыков offensive security по сравнению с теми, кто проходил только изолированные лабораторные упражнения.

Помощь сообществу. По данным CTFtime, ежегодно проходит более 400 соревнований, на каждом — десятки задач. Новичок, застрявший на таске, ищет не академическую лекцию, а конкретный ход мысли: что увидел, что предположил, что сделал, почему сработало. Write-up CTF для новичков закрывает именно эту потребность.

Портфолио. На собеседовании строчка «участвовал в CTF» весит мало. Ссылка на репозиторий с детальными разборами — наглядное доказательство того, как вы мыслите, какими инструментами владеете, как объясняете сложное. Умение чётко изложить механизм эксплуатации уязвимости так, чтобы его понял коллега из смежного отдела, — это пентестерский отчёт, IR-документация и обучение джуниоров в одном флаконе.

Что фиксировать во время соревнования

Главная ошибка — писать write-up по памяти после CTF. Через два часа после финиша вы забудете половину тупиков, порядок действий и тот самый флаг утилиты, который заставил эксплойт заработать. Документировать решение CTF нужно прямо в процессе.

Минимальный набор заметок

Скриншоты. Снимайте экран на каждом значимом шаге: условие задачи, вывод сканера, ответ сервера на payload, момент получения флага. Один лишний скриншот лучше, чем недостающий. Как советуют на learnhacking.io — если давать один совет по note-taking: take LOTS of screenshots.

Команды и их вывод. Копируйте команды из терминала в текстовый файл сразу после выполнения. Не надейтесь на history — он не сохраняет контекст: какой вывод вы увидели, почему набрали следующую команду. Каждая запись — пара «команда + что увидел в ответ».

Тупики. Записывайте то, что НЕ сработало. Это самая ценная часть документации — и именно её чаще всего пропускают. Пометка вроде tried LFI via ../ — WAF blocks double dots, switched to SSRF занимает десять секунд, но спасает чужой вечер. Читатель, идущий по тому же ложному пути, сэкономит часы.

Временные метки. Не с точностью до секунды, но порядок действий важен. «Сначала попробовал X, потом Y, потом вернулся к модифицированному X» — это ход рассуждений, который отличает полезный разбор задания CTF от бесполезного набора скриншотов.

Формат заметок на ходу

Markdown-файл — оптимальный выбор. Открывается в любом редакторе, рендерится на GitHub и большинстве форумов, поддерживает code-блоки и заголовки без дополнительных инструментов. Открываете notes.md перед стартом таска и пишете всё подряд — структуру write-up наведёте при финальном оформлении.

Альтернатива — рукописные заметки на бумаге. Звучит архаично, но для быстрых схем и стрелок «этот параметр влияет на тот» бумага работает быстрее любого редактора. Главное — перенести записи в цифру в течение суток, иначе собственный почерк через неделю превращается в шифротекст.

Структура write-up для новичков: шесть блоков

Шаблон write-up CTF, который набирает upvotes на CTFtime, содержит шесть секций в определённом порядке: метаинформация, разведка, идентификация уязвимости, эксплуатация, тупики, выводы. Разберём каждый блок.

Метаинформация и условие задачи

Первый экран write-up отвечает на пять вопросов: название CTF, название задачи, категория (web / pwn / crypto / forensics / reverse / misc), количество баллов, полный текст условия. Если в условии был файл — укажите формат и размер. Если ссылка на сервис — опишите, что увидели при первом открытии.

Зачем: читатель за десять секунд определяет, релевантен ли ему разбор. Если он ищет web-задачу на 300 баллов, а у вас crypto на 100 — он не тратит время. Это уважение к аудитории.

Разведка и первичный анализ

Опишите первые действия: что запустили, что увидели, какие гипотезы сформулировали. Для web-задачи — просмотр исходного кода страницы, анализ HTTP-заголовков в Burp Suite, перебор директорий. Для pwn — file и checksec на бинарнике. Для forensics — strings, exiftool, разбор в Wireshark.

Ключевой принцип: показывайте не только результат, но и причину действия. Не «запустил gobuster», а «в исходном коде увидел комментарий <!-- /api/debug -->, предположил наличие скрытых эндпоинтов и запустил перебор для подтверждения». Разница — между инструкцией «нажми кнопку» и объяснением «зачем нажимать».

Ход рассуждений и идентификация уязвимости

Ядро write-up — переход от «вижу что-то подозрительное» к «понимаю класс уязвимости». Нашли SQL-инъекцию (Injection, A03:2021 по OWASP Top 10) — объясните, что навело на мысль: нестандартный ответ на одинарную кавычку, ошибка MySQL в теле HTTP-ответа, изменение контента при ' OR 1=1--.

Привязывайте находки к классификациям. Нашли credentials в конфигурационном файле — Credentials In Files (T1552.001, credential-access) по MITRE ATT&CK. Эксплуатировали публично доступное приложение — Exploit Public-Facing Application (T1190, initial-access). Обнаружили SSRF — ссылка на A10:2021 по OWASP Top 10. Такие ссылки не для красоты: они помогают читателю выйти за рамки конкретной задачи и изучить класс атак целиком.

В сильных write-up'ах — например, в разборах задач Tinkoff CTF 2024 на Хабре — авторы показывают промежуточные шаги: декомпиляцию приложения, анализ JavaScript-кода в chrome://inspect, обнаружение нативных методов через @JavascriptInterface. Именно цепочка «увидел → предположил → проверил → подтвердил» делает write-up обучающим материалом, а не сухим отчётом.

Эксплуатация: пошаговый разбор

Каждый шаг — отдельный абзац или пункт списка. Читатель должен воспроизвести всё строка за строкой. Каждая команда — с пояснением нетривиальных флагов. Не голая строка curl -s -X POST -d '...' http://target/api, а пояснение: -s убирает прогресс-бар, -X POST задаёт метод, -d передаёт тело запроса в формате, который ожидает API.

Если писали эксплойт-скрипт — покажите его с комментариями к ключевым строкам. Скрипт без комментариев — это инструмент. Скрипт с комментариями — обучение. От этого зависит, кому полезен ваш write-up: только вам через месяц или всему сообществу.

Критерий качества: мысленно передайте текст человеку с базовыми навыками в категории задачи. Воспроизведёт решение без дополнительных вопросов — блок эксплуатации написан правильно. Остановится с «а что дальше?» — вы пропустили шаг. Как правило, пропускают «очевидные» действия, которые автору кажутся само собой разумеющимися. На практике именно эти пропуски убивают 80% write-up'ов.

Тупики и неудачные попытки

Блок, который 90% авторов выкидывают. А зря. На learnhacking.io формулируют точно: не упоминать тупики — рискуете выглядеть гением или везунчиком. Рассказать ровно столько, чтобы спасти другим время, — вот правильный баланс.

Формат: короткий абзац на каждый тупик. Что попробовали, почему не сработало, что натолкнуло на правильный путь. Пример: «Пробовал XXE через загрузку SVG — сервер парсит SVG, но external entities отключены. Переключился на SSRF (A10:2021 по OWASP Top 10) через параметр url в API загрузки аватара — сервер делал запрос к указанному URL без валидации».

Этот раздел — самая ценная часть для читателя, застрявшего на ложном пути. И одновременно самая полезная для вас: фиксация ошибок закрепляет понимание, почему конкретная техника не работает в конкретных условиях.

Выводы и альтернативные подходы

Финальный блок: что вынесли из задачи, какие техники закрепили, какие инструменты обнаружили. Если знаете альтернативный путь к флагу — опишите кратко. Альтернативы показывают глубину понимания задачи и помогают читателям с другим набором инструментов найти своё решение.

Добавьте ссылки на материалы, которые помогли: статьи, страницы OWASP или MITRE ATT&CK по соответствующей технике, документацию инструментов. Write-up превращается в точку входа для дальнейшего изучения темы, а не в тупик.

Шаблон write-up CTF в Markdown

Готовый скелет — копируйте и заполняйте под конкретный таск:

# [CTF] — [Задача]
**Категория:** Web | **Баллы:** 300 | **Решений:** 42
## Условие
> Полный текст условия. Файлы: app.py (1.2 KB)
## Разведка
Первые наблюдения, инструменты, гипотезы.
## Уязвимость
Класс (OWASP / CWE / MITRE ATT&CK). Ход мысли.
## Эксплуатация
Шаг 1 → вывод → Шаг 2 → вывод. Скрипты с комментариями.
## Тупики
Что не сработало и почему.
## Выводы
Альтернативные пути. Ссылки. Что узнал нового.

Шаблон — каркас, не догма. Web-задача потребует скриншотов Burp Suite и HTTP-обмена. Pwn — листинга из Ghidra с аннотациями. Crypto — математических выкладок. Наращивайте детали под категорию, но не убирайте ни один из шести блоков — каждый несёт отдельную функцию.

Оформление разбора CTF-таска: хороший vs плохой

Сравнение на примере одного шага — обнаружения SQL-инъекции в web-задаче:

Элемент Плохой write-up Хороший write-up
Условие Отсутствует Полный текст + категория + баллы + число решений
Описание шага «Нашёл SQLi в поле логина» «Ввёл кавычку в поле username — сервер вернул 500 с ошибкой MySQL. Предположил error-based SQLi»
Команда sqlmap -u URL --data="user=admin" без пояснений sqlmap -u URL --data="user=admin&pass=x" --technique=E с объяснением: --technique=E ограничивает поиск error-based, потому что WAF блокирует union-запросы
Скриншоты 1 скриншот флага Скриншот ошибки, вывод sqlmap, полученные данные, флаг — каждый с подписью
Тупики Нет «Пробовал union-based: WAF блокирует UNION. Переключился на error-based через extractvalue()»
Классификация Нет «SQL Injection, CWE-89, A03:2021 OWASP Top 10»
Выводы Нет «WAF пропускал error-based при блокировке union. На будущее: при WAF сразу тестировать нестандартные техники»

Левый столбец — заметка, которую через месяц не поймёт даже автор. Правый — пошаговый разбор уязвимости, работающий как обучающий материал.

Частая ошибка промежуточного уровня — write-up со скриншотами и командами, но без рассуждений. Читатель видит последовательность действий, но не понимает логику переходов. Одно предложение «переключился на error-based, потому что заметил SQL-ошибку в ответе при ручной проверке» превращает набор шагов в методологию написания write-up, которую можно перенести на другую задачу.

Чеклист write-up перед публикацией

Прогоните текст по этому списку до нажатия «Опубликовать»:

Полнота: - Условие задачи приведено целиком — текст или скриншот - Указаны категория, баллы, название CTF, число решивших - Каждая команда содержит пояснение нетривиальных флагов - Описан хотя бы один тупик или неудачная попытка - Скриншоты подписаны — читатель понимает контекст без догадок

Воспроизводимость: - Читатель повторит решение по тексту от начала до флага - Скрипты содержат комментарии к ключевым строкам - Версии инструментов указаны, если влияют на работоспособность (pwntools, Python 2 vs 3) - Финальный payload проверен повторно — нет copy-paste ошибок

Читабельность: - Текст разбит на блоки с подзаголовками - Код оформлен в code-блоках с указанием языка (python, bash, sql) - Абзацы не длиннее пяти-шести строк - Скриншоты читаемы на мобильном экране

Этика: - Write-up не публикуется к задачам активных соревнований - Правила платформы соблюдены (Hack The Box — только retired-машины) - Тиммейты упомянуты, если помогали в решении - Флаг не указан в открытом виде, если задача может быть переиспользована

Шестнадцать пунктов. Первые разы проверка займёт десять-пятнадцать минут. После третьего write-up — станет автоматической.

Инструменты для документирования решения CTF

Редактор. VS Code с расширением Markdown Preview Enhanced или Obsidian — live preview и подсветка синтаксиса. Для быстрых заметок во время CTF хватит nano или встроенного блокнота. Главное — писать сразу, а не «потом, когда будет время» (спойлер: «потом» не наступает).

Скриншоты. На Linux — flameshot: выделение области, аннотации стрелками и текстом прямо при захвате. На macOS — Cmd+Shift+4. На Windows — Win+Shift+S или Greenshot. Сохраняйте снимки в папку рядом с notes.md, чтобы вставлять относительные пути без возни с абсолютными ссылками.

Логирование терминала. Команда script session.log записывает всё происходящее в терминале, включая вывод команд. Завершение — через exit. Burp Suite хранит историю HTTP-запросов: экспортируйте нужные через Save item в формате XML — пригодится при описании пошаговой эксплуатации.

Организация файлов. Структура папок: CTF-Name/Task-Name/notes.md, CTF-Name/Task-Name/screenshots/, CTF-Name/Task-Name/exploits/. Рецепты CyberChef сохраняйте как URL — они содержат полную цепочку преобразований и не требуют отдельного экспорта. Для сложных задач с chained exploitation диаграммы Mermaid рендерятся прямо в Markdown на GitHub и в Obsidian — визуализация attack chain упрощает восприятие.

Где и как публиковать write-up

CTFtime. Крупнейшая площадка с профильной аудиторией. Write-up привязывается к конкретному соревнованию, участники находят его через карточку CTF. Для видимости в международном сообществе — первый выбор.

GitHub. Полный контроль над структурой и историей изменений. Минус — нет органического трафика: ваш репозиторий никто не найдёт, если не дать ссылку. Плюс — репозиторий с write-up'ами работает как портфолио: рекрутер видит не только текст, но и регулярность публикаций.

Специализированные форумы. Платформы вроде Codeby дают доступ к тысячам читателей из ИБ-сообщества. Публикация генерирует обратную связь: вопросы, уточнения, альтернативные решения от других участников. Для первых write-up'ов живая обратная связь ценнее молчаливого GitHub-репозитория.

Личный блог. Jekyll, Hugo, Notion — подходит при регулярных публикациях. Полный контроль над подачей, но требует усилий на поддержку.

Независимо от площадки — публикуйте write-up в течение 48 часов после окончания CTF. Через неделю мотивация падает, детали забываются, текст либо не выходит, либо получается поверхностным. Правило 48 часов — единственная дисциплинарная привычка, которая отделяет тех, кто пишет write-up'ы, от тех, кто «собирается написать».

Навык документирования переносится напрямую в рабочие задачи: пентестерский отчёт для заказчика — по сути тот же write-up с бизнес-контекстом и рекомендациями по устранению. IR-отчёт после инцидента — та же структура: хронология, находки, выводы. Чем раньше начнёте отрабатывать техническое описание эксплуатации на CTF-задачах, тем меньше времени уйдёт на адаптацию, когда этот навык потребуется за деньги.

Наблюдение, которое стоит проговорить прямо: большинство CTF-игроков, утверждающих, что «CTF бесполезен для карьеры», не ведут write-up'ы. Они решают таск, получают дофамин от флага и переходят к следующему. Через месяц от решения остаётся «я что-то делал с injection, кажется». Игрок, потративший тридцать минут на запись, через тот же месяц открывает свой write-up и восстанавливает всю цепочку. Одно соревнование — радикально разный выхлоп.

И есть неудобная правда, которую в CTF-сообществе не принято озвучивать: основная причина, по которой люди не пишут write-up'ы, — не лень и не нехватка времени. Это страх. Страх, что решение выглядит коряво рядом с элегантным эксплойтом от топовой команды. Страх, что кто-то заметит: четыре часа ушло на задачу в 100 баллов. Этот страх дорого обходится — он стоит каждого инсайта, который мог быть сохранён, каждого рекрутера, которого мог бы впечатлить живой разбор, каждого будущего-вас, которому понадобится именно эта техника.

Пишите «некрасивый» write-up. Пишите write-up, в котором пять первых попыток провалились. Пишите разбор задачи для новичков, за которую неловко. Навык складывается именно из таких публикаций, а не из идеальных. Если хочешь не просто writeup, а пройти всю атаку самому — на WAPT есть лаба на каждый кейс.

🚀 Хочешь закрепить на практике? Реши задачи по теме на HackerLab — категория «pentest-machines».

Поделиться

0 комментариев

Пожалуйста, войдите, чтобы оставить комментарий.

Загрузка комментариев...

Читайте также

Nmap для начинающих: сканируем сеть в CTF

12 мин.

4

Nmap для начинающих: сканируем сеть в CTF

Трёхфазная стратегия nmap: типы скана, NSE-скрипты, тайминг T0-T5 и обход IDS. Пошаговый гайд с командами для CTF — без потери сервисов.

8 НОЯБРЬ, 2026

Race condition эксплуатация в CTF через Turbo Intruder

16 мин.

4

Race condition эксплуатация в CTF через Turbo Intruder

Три сценария Turbo Intruder для race condition в CTF: limit overrun, file upload race, multi-endpoint. Чек-лист дебага когда гонка не срабатывает. CVE-2022-4037, CVE-2022-24800.

5 НОЯБРЬ, 2026

SSTI уязвимость: эксплуатация Jinja2 и Twig в CTF

12 мин.

4

SSTI уязвимость: эксплуатация Jinja2 и Twig в CTF

Пошаговая эксплуатация SSTI в CTF: определение движка, MRO-цепочка, обход WAF, RCE через Jinja2 и Twig. Готовые payload'ы с объяснением механики.

5 НОЯБРЬ, 2026