Skip to content
KitploitKITPLOIT
ツールエクスプロイトブログ
Log in
提出
ツールエクスプロイトブログ
提出

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

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

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

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
CVE-2026-89633 — CVE-2026-89633のPoCおよびエクスプロイトチェーン。Linux cifs.koのSMB1 TRANS2結合パスにおけるヒープ領域の境界外書き込みであり、cred上書きとPTEエイリアシングを経てuid 0へ権限昇格する。 | Kitploit
ツール/GitHubGitHub/woshigenm/cve-2026-89633
Androidセキュリティ特権昇格メモリフォレンジック脆弱性分析エクスプロイト論文と研究バイナリエクスプロイト
GitHubwoshigenm/cve-2026-89633

CVE-2026-89633

CVE-2026-89633のPoCおよびエクスプロイトチェーン。Linux cifs.koのSMB1 TRANS2結合パスにおけるヒープ領域の境界外書き込みであり、cred上書きとPTEエイリアシングを経てuid 0へ権限昇格する。

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

人気

すべて見る →

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

すべてのツールを探索

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

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

CVE-2026-89633 — cifs SMB1 coalesce_t2 ヒープOOB書き込み

日本語 | 简体中文

Linux cifs.ko SMB1クライアントにおけるヒープ境界外書き込みの研究用PoC/EXP。悪意のあるSMB1サーバーがTRANS2セカンダリレスポンス内のDataOffsetを制御し、coalesce_t2()が8バイトのセカンダリペイロードを&primary->Protocol + DataOffset + accumulatedへターゲット境界チェックなしにコピーする。コピー先はレスポンスバッファ(server->bigbuf)を基準に、サーバーが指定した任意の位置となる。

本リポジトリは役割の異なる2つのデモを保持しており、これらは代替関係にはない:

  • POC — OOB書き込みをトリガーして観測する: 悪意のあるSMB1サーバーと、実行時にDataOffsetをパッチするTCPプロキシ。
  • EXP 1 (最小プリミティブ) — 書き込みを実際のcredential上書きに変換するroot側の参照チェーン: ターゲットプロセスのcred slabページをパイプ制御の物理ページ上に配置し、4フレームのcoalesceレスポンスでuid/gid/suid/sgid/euid/egid/fsuid/fsgidをゼロにする。OOB書き込みが制御可能でありcredを改変できることを示す最も直接的な証明であり、依存関係が最も少ない。
  • EXP 2 (高度プリミティブ) — シェルのみのPTEチェーン: 同じOOB書き込みでユーザー書き込み可能なPTEを設置し、エイリアスがcredページおよび任意でselinux_stateをマップし、クローンがroot側の観測なしにuid 0かつ全capを持つようになる。これはEXP 1の拡張であり、置き換えではない。

カーネルモジュールのロードは本リポジトリでは意図的にスコープ外としている: チェーンはuid 0 (および任意でselinux_stateをpermissive) で停止し、モジュールをインストールしない。モジュールをロードしなくても、uid 0 + permissiveが本リポジトリの主張する完全なLPEデモである。

EXP 2のコストは明示されたままである: ウィンドウごとの抽選 (25–33%、12回の試行で97–99%)、再起動まで有効なままのベアPTE、シェル書き込み可能なtracefsへの依存、そしてビルド固有のdirect-map/コールサイト/SEL_PFNの仮定。EXP 1は最も単純なプリミティブ証明であり、シェル書き込み可能なtracefsが利用できない場合のフォールバックでもある。

ステータス

項目値
CVECVE-2026-89633
クラスヒープ境界外書き込み (CWE-787)
コンポーネントcifs.ko、SMB1 TRANS2セカンダリのcoalescing
アップストリーム修正36d01415d881 ("smb: client: fix ... coalesce_t2", 6.12.113)
POCトリガーとOOB書き込みを検証済み (マウント後およびマウント中)
EXP 1 (最小プリミティブ)root側観測下での4フレームOOB cred書き込み; uid 0を検証済み (マウント後およびマウント時の保持レスポンス)
EXP 2 (高度プリミティブ)シェルのみのPTEチェーン; uid 2000 → uid 0 + 全cap + Permissiveを検証済み (SEL_PFN/SEL_OFF); ベアPTEで停止し、モジュールロードなし
要件攻撃者制御のサーバーへのSMB1マウント (特権ゲート); 参照ゲートはsuを使用し、シェルのみの配置にはシェル書き込み可能なtracefsが必要

テスト環境: arm64 Android 16ベンダービルド、カーネル6.12.38、cifs.koは6.12.23 KMIベースラインからビルド、SELinux enforcing。

