Files
Tajna-tretej-stolicy/stego-art-gallery/WRITEUP.md
2026-04-22 10:58:32 +03:00

3.3 KiB
Raw Blame History

Художественная галерея

Stego 979 pts

Изучаем выданный gallery.psd — PSD-файл с пятью слоями:

# Имя Состояние
0 Background видимый
1 Title видимый
2 Pattern A скрытый
3 Pattern B скрытый
4 Encrypted скрытый

Два из трёх скрытых слоёв — ложный след, а настоящий QR-код лежит в третьем и дополнительно зашифрован AES'ом.

Решение

PSD разбираем руками по официальной спецификации Adobe. Структура файла такая:

block-beta
  columns 1
  H["8BPS header"]
  CM["Color Mode Data"]
  IR["Image Resources<br/>XMP ID 0x0424 ← ключ к расшифровке"]
  LMI["Layer and Mask Info<br/>слои, флаги, каналы"]
  ID["Image Data"]

  classDef base fill:#f3f4f6,stroke:#6b7280,color:#111827
  classDef hit  fill:#fef3c7,stroke:#f59e0b,color:#78350f
  class H,CM,LMI,ID base
  class IR hit

В секции Image Resources ищем XMP-метаданные (блок с ID 0x0424) — там и запрятан ключ ко всей задаче. Внутри XMP смотрим на тег <xmp:CreateDate>: ISO 8601 timestamp создания файла. В секции Layer and Mask Information для каждого слоя лежит имя, флаги видимости (бит 0x02 в flags = «скрытый»), opacity и сырые данные каналов. Пиксельные данные хранятся несжатыми — можно напрямую залить в numpy-массив h × w.

Первое, что теперь приходит в голову при виде двух скрытых «паттернов» — это XOR'нуть их между собой. Берём Pattern A и Pattern B, XOR — получается картинка с вполне читаемым QR-кодом. Сканируем, внутри флаг, таск решён… кроме того, что флаг внутри фейковый. Настоящий QR живёт в третьем скрытом слое — Encrypted, и это шифротекст исходного QR в режиме AES-ECB.

Ключ для AES собирается из той самой timestamp-метки:

aes_key = sha256(timestamp.encode()).digest()[:16]

Расшифровываем R-канал в AES.MODE_ECB, снимаем PKCS#7-паддинг по последнему байту, интерпретируем результат как h × w grayscale-картинку. Внутри — настоящий QR, внутри QR — флаг. Если pyzbar с первого раза не узнал код, помогает NEAREST-апскейл в 23 раза.

Готовый солвер — solve/solver.py.

Флаг

caplag{l4y3rs_0f_d3c3pt10n_unv31l3d}