Главная / Блог / Стеганография CTF: steghide, zsteg и binwalk

13 мин.00

Стеганография CTF: steghide, zsteg и binwalk

Стеганография CTF: steghide, zsteg и binwalk

На рейтинговом CTF в прошлом сезоне наша команда убила два часа на один stego-таск. PNG с котиком, внутри которого binwalk нашёл ZIP-архив, а пароль к нему лежал в LSB красного канала второй картинки из того же задания. Два часа вместо десяти минут — потому что запускали инструменты наугад, пропускали тривиальные проверки и возвращались к началу. Классическая стего-матрёшка, а мы ковыряли её как первоклассники.

После того случая я собрал алгоритм, который с тех пор закрывает типовые forensics CTF задания за 5-15 минут. Ниже — тот самый workflow: от первого взгляда на файл до извлечения флага. С конкретными командами, разбором вывода и ловушками, на которых обжигается каждая вторая команда.

Алгоритм разбора стего-таска: от file до флага

Главная ошибка при решении заданий на стеганографию в CTF — хаотичный перебор инструментов. Запускаешь steghide на PNG (он не поддерживает PNG), потом zsteg на JPEG (он не поддерживает JPEG), теряешь время и нервы. Знакомо?

Workflow, который я использую на каждом стего-таске:

  1. file — определяем реальный формат (расширение может врать)
  2. strings | grep -i flag — ищем флаг в открытом тексте
  3. exiftool — проверяем метаданные на скрытые комментарии
  4. binwalk — ищем вложенные файлы
  5. Формат-специфичный инструмент: zsteg для PNG/BMP, steghide для JPEG/WAV, спектрограмма для аудио
  6. Hex-редактор — ручной анализ, если автоматика молчит

Порядок не случаен. Шаги 1-3 занимают секунды и решают простейшие задания. Шаг 4 ловит файлы-матрёшки. И только если ничего не всплыло — переходим к тяжёлой артиллерии. Согласно Trail of Bits CTF Field Guide, для forensics-тасков нужны три навыка: распознавание форматов, работа с бинарными данными и знание Python. Алгоритм выше построен на них.

Разведка: file, strings и анализ метаданных файла

Magic bytes и определение формата

Первое правило стеганографии CTF — не доверяй расширению файла. На соревнованиях я встречал JPEG, переименованные в .txt, PNG с расширением .docx и ELF-бинарники под видом картинок. Утилита file читает magic bytes — сигнатурные байты в заголовке — и показывает настоящий формат.

file suspicious.png может вернуть JPEG image data, JFIF standard 1.01 — и сразу ясно, что расширение подменено. Дальше работать нужно с JPEG-инструментами, а не с PNG.

Следующий шаг — strings. Утилита вытаскивает все читаемые ASCII-последовательности из бинарного файла. Комбинация strings image.png | grep -i flag ловит флаги, которые автор таска спрятал в конце файла или в текстовых чанках PNG. Параметр -o добавляет смещение: strings -o screenshot.png — пригодится для ручного извлечения через dd.

Отдельно стоит проверить base64. Если среди вывода strings попалась длинная алфавитно-цифровая строка с = или == на конце — пробуйте echo "строка" | base64 -d. Бывает, что весь таск сводится к этому.

exiftool: скрытые данные в метаданных

Метаданные — частый кандидат на хранение скрытого сообщения в файле. Exiftool читает EXIF, IPTC, XMP и текстовые чанки PNG (tEXt, zTXt, iTXt). В forensics CTF заданиях флаги прячут в полях Comment, Artist, Copyright, Description и даже в GPS-координатах (да, и такое бывает).

Запуск: exiftool image.jpg. Если вывод объёмный — фильтруйте: exiftool image.jpg | grep -i -E "comment|flag|hint|description".

