Главная / Блог / Стеганография в CTF: прячем и находим данные в картинках и аудио с помощью steghide, zsteg и binwalk

15 мин.00

Стеганография в CTF: прячем и находим данные в картинках и аудио с помощью steghide, zsteg и binwalk

Стеганография в CTF: прячем и находим данные в картинках и аудио с помощью steghide, zsteg и binwalk

Стеганография в CTF: прячем и находим данные в картинках и аудио с помощью steghide, zsteg и binwalk

На одном из недавних CTF-ивентов задача за 300 очков висела нерешённой полтора часа: обычный JPEG с котиком, 200 КБ, без видимых аномалий. strings — пусто, exiftool — чисто, binwalk — тишина. Флаг оказался внедрён через steghide с паролем из четырёх символов, который stegseek подобрал за 8 секунд по rockyou.txt. Вся разница между «решили» и «не решили» — знание правильного порядка инструментов и понимание, когда один заканчивает работу и начинает другой.

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

Как найти скрытые данные в изображении: разведка файла

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

  • ОС: Kali Linux 2023+ (предустановлено большинство инструментов) или Ubuntu 20.04+ / Debian 11+
  • RAM: 2 ГБ минимум, 4 ГБ рекомендуется (Stegsolve и Audacity потребляют больше)
  • Основные пакеты: steghide, binwalk, exiftool, foremost — ставятся через apt
  • Ruby 2.7+ для zsteg (gem install zsteg)
  • Java 8+ для Stegsolve (java -jar stegsolve.jar)
  • Опционально: stegseek (deb-пакет с GitHub), Audacity, Sonic Visualizer, Python 3.8+ с Pillow
  • Сеть: не нужна — всё работает offline

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

Шаг 1 — определить реальный тип файла. Расширение в CTF часто врёт. Файл flag.jpg может оказаться PNG, ZIP-архивом или ELF-бинарником. Команда file flag.jpg покажет реальный формат по magic bytes — сигнатурным байтам в начале файла. PNG начинается с 89 50 4E 47, JPEG — с FF D8 FF, ZIP — с 50 4B 03 04. Если file сообщает, что предполагаемый JPEG на самом деле «PNG image data» — переименуйте файл и работайте с правильным форматом. Шаг тривиальный, но на соревнованиях его пропускают регулярно.

Шаг 2 — поиск текстовых строк. strings flag.png | grep -i flag — первое, что стоит запустить. По данным ресурсов по CTF-форензике (hacklido.com, 0xrick.github.io), заметная часть задач начального уровня прячет флаг в виде читаемого текста внутри бинарного файла. Пусто? Попробуйте strings -n 6 flag.png для фильтрации строк от шести символов. Иногда флаг закодирован в Base64, и тогда strings flag.png | grep -iE '[A-Za-z0-9+/=]{20,}' поможет выловить подозрительные последовательности.

Шаг 3 — анализ метаданных изображений. exiftool flag.png выводит EXIF, IPTC и XMP-метаданные. В CTF-задачах авторы прячут подсказки или флаг в полях Comment, Artist, Copyright, Description. Обратите внимание на GPS-координаты — они могут указывать на следующий этап задания. Нестандартное значение в любом мета-поле — почти наверняка зацепка.

Шаг 4 — hex-анализ. Откройте файл в hex-редакторе (xxd flag.png | tail -30 или GUI — HxD, Bless, GHex) и проверьте область после маркера конца файла: для PNG это IEND, для JPEG — FF D9. Данные, дописанные после EOF-маркера, — классическая техника скрытия данных в файлах. Если после FF D9 в JPEG идут байты 50 4B (сигнатура ZIP) — внутри спрятан архив.

На этом этапе цифровая стеганография в CTF отделяется от базового анализа. Если ничего не обнаружено — переходим к специализированным инструментам.

Инструменты для стеганографии CTF: когда что применять

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

