2.5 KiB
Allocator War
С первого взгляда обычный каталог: создать запись, изменить описание, посмотреть, удалить. Косяк опять с памятью, там самописный аллокатор с кешем. При старте сервис кладёт флаг в 64-байтный буфер, сохраняет указатель в глобальной last_freed_ptr — и этот буфер никогда не чистится.
Создание записи идёт через обычный malloc, а вот изменение — через alloc_or_reuse(). Если в edit попросить буфер ровно такого же размера, как лежит в кеше, аллокатор без проблем отдаст старый буфер с флагом.
Решение
Первая подсказка скрыта прямо в интерфейсе — в меню есть недокументированная диагностическая команда 9:
cache: last_freed_size=64, flag_cache_size=64
Значит, чтобы выдернуть флаг, надо заставить сервис переиспользовать именно 64-байтный блок, и сделать это на этапе edit.
План:
- Создаём любую запись произвольного размера (лишь бы жила).
- Редактируем её, просим новый размер
64. - На ввод описания отправляем пустую строку.
- Смотрим запись.
Сервис сначала выделит буфер из кеша, а потом запишет в него ровно столько байт, сколько пришло от пользователя. Ноль байт = ноль записи, и старое содержимое буфера (флаг) остаётся на месте.
При просмотре сервис печатает и описание, и hex-дамп содержимого. В дампе и светится флаг.
Минимальный солвер.
Флаг
caplag{Some_thing_is_here_not_there}