Нюанс с PNG: Windows не показывает EXIF-данные PNG через стандартные свойства файла. Формат PNG технически не поддерживает EXIF-стандарт (в отличие от JPEG), но может хранить метаданные в текстовых чанках. Exiftool корректно читает эти чанки на любой платформе — не полагайтесь на «Свойства файла» в проводнике.

Для полноты картины стоит запустить pngcheck -v file.png. Утилита проверяет целостность всех чанков и покажет ошибки CRC — верный признак модифицированного заголовка IHDR (техника PNG-padding, о ней ниже).

LSB стеганография в PNG: zsteg и Stegsolve

Least Significant Bit — самая распространённая техника стеганографии в CTF. Суть: младший бит каждого байта цветового канала заменяется битом скрытого сообщения. Визуально изменение незаметно — разница в цвете пикселя составляет 1 из 256 градаций. Но если собрать все младшие биты вместе — получим спрятанные данные.

Как отмечает SANReN CSC в forensics-руководстве, LSB стеганография работает потому, что значения 255 (11111111) и 254 (11111110) для человеческого глаза неразличимы, а в последнем бите уже содержится другая информация. Один бит на пиксель — мало. Но в картинке 1920×1080 это 2 073 600 бит, то есть около 253 КБ скрытых данных. Хватит за глаза.

zsteg — инструмент быстрого анализа PNG и BMP

zsteg — Ruby-утилита, которая автоматически проверяет PNG и BMP на LSB-стеганографию по всем каналам и bit planes. Это первое, что стоит запускать на PNG-файле после базовой разведки.

Базовый вызов: zsteg image.png — проверяет стандартные LSB-комбинации (RGB, BGR, обход по строкам и столбцам). Расширенный анализ: zsteg image.png --all — перебирает все возможные комбинации каналов, порядков битов и направлений обхода.

Пример реального вывода:

b1,r,lsb,xy         .. text: "flag{lsb_is_easy_peasy}"
b1,rgb,lsb,xy        .. file: PNG image data, 200 x 50
b2,g,msb,xy          .. text: "\x03\x8a random noise"

Читаем: b1,r,lsb,xy — первый бит, красный канал, least significant bit, обход по строкам (xy). Обращайте внимание на строки с осмысленным текстом или сигнатурами файлов. file: PNG image data — признак вложенного изображения в LSB.

Ловушка: zsteg --all на зашумлённых изображениях генерирует десятки ложных срабатываний. Фильтруйте: zsteg image.png --all | grep -v "^b[2-8]" — отсекает старшие битовые плоскости, где данные прячут редко. Ещё вариант — направить вывод в файл (zsteg --all image.png > results.txt) и искать осмысленное руками.

Stegsolve: визуальный разбор слоёв

Stegsolve — Java-приложение с GUI, которое показывает изображение по отдельным битовым плоскостям каждого канала. Где zsteg ищет текст автоматически, Stegsolve визуализирует результат — иногда скрытое сообщение буквально нарисовано в одном из слоёв.

Запуск: java -jar Stegsolve.jar, затем File → Open. Стрелками переключайте фильтры: Red plane 0, Green plane 0, Blue plane 0 — это LSB каждого канала.

Три режима, которые нужно знать:

Data Extract — выбираете конкретные биты конкретных каналов для извлечения данных. Если zsteg показал, что данные в b1,rgb,lsb — отмечаете бит 0 в каналах R, G, B и получаете файл.

Image Combiner — накладывает два изображения с операциями XOR, AND, SUB. Применяется когда в задании дают оригинал и модифицированную копию: XOR двух картинок покажет только изменённые пиксели.

Frame Browser — разбирает GIF и APNG на отдельные кадры. Символы флага могут быть раскиданы по разным кадрам анимации.

Когда zsteg не находит ничего осмысленного, а задание явно указывает на LSB — открывайте Stegsolve и перебирайте плоскости вручную. Автоматика не всегда ловит данные, записанные в нестандартном порядке (по столбцам вместо строк или в альфа-канале).

steghide CTF: извлечение данных из JPEG и аудио

