/Разборы задач
6 ноября 2026
Райтап на задачу «Слив флагов»
Исследуем WIM-образ через 7-Zip, находим альтернативный поток flag_404.txt и декодируем спрятанную строку Base64.8
17

Forensic
Задача «CTF-ер, который смог»
— Пейн, я не чувствую центральной директории!
— Буба, у тебя её нет!
Из условия задачи получаем подсказку: центральная директория — это «центральный каталог» формата ZIP, по сути, оглавление, лежащее в конце файла.
Пробуем переименовать Bubba в Bubba.zip и пробуем открыть:
Проводник, 7-Zip, WinRAR говорят, что архив повреждён либо у него неверный формат.
Но данные-то внутри остались. Надо достать их ручками.
Сигнатуры (байты), которые нам сто процентов пригодятся:
50 4B 03 04 — локальный заголовок файла;50 4B 07 08 — data descriptor, размеры после данных;50 4B 01 02 — запись центрального каталога;50 4B 05 06 — конец центрального каталога, EOCD.Открываем Bubba в HxD. Первое, что видим:
Мы ожидали 50 4B 03 04 — начало локального заголовка ZIP. А тут 66 69 66 75 78 = fifux.
Смотрим конец файла:
Вот он, 50 4B 07 08 — data descriptor. Разбираем его поля:
50 4B 07 08 — PK\x07\x08 (синий);B7 85 1A AD — 0xAD1A85B7 (красный);2A DE 03 00 — 253 482 (фиолетовый);27 F6 .. — обрезан (зелёный): в файле не хватает последних 2 байт. Это нам не мешает, так как наш сжатый размер полностью цел.Теперь желательно дополнительно пройтись по всему файлу и посмотреть, сколько раз встречается каждая сигнатура (удобнее через встроенный поиск, не забудьте поменять со строки на hex-значение):
50 4B 03 04 — 0;50 4B 01 02 — 0;50 4B 05 06 — 0;50 4B 07 08 — 1, его мы уже находили.То есть заголовки и оглавление кто-то «снёс», а дескриптор в конце остался. Именно он даёт нам зацепку.
Логика простая: data descriptor идёт сразу после сжатых данных. Значит, начало данных — это позиция дескриптора минус сжатый размер:
data_start = descriptor_offset − csize = 253517 − 253482 = 35 (0x23)Схема расположения:
Проверяем по hex: по смещению 0x23 (= 35) действительно начинаются байты 9C BB 69 58 52 6B ... — это уже похоже на сжатый поток (никакого 78 9C, как и должно быть в ZIP).
Теперь нужно распаковать raw deflate. Для этого берём байты с offset 35 до дескриптора (ровно 253 482 байта) и распаковываем.
import zlib
d = open('Bubba', 'rb').read()
i = d.rfind(b'PK\x07\x08') # позиция дескриптора
csize = int.from_bytes(d[i+8:i+12], 'little')
start = i - csize
raw = zlib.decompress(d[start:i], -15) # -15 = raw deflate
open('bubba.jpg', 'wb').write(raw)
print(start, csize, len(raw))С помощью скрипта мы получаем вывод, где FF D8 FF E0 — сигнатура JPEG:
start = 35
packed = 253482
unpacked = 259623
первые байты = FF D8 FF E0Открываем bubba.jpg, записываем флаг и ставим 5 звёзд таску за хороший фильм: