Главная / Блог / Как написать write-up CTF: шаблон, структура и ошибки, которые убивают портфолио

12 мин.00

Как написать write-up CTF: шаблон, структура и ошибки, которые убивают портфолио

Как написать write-up CTF: шаблон, структура и ошибки, которые убивают портфолио

Как написать write-up CTF: шаблон, структура и ошибки, которые убивают портфолио

По данным CTFtime.org, ежегодно проходит более 400 CTF-соревнований. После каждого в сеть выливаются тысячи write-up. По-настоящему полезных — единицы. Остальные — стена кода без контекста, три строчки «нашёл SQLi, получил флаг» или десять страниц с фиксацией каждого клика мыши. За два года активной игры я написал больше 30 разборов и отревьюил сотни чужих. Ошибки повторяются с пугающей стабильностью. Эта статья — конкретный шаблон write-up CTF с разбором типичных провалов и объяснением, почему оформление отчёта CTF напрямую влияет на то, позовут ли вас на собеседование.

Зачем писать write-up после каждого CTF

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

Три причины тратить время на документирование:

Закрепление навыков. Когда описываете шаги решения, мозг переключается из режима «угадал» в режим «понял». По опыту многих CTF-игроков, разбор чужих write-up и написание своих ускоряют рост в наступательной безопасности куда сильнее, чем решение задач без рефлексии.

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

Портфолио пентестера CTF. Главная причина, которую новички недооценивают. Работодатель на джуниор-позиции хочет видеть не строчку «участвовал в CTF» в резюме, а реальный пример вашего мышления. Write-up на GitHub или Codeby — это рабочий код, только в текстовом формате. Подробнее — в разделе про собеседования.

Структура write-up CTF: шаблон, который работает

Хороший write-up — не литературное произведение. Это технический документ с фиксированной структурой, где каждый блок решает конкретную задачу. Ниже — готовый шаблон для write-up CTF, который можно копировать и адаптировать под любую категорию: web, crypto, pwn, forensics или reverse.

Обязательные элементы каждого write-up

По рекомендациям pequalsnp-team (одного из самых цитируемых CTF-гайдов по оформлению), минимальный набор информации в write-up:

  • Название CTF и дата проведения — через год без этого невозможно найти нужный разбор
  • Название задачи и категория (Web, Pwn, Crypto, Forensics, Reverse, Misc)
  • Количество очков — показывает сложность для контекста
  • Описание задачи — оригинальный текст от организаторов, лучше скриншотом
  • Скриншоты ключевых этапов — без них write-up теряет основную часть ценности
  • Код и payload'ы с комментариями — голый скрипт без объяснений бесполезен
  • Флаг или указание формата, если challenge может быть переиспользован

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

Готовый markdown-шаблон для write-up CTF

# [Название CTF] — [Название задачи]
**Категория:** Web | **Очки:** 200 | **Дата:** 2025-06-15
## Описание
> Текст задания от организаторов (цитата или скриншот)
## Разведка
Первые наблюдения, сканирование, анализ исходников
## Тупиковые ветки
Что попробовали и почему не сработало
## Эксплуатация
Пошаговый путь от обнаружения уязвимости до флага
## Флаг
`flag{example}` — итог и краткие выводы

Для платформ с полноценными машинами (HackTheBox, TryHackMe) добавьте разделы «Первоначальный доступ» (initial access) и «Повышение привилегий» (privilege escalation) — они зеркалят этапы реальной цепочки атаки.

Хотите выделиться в портфолио — укажите используемые техники по MITRE ATT&CK. Разведка маппится на System Information Discovery (T1082, Discovery) и File and Directory Discovery (T1083, Discovery). Эксплуатация веб-приложения — Exploit Public-Facing Application (T1190, Initial Access). Извлечение паролей из конфигов — Credentials In Files (T1552.001, Credential Access). Такая привязка показывает рекрутеру, что вы понимаете контекст шире, чем «собрал флаг».

Методология написания write-up: от заметок до публикации

Заметки во время CTF — фундамент хорошего write-up

Главная ошибка новичков — надеяться на память. После 12-часового марафона вы не вспомните порядок команд и тем более не восстановите логику решения. Заметки ведутся прямо во время игры.

Что фиксировать:

  1. Скриншоты — всего. Экран задачи, каждый ответ сервера, каждый вывод инструмента. Лучше 50 лишних скриншотов, чем потом писать «тут был вывод nmap, но я его не сохранил». На Linux — Flameshot (горячая клавиша, моментальный снимок в файл), на Windows — Win+Shift+S или Lightshot.
  2. Команды и payload'ы — копируйте в markdown-файл. Не полагайтесь на bash_history: она не сохраняет контекст, обрезается и не покажет, какой из 40 вариантов payload'а сработал.
  3. Логи инструментов — Burp Suite хранит историю запросов, Wireshark позволяет экспортировать pcap. Сохраняйте всё в директорию конкретного таска.
  4. Гипотезы и мысли — короткие пометки вида «похоже на SSTI, проверить Jinja2» или «base64, потом rot13?». Из этих пометок потом получаются разделы «Разведка» и «Тупиковые ветки».