テストスコープ

  • 検証済み: 上記のarm64 Android 16ビルド (カーネル6.12.38、cifs.koは6.12.23 KMIベースライン由来) — POCのトリガー/OOB書き込み (マウント後およびマウント自体の最中、マウントポイントへのアクセスなし)、EXP 1のroot側参照チェーン (uid 0)、マウント時の保持レスポンス変種 (statfsなし、マウントポイントへのアクセスなし)、EXP 2のシェルのみの配置 (tracefsのみ、root側観測なし)、EXP 2の完全な受け入れ (uid 0 + 全capビット + SEL_PFN/SEL_OFFによるPermissive)、およびsu駆動のマウントゲート (マウントのみrootで実行; 配置はuid 2000で実行) を、SELinux enforcing下でテストした。
  • 未検証: 他の6.12.xビルド、他のAndroidバージョン/SoC、純正AOSP GKIカーネル、または非arm64プラットフォーム。コールサイトのリンク、構造体オフセット、direct-map定数はビルド固有である; EXPが動作することを期待する前に、別のカーネルで再検証すること。

バグ

MAX_CIFS_SMALL_BUFFER_SIZE - 4(444 バイト)を超える SMB1 TRANS2 レスポンスの場合、クライアントはプライマリを server->bigbuf に保持し、それを mid->resp_buf に格納します。後続の SMB_COM_TRANSACTION2_SECONDARY レスポンスは cifs_check_trans2() -> check2ndT2() -> coalesce_t2() を経由します:

data_area_of_tgt = &primary->Protocol + primary->DataOffset + total_in_tgt;
memcpy(data_area_of_tgt, data_area_of_src, secondary->DataCount);

DataOffset はサーバー応答からそのまま取得されます。カウンターチェック (total_in_tgt/byte_count のオーバーフロー、ソースバッファの境界)は存在しますが、 data_area_of_tgt が応答バッファ内に収まるかどうかのチェックはありません。 各セカンダリフレームは 8 バイトずつ先に進む(累積された DataCount)ため、 マルチフレーム応答では、バッファベースからの攻撃者指定のオフセット(16 ビット)に 8*N バイトの書き込みが発生します。

トリガー条件:

  1. クライアントが、攻撃者が制御するサーバーから SMB1 共有をマウントする(vers=1.0)。
  2. クライアントが任意の TRANS2 リクエストを発行する(PoC では statfs 経由で QUERY_FS_INFORMATION を使用)。
  3. サーバーが、TotalDataCount > DataCount かつ bigbuf パスに十分な大きさの プライマリで応答し、その後 TotalDataCount > DataCount のセカンダリフレームを 1 つ以上返す。

リポジトリ構成

Makefile
src/poc/poc_smb1_trans2.py   malicious SMB1 server (QFS hook, runtime ctl)
src/poc/smb1_proxy.py        TCP proxy: patches DataOffset, repeats secondaries
src/exp/pipesearch.c         pipe placement/write driver (modes 3, 8, 9)
src/exp/shcred.c             shell-side drain + clone helper (uid 2000)
src/exp/shp4a2.c             trace-based drainer/observer/clone (modes 8/9)
src/exp/pte_fault.c          2 MiB fault + PTE alias writes
src/exp/bscan.c              bigbuf discovery by call site (no kprobes)
src/exp/kslide.c             KASLR slide from a raw call site
src/exp/smbd.c               device-side SMB1 server (held TRANS2)
src/exp/smbd_templates.h     SMB1 response templates for smbd
src/exp/pfn.c                linear-map VA to pfn
src/exp/kflags.c             /proc/kpageflags reader
scripts/setup_device.sh      trace instance + kprobes (root on device)
scripts/start_servers.sh     host: SMB1 server + proxy + mount helper
scripts/probe_round.sh       one probe round: bigbuf base + free target page
scripts/place.sh             placement: pipesearch mode 3 + shcred
scripts/write_cred.sh        4-frame coalesce write + /proc verification
scripts/mount_su.sh          generic su mount gate (target/decoy/abort/unmount)
scripts/chain_shell.sh       shell-only placement for an already-held TRANS2
scripts/gen_smb_templates.py regenerates smbd_templates.h from a capture
docs/analysis.md             vulnerability and chain analysis
docs/exp-protocol.md         shared-page and smbd ctl protocols

ビルド

make deps        # checks impacket
make helpers     # NDK cross-build of all C helpers
make push        # adb push to /data/local/tmp

NDK、API、ARCH、ADB、DEVICE_DIR は上書き可能です。

