Files
2026-09-17 00:50:07 +03:00

44 lines
2.3 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<h1 align="center">GumboGate</h1>
<p align="center">
<img src="https://img.shields.io/badge/category-PWN-blueviolet" alt="PWN"/>
<img src="https://img.shields.io/badge/difficulty-easy-brightgreen" alt="easy"/>
</p>
На старте доступны сервис очистки 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}`