Главная / Блог / Стеганография CTF: чеклист инструментов поиска

14 мин.00

Стеганография CTF: чеклист инструментов поиска

Стеганография CTF: чеклист инструментов поиска

За полтора года соревнований на CTFtime — picoCTF, HackTheBox CTF, DownUnderCTF — я вывел одно рабочее правило: порядок запуска инструментов стеганоанализа важнее знания самих инструментов. Команда, которая начинает с steghide на PNG (он PNG не поддерживает в принципе), теряет десять минут на ошибку и ещё двадцать на разбирательство. Команда, которая стартует с file → exiftool → strings → формат-специфичный инструмент, закрывает таск до того, как первая допьёт кофе.

Этот алгоритм покрывает подавляющее большинство стего-тасков лёгкого и среднего уровня на forensics CTF тасках. Оставшиеся — Python-скрипты и ручной разбор битовых плоскостей. Ниже — полная последовательность с командами, таблицей совместимости и разбором типичных ловушек.

Базовый анализ: три команды перед любым инструментом стеганоанализа

Любой таск на поиск спрятанных данных начинается одинаково. Не с Stegsolve, не с zsteg, не с steghide — с трёх универсальных команд, которые работают на любом формате.

Первая — file. Расширение файла в forensics CTF заданиях врёт через раз: challenge.txt окажется PNG, image.jpg — ZIP-архивом. Как описывает Trail of Bits CTF Field Guide: «in a CTF, part of the game is to identify the file ourselves, using a heuristic approach.» Команда file challenge.txt определяет реальный тип по магическим байтам в заголовке. Если ответ — PNG image data, 800 x 600, 8-bit/color RGBA, а расширение .txt — перед вами картинка с подменённым расширением. Две секунды на проверку экономят двадцать минут мучений с неподходящим инструментом.

Дополнение для PNG: pngcheck -v challenge.png проверяет целостность чанков. Если авторы таска модифицировали заголовок, изменили размеры в IHDR или дописали данные после IEND — pngcheck это покажет. В отличие от file, которая читает только первые байты, pngcheck валидирует весь файл и ругается на каждый битый чанк.

Вторая — exiftool. Метаданные — классическое место для сокрытия флагов или подсказок. Comment, Author, Description, GPS-координаты, пользовательские XMP-теги — всё вытаскивается одной командой: exiftool challenge.png. На простых тасках Base64-строка в поле Comment — стабильный паттерн. Нюанс: exiftool извлекает не только стандартные EXIF-поля, но и текстовые чанки PNG (tEXt, iTXt, zTXt), IPTC-блоки и даже миниатюры из JPEG. Windows через «Свойства файла» покажет жалкую часть — только CLI покрывает всё. GPS-координаты из EXIF иногда ведут к названию города, которое и оказывается флагом.

Третья — strings с фильтром. strings challenge.png | grep -iE "flag|ctf|key|{|}" вытаскивает все текстовые строки из бинарного файла и фильтрует по паттернам флагов. Тривиально, но на лёгких и средних тасках это решает задачу чаще, чем хотелось бы признавать — флаг просто дописан в конец файла, спрятан в текстовом чанке или валяется в нестандартном поле метаданных. Параметр -n 6 ограничит вывод строками длиннее 6 символов и уберёт мусор.

На этих трёх шагах заканчивается заметная часть стего-тасков. Нет результата — копаем дальше.

Binwalk и извлечение вложенных файлов

Следующий обязательный шаг — проверка на вложенные файлы. File carving, как описывает Trail of Bits — обнаружение файла внутри другого файла и его извлечение. В CTF это стандартный приём: ZIP-архив внутри PNG, второе изображение после маркера IEND, исполняемый файл в аудиозаписи. Матрёшка, короче.

binwalk challenge.png сканирует бинарный файл на известные сигнатуры и показывает все совпадения с их смещениями. Если в выводе есть Zip archive data или JPEG image data на ненулевом смещении — внутри спрятан другой файл. Извлечение одной командой: binwalk -e challenge.png, результат попадёт в папку _challenge.png.extracted.

Но binwalk — штука нервная. Он ищет сигнатуры по смещениям и регулярно генерирует ложные срабатывания. Сжатые данные внутри IDAT-чанков PNG или DCT-блоки JPEG случайно совпадают с заголовками ZIP или TIFF. Как отмечают на форуме Codeby: инструменту не стоит слепо верить, он просматривает только сигнатуры начала. Каждый извлечённый файл обязательно проверяйте через file и пробуйте открыть. Если «архив» не открывается — это фантом.

