/Разборы задач
5 ноября 2026
Райтап на задачу «Слепая инъекция»
Пишем скрипт для слепой SQL-инъекции по ответам true/false и разбираем альтернативу с sqlmap.2
3

Web
Задача «Оптимизатор PNG»
Открываем таску и кайфуем от нового интерфейса БАГодельни. Спасибо Бегету, что немножко подтолкнул с релизом новой версии?) Прочитаем внимательно условие, нам надо положить сервер на 2+ секунды. Посмотрим, что вообще из себя представляет.
Мы можем загружать изображения. Попробуем загрузить скриншот этого сайта. Нажимаем оптимизировать и получаем ошибку.
Гуглим, что это вообще значит — «без чересстрочной развёртки». Гугл говорит, что это когда файл загружается в браузере или программе сверху вниз, строка за строкой. Попробуем наш скриншот конвертировать. Для этого используем ImageMagick.
И всё равно получаем эту же ошибку.
Оказывается, эта картинка — RGBA, то есть поддерживает alpha-канал. Серверу такие картинки не нравятся, поэтому загуглим, как получить чистый 8-битный RGB без альфа-канала.
Почему мы использовали PNG24? Это разве не 24 бита? Тут оно работает, что 24=8*3, то есть 8 бит на каждый RGB-канал.
Но всё равно мы получили ошибку. Загуглим, что вообще такое «способ фильтрации строк» и как его читать. Оказывается, что это предварительный этап обработки растрового изображения перед сжатием по алгоритму Deflate. Он может принимать разные значения, такие как None, Sub, Up, Average и Paeth. Я не буду делать вид, что понимаю, как это всё работает, нам оно и не надо. Наша цель — сделать максимально тупую и простую картинку, значит нам, скорее всего, нужен режим None, то есть 0, то есть фильтр не применяется, значения пикселей записываются в исходном виде. Как посмотреть, что у нас сейчас используется в картинке?
Для этого используем pngcheck и видим, что у нас используются самые разные фильтры. Чтобы сделать всё в 0, используем optipng.
Сохраняем скриншот и грузим его на сайт.
Отлично, мы проделали столько действий, чтобы понять какие же скриншоты всё-таки кушает сайт. Теперь нам по условию его надо как-то положить… Лимит на 64 КБ на сайте не врет, действительно 64+ КБ не принимает. Значит, нужна картинка, которая весит мало, а работы серверу даёт много.
Первая мысль — сделать decompression bomb, то есть маленький файл, который распаковывается в гигабайты. Но, увы, сервер ограничивает распакованный IDAT и отвечает «Размер данных изображения слишком большой для обработки». Значит, давить надо не объёмом данных, а метаданными.
Опытным путём можно понять, что сервер первым делом смотрит секцию IHDR. Попробуем указать там разрешение больше, чем есть по факту. Но если мы даже вручную в hex-редакторе поменяем размеры в IHDR-секции, то у нас не будет сходиться чексумма, о чём оповестит сервер. Вот бы была программа, которая всё сделает за нас…
Небольшим осинтом находим простенькую старую программу TweakPNG. Изначально она только для Windows, но и на Linux под Wine запускается замечательно. Открываем программу, закидываем скриншот и модифицируем секцию IHDR.
Вуаля, теперь сохраняем файл и пытаемся его отправить на сайт.
Для экстремалов, которые хотят вручную из консоли поменять 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