Инструмент Форматы Преимущества Ограничения Когда использовать Когда не использовать
steghide JPEG, BMP, WAV, AU Шифрование с паролем, низкий порог входа Не поддерживает PNG; требует пароль JPEG/BMP с подозрением на внедрённые данные Любые PNG-файлы
zsteg PNG, BMP Перебирает все LSB-комбинации каналов, быстрый Только PNG/BMP, нет аудио PNG, подозрение на LSB-кодирование JPEG (сжатие уничтожает LSB)
binwalk Любые Находит вложенные файлы по сигнатурам, автоизвлечение Не детектирует LSB-стеганографию Файл подозрительно большой или данные после EOF Задачи на LSB без вложений
Stegsolve Изображения (все) Визуальный анализ битовых плоскостей, GUI Требует Java, нет автоматического извлечения QR-коды и паттерны в цветовых каналах Аудиофайлы
foremost Любые Карвинг файлов по headers/footers Не определяет стеганографию Восстановление из дампов и образов Задачи на LSB и спектрограммы
stegseek JPEG, BMP, WAV, AU Brute-force steghide-паролей, в 1000+ раз быстрее stegcracker Только steghide-файлы Неизвестный пароль к steghide Файлы, обработанные другими инструментами
Sonic Visualizer WAV, MP3, FLAC, Ogg Спектрограммы, визуализация частот GUI, не автоматизируется Аудиозадачи со скрытыми визуальными сообщениями Изображения

Ключевое различие, которое новички упускают: zsteg и steghide решают разные задачи. zsteg анализирует LSB-слои в PNG — пассивный анализ существующих данных. steghide — активный инструмент, который шифрует и внедряет с использованием пароля. Путать их — терять время. Я видел, как команда 40 минут гоняла steghide по PNG-файлу, хотя steghide PNG в принципе не поддерживает.

Отдельно упомяну stegoveritas (pip3 install stegoveritas + stegoveritas_install_deps) — мультиформатный комбайн, который прогоняет кучу тестов автоматически. Из-за этого работает медленнее специализированных утилит. Полезен как «последний шанс», когда целевые инструменты ничего не нашли.

zsteg: примеры LSB-анализа в PNG и BMP

zsteg — основной инструмент для работы с Least Significant Bit стеганографией в PNG. LSB-кодирование меняет последний (наименее значимый) бит каждого байта цветового канала. Для глаза разница между значением пикселя 254 и 255 неотличима, но в этих битах может храниться полноценное сообщение.

Предусловия и ограничения

Работает если: файл — PNG или BMP без сжатия с потерями. Данные внедрены через LSB-подмену в цветовых каналах (R, G, B) или альфа-канале.

Не работает если: файл — JPEG (сжатие с потерями перезаписывает младшие биты), данные внедрены через steghide (другой алгоритм), данные скрыты в метаданных или после EOF-маркера.

Установка: gem install zsteg. Базовый запуск zsteg flag.png проверяет несколько стандартных конфигураций LSB. Для полного анализа — zsteg -a flag.png: перебираются все комбинации каналов (RGB, BGR, RBG и т.д.), порядок битов (MSB/LSB), направления чтения (по строкам и столбцам). Типичный вывод при обнаружении:

b1,rgb,lsb,xy       .. text: "flag{lsb_1s_n0t_s0_h1dd3n}"
b1,bgr,lsb,xy       .. file: PNG image data, 32 x 32
b2,r,lsb,xy         .. text: "nothing here"

Строка b1,rgb,lsb,xy расшифровывается так: первый бит (b1), каналы в порядке RGB, least significant bit, чтение по строкам (x) затем по столбцам (y). Если zsteg обнаружил текст или заголовок файла — данные перед вами. Для извлечения конкретного payload: zsteg -E b1,rgb,lsb,xy flag.png > extracted.bin.

Когда zsteg -a выдаёт десятки строк нечитаемого мусора — не паникуйте. Инструмент проверяет сотни комбинаций, большинство не содержат осмысленных данных. Ищите строки с ASCII-текстом, заголовками известных форматов (PNG, PK, %PDF) или подозрительно длинные последовательности.

Частая ловушка: автор задачи использует нестандартный порядок каналов. Если данные внедрены в порядке BGR с MSB вместо LSB — базовый zsteg flag.png без -a их пропустит. Флаг -a — обязателен на соревнованиях. Без него вы просто не увидите половину возможных вариантов.

steghide: как пользоваться для внедрения и извлечения

