
На прошлом CTF наша команда получила forensics-задание на 300 очков: файл весом 12 МБ без расширения, без описания, без подсказок. Половина команды рефлекторно загрузила его в Ghidra. Другая половина набрала file mystery.bin и через восемь минут сдала флаг. Файл оказался PNG-изображением с ZIP-архивом, приклеенным к хвосту. Вся «обратная разработка» свелась к binwalk -e.
Четыре утилиты — file, strings, hexdump и binwalk — закрывают подавляющее большинство forensics-задач уровня easy–medium. Ни дизассемблер, ни знание ассемблера для этого не нужны. Дальше — конкретный workflow: в каком порядке запускать, что искать в выводе и где новички теряют время.
file, strings, hexdump, xxd предустановлены на любом Linux-дистрибутиве. binwalk ставится через apt install binwalk. PyPI-пакет устарел — текущая ветка (v3, Rust) живёт на GitHub (ReFirmLabs/binwalk). Старые версии содержат уязвимости path traversal и symlink following (GHSA-3cm8-v4mc-gppg, GHSA-8m3f-g62j-3vx8) — при использовании -e/-eM на недоверенных CTF-файлах запускайте извлечение в изолированном каталоге или контейнере. exiftool — через apt install libimage-exiftool-perlПолучили файл без расширения. Первое действие — file mystery. Утилита читает первые байты и сверяет их с базой сигнатур libmagic. Эти начальные байты называются magic bytes (magic numbers) — уникальные последовательности, по которым определяется формат файла независимо от расширения.
На CTF авторы задач регулярно подменяют расширения: файл flag.jpg на самом деле — ZIP-архив, а readme.txt — ELF-бинарник. Команда file игнорирует расширение полностью — она работает только с содержимым. Набор magic bytes, которые стоит знать наизусть:
| Magic bytes (hex) | Формат | Что покажет file |
|---|---|---|
| 89 50 4E 47 | PNG | PNG image data |
| FF D8 FF | JPEG | JPEG image data |
| 50 4B 03 04 | ZIP | Zip archive data |
| 7F 45 4C 46 | ELF | ELF 64-bit LSB executable |
| 4D 5A | PE (exe/dll) | PE32 executable |
| 25 50 44 46 | PDF document | |
| 1F 8B | gzip | gzip compressed data |
| 52 61 72 21 | RAR | RAR archive data |
Согласно CTF Field Guide от Trail of Bits, распознавание форматов по magic bytes — один из трёх ключевых навыков для forensics-категории наряду со скриптингом на Python и знанием кодировок. Этот список покрывает 80% файлов из forensics-задач. Остальные 20% — специализированные форматы (дампы памяти, сетевые захваты, образы дисков), magic bytes которых проще искать в справочнике List of file signatures на Wikipedia.
На CTF вам подсунут файл, который file определит как data — сигнатуру распознать не удалось. Типичная причина: автор таска перезаписал первые байты. Файл технически повреждён, но структура дальше сохранена.
Приём, который спасает: file -k mystery (флаг --keep-going) заставляет утилиту не останавливаться на первом совпадении. Если файл — полиглот (одновременно валидный PDF и ZIP), -k покажет оба типа. Polyglot-файлы — один из типичных приёмов в forensics, и без -k вы увидите только первый слой.
Ограничения file. Утилита анализирует только заголовок. Если к PNG-изображению дописан ZIP-архив в хвост, file покажет лишь PNG image data — о ZIP вы не узнаете. Для обнаружения вложенных файлов нужен binwalk. file использует эвристики, которые легко обмануть: вставьте правильные magic bytes в начало случайных данных, и утилита уверенно объявит мусор «PNG-изображением».
Место в цепочке анализа. file — шаг разведки. После него вы знаете, с чем имеете дело: изображение, архив, исполняемый файл, дамп. Это определяет выбор следующего инструмента.
Статус инструмента. file входит в стандартный пакет утилит Linux (file-5.x). Обновляется вместе с дистрибутивом, отдельная установка не нужна.
strings извлекает из файла все последовательности печатных символов длиной от 4 байт (по умолчанию). Самый тупой и одновременно самый результативный способ найти флаг: strings mystery | grep -i flag. На easy-тасках это работает чаще, чем хотелось бы признавать.
В реальных CTF-задачах флаг может лежать прямо в открытом виде — особенно на уровнях easy. Авторы тасков прячут его среди тысяч строк бинарного мусора, рассчитывая, что новичок не догадается запустить strings. На более сложных уровнях флаг закодирован в base64 или XOR, но strings покажет закодированную строку, а дальше CyberChef или echo "..." | base64 -d сделают остальное.
Полезные вариации, которые стоит держать в голове:
strings -o mystery — выводит смещение (offset) каждой строки. Потом можно прыгнуть на это смещение в hex-редакторе или вытащить блок через ddstrings -n 8 mystery — строки от 8 символов, отсекает мусорные короткие совпадения типа IHDR или sRGBstrings -el mystery — ищет строки в UTF-16 Little Endian. Без этого флага вы пропустите данные из PE-файлов и документов Office, где строки хранятся в 16-битной кодировкеstrings mystery | grep -E '(flag|ctf|key|pass|secret|{)' — фильтр по типичным маркерам флаговТипичная ошибка новичков: запускать strings без grep и пытаться прочитать весь вывод глазами. На файле в 10 МБ утилита выдаст десятки тысяч строк. Всегда фильтруйте: grep, sort -u, head, tail. Также проверяйте строки, похожие на base64 — ровные блоки из букв, цифр, символов +, / и = на конце. Паттерн strings mystery | grep -E '^[A-Za-z0-9+/]{20,}={0,2}$' выловит таких кандидатов.
Отдельный класс задач — Windows-бинарники и документы Office. В PE-файлах строковые литералы хранятся в UTF-16 LE, и стандартный strings (который ищет ASCII) их не видит. strings -el mystery.exe решает проблему: флаг -e l переключает на 16-битную кодировку Little Endian. Для Big Endian (редко, но бывает) — strings -eb.
В терминах MITRE ATT&CK работа со strings напрямую связана с техникой Deobfuscate/Decode Files or Information (T1140, Defense Evasion): в реальных инцидентах аналитики извлекают индикаторы компрометации из подозрительных бинарников теми же командами, что и CTF-игрок — разница в том, что вместо флага ищут URL C2-серверов, ключи шифрования и имена файлов.
Ограничения. strings не находит ничего, что не является последовательностью печатных символов. Зашифрованные данные, сжатые блоки, стеганография в младших битах пикселей — всё это невидимо. Утилита не понимает структуру файла: она не отличает строку из секции .rodata ELF-файла от случайного совпадения в блоке сжатых данных.
Когда file и strings не дали результата, пора смотреть на сырые байты. Два инструмента делают одно и то же разными способами: hexdump -C и xxd.
hexdump -C mystery | head -n 20 покажет первые 20 строк файла: 16 байт в hex-формате плюс ASCII-представление справа. Базовый навык для любого forensics-задания.
Что конкретно искать в hex-дампе:
file сказал data, открываете hex-дамп и видите 89 50 4E 47 — это PNG с повреждённым первым байтом50 4B 03 04 — внутри основного файла спрятан ZIP-архив. Нашли вложение без binwalk00 00 00 00 — padding. Нули перед magic bytes другого формата — признак склейки файловhexdump -C печатаются символы. Иногда флаг виден прямо там, разбитый на фрагменты по 16 символовxxd выдаёт аналогичный результат, но с другим форматом. Главное преимущество — обратная конвертация: xxd -r превращает hex-дамп обратно в бинарный файл. Для ремонта повреждённых заголовков это критично.
Типичная CTF-задача: вам дают PNG-файл, который не открывается. Смотрим заголовок:
$ hexdump -C corrupted.png | head -n 4
00000000 00 50 4e 47 0d 0a 1a 0a 00 00 00 0d 49 48 44 52 |.PNG........IHDR|
00000010 00 00 07 80 00 00 04 38 08 06 00 00 00 e8 d1 66 |.......8.......f|
00000020 00 00 00 01 73 52 47 42 00 ae ce 1c e9 00 00 00 |....sRGB........|
00000030 00 04 67 41 4d 41 00 00 b1 8f 0b fc 61 05 00 00 |..gAMA......a...|
Первый байт 00 вместо 89. Стандартные magic bytes PNG — 89 50 4E 47 0D 0A 1A 0A. Автор таска обнулил первый байт. Ремонт: xxd corrupted.png > fix.hex, в текстовом редакторе заменяете 00 на 89 в нужной позиции, затем xxd -r fix.hex > repaired.png. Открываете — и видите изображение с флагом.
Для простых случаев (один-два байта) быстрее через printf '\x89' | dd of=corrupted.png bs=1 seek=0 count=1 conv=notrunc — прямая запись байта по смещению без промежуточного дампа.
Когда hexdump эффективнее binwalk. При работе с кастомными бинарными форматами. Если файл — не стандартный архив или изображение, а самодельная структура данных (частый приём на medium–hard), binwalk ничего не найдёт, потому что в его базе нет сигнатур этого формата. Остаётся ручной анализ hex-дампа: определяете повторяющиеся структуры, вычисляете формат заголовков и длины блоков. Подход из блога Pentest Partners по анализу прошивок Zyxel напрямую применим к CTF: находите паттерн <тип> <длина> <данные>, вычисляете оффсеты и вырезаете блоки через dd if=mystery of=extracted bs=1 skip=<offset> count=<length>.
binwalk — главное оружие для задач типа «файл-матрёшка». Он сканирует бинарный файл целиком, ищет сигнатуры известных форматов на каждом смещении и показывает, что найдено и где.
Базовый запуск — binwalk mystery.bin. Пример вывода:
DECIMAL HEXADECIMAL DESCRIPTION
--------------------------------------------------
0 0x0 PNG image, 1920 x 1080, 8-bit/color RGBA
24576 0x6000 Zip archive data, at least v2.0 to extract
24602 0x601A End of Zip archive, footer length: 22
PNG начинается с нулевого смещения, а на 0x6000 — ZIP-архив. Автор таска приклеил архив к хвосту картинки. Программы просмотра PNG игнорируют данные после маркера IEND. Но binwalk находит всё, что имеет известную сигнатуру.
Для автоматического извлечения: binwalk -e mystery.bin. Создастся директория _mystery.bin.extracted/ с отдельными файлами. Для рекурсивного извлечения многоуровневых матрёшек: binwalk -eM mystery.bin (флаг -M — matryoshka mode). На практике я предпочитаю извлекать уровень за уровнем: -eM иногда создаёт десятки вложенных директорий из-за ложных срабатываний, и потом разгребать это хозяйство — то ещё удовольствие.
Ложные срабатывания — главная боль binwalk. Согласно CTF Field Guide от Trail of Bits и блогу Pentest Partners, утилита генерирует много false positives. Она ищет паттерны байтов, совпадающие с сигнатурами, но не проверяет, действительно ли по этому смещению находится валидный файл. Типичная картина: binwalk находит 15 «gzip compressed data» внутри одного файла, из которых 12 — мусор.
Как фильтровать false positives:
binwalk нашёл «gzip» на смещении 0x1234, а следующая запись на 0x1238 — это 4 байта, слишком мало для реального gzip-потокаfile. Если file подтверждает тип — блок реальныйbinwalk безоговорочно. Каждую находку проверяйте вручнуюEntropy анализ файлов. binwalk -E mystery.bin строит график энтропии. Высокая энтропия (близко к 1.0) — сжатые или зашифрованные данные. Низкая — текст, неструктурированные данные, padding нулями. Резкий скачок энтропии на определённом смещении — вероятная граница между разными блоками. На CTF entropy-анализ помогает обнаружить зашифрованные фрагменты, которые binwalk не может распознать по сигнатурам: зашифрованный блок выглядит как «ровная полка» на максимуме энтропии.
Статус инструмента. binwalk создан Крейгом Хеффнером, репозиторий на GitHub (ReFirmLabs/binwalk). Текущая ветка (v3) переписана на Rust. Для CTF стабильная версия из apt работает нормально, но при извлечении (-e) недоверенных файлов — изолированный каталог или контейнер, из-за тех самых path traversal в старых версиях.
Конкретная последовательность для каждого forensics-задания. Не запоминайте — распечатайте и держите рядом с терминалом первые десять соревнований. Потом она войдёт в мышечную память.
Шаг 1. Идентификация. file mystery — определяем тип. Если в ответе data — сразу к шагу 3.
Шаг 2. Быстрый поиск. strings mystery | grep -iE '(flag|ctf|{|key|pass)' — ищем флаг в лоб. На easy-тасках срабатывает обидно часто.
Шаг 3. Заголовок. hexdump -C mystery | head -n 5 — смотрим magic bytes. Заголовок повреждён — чиним через xxd и xxd -r.
Шаг 4. Метаданные. exiftool mystery — для изображений, PDF, документов Office. Флаг может сидеть в поле Comment, Author или Description. Авторы тасков регулярно прячут флаги или подсказки в EXIF.
Шаг 5. Вложенные файлы. binwalk mystery — сканируем на вложения. Есть находки — binwalk -e mystery для извлечения. Каждый извлечённый файл проверяем рекурсивно с шага 1.
Шаг 6. Хвост файла. hexdump -C mystery | tail -n 20 — смотрим конец. Данные после маркера конца формата (IEND для PNG, FFD9 для JPEG) — потенциальный payload.
Шаг 7. Полный strings. strings -n 10 mystery | sort -u | less — если предыдущие шаги не дали результата, просматриваем все уникальные строки от 10 символов. Ищем URL, пути файловой системы, base64-блоки, hex-строки.
Шаг 8. Энтропия. binwalk -E mystery — ищем аномалии. Зашифрованные и сжатые блоки выделяются характерной «полкой» наверху графика.
Если все восемь шагов не дали зацепки — задача требует другого подхода: стеганографии (zsteg, steghide), анализа сетевого трафика (Wireshark), дампа памяти (Volatility) или полноценного реверса.
Зная инструменты, нужно понимать, что именно авторы тасков прячут и каким способом. Типичные паттерны forensics-категории:
Склейка файлов (appended data). Самый частый приём на easy–medium. К валидному изображению дописывают ZIP, RAR или второе изображение. binwalk находит это за секунду. В терминах MITRE ATT&CK — техника Steganography (T1027.003, Defense Evasion): обфускация данных внутри легитимных файлов для обхода детектирования.
Повреждённые заголовки. Первые 2–8 байт заменены нулями или случайными значениями. file говорит data, но hexdump показывает стандартную структуру PNG/ZIP/ELF дальше. Чиним magic bytes — получаем рабочий файл.
Стеганография в LSB. Данные закодированы в младших битах пикселей изображения. strings и binwalk тут бесполезны — нужны zsteg для PNG или steghide для JPEG. Подсказка: если file показывает изображение, binwalk не находит вложений, strings молчит, а задание помечено как stego — пробуйте zsteg -a mystery.png. В ATT&CK это T1027.003 (Steganography, Defense Evasion).
Base64 и hex-кодирование. Флаг закодирован и лежит как строка. strings находит её, но она выглядит как ZmxhZ3t0ZXN0fQ==. Декодируете: echo 'ZmxhZ3t0ZXN0fQ==' | base64 -d — готово. Прямое моделирование техники T1140 (Deobfuscate/Decode Files or Information).
Данные в EXIF. Флаг записан в метаданные изображения. exiftool mystery.jpg | grep -i comment — проверка за секунду.
Файлы в slack-пространстве. В образах файловых систем данные спрятаны в неиспользуемых блоках. Тут нужны autopsy, sleuthkit, foremost. Но первый шаг — всё тот же binwalk image.dd.
Все описанные утилиты покрывают фазу triage — первичный осмотр и извлечение данных, лежащих на поверхности. Вот где они перестают работать и что использовать вместо:
| Инструмент | Сильная сторона | Ограничение | Когда не работает | Альтернатива |
|---|---|---|---|---|
| file | Мгновенная идентификация формата | Анализирует только заголовок | Повреждённые magic bytes, кастомные форматы | hexdump + ручной анализ |
| strings | Быстрый поиск текста | Не видит сжатые/зашифрованные данные | Флаг зашифрован XOR/AES | CyberChef, xortool |
| hexdump/xxd | Полный контроль над байтами | Требует ручного анализа | Файл >100 МБ, сложная структура | Python-скрипт |
| binwalk | Автоматический поиск вложений | Много false positives | Кастомные форматы без сигнатур | Entropy-анализ + dd |
| exiftool | Метаданные за секунду | Только стандартные форматы | Файл без метаданных | strings + grep |
Правило 15 минут. Если за 15 минут полный прогон file + strings + hexdump + binwalk + exiftool не дал зацепки — переключайтесь. Либо задача требует реверса (Ghidra, Binary Ninja), либо стеганографии (zsteg, steghide, stegsolve), либо анализа в рантайме (ltrace, strace, GDB). Продолжать крутить одни и те же пять команд с разными флагами — потеря времени на соревновании.
Ещё один момент, о котором молчат русскоязычные руководства: все пять инструментов — пассивные. Они читают файл, но не запускают его. Это принципиально безопасно: можете анализировать подозрительный бинарник через strings и hexdump без риска выполнить вредоносный код. В Incident Response это свойство критично — артефакт изучается без компрометации рабочей станции аналитика.
В CTF-сообществе за file, strings, hexdump, binwalk и exiftool закрепилось неформальное название «первый эшелон». Работа во «втором эшелоне» — Wireshark для PCAP, Volatility для дампов памяти, Ghidra для бинарников — начинается только когда первый эшелон не дал результата. Разница между CTF-игроком с 20 и 200 решёнными тасками не в знании продвинутых инструментов, а в скорости прогона первого эшелона и умении правильно интерпретировать вывод.
За семь лет CTF-практики я убедился: подавляющее большинство новичков тратят время не на ту фазу. Они сразу лезут в дизассемблер, потому что это выглядит круто, а прогон strings | grep flag кажется слишком примитивным. Но примитивный — не значит неэффективный. На каждом соревновании, в котором я участвовал, минимум одна задача forensics решалась парой команд из первого эшелона. Иногда на 200–300 очков.
Обратная сторона тоже есть: первый эшелон создаёт ложное чувство контроля. Находите строку, похожую на base64, декодируете — мусор. Или binwalk рапортует о пяти вложенных gzip, а ни один не распаковывается. Навык не в знании команд, а в интерпретации вывода: отличить реальную находку от шума, понять, когда инструмент выдаёт false positive, и вовремя переключиться на ручной разбор. Этот навык нарабатывается только практикой — решайте таски на PicoCTF, CyberDefenders, разбирайте writeup'ы с CTFtime, повторяя каждую команду у себя в терминале. Через пятьдесят–сто решённых заданий вы перестанете думать «какую команду запустить» и начнёте думать «что автор таска хочет, чтобы я НЕ заметил». Это и есть переход от инструментальной грамотности к forensics-мышлению.
🚀 Хочешь закрепить на практике? Реши задачи по теме на HackerLab — категория «pentest-machines».
0 комментариев
Пожалуйста, войдите, чтобы оставить комментарий.
Загрузка комментариев...