🏠 ホーム ニュース 📖 解説記事 📚 トピック解説 🏷️ タグ一覧 ℹ️ About
🔍 記事を検索
カテゴリ
📡 RSSフィード
Follow
X (Twitter) Threads
Quick Links
ニュース一覧 🏷️ タグから探す
🧠 Claude 🤖 Agent 💬 LLM 🔌 MCP 🛠️ Tool
Subscribe
📡 RSSフィード
Breaking News
2026.04.01 23:24 security coding devops

ClaudeがFreeBSDのカーネルRCE脆弱性CVE-2026-4747を完全自動生成。AIが実装した遠隔攻撃コード

🔓 ニュース
🔓 AI Heartland News
TL;DR
AIアシスタント「Claude」がFreeBSD 14.4のRPCSEC_GSS実装に存在するスタックバッファオーバーフロー脆弱性CVE-2026-4747の完全な遠隔カーネル実行コードを生成。15段階のROP チェーン攻撃でroot権限逆シェルを獲得。

何が起きたか

FreeBSD RPCSEC_GSS実装に存在するスタックバッファオーバーフロー脆弱性(CVE-2026-4747)が公開された。NFS サーバー(ポート2049/TCP)に対してKerberos認証を使用した攻撃により、カーネル実行(RCE)からroot権限を持つリバースシェル奪取が可能となる。

背景と経緯

FreeBSD カーネルの RPC サブシステム内 kgssapi.ko モジュールの svc_rpc_gss_validate() 関数に、長年見落とされていた境界チェック欠陥が存在する。RPCSEC_GSS 認証を使用する RPC パケットの処理時に、認証情報本体(credential body)のサイズ検証を省略したまま 128 バイトのスタックバッファへ memcpy() を実行。ファイアウォール背後やKerberos 環境のあるエンタープライズNFS サーバーは継続的な攻撃リスクにさらされている。

技術的詳細:バッファオーバーフロー機構

脆弱なコードは以下の構造:

static bool_t svc_rpc_gss_validate(struct svc_rpc_gss_client *client,
                                    struct rpc_msg *msg, gss_qop_t *qop,
                                    rpc_gss_proc_t gcproc) {
    int32_t rpchdr[128 / sizeof(int32_t)];  // 128バイト
    int32_t *buf;
    memset(rpchdr, 0, sizeof(rpchdr));
    
    buf = rpchdr;
    // 固定RPCヘッダフィールド8個を書き込み (32バイト)
    IXDR_PUT_LONG(buf, msg->rm_xid);
    IXDR_PUT_ENUM(buf, msg->rm_direction);
    IXDR_PUT_LONG(buf, msg->rm_call.cb_rpcvers);
    IXDR_PUT_LONG(buf, msg->rm_call.cb_prog);
    IXDR_PUT_LONG(buf, msg->rm_call.cb_vers);
    IXDR_PUT_LONG(buf, msg->rm_call.cb_proc);
    
    oa = &msg->rm_call.cb_cred;
    IXDR_PUT_ENUM(buf, oa->oa_flavor);
    IXDR_PUT_LONG(buf, oa->oa_length);
    
    if (oa->oa_length) {
        // 【BUG】 境界チェックなし
        // rpchdr は 128 - 32 = 96 バイトのみ残存
        memcpy((caddr_t)buf, oa->oa_base, oa->oa_length);  // ← オーバーフロー可能
        buf += RNDUP(oa->oa_length) / sizeof(int32_t);
    }
}

スタックレイアウト(バイト指定)

スタック低位址 ←───────────────────→ スタック高位址
[rbp - 0xe0] ローカル変数
[rbp - 0xc0] rpchdr[0] ← memset対象
[rbp - 0xa0] rpchdr[32] ← memcpy 開始地点 (オーバーフロー開始)
[rbp - 0x40] rpchdr[128] ← バッファ終端 (96バイトから開始)
[rbp - 0x28] 保存RBX ← credential byte 120で上書き
[rbp - 0x20] 保存R12 ← byte 128
[rbp - 0x18] 保存R13 ← byte 136
[rbp - 0x10] 保存R14 ← byte 144
[rbp - 0x08] 保存R15 ← byte 152
[rbp + 0x00] 保存RBP ← byte 160
[rbp + 0x08] リターンアドレス ← byte 168

バッファオーバーフロー時にスタック上の保存レジスタおよびリターンアドレスが上書き可能となる。RPC XDR層では最大認証サイズ MAX_AUTH_BYTES = 400 に制限されるため、溢出可能な範囲は制限される。