Структура директории для каждого соревнования:

CTF_Name_2025/
├── challenge_name/
│   ├── notes.md          # заметки во время игры
│   ├── screenshots/      # все скриншоты
│   ├── files/            # скачанные файлы задачи
│   ├── exploit/          # ваши скрипты
│   └── writeup.md        # финальный write-up

Сборка write-up после соревнования

Идеальное время для написания — первые 24-48 часов после CTF. Дальше детали стираются. Процесс:

  1. Откройте заметки и скриншоты. Разложите скриншоты в хронологическом порядке — это скелет write-up.
  2. Заполните шаблон сверху вниз. Начните с мета-информации (название, категория, очки), затем вставьте описание задачи.
  3. Раздел «Разведка» стройте как нарратив: «Открыл страницу — увидел форму авторизации — посмотрел исходники — нашёл комментарий в HTML». Каждый шаг — один абзац + скриншот.
  4. «Тупиковые ветки» — коротко, 2-3 предложения на каждую гипотезу. Что попробовали, почему отбросили.
  5. «Эксплуатация» — самый подробный раздел. Каждая команда, каждый payload с пояснением, почему именно этот. Если использовали скрипт — приведите его с комментариями к ключевым строкам.
  6. Прочитайте финальный текст глазами человека, который видит задачу впервые. Если хотя бы один шаг непонятен без контекста — допишите.

Совет от learnhacking.io: если challenge-среда ещё доступна, прогоните шаги заново. Это ловит пропущенные этапы и copy-paste ошибки в payload'ах — бич многих write-up.

Оформление отчёта CTF: инструменты и площадки

Требования к окружению

Для написания и публикации write-up достаточно минимального набора:

  • ОС: любая (Windows / Linux / macOS)
  • RAM: 4 ГБ для редактора и браузера; 8 ГБ, если параллельно работаете с VM
  • Редактор Markdown: VS Code с расширением Markdown Preview Enhanced, Obsidian или Typora
  • Скриншоты: Flameshot (Linux), Lightshot (Windows/macOS) или стандартные средства ОС
  • Git: для версионирования и публикации на GitHub
  • Pandoc + TeXLive (опционально): генерация PDF из markdown — полезно при отклике на вакансию

Для конвертации markdown в PDF через Pandoc:

pandoc writeup.md -o writeup.pdf \
  --from markdown --pdf-engine=xelatex \
  --template eisvogel --listings

Шаблон Eisvogel даёт чистый профессиональный PDF с подсветкой синтаксиса. Установка: скачать с GitHub-репозитория eisvogel и положить в ~/.pandoc/templates/. Для защиты PDF паролем — утилита pdftk. Это актуально при публикации write-up для активных машин HackTheBox, где открытые решения нарушают правила платформы.

Выбор площадки для публикации write-up

Куда публиковать — зависит от цели:

Площадка Аудитория Обратная связь Ценность для портфолио Контроль
GitHub Рекрутеры, команды Минимальная Высокая — рекрутер видит первым Полный
Codeby CTF-сообщество RU Комментарии, рейтинг Средняя — профиль на платформе Частичный
Habr Широкая IT-аудитория Комментарии, карма Средняя — профиль автора Частичный
CTFtime CTF-команды мира Рейтинг write-up Высокая для командного рейтинга Минимальный

Для старта рекомендую гибридный подход: пишете write-up в markdown, храните в Git-репозитории на GitHub (ваше портфолио, которое рекрутер видит первым) и дублируете на одну из площадок для обратной связи. Codeby — для русскоязычной аудитории, которая реагирует именно на CTF-контент. CTFtime — для международной видимости.

Репозиторий с write-up на GitHub должен иметь понятный README с оглавлением по CTF и категориям. Рекрутер не будет разбираться в хаосе из 50 файлов без навигации.

Типичные ошибки в write-up и как их избежать

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

Ошибка 1: Write-up без скриншотов. Текстовое описание «запустил nmap, увидел открытый порт 80» — это конспект для себя, не write-up. Скриншот вывода nmap, скриншот веб-страницы, скриншот ответа Burp Suite — каждый визуальный элемент экономит читателю минуты на реконструкцию контекста. Опирайтесь на скриншоты, а текст тратьте на объяснение того, что не видно на картинке.

Ошибка 2: Код без комментариев. Три десятка строк Python-скрипта без единого пояснения — приглашение закрыть вкладку. Достаточно одного комментария на каждые 3-5 строк: что делает этот блок, почему выбран такой подход. Если скрипт содержит hardcoded значения (смещения, magic bytes, конкретные строки) — объясните, откуда они взялись.

Ошибка 3: Прыжок от задачи к флагу. Классика: «Скачал файл — запустил strings — нашёл флаг». Где анализ? Где объяснение, почему strings был правильным выбором? Что проверяли до этого? Промежуточные шаги — самая ценная часть write-up. Читатель хочет понять ход мышления, а не получить рецепт.

Ошибка 4: Избыточная детализация без иерархии. Противоположная крайность — документировать каждое движение. «Открыл Firefox. Ввёл URL. Нажал Enter. Страница загрузилась.» Это шум. Детализация нужна на ключевых развилках: где приняли решение, где сработал payload, где изменилось поведение системы. Остальное — обзорно.

