# Sonobank: описание, уязвимости + PoCs, харденинг ## Что за сервис UDP‑сервис, говорящий на SysEx‑фреймах (опкоды 0x01–0x05). Основные операции: - `Diag` — проверка живости. - `Put` — принимает Lua DSP‑скрипт, шифрует и сохраняет как патч (`patch_id`, приватный ключ выдаётся в ответе). - `Get` — возвращает публичный ключ и шифротекст патча по `patch_id`. - `RenderHash` — расшифровывает Lua и вызывает `sample()`, хешируя значения. - `GetCryptoParams` — отдаёт параметры группы. Патчи лежат на диске как `data/.pb` в TLV‑формате: k, c1, ct, iv, End. ## Уязвимость 1: Lua не песочница, утечки через RenderHash - `lua-sandbox::render_hash` создаёт полноценный Lua без ограничения stdlib; доступны `io.open`, `os`, и т.п. - Ошибки из Lua пробрасываются в ответ `RenderHash` (server возвращает `Error("Couldn't compute hash: <сообщение>")`). - Итог: любой может загружать произвольный Lua и читать локальные файлы, затем вернуть их содержимое через `error()`. ### Эксплуатация (PoC `lua_poc.py`) Выгружает содержимое чужого патча `data/.pb`, расшифровывает его и печатает исходный Lua (в нём хранится флаг). ``` python3 sploits/sonobank/lua_poc.py [port=5004] ``` Скрипт: 1) Делает `Put` с Lua, который читает `data/.pb` и бросает его в ошибке как hex. 2) Делает `RenderHash` на своём патче, получает `Error`, парсит TLV, выводит расшифрованный Lua жертвы. ### Харденинг - Создавать Lua с отключёнными I/O: `Lua::new_with(mlua::StdLib::BASE | ... )` без `IO`/`OS`, или `set_sandboxed(true)`. - Явно очищать/затирать глобальные таблицы (`io`, `os`, `package`). - Не выдавать текст ошибки пользователю — логировать на сервере, клиенту слать общий код. ## Уязвимость 2: Крипто на слабой группе, dlog решается - Кольцо — GF(2)[x]/P(x), которое притворяется GF(p). - Полином P(x) раскладывается как Q(x)^5, поэтому порядок мультипликативной группы (2^210 - 1) умножить на небольшое число. - В этом случае порядок группы равен (2^210 - 1) * 8, Этот порядок гладкий и позволяет алгоритмом Полига-Хеллмана посчитать длог. Для ускорения сначала считаем по модулю Q(x). ### Эксплуатация (PoC `crypto_sploit.py`) Запуск под `sage -python` (используется `sage.all`): ``` sage -python sploits/sonobank/crypto_sploit.py ``` Скрипт: 1) Берёт `GetCryptoParams`, затем `Get` по `flag_id` (`patch_id`). 2) Факторизует модуль, решает дискретный логарифм, восстанавливает общий ключ и расшифровывает AES‑CBC. 3) Печатает Lua с флагом. ### Харденинг - Заменить модуль на неприводимый с удачной степенью, например, 127 (2^127 - 1 является простым числом Мерсенна). Тогда группа будет вполне подходящей. ## Полезные файлы - `sploits/sonobank/lua_poc.py` — утечка через Lua. - `sploits/sonobank/crypto_sploit.py` — взлом DLog. - `services/sonobank/crates/lua-sandbox/src/lib.rs` — источник Lua уязвимости. - `services/sonobank/crates/crypto/src/encryption.rs` — уязвимый DH.