Skip to content
KitploitKITPLOIT
工具漏洞利用博客
Log in
提交
工具漏洞利用博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

订阅源联系隐私© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
netprobe-cve-2026-98432 — 黑盒远程探测工具,通过差分 SYN-ACK 选项回显检测 Linux IPv4 TCP ireq_opt 释放后使用漏洞 CVE-2026-98432,并支持静态 vmlinux 验证。 | Kitploit
工具/GitHubGitHub/xen0bit/netprobe-cve-2026-98432
数据包嗅探与分析漏洞扫描器漏洞分析漏洞利用模糊测试网络安全二进制分析
GitHubxen0bit/netprobe-cve-2026-98432

netprobe-cve-2026-98432

黑盒远程探测工具,通过差分 SYN-ACK 选项回显检测 Linux IPv4 TCP ireq_opt 释放后使用漏洞 CVE-2026-98432,并支持静态 vmlinux 验证。

查看仓库
62204天前尚未审核

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

netprobe — CVE-2026-98432

你好。CVE-2026-98432 是 Linux 内核中一个可远程利用的释放后使用(Use-After-Free)漏洞。部分报道称,AI 实验室通过多路径 TCP(MPTCP)在大约 45 分钟内利用了该漏洞。该漏洞实际上存在于 IPv4 TCP 协议栈本身,只是 MPTCP 是唯一勉强可行的、能够到达易受攻击代码路径的方式。即便如此,对于约 45 分钟这一说法,也应当以极其审慎的眼光加以审视。

  • 易受攻击的时间窗口由代码固定,大致等于从 ireq_opt 加载到第一次解引用之间的距离。
  • 释放发生在 100 微秒到数毫秒之后(accept + close)。
  • 仅仅让中断落入该窗口是不够的;CPU 必须在比释放延迟更长的时间内远离读取方。
  • 在普通的(非 !PREEMPT_RT)内核上,软中断根本不会被调度,即使大量硬中断涌入,也会在约 10 纳秒内完成,远早于释放需要触发释放后使用的时间点。
  • 重复的 SYN 和 ACK 携带相同的四元组,因此 RSS/RPS/sk_incoming_cpu 会将它们放入同一个接收队列,并在同一个 CPU 上处理。换句话说:一个 CPU 上的软中断是串行化的,并且由于流亲和性,不存在可供竞争 UAF 的读取方。

当然,确实存在一些自定义 Linux 内核,它们使用 MPTCP 并配合逐包引导选项,这很可能使该漏洞在“最纯粹的意义上”变得“可达”。但实际而言,你几乎可以肯定没有运行这样的内核配置,而且你也不太可能倒霉到有人延迟足够接近、又足够执着地恰好击中那个间隙。

使利用勉强具备实际可行性的主要因素是虚拟化/超售的虚拟机,配合 PREEMPT_RT、threadirqs 等……而这并非攻击者所能控制或影响,除非他们拥有某种额外的特权/已认证访问权限。我在业界有些朋友,他们大概知道一两个能改变我想法的技巧,但我并不知道任何此类技巧,AI 也一无所获,而且至少那个“技巧”——如果存在的话——并不广为人知。

你应该为服务器打补丁,但大概不必为此恐慌。本仓库中的其他所有内容,包括下面这些文字,都是 AI 生成的,但我引导了会话,并已审查了产物的准确性。

如下所述:

一个远程黑盒探测工具,通过数据包级证据证明 CVE-2026-98432(Linux IPv4 TCP ireq_opt / inet_opt 释放后使用)的存在——而非通过匹配内核版本。

它止步于释放后使用:它证明内核读取了已释放的内存,并在网络上表明了这一点。它不绕过 KASLR、不劫持控制流、也不执行代码。

仅限授权测试。竞争探测可能使目标不稳定;内核崩溃是可能的结果。仅在你拥有或已获得书面许可测试的主机上使用。


漏洞是什么

修复提交是 e3f33b0a1d89d738e2b913dab519226eaf76e15b(ipv4: free inet_opt and ireq_opt after an RCU grace period),这是一个两行改动,将 inet_sock_destruct() 和 tcp_v4_reqsk_destructor() 中的 kfree() 改为 kfree_rcu()。

  • tcp_v4_init_req() 将 SYN 回显的 IP 选项(Record Route / Timestamp)存储在 ireq->ireq_opt 中。
  • tcp_v4_syn_recv_sock() 转移该指针到子套接字,而不是复制它。
  • 并发的重传 SYN 仍在 rcu_read_lock() 下读取 ireq->ireq_opt,并在 ip_options_build() 中使用它。
  • 如果子套接字(或请求套接字)先被释放,那么该读取就是释放后使用,已释放对象的内容会被复制到 SYN-ACK 中。

最后一点就是检测器:内核将过期的选项字节回显给发送方。

范围更正:CVE 记录是通用 IPv4 TCP。只有 Anthropic 的博客将其与“多路径 TCP 监听器”联系起来;没有任何 CVE/NVD/Red Hat/Debian/Ubuntu 文本提及 MPTCP。该探测首先测试普通 TCP。


证据状态