Ошибка 5: Нет секции «Тупиковые ветки». Если write-up читается как «я сразу всё понял и с первой попытки взял флаг» — ему не верят. И правильно делают. Честное описание ошибочных гипотез показывает процесс мышления и помогает другим избежать тех же тупиков. Хороший пример: автор последовательно показывает разведку, описывает каждую проверенную гипотезу, приводит код с объяснениями — и только после нескольких неудачных экспериментов собирает рабочий payload.

Ошибка 6: Битые ссылки и потерянные файлы. Ссылка на скрипт с pastebin, удалённый через месяц. Скриншоты на хостинге, который закрылся. Решение простое: храните всё в одном репозитории. Файлы задачи, скрипты, скриншоты — в одной директории рядом с write-up.

Ошибка 7: Нет мета-информации. Без названия CTF, даты и категории write-up невозможно найти через поиск. Через год вы сами не поймёте, к какому соревнованию он относится. По чеклисту pequalsnp-team: CTF name, challenge name, category, points, date — обязательный минимум в заголовке.

Документирование эксплойта CTF: как описать цепочку атаки

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

Шаг 1: Обнаружение точки входа. Что навело на уязвимость? Конкретный параметр в URL, подозрительный заголовок ответа, строка в исходном коде. Скриншот и пояснение — что именно привлекло внимание.

Шаг 2: Идентификация класса уязвимости. Назовите тип: SQL Injection, XSS, SSRF, SSTI, path traversal. Если уязвимость входит в OWASP Top 10 (Injection — A03:2021, SSRF — A10:2021), упомяните это. Для рекрутера в пентесте такая привязка показывает, что вы понимаете стандарты индустрии, а не просто «что-то нашли».

Шаг 3: Подтверждение уязвимости (PoC). Минимальный payload, доказывающий наличие проблемы. Для SQL Injection — проверка через ' OR 1=1 --. Для SSTI — тег {{7*7}} в поле ввода. Приведите запрос и ответ сервера в виде скриншота.

Шаг 4: Разработка эксплойта. Переход от PoC к получению флага. Если писали скрипт — приведите его с комментариями. Если использовали инструмент (sqlmap, Burp Intruder, pwntools) — укажите конкретные параметры запуска и объясните выбор. Почему sqlmap, а не ручная инъекция? Почему Intruder, а не Repeater? Эти решения — часть вашего мышления.

Шаг 5: Получение флага. Финальная команда или действие, скриншот с подтверждением.

Для полноценных машин цепочка длиннее и ближе к реальному пентесту. Начальный доступ через эксплуатацию публичного сервиса — Exploit Public-Facing Application (T1190, Initial Access). Получение шелла на Linux — Unix Shell (T1059.004, Execution). Поиск учётных данных в конфигурационных файлах — Credentials In Files (T1552.001, Credential Access). Повышение привилегий — отдельный подраздел с описанием конкретного вектора (SUID-бинарь? cron-задача? sudo-мисконфигурация?). Каждый этап в write-up оформляется как отдельный блок с заголовком, скриншотом и пояснением.

Такая структура один-в-один маппится на формат пентестерского отчёта. Работодатель, открывший ваш write-up, видит не просто решение задачки — он видит готовый стиль мышления и документирования, который можно завтра применить в рабочем проекте.

Write-up для собеседования: что видит работодатель

Когда тимлид смотрит на GitHub-профиль кандидата на джуниор-позицию, write-up — первое, что открывается. Решение «читать дальше или закрыть» принимается за 30 секунд.

Что оценивается:

Структурированность мышления. Хаотичный write-up — сигнал, что и отчёт для заказчика будет хаотичным. Чёткая последовательность (разведка → анализ → эксплуатация → результат) напрямую маппится на формат пентестерского отчёта.

Способность объяснять. Пентестер, который находит уязвимость, но не может описать её для разработчика, — проблема. Write-up проверяет этот навык: можете ли вы объяснить техническую деталь так, чтобы понял человек, не решавший конкретно эту задачу?

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

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

Конкретная рекомендация: создайте репозиторий ctf-writeups с README, где разборы сгруппированы по категориям (Web, Crypto, Pwn, Forensics) и отсортированы по дате. Ссылку — в резюме, LinkedIn и сопроводительное письмо. Это ваше портфолио пентестера в чистом виде: не сертификаты, не строчки в резюме, а реальные примеры работы.

Большинство CTF-игроков тратят десятки часов на решение задач и ноль минут на документирование — и потом удивляются, что на собеседовании нечего показать. Я видел десятки таких ситуаций при ревью кандидатов: человек прошёл 50 машин на HackTheBox, но не написал ни одного write-up. Вся работа — невидима для работодателя.

Навык писать отчёт не менее важен, чем навык ломать. Рынок переполнен людьми, которые умеют запускать инструменты. Тех, кто умеет понятно объяснить, что нашёл и почему это критично, — дефицит. Write-up тренирует именно этот навык, причём бесплатно.

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

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

Поделиться

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

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

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