Если binwalk молчит — foremost -i challenge.png -o output/. Foremost ищет пары header/footer для восстановления файлов и иногда вытаскивает то, что binwalk пропускает. Для ручного извлечения фрагмента с известного смещения: dd if=challenge.png of=extracted.zip bs=1 skip=524288 скопирует данные начиная с байта 524288. Учтите: bs=1 означает побайтовое копирование и на больших файлах работает мучительно медленно; для ускорения: dd if=challenge.png of=extracted.zip bs=4096 iflag=skip_bytes skip=524288.

Какой инструмент для какого формата: таблица совместимости

Главная ошибка новичков в стеганографии CTF — путать инструменты между форматами. steghide на PNG не работает. zsteg на JPEG бесполезен. Таблица ниже — не декорация, а рабочий справочник:

Инструмент Форматы Метод анализа Когда НЕ подходит
zsteg PNG, BMP LSB всех каналов и битовых плоскостей JPEG, аудио, любой lossy-формат
steghide JPEG, BMP, WAV, AU Парольная стеганография (графовый алгоритм) PNG — не поддерживает
stegseek JPEG, BMP, WAV, AU Брутфорс пароля steghide Без словаря бесполезен
Stegsolve Любые изображения Визуальный анализ битовых плоскостей Нет CLI, требует Java GUI
StegOnline Любые изображения Веб-аналог Stegsolve Ограничение на размер файла
binwalk Любые файлы File carving по сигнатурам Ложные срабатывания на сжатых данных
foremost Любые файлы File carving по header/footer Медленнее binwalk
exiftool Любые файлы Метаданные Не анализирует пиксели и семплы
Sonic Visualiser WAV, MP3, FLAC Спектрограмма Только визуальный анализ
Audacity WAV, MP3, FLAC Спектрограмма Менее тонкая настройка спектра
Aperi'Solve Изображения Агрегатор: strings, zsteg, binwalk, exiftool Онлайн, зависит от интернета

Алгоритм ветвления по типу файла:

  • PNG/BMP → zsteg → Stegsolve/StegOnline → Python-скрипт для ручного LSB
  • JPEG → steghide (пустой пароль → слова из описания → stegseek с rockyou.txt) → binwalk
  • WAV/AU → спектрограмма в Sonic Visualiser → steghide → LSB-анализ
  • GIF → разбить на кадры: convert challenge.gif frame_%03d.png (ImageMagick), анализировать каждый как PNG
  • MP3 → exiftool на метаданные → конвертировать в WAV через ffmpeg -i challenge.mp3 challenge.wav → анализ WAV

LSB стеганография изображений: zsteg и визуальный анализ

LSB (Least Significant Bit) — самый распространённый метод стеганографии в CTF-задачах. Младший бит каждого цветового компонента пикселя заменяется битом скрытого сообщения. Визуально разница в один уровень из 256 неразличима для глаза, но данные полностью сохраняются в младших битах. Красивый фантик — а внутри секрет.

zsteg — инструмент на Ruby, который автоматически перебирает десятки комбинаций каналов, битовых порядков и направлений обхода. Установка: gem install zsteg. Базовый запуск и пример вывода:

$ zsteg challenge.png
b1,r,lsb,xy   .. text: "FLAG{hidden_in_plain_sight}"
b1,rgb,lsb,xy  .. file: Zip archive data
b2,g,msb,xy   .. text: "\x00\x00\x00"

Каждая строка — комбинация параметров. b1,r,lsb,xy означает: первый бит (b1), красный канал (r), порядок от младшего бита (lsb), построчное чтение (xy). Если в выводе появился читаемый текст или файловая сигнатура (PK для ZIP, \x89PNG для PNG) — скрытые данные найдены. Для исчерпывающей проверки: zsteg -a challenge.png перебирает все комбинации, включая обход по столбцам (yx), отдельные битовые плоскости альфа-канала, MSB-порядок. Работает дольше, зато покрывает экзотику.

Ограничение zsteg: только PNG и BMP. Для JPEG не подходит принципиально — lossy-сжатие (DCT) разрушает данные в младших битах. Если дали JPEG с подозрением на LSB — автор таска использовал что-то вроде jsteg, и zsteg этого не увидит.

