Главная / Блог / Стеганография CTF: от файла до флага

13 мин.00

Стеганография CTF: от файла до флага

Стеганография CTF: от файла до флага

На picoCTF Hidden in Plainsight (классический стего-таск, описанный в десятках write-up'ов) участники получали единственный JPEG без подсказок. Большинство сразу запускали steghide extract, вводили случайные пароли, переключались на brute force и теряли полчаса. А пароль лежал в поле Comment метаданных самого файла, закодированный двойным Base64 — exiftool challenge.jpg показал бы его в первых строках вывода. Десять секунд вместо тридцати минут.

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

Первый шаг: file, strings и exiftool — анализ метаданных файла

Любой таск по стеганографии в картинках или аудио начинается с трёх команд. Порядок критичен: перепрыгнете базовый анализ — будете полчаса гонять тяжёлые утилиты вхолостую.

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

Следующий обязательный шаг — exiftool для анализа метаданных. Поля Comment, Artist, Description, XMP-теги, GPS-координаты — классические места для сокрытия флагов и хинтов. На среднем уровне Base64-строка в поле Comment — устойчивый паттерн. Для примера: допустим, exiftool img.jpg содержит comment-поле с Base64-строкой c3RlZ2hpZGU6Y0VGNmVuZHZjbVE9. Первое декодирование даёт steghide:cEF6endvcmQ=, второе (для части после двоеточия) — pAzzword. Имя инструмента и passphrase в одной строке. Три секунды работы — и задача фактически решена.

Принцип: читайте вывод file и exiftool целиком, включая segment length, OEM-ID и нестандартные теги. Skim-reading здесь стоит потерянного часа.

Параллельно — strings для вытаскивания текстовых строк из бинарного файла. Комбинация с grep сужает поиск: strings challenge.png | grep -iE "flag|ctf|key|\{|\}". На лёгких и средних тасках по поиску скрытых файлов в изображении это закрывает задачу удивительно часто — флаг или подсказка просто валяются открытым текстом внутри файла.

Нюанс, который пропускают: strings по умолчанию ищет ASCII. Для UTF-16 (частый кейс в Windows-артефактах) добавьте флаг -el (little-endian) или -eb (big-endian). Без этого целый пласт строк останется невидимым.

Три команды — file, exiftool, strings — занимают 30 секунд и закрывают примерно треть стего-тасков. Если результата нет — копаем глубже.

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

Binwalk сканирует бинарный образ на известные файловые сигнатуры и показывает всё, что спрятано внутри. По сути — file carving, стандартная техника цифровой форензики. Команда binwalk challenge.png выводит карту вложенных объектов:

DECIMAL    HEXADECIMAL   DESCRIPTION
0          0x0           PNG image, 800 x 600
524288     0x80000       Zip archive data

Если binwalk нашёл ZIP, вторую картинку или данные после маркера конца файла (IEND для PNG, FFD9 для JPEG) — извлекаем: binwalk -e challenge.png. Результат попадёт в директорию _challenge.png.extracted.

Но тут есть подвох. Binwalk ищет сигнатуры по смещениям, и ложные срабатывания — обычное дело. Случайное совпадение байт с сигнатурой PK (ZIP) или FFD8 (JPEG) в бинарных данных происходит регулярно. Как точно подметили на форуме Codeby: binwalk «просматривает только сигнатуры начала», и слепо верить ему не стоит. Каждый извлечённый файл проверяйте через file и пробуйте открыть.

Если binwalk молчит — пробуйте foremost. Команда foremost -i challenge.png -o output/ работает иначе: ищет пары header/footer для восстановления файлов. Foremost особенно хорош для JPEG и PNG, вложенных за маркером конца основного файла, и иногда цепляет то, что binwalk пропускает.

Ещё один приём — ручная проверка через xxd challenge.png | tail. Если после IEND-чанка PNG или маркера FFD9 в JPEG есть значимые данные — это почти наверняка appended payload. Вытащить можно через dd с нужным смещением.

На этом базовый анализ завершён. Ничего не нашли? Переходим к инструментам, специфичным для типа файла.

Скрытые данные в изображениях: от LSB стеганографии до визуального анализа

Абсолютное большинство стего-тасков в CTF — изображения. PNG, JPEG, BMP, GIF — у каждого формата свои механизмы сокрытия данных. Путать инструменты между форматами — ошибка номер один. Steghide не читает PNG. zsteg бесполезен для JPEG. Запомните это и сэкономите часы.

zsteg: поиск LSB стеганографии в PNG и BMP

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

zsteg автоматически перебирает десятки комбинаций LSB-кодирования и показывает результат:

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, b2), канал (r, g, b, rgb), порядок (lsb/msb), направление обхода пикселей (xy/yx). Нашёл осмысленный текст или файловую сигнатуру — таск решён. Для глубокого анализа: zsteg -a challenge.png проверяет все доступные комбинации, включая экзотические — обход по столбцам, битовые плоскости альфа-канала. Извлечь конкретный payload: zsteg -E b4,bgr,msb,xy name.png (параметры из найденной комбинации).

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