steghide работает с JPEG, BMP, WAV и AU — форматами, которые zsteg не поддерживает (или поддерживает частично). Принципиальное отличие: steghide внедряет данные и защищает их парольной фразой. Без правильного пароля извлечь содержимое не получится.

Предусловия и ограничения

Работает если: файл — JPEG, BMP, WAV или AU. Данные внедрены через steghide (у инструмента собственный формат внедрения, несовместимый с другими).

Не работает если: файл — PNG. Это одно из самых частых заблуждений новичков — steghide PNG не поддерживает, точка. Также steghide не извлечёт данные, внедрённые через outguess или openstego — у каждого свой формат.

Чтобы спрятать данные в картинке: steghide embed -cf cover.jpg -ef secret.txt — инструмент запросит пароль. Извлечение: steghide extract -sf cover.jpg — снова нужен пароль. Проверка без извлечения: steghide info cover.jpg.

В CTF-задачах пароль бывает пустым. Попробуйте steghide extract -sf cover.jpg -p "" — это первое, что стоит проверить. Не сработало — ищите пароль в метаданных (поле Comment из exiftool), в имени файла, в описании задачи на платформе. Авторы любят прятать подсказки на виду.

Brute-force паролей: stegcracker и stegseek

Если пароль неизвестен и подсказок нет — brute-force. Два варианта:

stegcracker (pip3 install stegcracker) вызывает steghide для каждого пароля как отдельный процесс. На rockyou.txt с 14 миллионами записей перебор занимает часы. Команда: stegcracker cover.jpg /usr/share/wordlists/rockyou.txt. Честно говоря, на CTF-ивенте с ограниченным временем это почти бесполезно.

stegseek — замена на C++, которая делает то же самое, но в тысячи раз быстрее: полный перебор rockyou.txt завершается за секунды. Установка: скачать deb-пакет с GitHub-репозитория, затем dpkg -i stegseek_*.deb. Запуск: stegseek cover.jpg /usr/share/wordlists/rockyou.txt. При нахождении пароля данные извлекаются автоматически.

Если у вас Debian или Ubuntu — используйте stegseek, без вариантов. Синтаксис идентичен stegcracker, скорость на порядки выше. stegcracker оправдан только когда установить stegseek невозможно (экзотическая ОС, нет прав на dpkg).

binwalk: извлечение файлов из бинарных контейнеров

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

Предусловия и ограничения

Работает если: внутри файла есть вложение с распознаваемой сигнатурой (ZIP, RAR, PNG, PDF, gzip, ELF и т.д.), или данные дописаны после EOF-маркера основного файла.

Не работает если: данные закодированы через LSB, зашифрованы или лишены стандартной файловой сигнатуры.

Базовый анализ: binwalk flag.png — выводит все обнаруженные сигнатуры. Пример вывода:

DECIMAL       HEXADECIMAL     DESCRIPTION
-------------------------------------------
0             0x0             PNG image, 800 x 600
98304         0x18000         Zip archive data, name: secret.txt
98450         0x18092         End of Zip archive

Автоматическое извлечение: binwalk -e flag.png — результат окажется в директории _flag.png.extracted/. Для рекурсивного извлечения: binwalk --dd='.*' flag.png.

Нюанс, который стоит держать в голове: binwalk ищет сигнатуры по фиксированным смещениям. Если автор задачи намеренно повредил magic bytes вложенного файла (например, заменил первые два байта ZIP), binwalk его не обнаружит. Тут спасает только ручной hex-анализ.

Альтернатива для карвинга — foremost. Команда foremost -i flag.png -o output_dir/ восстанавливает файлы по заголовкам и футерам. foremost иногда находит то, что binwalk пропускает, поэтому на соревнованиях стоит запускать оба — 10 секунд лишних, зато шанс не упустить вложение.

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

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

Спектрограммы

Самый распространённый приём — скрытие визуального сообщения в спектрограмме. Откройте WAV-файл в Sonic Visualizer, добавьте слой спектрограммы (Layer → Add Spectrogram) — и увидите текст или QR-код, нарисованный частотами. Audacity тоже умеет показывать спектрограммы (смена вида трека на Spectrogram), но Sonic Visualizer даёт более тонкую настройку визуализации.

