Files
Tajna-tretej-stolicy/reverse-dungeon-crawler/WRITEUP.md
2026-04-22 10:58:32 +03:00

40 lines
3.3 KiB
Markdown
Raw 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">Dungeon Crawler</h1>
<p align="center">
<img src="https://img.shields.io/badge/category-Reverse-blueviolet" alt="Reverse"/>
<img src="https://img.shields.io/badge/points-888-orange" alt="888 pts"/>
</p>
Бинарь перед нами — прототип навигационной системы для подземельного робота. Робот обязан пройти лабиринт от входа до выхода, и если маршрут верный, программа выдаёт секретный код. Формат ввода — строка из `U`/`D`/`L`/`R`. Внутри бинаря, если аккуратно поковыряться, находится сразу четыре лабиринта — три в открытом виде и один зашифрованный. Вся задача построена вокруг того, чтобы сбить с пути автоматические солверы.
## Решение
Начинаем с того, что лежит на виду. В `.rodata` три лабиринта 20x20 в plaintext, у каждого даже есть корректный путь от входа до выхода. Подставляем — получаем мусор.
Настоящий лабиринт четвёртый, того же размера, но хранится зашифрованным. Ключ — CRC32 от конкатенации:
```text
checkpoint_keys ‖ moving_wall_positions ‖ magic_constant
```
То есть чтобы его расшифровать, нужно сначала восстановить всю структуру данных, а не просто дёрнуть строку. Дальше три ловушки:
| # | Ловушка | Как работает |
|---|---|---|
| 1 | Три plaintext-лабиринта в `.rodata` | Все три имеют валидный путь, но ведут к неправильным ответам |
| 2 | Движущиеся стены | 3 позиции меняются в зависимости от номера шага: `step % 5 < 3` → открыто, иначе → закрыто |
| 3 | `getpid() ^ getpid()` в расшифровке флага | Выглядит как PID-зависимая соль, всегда равен нулю |
Вторая ловушка — самая неприятная. Если извлечь лабиринт статикой и запустить обычный BFS, правильного пути он не найдёт. BFS обязан знать текущий шаг и состояние подвижных стен именно на этом шаге.
Правильный порядок действий:
1. Разбираем структуру данных (checkpoints + moving walls → derived key).
2. Расшифровываем настоящий лабиринт.
3. Гоняем BFS с учётом номера шага и состояния движущихся стен.
4. Собираем контрольные точки по пройденному маршруту.
5. Расшифровываем флаг через [LFSR](https://en.wikipedia.org/wiki/Linear-feedback_shift_register).
## Флаг
`caplag{3v3ry_w4ll_h4s_4_d00r}`