
CVE-2026-46331 act_pedit ページキャッシュ破損エクスプロイト、Alpine PIE修正付き
net/sched act_pedit の部分 COW ページキャッシュ破損(原因コミット 899ee91156e5、v5.18 で存在、v7.1-rc7 で修正)。packet_edit_meme.c はこれを非特権ユーザーによるローカル root 取得に利用します:userns 内で CAP_NET_ADMIN を持つ子プロセスが、setuid-root バイナリのキャッシュ済み ELF メタデータを setgid(0)+setuid(0)+execve("/bin/sh") シェルコードで上書きします。
make
./packet_edit_meme
./packet_edit_meme --ubuntu # AppArmor-gated Ubuntu: aa-exec bypass first
| ディストリ | カーネル | フラグ | 結果 |
|---|---|---|---|
| RHEL 10.0 | 6.12.0 | (なし) | ROOT |
| Debian 13 trixie | 6.12.90+deb13.1 | (なし) | ROOT |
| Ubuntu 24.04.4 | 6.17.0-22 | --ubuntu | ROOT |
| Alpine edge | 7.0.10-0-stable | (なし) | ROOT |
Alpine Linux (musl) は、実行可能 PT_LOAD セグメントがファイルオフセット ≥ 0x1000 から始まる PIE 実行ファイルを生成します — これは pedit の TCP ヘッダーオフセット上限 511 バイトを超えています。ELF ヘッダーとプログラムヘッダーは最初の読み取り専用 PT_LOAD(ファイルオフセット 0)を占めます。この適応版エクスプロイトは:
ページ 0 を実行可能にする:PF_X を最初の PT_LOAD の
p_flags フィールド(ファイルオフセット 0xB4、phdr[2] + 4)に追加します。
シェルコードを分割して、重要な LOAD プログラムヘッダーの破損を回避します:
e_entry → 0x28(exec 時にカーネルがチェックしない
e_shoff フィールド)。0x28 に 5 バイトの jmp 0x1C8 を配置。0x1C8 に配置し、exec 時に
カーネルが無視する PT_NOTE プログラムヘッダーを上書きします。ターゲットを自動検出:パスをハードコードせず、実行時に find / -xdev -type f -perm -4000 -user root で検索します。見つかった最初のワールドリーダブルな
setuid-root ELF バイナリが使用されます — Alpine の /bin/su(-> /bin/bbsuid、
---s--x--x)は開けないため自動的にスキップされます。
Ubuntu は、unconfined な非特権 userns を次の 2 つの sysctl で拒否します:
kernel.apparmor_restrict_unprivileged_userns # denies unconfined userns creation
kernel.apparmor_restrict_unprivileged_unconfined # forces unconfined change_profile to STACK,
# so an aa-exec permissive profile cannot
# shed the userns restriction
--ubuntu は aa-exec -p {trinity,chrome,flatpak} を介して再実行します(userns, ルールを持つプロファイル)。
| Ubuntu | userns | unconfined | aa-exec バイパス |
|---|---|---|---|
| 24.04.4 | 1 | 0 | 動作 |
| 26.04 | 1 | 1 | 不可 |
静的 x86_64-linux-gnu クロスコンパイラ:
# Debian / Ubuntu
apt install gcc-x86-64-linux-gnu
# Alpine
apk add gcc musl-dev