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

43 lines
2.6 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">RawForge X3F</h1>
<p align="center">
<img src="https://img.shields.io/badge/category-PWN-blueviolet" alt="PWN"/>
<img src="https://img.shields.io/badge/difficulty-hard-critical" alt="hard"/>
</p>
RawForge X3F обрабатывает RAW-снимки с дронов. По ELF `rawforge-x3f` видно, что размер изображения проверяется через произведение размеров, а число записываемых samples берётся из другого поля. Если произведение переполнится, проверка пропустит запись, которая выйдет за границу массива.
## Решение
Кадр начинается с `X3F0`, затем идут четыре `u32 LE`: `cols`, `rows`, `chans`, `samples`. Сервис вычисляет `alloc = cols * rows * chans` в 32 битах и требует `alloc <= 8`. Потом без дополнительной проверки записывает `samples` 16-битных слов в `pixels[8]`.
Берём `cols = 0x40000001`, `rows = 4`, `chans = 1`:
$$0x40000001 \cdot 4 \bmod 2^{32} = 4.$$
Лимит соблюдён, хотя реальные размеры огромные. Теперь используем независимое поле `samples`, чтобы выйти из 16-байтного массива пикселей в соседние поля:
| Смещение от `pixels` | Поле | Значение |
|---:|---|---|
| 16 | `magic`, 8 байт | `0x5833464a4f423031` |
| 24 | `target`, 8 байт | `0x5845504f52542121` |
| 32 | `approved`, 4 байта | `0x584f4b21` |
Собираем 36 байт данных, то есть 18 samples:
```python
import struct
values = b"\x00" * 16
values += struct.pack("<QQI", 0x5833464a4f423031, 0x5845504f52542121, 0x584f4b21)
frame = b"X3F0" + struct.pack("<IIII", 0x40000001, 4, 1, 18) + values
```
Кадр занимает 56 байт, включая 20 байт заголовка. В `1) upload x3f frame` на запрос `frame bytes:` передаём строку `56`, затем на `payload:` отправляем все 56 байт без добавленного перевода строки. Ответ `decoded alloc_words=4 samples=18` подтверждает нужное расхождение. После этого `2) export processed inspection` видит подменённые поля задания и отдаёт флаг.
[Солвер](solve/solve.py).
## Флаг
`caplag{raw_dimensions_wrapped_the_sensor_job}`