Практична стеганографія відкриває нові можливості для тих, хто цікавиться кібербезпекою, CTF-змаганнями та захистом даних. Формат PNG дозволяє сховати інформацію непомітно: від використання альфа-каналу до додавання прихованих байтів після зображення. Ці методи допомагають передавати секретні повідомлення, створювати цифрові водяні знаки чи навіть захищати авторські права. Стаття пояснює основи роботи PNG-структури та показує, як за допомогою стеганографії можна заховати дані у картинці так, що звичайний користувач нічого не помітить.
На змаганнях ігрового формату CTF (Capture The Flag) учасники доволі часто стикаються з задачами на стеганографію. Суть проста: організатори дають картинку, а в ній десь приховано повідомлення, яке потрібно знайти. Найбазовіший прийом — сховати текст у одному з колірних каналів зображення або в альфа-каналі (що відповідає прозорості). Для виявлення таких «закладок» існують утиліти на кшталт stegsolve, pngcheck і stegdetect. А буває, що учаснику доводиться вручну гратися з фільтрами у GIMP чи Photoshop, щоб щось побачити.
Але технології не стоять на місці. Сьогодні все частіше застосовуються інші, більш витончені методи, зокрема PNG-наповнення. Це вже інший рівень приховування, який складніше помітити класичними інструментами.
Тож варто почати з короткого теоретичного огляду «невидимих» ділянок у структурі PNG-файлів — саме там криються цікаві можливості для приховування даних.
На моніторі комп’ютера зображення формується шляхом поєднання трьох основних кольорів — червоного, зеленого та синього. Кожен із них відображається у своєму окремому шарі, який називають каналом. У сукупності вони утворюють модель RGB.
У форматі PNG часто додається ще один, четвертий канал — альфа-канал (A), що відповідає за рівень прозорості. Разом така структура має вигляд RGBA, де три канали визначають колір, а альфа задає, наскільки цей колір буде видно.
У більшості графічних стандартів альфа-канал має шкалу значень від 0 до 100% (або від 0 до 255 у байтовому представленні). Якщо прозорість дорівнює 0%, піксель стає повністю прозорим, а його RGB-компоненти ігноруються — замість них видно лише фон. Якщо ж значення дорівнює 100%, піксель цілком непрозорий, і його колір з RGB відображається без змін. Проміжні значення означають різні ступені напівпрозорості, де колір змішується з тлом у певній пропорції.

Значення альфа-градієнта зазвичай використовуються для накладання зображення на інше зображення або веб-сторінку. Альфа-градієнти є в PNG, WebP, ICO, ICN та інших растрових форматах. Формат GIF підтримує лише логічне значення (піксель або прозорий, або ні).
Альфа-канал – лише один із варіантів для розміщення прихованого тексту. Переходимо до PNG-наповнення (padding) для прямого запису даних у бінарний файл.
Формат PNG побудований досить логічно і структуровано. Кожен файл відкривається з восьми байтів стандартного підпису. У десятковому представленні це: 137 80 78 71 13 10 26 10. Перший байт (137) спеціально взято поза межами ASCII, аби редактор не сплутав файл із текстом. Наступні три значення відповідають літерам PNG, після чого йдуть службові символи: DOS-розрив рядка (13 10), маркер завершення файлу DOS (26), щоб утиліта type не показувала двійкові «сміттєві» дані, та Unix-новий рядок.
Далі починаються блоки (chunks) зі стандартною структурою. Перший — IHDR, який зберігає ключові характеристики: ширину та висоту зображення (по 4 байти), колірний простір, глибину кольору (біт на піксель), метод стиснення, фільтрацію та наявність/відсутність черезрядкового кодування (по 1 байту).
Наступним може йти tEXt — блок для метаданих, де відкритим текстом записується, наприклад, назва програми, якою створено PNG. Далі розміщуються блоки IDAT, що містять стиснені дані кольорових каналів (RGB або RGBA). При відтворенні спочатку обробляється IHDR, виділяється буфер, а пікселі розпаковуються і записуються туди. Завершує файл блок IEND.
У кінці кожного блоку знаходиться контрольна сума CRC, що обчислюється за стандартним алгоритмом для перевірки цілісності.
У типовому PNG канали мають 8 або 16 біт на колір, тобто кожен піксель займає від 3 до 8 байтів. У такому випадку всі байти використовуються під корисну інформацію, і в кінці рядків місця для «зайвих» даних немає.
Але є нюанс: формат дозволяє меншу глибину кольору — 1, 2 або 4 біти. Тут один байт кодує кілька пікселів, а якщо ширина картинки не кратна 8, у кінці рядка залишаються невикористані біти. Вони накопичуються у вигляді «невидимого стовпця», де можна заховати сторонні дані. Наприклад:
при 1-бітному зображенні лишається до 7 вільних бітів на рядок,
при 2-бітному — до 3 бітів.
Онлайн-сервіси на кшталт FotoForensics здатні виявляти такі «порожні стовпці». Втім, на практиці PNG із малою глибиною кольору зустрічаються дуже рідко, тому цей метод є швидше екзотичним. Уже сама поява 2-, 4- чи 16-кольорового PNG може викликати підозру і змусити перевіряти його на приховані вкраплення.
Набагато цікавіше інше — PNG-наповнення за межами основного зображення. Це простіший і водночас значно ємніший метод стеганографії, який дозволяє сховати в картинці набагато більше інформації, ніж використання вільних бітів.
PNG-наповнення за межами картинки (post-pixel padding) часто використовується в різних іграх, головоломках та конкурсах, не тільки хакерських. Ось як працює цей метод:
1. Беремо зображення PNG (з будь-якою глибиною кольору).
2. Вставляємо секретну інформацію у нижню частину картинки.
3. Зберігаємо PNG, не використовуючи надрядкове кодування.
4. Відкриваємо файл у hex-редакторі.
5. Знаходимо блок IHDR. Він знаходиться на початку файлу після восьми обов’язкових байт підпису і позначений як IHDR.
6. Перші чотири байти після позначки IHDR – це ширина файлу, наступні чотири байти – висота. Зменшуємо це значення c 00 00 01 9D(413 пікселів), наприклад до 00 00 01 7E(382 пікселя).
7. Не забудьте перерахувати чотири байти CRC (у форматі PNG обчислюється значення CRC для кожного блоку даних, у тому числі IHDR), які записані в кінці блоку. Якщо ви не можете порахувати CRC самостійно, перегляньте це значення у будь-якому PNG-файлі з аналогічними значеннями блоку IHDR.
Отримуємо результат.
Зверніть увагу: приховані дані розміщені в нижній частині зображення. При цьому загальний розмір файлу залишився незмінним — 335 906 байт. Просто стандартний парсер ігнорує ці пікселі — тому нижня ділянка зображення не відображається на екрані.
Легко уявити, що в цій «прихованій» зоні можна зберігати не лише текст, а й будь-які файли. Наприклад, туди можна запхати зашифрований архів RAR. Таку картинку з секретом можна опублікувати на Habrastorage або будь-якому іншому публічному хостингу — і лише той, хто знає, як діставати дані та має пароль, зможе прочитати послання. Саме цим методом зловмисні програми інколи передають свій payload через загальнодоступні сервіси.
PNG дає широкий простір для стеганографії — від простих приховань у каналах RGBA до більш хитромудрих прийомів, як PNG-наполнення поза видимою частиною зображення. Хоча базові методи (LSB в каналах, альфа-шари) легко перевірити звичайними інструментами, наповнення за межами картинки і зміна IHDR — це вже рівень, який вимагає уваги на бінарну структуру файлу й роботи з hex-редактором.