2.9 KiB
CommBridge
CommBridge работает как шлюз между SCADA-сервером и контроллерами. В нём авторизуемся, отправляем команду и подтверждаем её выполнение. В раздатке есть ELF commbridge. Для экспорта нужны два служебных поля, которые обычная команда не выставляет.
Решение
В обработчике auth находим сравнение с постоянным токеном operator. Передаём его в пункте 1) auth и переходим к приёму команды. Она декодируется в такую структуру на стеке:
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:
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 и возвращает флаг.
Флаг
caplag{escaped_scada_command_expanded_into_dispatch_rights}