
На picoCTF Hidden in Plainsight (классический стего-таск, описанный в десятках write-up'ов) участники получали единственный JPEG без подсказок. Большинство сразу запускали steghide extract, вводили случайные пароли, переключались на brute force и теряли полчаса. А пароль лежал в поле Comment метаданных самого файла, закодированный двойным Base64 — exiftool challenge.jpg показал бы его в первых строках вывода. Десять секунд вместо тридцати минут.
Вся стеганография CTF сводится к одному навыку: знать, куда смотреть, прежде чем хвататься за инструменты. Ниже — полный алгоритм от получения файла до флага с таблицей совместимости форматов, decision tree и разбором ловушек, на которые стабильно попадают даже опытные игроки.
Любой таск по стеганографии в картинках или аудио начинается с трёх команд. Порядок критичен: перепрыгнете базовый анализ — будете полчаса гонять тяжёлые утилиты вхолостую.
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 сканирует бинарный образ на известные файловые сигнатуры и показывает всё, что спрятано внутри. По сути — 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 с нужным смещением.
На этом базовый анализ завершён. Ничего не нашли? Переходим к инструментам, специфичным для типа файла.
Абсолютное большинство стего-тасков в CTF — изображения. PNG, JPEG, BMP, GIF — у каждого формата свои механизмы сокрытия данных. Путать инструменты между форматами — ошибка номер один. Steghide не читает PNG. zsteg бесполезен для JPEG. Запомните это и сэкономите часы.
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 — классика категории стеганография CTF. Прячет данные в JPEG и BMP с шифрованием паролем. Нюанс, который большинство туториалов упускают: для JPEG steghide работает не через LSB, а через модификацию DCT-коэффициентов (Discrete Cosine Transform) — числовых значений, возникающих при JPEG-сжатии. Steghide подменяет пары коэффициентов по графовому алгоритму, минимизируя количество изменений. Метод не идеален — существуют стегоаналитические методы (например, chi-square test), способные детектировать steghide. Но именно поэтому binwalk ничего не находит: нет appended данных, нет файловых сигнатур. Payload вплетён в артефакты сжатия на уровне частотных коэффициентов.
Steghide также работает с WAV и AU — прячет данные в младших битах аудиосэмплов.
Рабочий workflow steghide:
steghide info challenge.jpg показывает, есть ли embedded data, размер и метод шифрования.steghide extract -sf challenge.jpg и нажать Enter на запросе passphrase. Заметная доля Easy-тасков содержит данные без пароля вообще. Этот шаг пропускают почти все новички — и сразу лезут в словарные атаки.exiftool), в strings, в описании таска, в имени файла.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 — Java-приложение для просмотра изображения по отдельным цветовым каналам и битовым плоскостям. Запуск: java -jar stegsolve.jar, загружаете файл, стрелками листаете режимы отображения.
Что искать:
Два режима, о которых часто забывают: Data Extract позволяет выбрать конкретные биты конкретных каналов и извлечь из них данные (аналог ручного zsteg с визуальным контролем). Frame Browser разбивает GIF на отдельные кадры — иногда флаг спрятан в одном фрейме анимации.
Если нет GUI-окружения (SSH, headless-сервер) — используйте веб-альтернативу StegOnline (georgeom.net/StegOnline). Те же функции в браузере: битовые плоскости, LSB-извлечение, анализ гистограмм.
Отдельно стоит упомянуть Aperi'Solve (aperisolve.com) — веб-инструмент, который агрегирует результаты сразу нескольких утилит (zsteg, steghide с пустым паролем, exiftool, binwalk, strings) в едином отчёте. Загрузили файл — получили сводку. Удобно для быстрой первичной проверки, но для глубокого анализа всё равно придётся лезть в отдельные инструменты.
Аудио-таски встречаются реже изображений, но стабильно появляются в категориях 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 покажет точки и тире как короткие и длинные импульсы на одной частоте.
Главная проблема новичков в стего-тасках — запуск неподходящего инструмента для конкретного формата. Таблица ниже закрывает вопрос совместимости:
| Формат | Первый инструмент | Второй инструмент | Чего НЕ делать |
|---|---|---|---|
| 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 | Не пропускать базовый анализ |
Универсальная последовательность для любого файла:
file → реальный тип файлаexiftool → метаданные (Comment, Description, GPS, нестандартные теги)strings | grep -iE "flag|ctf|key|base64|\{|\}" → открытый текстbinwalk → встроенные файлы в изображении или аудиоЕсли все пять шагов пусты — проверяйте менее очевидные вещи. Не скрыты ли данные в манипуляции с высотой 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-аналитика и форензика.
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 комментариев
Пожалуйста, войдите, чтобы оставить комментарий.
Загрузка комментариев...