2.3 KiB
GumboGate
На старте доступны сервис очистки HTML-накладных и бинарь gumbogate. Загружаем тег поставщика, затем запрашиваем отчёт. Сервис возвращает отчёт только после одобрения, а поле одобрения лежит сразу за массивом атрибутов.
Решение
Смотрим структуру страницы в куче:
struct attr { char name[8]; char value[8]; };
struct page {
struct attr attrs[8];
uint32_t approved;
char report[64];
};
Для экспорта нужно approved == 0x52505041. В little-endian это четыре ASCII-байта APPR.
Парсер выбирает корзину по длине имени: bucket = strlen(name) & 7. Затем берёт slot = used[bucket]++ и пишет в attrs[slot]. Верхнюю границу счётчика не проверяют, поэтому девятый атрибут одной корзины попадает в несуществующий attrs[8].
Один атрибут занимает 16 байт, поэтому девятый начинается по смещению 8 × 16 = 128, ровно на поле approved. Первые четыре байта его имени зададут значение этого поля.
Все имена делаем длиной восемь символов, чтобы они попали в корзину 0:
attrs = [f"A{i:07d}=x" for i in range(8)]
attrs.append("APPR0000=x")
tag = "<" + " ".join(attrs) + ">"
Восемь первых имён заполняют массив, APPR0000 выходит за его границу и выставляет нужную константу. Отправляем тег в 1) ingest supplier tag, затем выбираем 2) export cleaned report. Проверка одобрения проходит, сервис отдаёт флаг.
Флаг
caplag{attribute_bucket_walked_past_the_sanitizer}