Stegsolve — Java-приложение для визуального анализа по отдельным битовым плоскостям. Запуск: java -jar Stegsolve.jar. Открываете файл, листаете стрелками между режимами: Red plane 0, Green plane 0, Blue plane 0, Alpha plane 0 и далее. Скрытое изображение, QR-код или текст проявляются как контрастный рисунок на одной из плоскостей. Режим «Data Extract» позволяет вручную задать каналы и порядок для извлечения данных в файл.

Веб-альтернатива — StegOnline (georgeom.net/StegOnline). Те же функции в браузере: битовые плоскости, извлечение LSB, гистограммы. Спасает, когда нет GUI-окружения или Java не установлена. Из каталога CTF-инструментов на GitHub: «big stego tool, upload image and modify/extract data.»

Отдельный момент — альфа-канал. В PNG с прозрачностью (RGBA) данные могут быть спрятаны в альфа-плоскости, которую большинство инструментов не проверяют по умолчанию. zsteg -a проверяет альфа-канал, но в Stegsolve нужно явно пролистать до Alpha plane 0–7. На тасках среднего уровня это встречающийся вектор — и пропустить его обидно.

Steghide: как использовать парольную стеганографию JPEG

Steghide — утилита, встраивающая данные в JPEG, BMP, WAV и AU с шифрованием паролем. Последний релиз — версия 0.5.1, 2003 год. Двадцать с лишним лет без обновлений, но входит в стандартные репозитории Kali и Debian и остаётся де-факто стандартом для CTF-задач с парольной стеганографией. Альтернатив по-прежнему нет — такой вот долгожитель.

Порядок действий на JPEG-таске:

  1. steghide info challenge.jpg — проверить наличие встроенных данных; при запросе пароля нажать Enter (пустая строка).
  2. steghide extract -sf challenge.jpg -p "" — попробовать пустой пароль. Срабатывает на простых тасках чаще, чем вы думаете.
  3. Если задание содержит хинт в описании или в имени файла — подставить слова как пароль.
  4. Если ничего не помогает — stegseek со словарём: stegseek challenge.jpg /usr/share/wordlists/rockyou.txt. Stegseek — форк steghide, заточенный под перебор. Проходит rockyou.txt (14 миллионов записей) за секунды, тогда как встроенный перебор steghide занял бы часы. На Kali: apt install stegseek, отдельно — .deb из GitHub-репозитория RickdeJager/stegseek.

Критическое ограничение: steghide не поддерживает PNG. Это архитектурное ограничение, а не баг. Сообщение the file format of "challenge.png" is not supported означает именно то, что написано. Для PNG — zsteg или Stegsolve. Steghide использует графовый алгоритм выбора позиций встраивания: для JPEG модифицируются DCT-коэффициенты, для BMP — младшие биты пиксельных данных, для WAV/AU — младшие биты семплов. Поэтому zsteg не обнаружит steghide-вставку — принципиально разные методы.

Стеганография в аудио файлах: спектрограммы и скрытые сигналы

Аудио-стеганография встречается реже изображений, но стабильно всплывает в категориях forensics и misc на CTF. Три основных вектора: визуальные сообщения в спектрограмме, LSB в WAV-семплах и специализированные кодировки.

Спектрограмма аудио: текст и QR-коды в частотном спектре

Самый зрелищный приём — спрятать текст или картинку в спектрограмме аудиофайла. Ухо слышит звуки определённых частот, но не «видит» их распределение по спектру. Авторы тасков генерируют аудио, визуализация которого на спектрограмме проявляет текст флага, QR-код или координаты.

Sonic Visualiser — специализированное приложение для анализа аудио. Откройте файл, добавьте слой спектрограммы через Pane → Add Spectrogram. Настройки: FFT size 1024 или 2048, Window Type — Hann. Если скрытое сообщение есть — оно проявится как рисунок на частотном спектре.

Audacity — более распространённый вариант. Откройте файл, переключите отображение дорожки с Waveform на Spectrogram (выпадающее меню слева от трека). Через Spectrogram Settings: FFT Size 2048–4096, диапазон частот до 22 кГц. Если сообщение спрятано в высокочастотной области — стандартные настройки его обрежут, так что расширение диапазона обязательно.

