CVE-2026-39987 в marimo позволила получить шелл без аутентификации
CVE-2026-39987 позволяет выполнять код удалённо до аутентификации в marimo и затрагивает версии до 0.20.4 включительно. Уязвимость исправлена в версии 0.23.0. Эксплуатация привела к получению интерактивной PTY-оболочки с привилегиями пользователя процесса marimo, извлечению учётных данных и последующей аутентификации на хосте-бастионе по закрытому SSH-ключу.
Эксплуатация WebSocket-эндпоинта и учётные данные
Эндпоинт /terminal/ws не выполнял проверку аутентификации. Любой клиент, способный установить WebSocket-соединение, мог получить интерактивную PTY-оболочку. Для эксплуатации требовалось только открытое WebSocket-соединение, кодирование полезной нагрузки не применялось.
Актор провёл цепочку атак на основе перехвата учётных данных. Один набор учётных данных был получен из переменных окружения и локальных файлов с учётными данными. Второй набор восстановили с помощью запроса к Redis к зашифрованным данным учётных данных, хранившимся в приложении.
Затем актор использовал скрипты boto3 для запроса к AWS Secrets Manager, получил закрытый SSH-ключ хоста-бастиона, записал его локально и аутентифицировался на бастионе. Полная последовательность действий, от установления WebSocket-соединения до запроса в AWS и аутентификации по SSH, заняла примерно восемь секунд.
Скрипты, AWS EC2 Instance Connect и индикаторы
Актор вручную разрабатывал и отлаживал инструменты на Python в течение нескольких сессий. Скрипты передавались в каталог /tmp/ в виде файлов, закодированных в base64, а затем запускались фоновыми командами nohup python3. Среди инструментов были код обратной оболочки на основе стандартной библиотеки Python и автоматизация SSH на базе Paramiko.
За 17 минут актор создал восемь вариантов скриптов. В более поздних версиях появились обработка исключений и тайм-ауты сокетов. Также актор предпринял попытку использовать AWS EC2 Instance Connect. Перечисление инстансов вернуло ошибку UnauthorizedOperation, однако автоматизация всё равно вызвала SendSSHPublicKey, передав идентификатор инстанса-заглушку i-0000000000000000. Это сформировало характерный поведенческий индикатор.
К соответствующим индикаторам на хосте относятся:
/tmp/chain.py;/tmp/full_chain.py;/tmp/bastion_keyс ограничительными правами доступа;/tmp/chain.log;/tmp/chain_output.txt;/tmp/callback.log.
Наблюдаемые поведенческие индикаторы включают:
- декодирование скриптов Python из base64 в каталог
/tmp/; - быстрое выполнение фоновых цепочечных скриптов;
- вызовы Secrets Manager через boto3 с перебором регионов
us-west-2,eu-west-1,ap-southeast-1иus-east-2; - SSH-соединения через Paramiko от имени root.
Наблюдаемые адреса источника и C2, 172.236.12.17 и 45.79.187.72, размещались в AS63949.
При обнаружении авторы отчёта рекомендуют уделять приоритетное внимание такой последовательности:
- доступ через WebSocket;
- использование учётных данных;
- извлечение данных из Secrets Manager;
- развёртывание SSH-ключа;
- исходящее соединение с бастион-хостом.
Отчет получен из сервиса CTT Report Hub. Права на отчет принадлежат его владельцу.
Ознакомиться подробнее с отчетом можно по ссылке.



