漏洞影响范围
该漏洞的影响范围与 Dirty Frag 基本相同,几乎覆盖所有尚未合入修复补丁的主流企业级和桌面 Linux 发行版。自 cef401de7be8 引入 SKBFL_SHARED_FRAG 机制起,到本次修复之间的相关内核版本均受影响。 Ubuntu 默认的 AppArmor 配置会限制非特权 user namespace,从而对公开利用形成缓解,因此默认情况下利用受限。 Android 方面,由于默认禁用 CONFIG_USER_NS,标准设备通常不受该漏洞影响。
漏洞描述
近期,William Bowling 与 V12 团队开发并公开了一个通用的 Linux 本地提权漏洞利用程序Fragnesia。 Fragnesia 属于 Dirty Frag 漏洞类别的一员。这是 ESP/XFRM 子系统中的一个独立漏洞,与 dirtyfrag 不同,并且已经获得了单独的补丁。不过,它位于相同的攻击面,缓解措施也与 dirtyfrag 相同。 它利用 Linux XFRM ESP-in-TCP 子系统中的一个逻辑漏洞,在无需任何竞争条件(race condition)的情况下,实现对只读文件内核页缓存(kernel page cache)的任意字节写入。 该技术扩展了包括 Dirty Pipe 在内的页缓存写入漏洞类别:当一个 TCP socket 在已有数据从文件 splice 到接收队列后,再切换到 espintcp ULP 模式时,内核会将这些已排队的文件页当作 ESP 密文进行处理。AES-GCM 密钥流在 counter block 位置 2、字节 0 的值,会被直接 XOR 到缓存文件页中。通过选择合适的 IV nonce 以生成目标密钥流字节,攻击者即可将文件中的任意目标字节设置为任意值——每次触发调用可修改一个字节。 该利用程序会构建一个包含 256 个条目的查找表,将每一种可能的密钥流字节映射到对应的 nonce,然后遍历 payload,对每一个需要修改的字节重复触发 splice/ULP 流程。它会将一个小型位置无关 ELF stub(执行 setresuid/setresgid/execve /bin/sh)写入 /usr/bin/su 的前 192 字节页缓存中,随后调用 execve("/usr/bin/su") 获取 root shell。页缓存中的修改不会回写到磁盘,磁盘上的原始二进制文件不会被修改。
漏洞复现
poc: https://github.com/v12-security/pocs/tree/main/fragnesia

漏洞风险
可以在已获取低权限用户的前提下,提权至root权限
修复建议
正式防护方案
官方发布了正式的修复Patch,详情如下:
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 7dad68e3b..9c4e8d331 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -6200,6 +6200,8 @@ boolskb_try_coalesce(struct sk_buff *to, struct sk_buff *from,
from_shinfo->frags,
from_shinfo->nr_frags * sizeof(skb_frag_t));
to_shinfo->nr_frags += from_shinfo->nr_frags;
+ if (from_shinfo->nr_frags)
+ to_shinfo->flags |= from_shinfo->flags & SKBFL_SHARED_FRAG;
if (!skb_cloned(from))
from_shinfo->nr_frags = 0;
修复后只在实际有 frag 被转移时才传播标志(nr_frags > 0 的守卫), 使用 |= 而非赋值,保留 to 已有的其他 flags 状态, 用 & SKBFL_SHARED_FRAG 掩码精确传播,不引入其他 flags 的副作用,修复后 skb_has_shared_frag() 能正确识别合并后的 skb,ESP 路径重新走 COW,彻底封堵了从"标志丢失"到"错误 in-place 解密"的整条利用链。
Linux Kernel fragnesia本地提权漏洞复现
https://blog.atoposx.com/archives/019e2471-7669-771c-8a62-7b7f7142b9e9
评论