Files
Serdtse-Sysoly/qualifiers/commbridge-pwn-medium/WRITEUP.md
T
2026-09-17 00:50:07 +03:00

48 lines
2.9 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">CommBridge</h1>
<p align="center">
<img src="https://img.shields.io/badge/category-PWN-blueviolet" alt="PWN"/>
<img src="https://img.shields.io/badge/difficulty-medium-orange" alt="medium"/>
</p>
CommBridge работает как шлюз между SCADA-сервером и контроллерами. В нём авторизуемся, отправляем команду и подтверждаем её выполнение. В раздатке есть ELF `commbridge`. Для экспорта нужны два служебных поля, которые обычная команда не выставляет.
## Решение
В обработчике `auth` находим сравнение с постоянным токеном `operator`. Передаём его в пункте `1) auth` и переходим к приёму команды. Она декодируется в такую структуру на стеке:
```c
struct frame {
char decoded[64];
uint32_t access;
uint32_t cmd;
};
```
Для экспорта нужны `access = 0x434d4447` и `cmd = 0x26050613`. Оба поля лежат сразу за `decoded`, так что смотрим, сколько данных туда можно записать.
Сырая строка ограничена 120 символами. Но декодер понимает последовательность `@NNXX`: пять символов превращаются в `NN` копий байта `XX`, причём оба числа записаны в hex. Размер результата уже никто не проверяет. Получаем переполнение стека через расширение короткой команды.
Заполняем 64 байта буфера одной последовательностью `@40aa`, а затем дописываем две нужные константы в little-endian:
```python
import struct
rights = struct.pack("<II", 0x434d4447, 0x26050613)
payload = "@40aa" + "".join(f"@01{byte:02x}" for byte in rights)
```
| Представление | Длина |
|---|---:|
| Сырая команда | `5 + 8 × 5 = 45` символов |
| После декодирования | `64 + 8 = 72` байта |
| Буфер назначения | 64 байта |
45 символов легко проходят входной лимит, а лишние восемь байт затирают `access` и `cmd`. Отправляем строку через `2) send escaped command`, после чего поля копируются в `pending_access` и `pending_cmd`. Выбираем `3) commit command`. Сервис проверяет значения `pending_access` и `pending_cmd` и возвращает флаг.
[Солвер](solve/solve.py).
## Флаг
`caplag{escaped_scada_command_expanded_into_dispatch_rights}`