Установка: gem install zsteg (нужен Ruby). На Linux и macOS — из коробки, на Windows — через WSL2.

Steghide: извлечение данных из JPEG с паролем и brute force через stegseek

Steghide — классика категории стеганография CTF. Прячет данные в JPEG и BMP с шифрованием паролем. Нюанс, который большинство туториалов упускают: для JPEG steghide работает не через LSB, а через модификацию DCT-коэффициентов (Discrete Cosine Transform) — числовых значений, возникающих при JPEG-сжатии. Steghide подменяет пары коэффициентов по графовому алгоритму, минимизируя количество изменений. Метод не идеален — существуют стегоаналитические методы (например, chi-square test), способные детектировать steghide. Но именно поэтому binwalk ничего не находит: нет appended данных, нет файловых сигнатур. Payload вплетён в артефакты сжатия на уровне частотных коэффициентов.

Steghide также работает с WAV и AU — прячет данные в младших битах аудиосэмплов.

Рабочий workflow steghide:

  1. Проверить наличие данных: steghide info challenge.jpg показывает, есть ли embedded data, размер и метод шифрования.
  2. Попробовать пустой пароль: steghide extract -sf challenge.jpg и нажать Enter на запросе passphrase. Заметная доля Easy-тасков содержит данные без пароля вообще. Этот шаг пропускают почти все новички — и сразу лезут в словарные атаки.
  3. Если пароль нужен — искать в метаданных (exiftool), в strings, в описании таска, в имени файла.
  4. Последний резерв — stegseek для brute force.

Steghide не поддерживает PNG. При попытке — ответ the file format of "challenge.png" is not supported. Для PNG — zsteg, Stegsolve, StegOnline. Это источник потерянного времени номер один у начинающих CTF-игроков.

Ещё одна ловушка: steghide выдаёт одинаковое сообщение об ошибке при неправильном пароле и при полном отсутствии данных — could not extract any data with that passphrase!. Замкнутый круг. Практическое правило: если таск содержит JPEG или WAV и намекает на пароль — предполагайте steghide и ищите passphrase упорнее, а не бросайте инструмент.

Stegseek — брутфорсер для steghide, который решил проблему скорости. Устаревший Stegcracker перезапускает процесс steghide на каждой попытке. Stegseek работает напрямую с библиотекой steghide, пропуская избыточные перевычисления хешей. Разница — не в процентах, а в порядках: Stegcracker перебирает rockyou.txt часами, stegseek — за секунды:

stegseek challenge.jpg /usr/share/wordlists/rockyou.txt
[i] Found passphrase: "sunshine"
[i] Original filename: "flag.txt"
[i] Extracting to "challenge.jpg.out"

Если пароль в словаре — данные извлекаются автоматически. В тасках средней сложности пароль часто сидит в rockyou.txt или является словом из описания задания. Установка stegseek: .deb-пакеты для Kali и Ubuntu в репозитории RickdeJager/stegseek на GitHub. Если вы до сих пор используете Stegcracker — переключайтесь, на турнире с ограниченным временем эта разница решает.

Stegsolve и визуальный анализ битовых плоскостей

Stegsolve — Java-приложение для просмотра изображения по отдельным цветовым каналам и битовым плоскостям. Запуск: java -jar stegsolve.jar, загружаете файл, стрелками листаете режимы отображения.

Что искать:

  • Текст или QR-код на плоскости 0 (младший бит) любого канала — визуализация LSB стеганографии.
  • Выраженный шум или паттерн на нулевой плоскости при чистых верхних битах — признак модифицированных LSB.
  • Разница между двумя изображениями через Image Combiner (XOR) при наличии оригинала. Все пиксели, где данные внедрены, подсветятся.