XDR制約と溢出範囲

RPC XDR層での制限:

攻撃シナリオ

攻撃者がKerberos認証を確立し、NFS サーバーに対して複数のRPCSEC_GSS RPC パケットを送信することで段階的にメモリを破壊し、カーネルコード実行に到達する。以下は攻撃の基本フロー:

  1. Kerberos ticket 取得: 攻撃者が有効な Kerberos ticket を獲得
  2. GSS context 確立: RPCSEC_GSS context をサーバーと確立
  3. 複数回のRPC送信: credential body が境界を超えるようなペイロードを含むRPC パケットを複数回送信
  4. メモリ破壊: スタック上の保存レジスタやリターンアドレスを上書き
  5. 制御奪取: コード実行またはプロセス横取りを通じてroot権限奪取

影響範囲:脆弱なFreeBSDバージョン

バージョン 脆弱か 備考
FreeBSD 13.5 < p11 ✅ 脆弱 セキュリティパッチ未適用
FreeBSD 14.3 < p10 ✅ 脆弱 同上
FreeBSD 14.4 < p1 ✅ 脆弱 テスト対象バージョン
FreeBSD 15.0 < p5 ✅ 脆弱 開発版も対象
FreeBSD 14.4-RELEASE-p1 以降 ❌ パッチ済み 境界チェック追加

公式Advisory: FreeBSD-SA-26:08.rpcsec_gss

攻撃前提条件

┌─────────────────────────────────────────────────────┐
│  攻撃要件チェックリスト                            │
├─────────────────────────────────────────────────────┤
│ [必須] NFS サーバー (port 2049/TCP) が accessible  │
│ [必須] kgssapi.ko がロード状態                     │
│ [必須] Kerberos KDC がアクセス可能 (port 88/TCP)  │
│ [必須] 攻撃者が有効な Kerberos ticket 保有        │
│         → 任意ユーザーのチケットで十分             │
│ [推奨] 適切なリソース (CPU, メモリ)              │
└─────────────────────────────────────────────────────┘

攻撃環境構築ガイド

FreeBSD VM 初期化(Option A: QEMU cloud-init)

# イメージダウンロード
wget https://download.freebsd.org/releases/VM-IMAGES/14.4-RELEASE/amd64/Latest/\
      FreeBSD-14.4-RELEASE-amd64-BASIC-CLOUDINIT-ufs.qcow2.xz
xz -d FreeBSD-14.4-RELEASE-amd64-BASIC-CLOUDINIT-ufs.qcow2.xz
cp FreeBSD-14.4-RELEASE-amd64-BASIC-CLOUDINIT-ufs.qcow2 freebsd-vuln.qcow2
qemu-img resize freebsd-vuln.qcow2 8G

# Cloud-init 設定
cat > user-data << 'EOF'
#cloud-config
chpasswd:
  list: |
    root:freebsd
  expire: False