Morse, SSTV, DTMF: кодировки за пределами стандартных инструментов

На тасках среднего и высокого уровня встречаются аудиокодировки, которые не связаны с классической стеганографией, но попадают в ту же CTF-категорию:

  • Morse — азбука Морзе в аудио. На спектрограмме видны характерные точки и тире. Декодировать можно онлайн-инструментами или на слух (если терпения хватит).
  • SSTV (Slow-Scan Television) — передача изображений через звук, метод радиолюбителей. Программа qsstv на Linux декодирует аудиозапись обратно в картинку. Характерный звук SSTV ни с чем не спутаешь — нарастающее чередование тонов, будто модем из 90-х пытается выйти на связь.
  • DTMF — тональные сигналы телефонных кнопок. Каждая кнопка — комбинация двух частот. Онлайн-декодеры DTMF восстанавливают набранный номер или текст из записи.

Эти кодировки стандартные стего-инструменты не находят. Если steghide info, спектрограмма и LSB-анализ ничего не дали — просто послушайте файл. Morse, SSTV, DTMF опознаются на слух за секунды.

LSB в WAV-файлах

WAV — формат без сжатия, семплы хранятся как есть. Принцип аналогичен изображениям: младшие биты семплов заменяются битами скрытого сообщения. Steghide работает с WAV, но через собственный алгоритм. Для классической LSB стеганографии в аудио есть WavSteg. Альтернативно — Python-скрипт с модулем wave для чтения семплов напрямую и извлечения младших битов.

Python-скрипт для нестандартных задач стеганоанализа

Когда автоматика молчит — остаётся Python. Pillow позволяет читать пиксели напрямую и визуализировать любую битовую плоскость. Ниже — скрипт визуализации LSB красного канала: каждый пиксель нового изображения становится чёрным (бит = 0) или белым (бит = 1) в зависимости от младшего бита оригинала.

from PIL import Image

img = Image.open("challenge.png")
out = Image.new("RGB", img.size)
for y in range(img.height):
    for x in range(img.width):
        r, g, b = img.getpixel((x, y))[:3]
        val = (r & 1) * 255  # вытаскиваем младший бит
        out.putpixel((x, y), (val, val, val))
out.save("lsb_red.png")

Если в lsb_red.png виден текст, QR-код или контрастный рисунок — данные спрятаны в LSB красного канала. Для других каналов замените r на g или b. Для второго бита: (r >> 1) & 1. Для альфа-канала на RGBA: img.getpixel((x, y))[3].

На продвинутых тасках данные распределяются по нескольким каналам, шифруются XOR-маской или записываются в нестандартном порядке — по столбцам, по спирали, через каждый N-й пиксель. Тут zsteg бессилен, а скрипт на Python — единственный путь. Типичный паттерн: прочитать биты из нужных каналов, собрать в байты, декодировать как ASCII или сохранить как файл. Попробуйте модифицировать скрипт под обход по столбцам (yx вместо xy) — на удивление часто это и есть разгадка.

Aperi'Solve и онлайн-инструменты поиска скрытых данных

Aperi'Solve (aperisolve.com) — онлайн-агрегатор, который за один запрос запускает strings, exiftool, binwalk, foremost, zsteg и ещё несколько утилит на загруженном файле. По описанию автора: «it gather about 9 or 10 tools at the same time.» На соревновании, когда каждая минута на счету, это экономит время на переключение между утилитами и покрывает базовый анализ одним действием. Ограничение: размер файла и зависимость от интернета. На серьёзных тасках всё равно придётся работать локально.

Ещё один полезный веб-инструмент — CyberChef (gchq.github.io/CyberChef). Не стего-инструмент напрямую, но незаменим для декодирования того, что вы нашли: Base64, hex, XOR, ROT13 и десятки других преобразований. Операция «Magic» автоматически определяет формат и декодирует — особенно спасает, когда из LSB вытащили строку непонятного вида и не ясно, что с ней делать.

Ошибки, которые стоят часов на forensics CTF тасках

Пять ошибок, которые я вижу на каждом соревновании:

1. steghide на PNG. Steghide не поддерживает PNG — архитектурное ограничение. file format not supported означает именно то, что написано. Для PNG — zsteg. Для JPEG — steghide. Путаница между этими двумя — ошибка номер один.