Два режима, о которых часто забывают: Data Extract позволяет выбрать конкретные биты конкретных каналов и извлечь из них данные (аналог ручного zsteg с визуальным контролем). Frame Browser разбивает GIF на отдельные кадры — иногда флаг спрятан в одном фрейме анимации.

Если нет GUI-окружения (SSH, headless-сервер) — используйте веб-альтернативу StegOnline (georgeom.net/StegOnline). Те же функции в браузере: битовые плоскости, LSB-извлечение, анализ гистограмм.

Отдельно стоит упомянуть Aperi'Solve (aperisolve.com) — веб-инструмент, который агрегирует результаты сразу нескольких утилит (zsteg, steghide с пустым паролем, exiftool, binwalk, strings) в едином отчёте. Загрузили файл — получили сводку. Удобно для быстрой первичной проверки, но для глубокого анализа всё равно придётся лезть в отдельные инструменты.

Аудио стеганография CTF: спектрограммы и скрытые данные в WAV

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

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

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

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

LSB в WAV — второй вектор. Steghide поддерживает WAV и может прятать данные в младших битах аудиосэмплов. Workflow тот же, что и для JPEG: steghide info audio.wav, пустой пароль, при неудаче — stegseek для перебора.

Для WAV-файлов, где steghide пуст, существует WavSteg — Python-инструмент для извлечения LSB-данных из WAV без шифрования: python3 WavSteg.py -r -s audio.wav -o output.txt. Инструмент упоминается в нескольких CTF-ресурсах (в частности, 0xrick.github.io) как дополнение к steghide.

Не забывайте базовый анализ для аудио: strings audio.wav | grep -i flag, exiftool audio.wav, binwalk audio.wav. Авторы тасков иногда appended данные после маркера конца WAV — binwalk это находит.

Ещё один редкий, но встречающийся приём — morse-код в аудио. Слышите ритмичные тоны — попробуйте декодировать вручную или через онлайн-декодеры. Спектрограмма в Audacity покажет точки и тире как короткие и длинные импульсы на одной частоте.

Decision tree: какой инструмент запускать первым

Главная проблема новичков в стего-тасках — запуск неподходящего инструмента для конкретного формата. Таблица ниже закрывает вопрос совместимости:

Формат Первый инструмент Второй инструмент Чего НЕ делать
PNG zsteg Stegsolve / StegOnline Не запускать steghide
JPEG steghide info stegseek (brute force) Не запускать zsteg
BMP zsteg, steghide Stegsolve —
GIF Stegsolve (Frame browser) strings, binwalk Steghide не поддерживает
WAV steghide info WavSteg, спектрограмма —
MP3 Спектрограмма (Audacity) strings, binwalk Steghide не поддерживает
AU steghide info strings, binwalk —
Любой file, exiftool, strings binwalk, foremost Не пропускать базовый анализ

Универсальная последовательность для любого файла:

  1. file → реальный тип файла
  2. exiftool → метаданные (Comment, Description, GPS, нестандартные теги)
  3. strings | grep -iE "flag|ctf|key|base64|\{|\}" → открытый текст
  4. binwalk → встроенные файлы в изображении или аудио
  5. Специализированный инструмент по формату (см. таблицу выше)

Если все пять шагов пусты — проверяйте менее очевидные вещи. Не скрыты ли данные в манипуляции с высотой PNG: трюк с IHDR, описанный на Habr, где уменьшение значения высоты в заголовке прячет нижнюю часть картинки. Нет ли стеганографии через альфа-канал (для RGBA-изображений значения прозрачности могут нести информацию). Не изменён ли заголовок файла — xxd challenge | head покажет реальные магические байты.

Ещё одна полезная эвристика: размер файла vs разрешение. JPEG 640x640 не должен весить 2 МБ. Если файл непропорционально большой для своего разрешения — с высокой вероятностью внутри embedded данные. Поле capacity в выводе steghide info подтвердит подозрение.

Стеганография — не только CTF-дисциплина. В MITRE ATT&CK описаны техники Steganography (T1001.002, Command and Control) и Steganography (T1027.003, Defense Evasion/Stealth), а также связанные T1027 (Obfuscated Files or Information) и T1140 (Deobfuscate/Decode Files or Information). Реальные APT-группировки используют те же методы для скрытой передачи C2-команд и обхода детектирования. Payload прячется в медиафайлах, публикуемых на легитимных хостингах. Алгоритм анализа тот же: определить тип → проверить метаданные → применить инструмент по формату. Навыки, прокачанные на CTF-тасках, прямо переносятся в работу SOC-аналитика и форензика.

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