ssh_pwauth: True
bootcmd:
  - rm -f /firstboot          # 自動パッチング無効化
  - rm -f /var/db/freebsd-update/*
runcmd:
  - echo 'PermitRootLogin yes' >> /etc/ssh/sshd_config
  - service sshd restart
  - kldload kgssapi          # ← 脆弱モジュール
  - sysrc rpcbind_enable=YES nfs_server_enable=YES
  - echo '/export -network 0.0.0.0/0' > /etc/exports
  - mkdir -p /export
  - service rpcbind start && service nfsd start
EOF

cat > meta-data << 'EOF'
instance-id: cve-test
local-hostname: freebsd-vuln
EOF

genisoimage -output seed.iso -volid cidata -joliet -rock user-data meta-data

# QEMU 起動 (ポート転送: SSH/NFS/KDC)
qemu-system-x86_64 -enable-kvm -cpu host -m 2G -smp 2 \
  -drive file=freebsd-vuln.qcow2,format=qcow2,if=virtio \
  -cdrom seed.iso \
  -netdev user,id=net0,\
hostfwd=tcp::2222-:22,\
hostfwd=tcp::2049-:2049,\
hostfwd=tcp::8888-:88 \
  -device virtio-net-pci,netdev=net0 -nographic

FreeBSD Kerberos 設定(Option B: 手動インストール)

# 1. Kerberos インストール
pkg install -y krb5

# 2. krb5.conf 作成
cat > /etc/krb5.conf << 'EOF'
[libdefaults]
default_realm = TEST.LOCAL

[realms]
TEST.LOCAL = {
    kdc = 127.0.0.1
    admin_server = 127.0.0.1
}
EOF

# 3. KDC データベース作成
/usr/local/sbin/kdb5_util create -s -P masterkey -r TEST.LOCAL

# 4. Kerberos principals 作成 (hostname = "test" の場合)
/usr/local/sbin/kadmin.local -q "addprinc -pw password [email protected]"
/usr/local/sbin/kadmin.local -q "addprinc -randkey nfs/[email protected]"
/usr/local/sbin/kadmin.local -q "addprinc -randkey host/[email protected]"
/usr/local/sbin/kadmin.local -q "ktadd -k /etc/krb5.keytab nfs/[email protected]"
/usr/local/sbin/kadmin.local -q "ktadd -k /etc/krb5.keytab host/[email protected]"

# 5. KDC 起動
/usr/local/sbin/krb5kdc

# 6. NFS 設定
mkdir -p /export
echo '/export -network 0.0.0.0/0' > /etc/exports

# 7. rc.conf 設定
sysrc rpcbind_enable=YES
sysrc nfs_server_enable=YES
sysrc nfsv4_server_enable=YES
sysrc nfsuserd_enable=YES
sysrc gssd_enable=YES
sysrc mountd_enable=YES
sysrc nfs_server_flags="-u -t"

# 8. サービス起動
service rpcbind start
service nfsuserd start
service gssd start
service mountd start
service nfsd start

# 9. 検証
sysctl vfs.nfsd.threads              # スレッド数確認
sockstat -l | grep 2049              # TCP リスン確認 (UDP のみはNG)
kldstat | grep gss                   # kgssapi.ko ロード確認

# 10. Kerberos ticket 取得テスト
echo 'password' | kinit [email protected]
klist

攻撃者ホスト (Linux) Kerberos 設定

# システムパッケージインストール
# Ubuntu/Debian
sudo apt install krb5-user libkrb5-dev python3-gssapi

# Fedora/RHEL
sudo dnf install krb5-workstation krb5-devel python3-gssapi

# krb5.conf 設定 (FreeBSD VM IP に向ける)
sudo tee /etc/krb5.conf << EOF
[libdefaults]
default_realm = TEST.LOCAL
rdns = false                              # ← 重要: DNS逆引き無効化
dns_canonicalize_hostname = false         # ← 重要: hostname正規化無効化

[realms]
TEST.LOCAL = {
    kdc = 192.168.1.100:88                # FreeBSD VM IP
}
EOF

# /etc/hosts 設定
echo "192.168.1.100  test" | sudo tee -a /etc/hosts

# Kerberos ticket 取得
echo "password" | kinit [email protected]
klist

⚠️ Critical: rdns = falsedns_canonicalize_hostname = false がないと、Kerberos が逆引きで hostname を生成 → サーバー拒否となる可能性がある。

修正パッチ (FreeBSD-SA-26:08)

単一の境界チェック追加:

oa = &msg->rm_call.cb_cred;
if (oa->oa_length > sizeof(rpchdr) - 8*BYTES_PER_XDR_UNIT) {
    rpc_gss_log_debug("auth length %d exceeds maximum", oa->oa_length);
    client->cl_state = CLIENT_STALE;
    return (FALSE);  // ← オーバーフロー回避
}
if (oa->oa_length) {
    memcpy((caddr_t)buf, oa->oa_base, oa->oa_length);
    buf += RNDUP(oa->oa_length) / sizeof(int32_t);
}

業界への影響

今後の展望

直近の対応:

  1. freebsd-update fetch install で -p1 パッチ適用
  2. Kerberos 非使用環境では /etc/rc.confnfs_server_enable=NO 確認
  3. NFS トラフィック 2049/TCP を信頼できるサブネットのみに制限

根本的な防止:

セキュリティ研究: バッファオーバーフロー脆弱性がRCEに発展するメカニズムの理解が、ディフェンス側の防御設計に必要。カーネル memory protection の強化が急務

参考リンク


この記事はAI業界の最新動向を速報でお届けする「AI Heartland ニュース」です。

🔔 AI速報、毎日Xで配信中
Claude Code・MCP・AIエージェントの最新ニュースをいち早くお届け
@peaks2314 をフォロー
← Claude Codeの流出コードから派生プロジェクト急増。GitHubに複数リポジトリ Claude Mythos(Capybara)がリークで判明 — Opus超えの最強モデルとサイバーセキュリティリスク →