Обращайте внимание на высокочастотный диапазон — выше 15 кГц. Ухо эти частоты почти не различает, что делает их удобным местом для скрытия информации. В Sonic Visualizer увеличьте масштаб по вертикальной оси и поэкспериментируйте с цветовой схемой — иногда сообщение видно только при определённой палитре. Я однажды минут двадцать крутил настройки, пока не переключил на «sunset» — и QR-код буйком всплыл.

Морзе и DTMF

Тональные сигналы (писки, длинные и короткие гудки) в аудиофайле — возможно, азбука Морзе или DTMF (тоновый набор телефонного номера). Для морзе используйте онлайн-декодеры или расшифруйте визуально по спектрограмме. DTMF-тоны декодируются через multimon-ng: multimon-ng -t wav -a DTMF file.wav.

LSB в аудио

WAV-файлы хранят несжатые семплы — к ним применима та же LSB-техника, что и к изображениям. steghide работает с WAV и AU напрямую. Для ручного LSB-анализа аудио есть WavSteg (Python-скрипт с GitHub): python3 WavSteg.py -r -s audio.wav -o output.txt -b 1 — извлекает данные из младшего бита каждого семпла.

Типичная ошибка: при получении аудиозадачи сразу бросаться на спектрограмму, проигнорировав базовые проверки. Начинайте с file, strings, exiftool, binwalk — ровно так же, как с изображениями. Встречаются задачи, где флаг лежит в EXIF-комментарии WAV-файла. Просто exiftool audio.wav — и готово, а вы бы полчаса ковыряли спектрограмму.

Визуальный анализ каналов: Stegsolve и LSB-кодирование вручную

Stegsolve — Java-приложение для переключения визуализации между битовыми плоскостями и цветовыми каналами. Запуск: java -jar stegsolve.jar, затем File → Open.

Стрелками переключайтесь между режимами: Red plane 0, Red plane 1, ..., Green plane 0, ..., Alpha plane 0 и т.д. Plane 0 — младший бит канала. Если в младшем бите красного канала скрыт QR-код, вы увидите его на слое «Red plane 0» как чёрно-белый паттерн. Иногда щёлкаешь по плоскостям и на третьем клике — бац, QR-код на весь экран.

Stegsolve также умеет комбинировать два изображения (Image Combiner) — полезно, когда задача содержит два похожих файла, а различия между ними несут скрытое сообщение. Frame Browser помогает с анимированными GIF: иногда один кадр из сотни содержит флаг.

Для ручного извлечения LSB без инструментов подходит Python с Pillow:

from PIL import Image

img = Image.open('secret.png')
bits = []
for y in range(img.height):
    for x in range(img.width):
        r, g, b = img.getpixel((x, y))[:3]
        bits.extend([r & 1, g & 1, b & 1])
data = bytes(int(''.join(map(str, bits[i:i+8])), 2)
             for i in range(0, len(bits), 8))
print(data[:200])

Скрипт извлекает младший бит из каждого канала RGB попиксельно и собирает биты в байты. Если данные внедрены в LSB — первые байты вывода покажут осмысленный текст или заголовок файла. Это пример для понимания концепции; для боевой работы используйте zsteg или stegoveritas.

Forensics CTF задания: пошаговый алгоритм решения stego-задач

Порядок действий при получении файла на stego-задачу:

  1. file challenge_file — определяем реальный тип. Расширению не доверяем.
  2. strings challenge_file | grep -i flag — ищем флаг в открытом виде. Варианты: grep -i ctf, grep -i key, grep -iE '[A-Za-z0-9+/=]{20,}' для Base64.
  3. exiftool challenge_file — все метаданные. Особое внимание на Comment, Artist, Description.
  4. xxd challenge_file | tail -20 — конец файла. Есть ли данные после EOF-маркера?
  5. binwalk challenge_file — вложенные файлы. Нашли — binwalk -e challenge_file.
  6. По формату файла — специализированный инструмент: - PNG/BMP — zsteg -a challenge_file - JPEG/BMP/WAV/AU — steghide extract -sf challenge_file -p "" (пустой пароль), затем stegseek challenge_file rockyou.txt - Любое изображение — Stegsolve: визуальный анализ битовых плоскостей - WAV/MP3 — Sonic Visualizer: спектрограмма, особенно диапазон выше 15 кГц
  7. Если ничего не далоforemost -i challenge_file, stegoveritas challenge_file, ручной hex-анализ для поиска повреждённых заголовков или нестандартных смещений.

