
本仓库包含针对 CVE-2026-68398 的特定构建版本本地权限提升利用。该漏洞是 PPPoL2TP 接收处理与未附加 PPP 通道销毁之间的一场释放后使用(use-after-free)竞态。它已在 QEMU 中针对官方 Ubuntu 22.04 软件包 linux-image-5.15.0-187-generic(5.15.0-187.197)完成验证。
最终测试以专用 UID 1001 用户身份启动,该用户没有附加组、没有 capabilities、也没有 sudo 访问权限,随后获得初始命名空间中的 UID 0。KASLR、SMEP、SMAP 和 AppArmor 均保持启用。客户机未使用 nokaslr、nopti、nosmep 或 nosmap 参数启动。
警告
此代码会故意破坏内核堆状态,并且只适用于一个确切的 Ubuntu 内核构建版本。 竞态失败可能导致内核崩溃(panic)或系统损坏。请仅在你自己的隔离且 一次性虚拟机中运行它。
pppol2tp_recv() 在 RCU 读端临界区内的 L2TP UDP 接收路径中执行,最终调用 ppp_input(&po->chan)。PPPoX 套接字及其内嵌的 ppp_channel 是 RCU 安全的,但 ppp_input() 使用的内部 struct channel 是单独分配的内存。
对于通过 PPPIOCGCHAN 绑定但既未附加到 PPP 单元也未桥接的通道,关闭路径会立即释放该内部对象:
RX: l2tp_udp_encap_recv -> pppol2tp_recv -> ppp_input(channel)
CLOSE: pppol2tp_release -> pppox_unbind_sock
-> ppp_unregister_channel -> ppp_release_channel -> kfree(channel)
因此,接收路径可能会对已释放通道的 skb 队列和等待队列(waitqueue)进行操作。修复方案为 struct channel 增加了一个 RCU 回调,并将队列清理(purge)和释放操作推迟到 RCU 宽限期(grace period)结束之后。
该漏洞由 Doyensec 的 Norbert Szetei 发现并在上游修复。主线修复提交为 ec4215683e47424c9c4762fd3c60f552a3119142。
Linux CNA 记录确认受影响版本谱系始于 Linux 4.15。厂商内核可能以不同的版本号承载该修复,因此确切的源码或软件包变更日志优先于本表。
较旧且仍在支持范围内的厂商版本分支需要移植(backport)补丁。截至 2026-08-12,Ubuntu CVE 跟踪器 将 Jammy 的 linux 软件包标记为 needs-triage;未找到已修复的 Ubuntu Jammy 软件包。经过测试的 5.15.0-187.197 源码仍直接调用 kfree(pch),因此存在漏洞。
内核未重新编译。精简云镜像缺少 linux-modules-extra-5.15.0-187-generic,因此安装了该官方 Ubuntu 软件包以提供 l2tp_ppp。使用 linux-generic 元软件包的常规 Jammy 安装本就依赖于对应的 modules-extra 软件包。当利用程序创建其 PPPoL2TP 套接字时,协议模块会自动加载。
自动 KASLR 检测器使用 x86 prefetch 时序侧信道,并且要求 KPTI 处于停用状态且 CPU 支持 RDTSCP。经测试的主机 CPU 暴露了 rdtscp、smep 和 smap,且不受 Meltdown 影响,因此 Ubuntu 在没有任何启动参数覆盖的情况下保持 KPTI 停用。在 /proc/cpuinfo 报告 pti 标志的 CPU 上,检测器将拒绝运行。这是利用程序特有的硬件条件:底层 CVE 仍然可达,但本版本不声称能在 KPTI 启用的系统上实现 KASLR 绕过。手动提供的 slide 仅用于受控诊断。
struct channel。仍在运行的 RX 路径将受控的密钥字节视为其 skb 队列和等待队列。core_pattern 作为泄露暂存区,并暴露一个密钥分配指针。override_creds()。UID/GID 字段、capabilities 以及所需的 user、namespace、ucount 和 group 指针均与该确切的 Ubuntu 构建匹配。/proc/self/exe 复制到 /tmp 下的一个唯一文件中,将其改为 root 所有的 4755 模式,并验证这些属性。/usr/bin/id。最后这一桥梁步骤是必要的,因为 override_creds() 改变的是当前内核任务的主观凭据;安装并执行经校验的 SUID 副本,可将这一短暂的原语转化为正常的进程凭据。
Makefile 将利用程序静态链接。对时序敏感的 prefetch 对象特意以 -O0 编译,而利用程序本身使用 -O2。
make
等效命令:
gcc -O0 -Wall -Wextra -Werror -c -o build/kaslr_prefetch.o kaslr_prefetch.c
gcc -O2 -static -pthread -Wall -Wextra -Werror \
-o build/CVE-2026-68398 exploit.c build/kaslr_prefetch.o
在完全相同的已验证内核上,从普通用户账户执行:
id
grep '^Cap' /proc/self/status
./CVE-2026-68398 auto 60
源码会检查 uname(),拒绝 5.15.0-187-generic 之外的任何发布版本。该竞态是概率性的;未命中或崩溃后重试前,请重新启动一个一次性快照。
成功运行的结果以如下内容结束:
[KASLR] image_base=0xffffffffb9200000 slide=0x38200000
CVE-2026-68398 Ubuntu local privilege-escalation exploit
uid=1001 euid=1001 slide=0x38200000
...
[9/9] invoking override_creds and installing the SUID transition...
override callback: uid=0 euid=0 gid=0 egid=0
installed root-owned mode 4755 helper: /tmp/.cve-2026-68398-root-948
SUID helper ready; executing it from the original unprivileged task...
SUID transition: uid=0 euid=0 gid=0 egid=0
uid=0(root) gid=0(root) groups=0(root),1001(poc)
该真实 QEMU 运行的完整精简转录见 docs/example-output.txt。
该利用链在三次全新且正常随机化的 Ubuntu 启动中均成功走通。自动恢复的镜像基址分别为 0xffffffff90800000、0xffffffffa5a00000 和 0xffffffffb9200000。最终运行使用了上文所述的专用非管理 UID 1001 账户,并验证了临时 SUID 文件在之后已被删除。
同样的最终竞态还在完全相同的上游修复提交上运行了 60 秒,启用了 KASAN,并使用相同的四 vCPU 拓扑。它完成了 5,969 次通道/密钥循环,报告了 stage 1: no controlled reclaim,且没有产生任何 KASAN 报告或利用阶段转换。
检查时间为 2026-08-12,早于本私有仓库的创建。SearchSploit/Exploit-DB 未返回任何利用程序;Packet Storm 未返回匹配文件;GitHub 精确代码搜索返回了 22 个 CVE/公告镜像且没有任何 PoC;精确网络搜索仅找到上游修复及相关元数据。这只是某一时间点的结果,并不保证日后不会出现其他 PoC。
kaslr_prefetch.c 的基础利用程序由 A. Ramos <[email protected]> 编写(Twitter:
@aramosf)。漏洞发现与上游修复归功于 Norbert Szetei(Doyensec)。
exploit.c 采用 GPL-2.0-only 许可。kaslr_prefetch.c 和 kaslr_prefetch.h 采用 MIT 许可,并在源文件中保留了 KASLD 的署名和完整的许可声明。
| 内核系列 | 首个修复版本 | 修复提交 |
|---|
| 6.6.y | 6.6.148 | 4bb84e964ff0 |
| 6.12.y | 6.12.101 | 3ab32218d718 |
| 6.18.y | 6.18.42 | c9574b8a8ede |
| 7.1.y | 7.1.6 | 06213c85d8c0 |
| Mainline | 7.2-rc4 | ec4215683e47 |
| 属性 | 值 |
|---|
| 发行版 | Ubuntu 22.04.5 LTS (Jammy) |
| 内核软件包 | linux-image-5.15.0-187-generic / 5.15.0-187.197 |
| 内核发布版本 | 5.15.0-187-generic #197-Ubuntu |
| 架构 | x86-64 |
| 虚拟机 | QEMU/KVM,-cpu host,四个 vCPU,5 GiB 内存 |
| 初始身份 | uid=1001(poc) gid=1001(poc) groups=1001(poc) |
| 初始 capabilities | inheritable、permitted、effective 和 ambient 全部为零 |
| 最终身份 | 处于初始命名空间的 uid=0(root) gid=0(root) |
| 启动变更 | 无;标准命令行,KASLR 已启用 |
| 需求 | Ubuntu 5.15.0-187 状态 | 利用程序用途 |
|---|
| PPP | CONFIG_PPP=y | 内建 |
| L2TP / PPPoL2TP | CONFIG_L2TP=m, CONFIG_PPPOL2TP=m | 官方 linux-modules-extra 模块 |
| 用户密钥 | CONFIG_KEYS=y | 回收已释放的 kmalloc-256 通道 |
| AppArmor | CONFIG_SECURITY_APPARMOR=y | 保持启用;伪造的 cred 包含有效的 unconfined 标签 |
| KASLR | CONFIG_RANDOMIZE_BASE=y | 保持启用;slide 在运行时恢复 |
| SMAP | CONFIG_X86_SMAP=y | 保持启用 |
| 用户/网络命名空间 | Ubuntu 已启用,但未使用 | 无需命名空间设置或 capability 获取 |
/dev/ppp | 不需要 | 通道已绑定,但从未连接到 PPP 单元 |