2. Слепое доверие binwalk. Случайное совпадение байт с заголовком ZIP или JPEG в сжатых IDAT-чанках PNG — обычное дело. Каждый извлечённый файл проверяйте через file и пробуйте открыть: если «архив» не открывается — это фантом, не тратьте на него время.

3. Пропуск метаданных. Comment в EXIF, GPS-координаты как название города, Base64 в Description — на простых тасках флаг сидит именно здесь. exiftool обязателен до запуска специализированных инструментов стеганоанализа.

4. Один инструмент на всё. zsteg не найдёт steghide-вставку. steghide не обнаружит LSB стеганографию в PNG. binwalk не увидит данные, распределённые по битовым плоскостям. У каждого инструмента свой метод и свой формат — поэтому таблица совместимости выше не для красоты.

5. Игнорирование звукового содержания аудио. Перед техническим анализом — послушайте файл. Morse-код, SSTV-сигнал, DTMF-тоны распознаются на слух за секунды. Спектрограмму это не заменит, но сузит область поиска.

Отдельная категория — таски с повреждёнными заголовками. Если file не определяет тип, а hexdump -C challenge | head показывает нестандартные первые байты — заголовок файла модифицирован. Сверьте магические байты с эталоном: PNG начинается с 89 50 4E 47 0D 0A 1A 0A, JPEG — с FF D8 FF, BMP — с 42 4D. Исправить можно через hex-редактор (hexedit на Linux, HxD на Windows) или pngcheck, который укажет на конкретный битый чанк. Восстановление сломанного IHDR (изменённые размеры изображения) — ещё один классический трюк авторов тасков: картинка открывается, но часть данных не видна, потому что заявленная высота меньше реальной. Подставляете правильные байты в IHDR — и скрытая часть изображения буйком всплывает.

Стего-категория на CTF — единственная, где порядок действий важнее глубины знаний. В pwn нужно понимать механику переполнения. В crypto — математику. В web — логику приложения. В стего достаточно знать инструменты и последовательность запуска.

Это создаёт иллюзию простоты. Просто — пока таск укладывается в стандартный чеклист. На тасках высокого уровня начинаются кастомные алгоритмы вставки, нестандартные кодировки, XOR-маски поверх LSB — и автоматика заканчивается, остаётся Python и понимание принципов.

Навык стеганоанализа выходит за пределы соревнований. В MITRE ATT&CK стеганография документирована как техника T1001.002 (Steganography, тактика command-and-control) и T1027.003 (Steganography, тактика stealth). Реальные группировки прячут payloads в PNG и JPEG, которые проходят через корпоративные файрволы как обычный веб-трафик. Тот, кто на CTF научился вытаскивать LSB из картинки за минуту, в SOC-команде быстрее обнаружит встроенный payload в подозрительном изображении из логов прокси.

Я бы потратил первые десять часов обучения не на зубрёжку флагов каждого инструмента, а на отработку алгоритма: file → exiftool → strings → формат-специфичный инструмент → Python. Инструменты меняются, последовательность — нет. На HackerLab есть лабы по стеганоанализу, где эту цепочку можно прогнать на реальных тасках — от тривиальных до тех, где без Python-скрипта никуда.

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

Поделиться

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

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

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

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

Взлом хэшей в CTF: John the Ripper и Hashcat

15 мин.

0

Взлом хэшей в CTF: John the Ripper и Hashcat

Пошаговый workflow подбора хэшей в CTF. Команды JtR и Hashcat, маски, правила, словари, GPU-ускорение и чек-лист отладки, если хэш не ломается.

3 НОЯБРЬ, 2026

Pwntools для начинающих: pwn на Python без боли

11 мин.

5

Pwntools для начинающих: pwn на Python без боли

Сквозной разбор pwntools от checksec до remote-эксплойта. GDB-интеграция из скрипта, cyclic для offset и 3 ошибки, на которые уходит по часу.

2 НОЯБРЬ, 2026

OSINT разведка для CTF: дорки, Shodan, фото

13 мин.

6

OSINT разведка для CTF: дорки, Shodan, фото

Конкретные Google Dorks, Shodan-запросы и приёмы reverse image search для OSINT-задач на CTF. Пошаговые воркфлоу с командами, готовые шаблоны дорков и цепочки pivot'ов.

2 НОЯБРЬ, 2026