POC — OOB 書き込みのトリガーと観測

トリガー自体に必要なのは SMB1 マウントと、実行中のサーバー/プロキシだけです。 kprobes と kflags は観測用の補助手段であり、トリガーの一部ではありません — dst/src/len の証拠が必要なときにインストールしてください(また、以下の EXP チェーンでは これらが必須です。bigbuf のベース、配置の監視、対象の cred アドレスが必要となるためです)。

  1. デバイス(root、任意 — 観測のみ): プローブをインストールします。

    adb push scripts/setup_device.sh /data/local/tmp/
    adb shell su -c 'sh /data/local/tmp/setup_device.sh'
    adb push build/kflags /data/local/tmp/kflags
    
  2. ホスト側: SMB1 サーバーとプロキシを起動します(このスクリプトは共有ディレクトリも作成し、マウントコマンドを表示します):

    scripts/start_servers.sh /tmp/cifs01-ctl
    

    1470 上で src/poc/poc_smb1_trans2.py を、また制御ディレクトリ /tmp/cifs01-ctl を指定して src/poc/smb1_proxy.py(1460 -> 1470)を実行します。

  3. ローカルテストトポロジ: プロキシポートをデバイスにマッピングし、デバイス上で root として共有をマウントします。

    adb reverse tcp:1460 tcp:1460
    adb shell su -c 'mkdir -p /mnt/cifs'
    adb shell su -c 'mount -t cifs //127.0.0.1/share /mnt/cifs \
        -o vers=1.0,port=1460,username=test,password=test,sec=ntlmssp'
    
    • vers=1.0 は脆弱な SMB1 パスを選択します(SMB2/3 は coalesce_t2 に到達しません)。
  • port=1460 はこのトポロジーにおけるプロキシポートです。サーバーがデフォルトの 445 で待ち受けている実際のネットワークではこれを省略してください。

  • username=test,password=test は PoC サーバーの認証情報です。

  • sec=ntlmssp は PoC サーバーが受け入れるセキュリティモードです。

  • //127.0.0.1/share はサーバー/共有です。マウントポイントは任意です。

    マウントは特権的なゲートです — 下記の「到達可能性」を参照してください。

  1. 1 ラウンドをトリガーします(フックを武装させ、悪意のあるプライマリを保持し、DataOffset をパッチし、解放します)。

    scripts/probe_round.sh 1
    

    プローブをインストールした状態では、インスタンストレースに oobpri(プライマリヘッダフィールド)と cifs01m/cifs01mv(memcpy の dst/src/len/val)が含まれる。デフォルトプローブ DataOffset=0x4100 では、dst - prim は 0x4104 となり、16640 バイトの cifs_request slab オブジェクト(32 KiB order-3 slab の末尾パディング)を超えるため、この書き込みは実際にオブジェクト外への書き込みであり、他のアロケーションを破壊することはない。一方 DataOffset=0 では SMB ヘッダフィールドをその場で書き換える。

EXP 1 — 最小プリミティブ: OOB cred 書き込み

単なるトリガーとは異なり、EXP 1 は観測補助をエクスプロイトの一部として使用する。cifsget は次のレスポンスの bigbuf ベース B を提供し、root ツールの /proc/kpageflags 読み取りがページ配置を誘導し、credprep トレースが対象子プロセスの cred アドレスを提供する。POC セクションと同じサーバ/プロキシを使用する。

連鎖の概要(詳細は docs/analysis.md と docs/exp-protocol.md を参照):

  1. probe — 次のレスポンスで使用される bigbuf ベース B と、pfn(B)+8..pfn(B)+16 内の空き物理ページ P を学習する(scripts/probe_round.sh)。
  2. place — scripts/place.sh が pipesearch モード 3 と shcred を実行する。対象ページは最後に解放されて CPU の per-CPU ページリストに入り、シェルは setfsuid で memcg cred キャッシュを排出し、root ツールは kpageflags(P) が cred slab(0x80)になるまでポーリングして排出を停止し、シェルは 1 つの子プロセスをクローンし、その copy_creds() が現在の slab の空きオブジェクト — P — を取得する。
  3. write — scripts/write_cred.sh が TotalDataCount=32 のプライマリと 4 つの 8 バイトセカンダリフレームを送信する。DataOffset = (cred - B) + 4 とすることで、4 つの合体書き込みが uid/gid、suid/sgid、euid/egid、fsuid/fsgid をゼロにする。
  4. verify — /proc/<child>/status が Uid: 0 0 0 0 / Gid: 0 0 0 0 を示す。

テストビルドで検証済み:

ツールをダウンロード