GumboGate
На старте доступны сервис очистки HTML-накладных и бинарь `gumbogate`. Загружаем тег поставщика, затем запрашиваем отчёт. Сервис возвращает отчёт только после одобрения, а поле одобрения лежит сразу за массивом атрибутов.
## Решение
Смотрим структуру страницы в куче:
```c
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`:
```python
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`. Проверка одобрения проходит, сервис отдаёт флаг.
[Солвер](solve/solve.py).
## Флаг
`caplag{attribute_bucket_walked_past_the_sanitizer}`