三条独立证据链,从最弱到最强:

环节展示内容产物
静态(build-id 固定)运行中内核的代码形态:两个析构函数处均为普通 kfree = 存在漏洞;kvfree_call_rcu = 已修补verify-local,见下表
合成预言机当响应方回显被复用的 slab 内存时,线上检测器触发scripts/validate_synthetic.sh → CONFIRMED VULNERABLE
动态、内核级(KVM 实验环境)KASAN 报告 ip_options_build 中实际的 slab-use-after-free,并附带该提交的调用栈;在相同流量下,kfree_rcu 内核保持干净evidence/guest-inst-vuln6-KASAN.log、evidence/guest-inst-patched2-CONTROL.log
线上可见、真实内核(非 KASAN 实验环境)线上的 SYN-ACK 携带了喷射的选项块(42 04 be ef…),而非回显的时间戳;kfree_rcu 对照组保持干净evidence/race-stage1-wire-uaf.json、evidence/race-control-kfree_rcu.json

动态环节是一个专门构建的 7.0.14 客户机(KASAN + 启动参数窗口拉伸),并配有逐包 CPU 引导:重传的 SYN 在一个 vCPU 上处理,ACK/传输在第二个 vCPU 上处理,受害者的 accept()+close() 在第三个 vCPU 上处理,因此该覆盖是常规发生的,而非偶然。内核本身报告了:

BUG: KASAN: slab-use-after-free in ip_options_build
Read of size 16 ... by task swapper/0 (cpu0, softirq)
  __asan_memcpy <- ip_options_build <- ip_build_and_send_pkt
  <- tcp_v4_send_synack <- tcp_rtx_synack <- tcp_check_req <- tcp_v4_rcv
Freed by task 1 (victim, cpu3):
  kfree <- inet_sock_destruct <- __sk_destruct <- inet_release <- __x64_sys_close
object: kmalloc-96, 16 bytes in (struct ip_options at the rcu_head offset)

加上 30 条读端 READ-AFTER-FREE 记录(在 free 之后 71–322 µs 读取,optlen=40,KASAN shadow 0xfb)。打过补丁的对照组(kfree_rcu,已在目标文件中验证)运行了相同的竞态与保持:0 KASAN,0 read-after-free。这就是漏洞本身,而不是版本猜测。

为什么一次干净的远程运行不等于补丁

读端并不是一个长循环。tcp_v4_send_synack() 加载 ireq->ireq_opt 并将其传给 ip_build_and_send_pkt()/ip_options_build(),后者的 memcpy 就是 use-after-free 读取;加载与读取之间只相隔几条指令(几十到几百纳秒)。而 free 一侧——受害者的 accept()+close() 之后的子对象销毁——要晚得多:仅实测的 close 周期就有 61–92 µs,而 ACK→销毁的延迟还要加上跨 CPU 唤醒。

因此这两个事件并非只是很少同时发生;它们在构造上就相隔约 90 µs,而读取早在 free 之前很久就结束了。自然时序实验对此进行了量化:在同一个插桩内核上,不做窗口拉伸,约 14 万次竞态尝试以及并发的半开连接搅动,

stats: frees=180223 overlaps=0 raf=0        KASAN: 0

从未有一次落在读取方的窗口内。第二次更强的尝试使用了实验环境的 slab 喷射:8,000 次尝试,每次携带 200 个重传 SYN(160 万个独立读取方窗口),针对一个干净的内核,其读取方 vCPU 保持可运行并被宿主 CFS 抢占任务抢占——仍然没有任何携带喷射的 SYN-ACK。读取方 vCPU 大约每 5 ms 运行时间被抢占一次;在 20-40 秒运行时间内,约 10 ns 的 200 万个窗口即使在完全均匀的模型下也应有若干次命中,而观察到的零说明抢占点在客户机指令流中并不均匀。

因此,线路级证明需要读取方被确定性地延迟,实验环境通过启动参数窗口拉伸(reader_hold_us)实现这一点;在真实目标上,只有在这约 10 ns 内发生 hypervisor 或调度器停顿才能做到。这就是为什么远程探测将阳性视为证明,将阴性视为一个界限,而绝不视为“已修补”。

还有一个后果:在 KASAN 内核上,隔离区会保持已释放字节的完整性,因此即使 UAF 发生,线路也无法显示它。在生产内核上,线路预言机仅在已释放的 kmalloc-96 槽位在读取方的 memcpy 之前被复用时才会触发。这条路径不再只是合成的:在非 KASAN 实验内核(无隔离区)中,受害者关闭子连接并立即用 40 字节的选项对象重新分配该槽位,内核将它们复制进一个 SYN-ACK(42 04 be ef…,evidence/race-stage1-wire-uaf.json)。同一内核使用 kfree_rcu 时没有产生任何结果(evidence/race-control-kfree_rcu.json)。


检测工作原理

1. 前置条件(安全,无竞争)

uv run netprobe preconditions -t <target> -p <port>
  • 发送一个带 Timestamp 选项的 SYN 和一个带 Record Route 选项的 SYN。
  • 如果两者都没有被回显,则 IP 选项向量不可达 → NOT_REACHABLE。
  • 还会尝试原生 IPPROTO_MPTCP 连接并检查 MPTCP_INFO,因此可以直接测试“MPTCP 监听器”这一说法。