steghide — один из самых популярных инструментов для стеганографии в CTF. Работает с JPEG, BMP, WAV и AU. В отличие от LSB-утилит, steghide использует собственный алгоритм встраивания с опциональной защитой паролем.

Основные команды: steghide info cover.jpg — проверяет наличие вложенных данных и показывает размер. steghide extract -sf cover.jpg — извлекает. Если пароль не установлен (пустой passphrase, просто Enter) — данные достаются мгновенно.

И вот тут граблями уложена целая аллея: steghide НЕ работает с PNG. Если у вас PNG — используйте zsteg или Stegsolve. Запускаешь steghide extract -sf image.png, получаешь ошибку формата и теряешь время. На каждом втором CTF кто-то из команды на это наступает.

Брутфорс пароля steghide

Когда steghide требует пароль, а хинт в задании не помогает — два пути.

Первый — ручной перебор очевидного: пустой пароль (Enter), имя файла, слова из описания задания, «password», «123456». В CTF авторы часто прячут пароль прямо в условии таска — читайте внимательнее.

Второй — автоматический перебор. stegcracker (pip install stegcracker) — обёртка над steghide, перебирающая пароли из словаря:

stegcracker cover.jpg /usr/share/wordlists/rockyou.txt

На типовых CTF-тасках среднего уровня пароль обычно находится за минуту — авторы используют словарные слова.

Если stegcracker не установлен — минимальный bash-скрипт:

while read pass; do
  steghide extract -sf cover.jpg -p "$pass" -xf out.txt 2>/dev/null
  if [ $? -eq 0 ]; then
    echo "Found: $pass"
    break
  fi
done < wordlist.txt

Не самый быстрый способ, но работает без зависимостей.

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

binwalk сканирует файл на наличие сигнатур известных форматов внутри него. Это ключевой инструмент для заданий типа «файл-матрёшка» — когда внутри картинки спрятан ZIP-архив, внутри архива другая картинка, а в ней флаг. По данным Trail of Bits CTF Field Guide, files-within-files — одна из самых частых конструкций в forensics-тасках.

Сканирование: binwalk image.jpg покажет список сигнатур с их смещениями. Если в выводе появились строки вроде «Zip archive data» или «gzip compressed data» со смещением больше нуля — внутри файла сидит другой файл.

Извлечение: binwalk -e image.jpg автоматически достанет найденное в директорию _image.jpg.extracted/. После извлечения проверьте содержимое через ls -la и каждый файл через file — убедитесь, что извлечённое не побилось.

Ручное извлечение через dd: если -e не справляется — dd if=image.jpg of=extracted.zip bs=1 skip=45678, где 45678 — смещение из вывода binwalk (столбец DECIMAL).

Ловушки и ложные срабатывания binwalk

Первая ловушка: binwalk распознаёт только сигнатуры заголовков. Если автор таска вставил файл без стандартного заголовка или с побитой сигнатурой — binwalk его пропустит. Тут спасает hex-редактор (xxd, HxD, Bless) и ручной поиск характерных байтов.

Вторая: вложенные архивы. Флаг binwalk -e вытаскивает первый уровень, но внутри могут быть ещё архивы. Прогоняйте каждый извлечённый файл через весь алгоритм заново — file, strings, binwalk. Не ленитесь.

Третья: ложные сигнатуры. binwalk может принять случайную последовательность байт за заголовок gzip или LZMA. Если извлечённый файл оказался мусором (нулевой размер, нечитаемое содержимое) — это фантом. Не тратьте время.

Альтернатива — утилита foremost, которая извлекает файлы по заголовкам и футерам. Иногда foremost находит то, что binwalk пропускает. Держите оба в арсенале.

Стеганография в аудио файлах

Аудио-стеганография в CTF встречается реже картинок, но задания на неё стабильно попадаются в категории forensics. Основные форматы — WAV и MP3. Две главные техники — спектрограммы и LSB в WAV-сэмплах.