Steghide на PNG. Повторяю отдельно, потому что каждый новый CTF-игрок наступает на эти грабли: steghide работает с JPEG, BMP, WAV и AU. PNG он не поддерживает. Для PNG — zsteg, Stegsolve, StegOnline.

Пропущенный пустой пароль. Прежде чем лезть в словарные атаки — steghide extract -sf file.jpg и Enter. Пустой passphrase — валидный и частый вариант в Easy-тасках. Десять секунд — и либо флаг у вас, либо переходите дальше без потерь.

Слепое доверие binwalk. Нашёл ZIP на смещении 0x80000 — не факт, что это реальный архив. Совпадение байт с сигнатурой PK (50 4B) в бинарных данных — норма, а не исключение. Проверяйте каждый извлечённый файл через file, пробуйте открыть и распаковать.

Забытый strings -el. По умолчанию strings ищет ASCII. Если таск связан с Windows-артефактами или Unicode-текстом — UTF-16 строки останутся невидимыми. Флаги -el (little-endian) и -eb (big-endian) решают проблему.

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

Пропуск спектрограммы в аудио. Получили WAV или MP3 — первым делом откройте в Audacity и переключите на Spectrogram. Десять секунд — и закрываете целый класс тасков, где текст нарисован в спектре.

Exiftool после binwalk, а не до. Классика — сразу запускать тяжёлые инструменты, пропуская метаданные. Флаг или подсказка к паролю в поле Comment — стабильный паттерн средних тасков. Три секунды на exiftool перед всем остальным.

Игнорирование имени файла и описания таска. Пароль для steghide нередко является частью имени файла (sunshine.jpg → пароль sunshine) или буквально написан в описании задания. Авторы тасков рассчитывают, что участники не прочитают условие до конца. И обычно не ошибаются.

Мой подход к стего-тасках за последние пару лет свёлся к одному принципу: инструменты вторичны, алгоритм первичен. Видишь новый файл — не хватайся за первый попавшийся инструмент. Пройди чеклист (file → exiftool → strings → binwalk), определи формат, открой таблицу совместимости, запусти правильную утилиту. Звучит банально, но 80% потерянного времени на CTF — это steghide на PNG, zsteg на JPEG и binwalk без проверки результатов.

Отдельная тема — эволюция тасков. Авторы заданий читают те же write-up'ы, что и участники. Каждый сезон появляются задачи, специально построенные против стандартного чеклиста: двойное кодирование пароля в метаданных, стеганография через альфа-канал вместо RGB, манипуляция высотой PNG через подмену IHDR, вложенная стеганография (steghide внутри файла, извлечённого binwalk из другого файла — матрёшка). Алгоритм — фундамент, но без понимания того, как именно работает каждый метод сокрытия — DCT-коэффициенты в JPEG, битовые плоскости в PNG, padding за IEND — выйти за пределы лёгких тасков сложно.

DCT-стеганография по-настоящему ощущается только когда сам прогоняешь steghide info на десятке файлов и видишь, как capacity меняется в зависимости от содержимого картинки. Берите любую forensics-категорию на picoCTF или CyberDefenders и прогоняйте чеклист руками, пока он не станет рефлексом.

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

Поделиться

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

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

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

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

XSS CTF: разбор задания от инъекции до кражи cookie

12 мин.

9

XSS CTF: разбор задания от инъекции до кражи cookie

Пошаговый разбор XSS задания в CTF: поиск точки инъекции через DevTools, сборка cookie stealer payload через fetch, обход фильтров и session hijacking через Burp.

2 ОКТЯБРЬ, 2026

Linux для CTF: команды, права и поиск флагов

15 мин.

8

Linux для CTF: команды, права и поиск флагов

Пошаговый гайд по Linux для CTF: bash-команды, чтение прав chmod, поиск флагов через find и grep, первый privesc через sudo -l и SUID-бинарники. С чеклистом.

2 ОКТЯБРЬ, 2026

John the Ripper и Hashcat для начинающих: гайд

15 мин.

13

John the Ripper и Hashcat для начинающих: гайд

Пошаговый workflow крекинга хэшей: от hashid до флага за 5 минут. Таблица режимов Hashcat, утилиты *2john, 6 ошибок новичков и разбор реального CTF-таска.

1 ОКТЯБРЬ, 2026