Райтап на задачу «Оптимизатор PNG»

dikiyponos

Автор:

dikiyponos

5 ноября 2026

3

05.11.2026
Оптимизатор PNG
Категория:

Web

Задача «Оптимизатор PNG»

LastTeamLead

Автор:

LastTeamLead

Первая кровь:
velvetway
Сложность:
medium
Дата публикации:
26.09.2026
Решений:
16
Рейтинг:
5/5
Ссылка:
Решать

Открываем таску и кайфуем от нового интерфейса БАГодельни. Спасибо Бегету, что немножко подтолкнул с релизом новой версии?) Прочитаем внимательно условие, нам надо положить сервер на 2+ секунды. Посмотрим, что вообще из себя представляет.

Решение задачи «Оптимизатор PNG»: иллюстрация 1

Мы можем загружать изображения. Попробуем загрузить скриншот этого сайта. Нажимаем оптимизировать и получаем ошибку.

Решение задачи «Оптимизатор PNG»: иллюстрация 2

Гуглим, что это вообще значит — «без чересстрочной развёртки». Гугл говорит, что это когда файл загружается в браузере или программе сверху вниз, строка за строкой. Попробуем наш скриншот конвертировать. Для этого используем ImageMagick.

Решение задачи «Оптимизатор PNG»: иллюстрация 3

И всё равно получаем эту же ошибку.

Решение задачи «Оптимизатор PNG»: иллюстрация 4

Оказывается, эта картинка — RGBA, то есть поддерживает alpha-канал. Серверу такие картинки не нравятся, поэтому загуглим, как получить чистый 8-битный RGB без альфа-канала.

Решение задачи «Оптимизатор PNG»: иллюстрация 5

Почему мы использовали PNG24? Это разве не 24 бита? Тут оно работает, что 24=8*3, то есть 8 бит на каждый RGB-канал.

Решение задачи «Оптимизатор PNG»: иллюстрация 6

Но всё равно мы получили ошибку. Загуглим, что вообще такое «способ фильтрации строк» и как его читать. Оказывается, что это предварительный этап обработки растрового изображения перед сжатием по алгоритму Deflate. Он может принимать разные значения, такие как None, Sub, Up, Average и Paeth. Я не буду делать вид, что понимаю, как это всё работает, нам оно и не надо. Наша цель — сделать максимально тупую и простую картинку, значит нам, скорее всего, нужен режим None, то есть 0, то есть фильтр не применяется, значения пикселей записываются в исходном виде. Как посмотреть, что у нас сейчас используется в картинке?

Решение задачи «Оптимизатор PNG»: иллюстрация 7

Для этого используем pngcheck и видим, что у нас используются самые разные фильтры. Чтобы сделать всё в 0, используем optipng.

Решение задачи «Оптимизатор PNG»: иллюстрация 8

Сохраняем скриншот и грузим его на сайт.

Решение задачи «Оптимизатор PNG»: иллюстрация 9

Отлично, мы проделали столько действий, чтобы понять какие же скриншоты всё-таки кушает сайт. Теперь нам по условию его надо как-то положить… Лимит на 64 КБ на сайте не врет, действительно 64+ КБ не принимает. Значит, нужна картинка, которая весит мало, а работы серверу даёт много.

Первая мысль — сделать decompression bomb, то есть маленький файл, который распаковывается в гигабайты. Но, увы, сервер ограничивает распакованный IDAT и отвечает «Размер данных изображения слишком большой для обработки». Значит, давить надо не объёмом данных, а метаданными.

Опытным путём можно понять, что сервер первым делом смотрит секцию IHDR. Попробуем указать там разрешение больше, чем есть по факту. Но если мы даже вручную в hex-редакторе поменяем размеры в IHDR-секции, то у нас не будет сходиться чексумма, о чём оповестит сервер. Вот бы была программа, которая всё сделает за нас…

Небольшим осинтом находим простенькую старую программу TweakPNG. Изначально она только для Windows, но и на Linux под Wine запускается замечательно. Открываем программу, закидываем скриншот и модифицируем секцию IHDR.

Решение задачи «Оптимизатор PNG»: иллюстрация 10
Решение задачи «Оптимизатор PNG»: иллюстрация 11

Вуаля, теперь сохраняем файл и пытаемся его отправить на сайт.

Решение задачи «Оптимизатор PNG»: иллюстрация 12

Для экстремалов, которые хотят вручную из консоли поменять IHDR-секцию, оставлю эту волшебную команду, которая сразу и CRC32 посчитает.

python3 -c 'import sys,zlib,struct;p=bytearray(open(sys.argv[1],"rb").read());struct.pack_into(">II",p,16,2000,2000);struct.pack_into(">I",p,29,zlib.crc32(p[12:29])&0xffffffff);open(sys.argv[2],"wb").write(p)' in.png out.png
Решение задачи «Оптимизатор PNG»: иллюстрация 13
Если вы нашли опечатку или ошибку, пожалуйста, выделите фрагмент текста и нажмите Ctrl+Enter

Также по теме:

Райтап на задачу «Слепая инъекция»

/Разборы задач

Райтап на задачу «Слепая инъекция»

Пишем скрипт для слепой SQL-инъекции по ответам true/false и разбираем альтернативу с sqlmap.
Прочитать

2

Райтап на задачу «Совсем слепая инъекция»

/Разборы задач

Райтап на задачу «Совсем слепая инъекция»

Извлекаем флаг через временную SQL-инъекцию в SQLite и отсеиваем случайные задержки ответа.
Прочитать

2