Спектрограммы в Audacity и Sonic Visualiser

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

Audacity — бесплатный аудиоредактор. Откройте файл, кликните на имя дорожки слева и выберите Spectrogram. По умолчанию отображается диапазон до 8 кГц — этого часто мало. В настройках спектрограммы увеличьте максимальную частоту до 22050 Гц, а Window Size до 2048 или 4096 для лучшего разрешения. Иногда сообщение спрятано выше 16 кГц — без корректных настроек вы его просто не увидите.

Sonic Visualiser — специализированный инструмент для анализа аудио. Layer → Add Spectrogram — и вы получаете спектрограмму с более гибкими настройками. Для сложных аудио-тасков он удобнее Audacity.

Базовые проверки для аудио те же: strings audio.wav | grep flag, exiftool audio.wav, binwalk audio.wav — флаг может быть в метаданных или дописан после аудиоданных простым текстом. steghide работает с WAV и AU: steghide extract -sf audio.wav — не забывайте попробовать пустой пароль.

LSB в WAV-файлах

Аналогично изображениям, данные можно записать в младшие биты аудио-сэмплов. Для WAV нет универсального инструмента вроде zsteg — часто приходится писать короткий Python-скрипт:

from scipy.io.wavfile import read
rate, samples = read('stego.wav')
bits = [s & 1 for s in samples.flatten()]
msg = ''.join(chr(int(''.join(map(str, bits[i:i+8])), 2))
              for i in range(0, min(len(bits), 800), 8))
print(msg)

Скрипт вытаскивает LSB из каждого сэмпла, собирает биты в байты и декодирует как ASCII. Ограничение до 800 бит (100 символов) — чтобы не ждать обработки всего файла. На реальном таске может потребоваться адаптация: стерео vs моно, 16-bit vs 8-bit сэмплы, другой порядок битов. Но для старта хватит за глаза.

Чеклист инструментов для стеганографии CTF

Таблица ниже — компактная шпаргалка. Формат файла определяет стартовый набор инструментов для извлечения данных из PNG, JPG, WAV и других форматов.

Формат Инструмент Команда Что ищет
PNG/BMP zsteg zsteg file.png LSB данные во всех каналах
PNG/BMP Stegsolve GUI, Data Extract Визуальный анализ битовых плоскостей
JPEG/BMP steghide steghide extract -sf file.jpg Встроенные данные (с паролем или без)
WAV/AU steghide steghide extract -sf file.wav Встроенные данные
WAV/MP3 Audacity Spectrogram view Текст/изображение в спектре
GIF/APNG Stegsolve Frame Browser Данные в отдельных кадрах
Любой binwalk binwalk -e file Вложенные файлы
Любой exiftool exiftool file Скрытые метаданные
Любой strings strings file \| grep flag Текст в открытом виде
Любой file file unknown_file Реальный формат файла

Порядок в таблице — приоритет: сначала формат-специфичный инструмент, затем универсальные.

Типичные ловушки в forensics CTF заданиях

Подменённое расширение. Файл назван image.png, а file показывает JPEG image data. Частая ловушка лёгкого уровня. Решение: всегда начинать с file. Если формат не совпадает — переименуйте файл и работайте с инструментами для реального формата.

Пустой пароль steghide. Новички вводят случайные пароли, когда steghide запрашивает passphrase. Первое действие — нажать Enter. По моим наблюдениям, примерно в трети CTF-тасков с steghide пароль пустой.

Данные после EOF. После маркера конца формата (IEND в PNG, FFD9 в JPEG) дописан текст или другой файл. binwalk это обычно ловит, но strings надёжнее для текстовых вставок — флаг может быть тупо приписан в конец файла.

Альфа-канал PNG. Канал прозрачности (Alpha в RGBA) может хранить скрытые данные. Если zsteg ничего не нашёл в RGB — проверьте альфа-канал через Stegsolve (Alpha plane 0). Отдельный подвох: пиксели с alpha=0 (полная прозрачность), у которых RGB-значения игнорируются при отображении, но содержат данные.

PNG-padding за границами картинки. Техника, при которой уменьшают значение высоты в заголовке IHDR: нижняя часть изображения перестаёт отображаться, но данные остаются в файле. Обнаруживается через pngcheck -v file.png — если CRC блока IHDR не совпадает, высота была изменена. Восстановление: откройте файл в hex-редакторе, найдите 4 байта высоты в IHDR (смещение 0x14-0x17) и увеличьте значение. После изменения пересчитайте CRC или используйте скрипт для автоматического исправления.

Стего в стего. Извлечённый файл из binwalk сам содержит стеганографию. Не останавливайтесь на первом уровне: прогоняйте каждый извлечённый файл через весь алгоритм с начала. На одном CTF я трижды распаковывал матрёшку, прежде чем добрался до флага.

QR-код в битовой плоскости. Отдельный подвид LSB-заданий: в младших битах спрятан не текст, а QR-код. Stegsolve покажет его при переключении на Red/Green/Blue plane 0, после чего нужно сделать скриншот и отсканировать QR любым ридером.

Стеганография в CTF — это ещё и тренировочная площадка для навыков digital forensics. Техники отсюда напрямую связаны с реальными TTP атакующих. В MITRE ATT&CK техника Steganography (T1001.002, Command and Control) описывает использование стеганографии для сокрытия C2-коммуникаций: команды малвари прячутся в пикселях PNG-изображений, загружаемых с легитимных хостингов. Техника T1027.003 (Defense Evasion) — обфускация вредоносной нагрузки внутри медиафайлов. Те же binwalk и zsteg, которые вы запускаете на CTF-тасках, пригодятся при анализе подозрительных файлов в реальных инцидентах.

Девять из десяти стего-тасков среднего уровня решаются за пять минут при наличии чёткого алгоритма. Проблема не в инструментах — их хватает. Проблема в хаосе: запускаешь всё подряд, тонешь в выводе zsteg --all, забываешь проверить strings. На каждом соревновании вижу команды, которые тратят полчаса на таск, решаемый через strings image.png | grep flag.

Мне кажется, стего-категория сильно недооценена. Навыки анализа бинарных форматов, работы с hex-данными, написания Python-парсеров — всё это переносится в форензику, анализ малвари и реверс. Те, кто отмахивается от stego как от «нетехнической» категории, упускают практику, которая пригодится при разборе реальных инцидентов.

Единственное, что раздражает — зависимость от конкретного инструмента встраивания. Если автор таска использовал кастомный скрипт, стандартные утилиты молчат. И тут приходит понимание: инструменты — стартовая точка, а не финишная. Настоящая сила — в способности написать свой парсер на 20 строк Python, когда готовый тул молчит. Если хочешь не просто writeup, а пройти всю атаку самому — на WAPT есть лаба на каждый такой кейс.

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

Поделиться

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

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

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

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

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

13 мин.

3

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

Пошаговый workflow подбора пароля по хешу в CTF: определение типа через hashid, словарные и mask-атаки, утилиты *2john. Hashcat vs JtR с реальными командами.

11 ОКТЯБРЬ, 2026

OSINT для начинающих: цифровой след в CTF

14 мин.

3

OSINT для начинающих: цифровой след в CTF

Пошаговый workflow CTF OSINT: поиск по нику через Maigret, пробив email через HIBP, обратный поиск фото. Команды, ловушки, разбор таска от ника до флага.

11 ОКТЯБРЬ, 2026

Wireshark для начинающих: фильтры и анализ трафика CTF

12 мин.

6

Wireshark для начинающих: фильтры и анализ трафика CTF

14 000 пакетов, один фильтр, 10 секунд до флага. Разбор pcap в Wireshark: 12 display-фильтров, анализ HTTP/DNS/FTP, ARP-спуфинг и CyberChef для CTF

10 ОКТЯБРЬ, 2026