Типичные ловушки

  • Двойное расширение. Файл flag.png.zip — сначала распакуйте архив, потом анализируйте изображение.
  • Переименованный файл. image.jpg с PNG-заголовком — file покажет несоответствие, но если шаг 1 пропущен — потратите время на steghide вместо zsteg.
  • Пароль в описании задачи. Авторы задач часто дают hint в описании: название, цитата, число. Пробуйте всё, что видите, как пароль к steghide.
  • Данные в альфа-канале. PNG с полностью непрозрачными пикселями может хранить информацию в альфа-канале со значениями 254-255. Визуально незаметно — zsteg обычно находит.
  • Изменённый IHDR в PNG. Высота изображения в заголовке IHDR может быть уменьшена — нижняя часть картинки скрыта. Исправьте значение высоты в hex-редакторе и пересчитайте CRC блока IHDR — скрытый фрагмент появится. Эта техника, описанная в материалах по CTF-стеганографии на Хабре, встречается на соревнованиях регулярно.

Минилаб для отработки стеганографии

Подготовьте тестовые файлы для каждого инструмента — это занимает 10 минут, после чего весь алгоритм воспроизводится без доступа к интернету.

Стенд:

  1. Возьмите JPEG (например, с unsplash.com) и создайте flag.txt с содержимым flag{test_steghide_123}.
  2. Внедрите через steghide: steghide embed -cf photo.jpg -ef flag.txt -p "test". Попробуйте извлечь: steghide extract -sf photo.jpg -p "test", а затем brute-force: stegseek photo.jpg rockyou.txt.
  3. Для zsteg: используйте PNG. Через Python с Pillow запишите строку в младшие биты и сохраните. Запустите zsteg -a modified.png — убедитесь, что данные обнаруживаются.
  4. Для binwalk: склейте PNG и ZIP через cat photo.png secret.zip > combined.png. Проверьте binwalk combined.png и binwalk -e combined.png.
  5. Для аудио: возьмите WAV и внедрите данные через steghide. Или найдите учебные задачи на picoCTF, HackTheBox, RingZer0 — на этих платформах stego-таски разного уровня.

Навыки форензики файлов CTF переносятся в реальный мир напрямую. В MITRE ATT&CK стеганография фигурирует как техника обфускации вредоносных файлов (T1027.003, Defense Evasion) и как канал управления C2-инфраструктурой (T1001.002, Command and Control). APT-группы скрывают полезные нагрузки в изображениях на легитимных хостингах — и аналитику SOC пригодятся те же binwalk, zsteg и steghide для анализа подозрительных файлов. Те, кто формулу LSB на бумаге усвоил, могут прощупать её руками на HackerLab.pro — там есть таски в категориях Forensics и Stego, для входа нужна регистрация, после неё открываются задачи всех уровней.

Три года назад я был уверен, что стеганография — «лёгкая» категория в CTF, разминка перед pwn и crypto. Потом четыре часа провозился с задачей, где данные спрятали в младших битах альфа-канала PNG, считываемых по столбцам, с порядком BGRA вместо RGBA. Стандартный zsteg нашёл их только с флагом -a, до которого я добрался последним. С тех пор каждую stego-задачу начинаю одинаково: file, strings, exiftool, binwalk -e, zsteg -a, steghide extract -p "", stegseek — строго в этом порядке, без пропусков. Каждый пропущенный шаг — потенциальные полчаса впустую на угадывание того, что утилита нашла бы за секунду.

Большинство команд проигрывают не потому, что не знают инструменты, а потому что не имеют системы. Stego проверяет не гениальность, а дисциплину. Проверил ли ты конец файла в hex-редакторе? Попробовал ли пустой пароль перед запуском brute-force на полчаса? Возьмите алгоритм из раздела выше, прогоните его на минилабе — и на следующем CTF вы будете тем, кто снимает stego-задачу за 300 очков, пока остальные гадают, какой инструмент запустить.

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

Поделиться

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

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

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