2. 差分重传回显(证明)

对于每个元组,探测会记录基线 SYN-ACK 选项结构 S0 = (total option length, ordered (kind, length, pointer))。

随后它以微秒级偏移竞速发送一个重复 SYN、一个 ACK 和一个 RST。重复 SYN 使 tcp_check_req() 读取 ireq_opt;ACK 将指针交给子套接字;RST 将其释放。

任何后续 SYN-ACK 若其结构与 S0 不同,在正确的内核上都不可能发生。这是一个单侧证明,不依赖于 KASLR 泄漏或崩溃。

时间戳值和记录路由地址被排除在比较之外: Linux 在回显中会重写这两者(已验证:指针被强制为 len+1,两个时间戳槽位都被替换为内核时钟)。

3. 判定结果

判定含义
CONFIRMED_VULNERABLE捕获到结构性回显异常,并附有数据包
INCONCLUSIVEN 次尝试,无异常;明确为弱否定
NOT_REACHABLE无 IP 选项回显,或无 ireq_opt 分配路径

该工具从不输出“已修补”。远程否定不能作为证明:在已修补的内核上,每次尝试的概率为零,但在存在漏洞的内核上,该概率很小且未知,因此一次干净运行只能对其给出上界(1-(1-p)^N)。


模式

spoof(已在此沙箱中验证)

从可路由但非本地的源地址(例如 203.0.113.7)发送 SYN。目标的 SYN-ACK 从接口发出;本地内核从不处理它,因此无法发出自己的 RST。探测使用 AF_PACKET 捕获 SYN-ACK,并完全掌控 ACK / 重复 SYN / RST 的时序。

适用于可从扫描主机访问的目标(实验室、链路上,或你可对其源地址欺骗的目标)。仅需 CAP_NET_RAW。

sudo uv run netprobe race -t 172.18.0.3 -p 9101 \
  --iface eth0 --spoof 203.0.113.7 --variant child -n 100000

firewall(远程目标,本沙箱中未实际执行)

针对真实的远程目标,SYN-ACK 会返回给扫描器自身的地址,内核会对其发送 RST。要抑制这些 RST 需要 CAP_NET_ADMIN:

sudo uv run netprobe race -t 198.51.100.10 -p 80 --mode firewall -n 100000

这会安装一条作用域受限的 nftables 规则,用于丢弃探测端口范围内本地生成的 RST,除非这些 RST 携带探测的 SO_MARK(netprobe/netfilter.py)。用于开发的沙箱没有 CAP_NET_ADMIN(CapEff 0xa80425fb),因此该路径虽已生成并通过单元测试,但在此处并未进行端到端验证。


静态基准事实

对于你可以检查的主机,自由调用的形态是确定性的:

uv run netprobe verify-local \
  --vmlinux /usr/lib/debug/boot/vmlinux-$(uname -r) \
  --expected-build-id "$(readelf -n /sys/kernel/notes | awk '/Build ID/{print $3}')"

kfree → 存在漏洞;kvfree_call_rcu → 已修补。已在两类镜像上验证:

镜像inet_sock_destructtcp_v4_reqsk_destructor判定
Ubuntu 7.0.0-42.42 (82d07c0b…)kfreekfree存在漏洞
Ubuntu 7.3.0-10.10 (a24c081e…)kvfree_call_rcukvfree_call_rcu已修补

scripts/fetch_vmlinux.sh 可从 Ubuntu ddebs 归档中复现下载/提取步骤。


目录结构

src/netprobe/
  l3/ipopts.py        option build/parse, structural fingerprint
  l4/tcp.py           raw IPv4/TCP build/parse
  l4/link.py          spoof (AF_PACKET) and connected links
  l4/fastsend.py      per-CPU forked senders (no GIL)
  netfilter.py        scoped RST suppression for remote mode
  probe/precondition.py
  probe/race.py
  probe/churn.py
  local/verify.py     static build-id + disassembly classifier
  steer.py            eBPF per-packet queue steering (two-queue and four-queue)
  cli.py
lab/victim.py         lab listener (MPTCP optional, accept/close/hold)
lab/fake_server.py    synthetic reuse responder (detector validation)
lab/guest/            KVM lab: kernels, initramfs, per-CPU steering, victims
evidence/             kernel logs of the dynamic proof and the patched control
docs/REMOTE-DEPLOYMENT.md  remote/firewall mode, calibration, safety
tests/                unit tests
NOTES.md              running engineering log and measurements

快速开始(实验环境)

uv sync
sudo .venv/bin/python lab/victim.py --port 9101 --host 0.0.0.0 &
uv run netprobe preconditions -t 172.18.0.3 -p 9101
sudo .venv/bin/python -m netprobe.cli race -t 172.18.0.3 -p 9101 \
  --iface eth0 --spoof 203.0.113.7 --variant child -n 2000

对检测器本身的合成检查(无需存在漏洞的内核):

下载工具