Skip to content
KitploitKITPLOIT
ToolsExploitsBlog
Log in
Submit
ToolsExploitsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

FeedsContactPrivacy© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
netprobe-cve-2026-98432 — Black-box remote probe that detects CVE-2026-98432, a Linux IPv4 TCP ireq_opt use-after-free, via differential SYN-ACK option echo, plus static vmlinux verification. | Kitploit
Tools/GitHubGitHub/xen0bit/netprobe-cve-2026-98432
Packet Sniffing & AnalysisVulnerability ScannersVulnerability AnalysisExploitationFuzzingNetwork SecurityBinary Analysis
GitHubxen0bit/netprobe-cve-2026-98432

netprobe-cve-2026-98432

Black-box remote probe that detects CVE-2026-98432, a Linux IPv4 TCP ireq_opt use-after-free, via differential SYN-ACK option echo, plus static vmlinux verification.

View Repository
62153 days agoNot yet reviewed

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

netprobe — CVE-2026-98432

Hello. CVE-2026-98432 is remotely exploitable Use-After-Free in the Linux Kernel. Some reporting states that AI labs exploited it after ~45min via Multi-Path TCP (MPTCP). The vulnerability is actually in the IPv4 TCP stack itself, it's just that MPTCP is the only even remotely practical way to reach the vulnerable code path. Even then, ~45min should receive a very deep squint of scrutiny.

  • The vulnerable interval is fixed by the code at roughly the distance between the ireq_opt load and the first dereference.
  • The free is 100 µs to milliseconds later (accept + close).
  • It is not enough for an interrupt to land in the window; the CPU must stay away from the reader for longer than the free latency.
  • On a normal (!PREEMPT_RT) kernel, softirqs are not scheduled at all and even a flood of hard IRQs would still finish in about 10ns, long before the free needed to hit a use-after-free.
  • The duplicate SYN and the ACK carry the same 4-tuple, so RSS/RPS/sk_incoming_cpu place them in the same receive queue and process them on the same CPU. Said another way: Softirqs on a CPU are serialized and due to flow affinity, there is not reader left to race for the UAF.

There are surely custom linux kernels which use MPTCP with per-packet steering options which likely make this vulnerability "reachable" in the purest sense. Practically speaking, you are almost certainly not running such a kernel configuration, and also aren't that unllucky for someone to be latency-close-enough and persistent enough to shoot that gap.

The primary factor that makes exploitation even remotely practical are virtualized/oversubscribed VMs, with PREEMPT_RT, threadirqs, etc... which is not something an attacker has any control or influence over unless that have some additional privileged/authenticated access. I have some friends in the industry who probably know a trick or two that would change my mind, but I don't know of anything, AI came up blank, and at the very least that "trick" if it exists, isn't widely known.

You should patch your servers, but probably not panic about it. Everything else in this repo, including the below lines is AI generated, but I steered the session and have reviewed the artifacts for accuracy.

As follows is:

A remote black-box probe that demonstrates the presence of CVE-2026-98432 (Linux IPv4 TCP ireq_opt / inet_opt use-after-free) with packet-level evidence — not by matching kernel versions.

It stops at the use-after-free: it proves the kernel read freed memory and said so on the wire. It does not bypass KASLR, hijack control flow, or execute code.

Authorized testing only. The race probe can destabilise a target; a crashed kernel is a plausible outcome. Use it only on hosts you own or have written permission to test.


What the bug is

The fix is e3f33b0a1d89d738e2b913dab519226eaf76e15b (ipv4: free inet_opt and ireq_opt after an RCU grace period), a two-line change from kfree() to kfree_rcu() in inet_sock_destruct() and tcp_v4_reqsk_destructor().

  • tcp_v4_init_req() stores the SYN's echoed IP options (Record Route / Timestamp) in ireq->ireq_opt.
  • tcp_v4_syn_recv_sock() transfers the pointer to the child socket instead of copying it.
  • A concurrent retransmitted SYN still reads ireq->ireq_opt under rcu_read_lock() and uses it in ip_options_build().
  • If the child (or request socket) is freed first, that read is a use-after-free and the freed object's contents are copied into a SYN-ACK.

That last point is the detector: the kernel echoes the stale option bytes back to the sender.

Scope correction: the CVE record is generic IPv4 TCP. Only Anthropic's blog ties it to a "multipath TCP listener"; no CVE/NVD/Red Hat/Debian/Ubuntu text mentions MPTCP. The probe tests plain TCP first.


Evidence status

Three independent legs, weakest to strongest:

LegWhat it showsArtifact
Static (build-id pinned)the running kernel's code shape: plain kfree at both destructors = vulnerable; kvfree_call_rcu = patchedverify-local, table below
Synthetic oraclethe wire detector fires when a responder echoes reused slab memoryscripts/validate_synthetic.sh → CONFIRMED VULNERABLE
Dynamic, kernel-level (KVM lab)KASAN reports the actual slab-use-after-free in ip_options_build, with the commit's stacks; a kfree_rcu kernel with identical traffic is cleanevidence/guest-inst-vuln6-KASAN.log, evidence/guest-inst-patched2-CONTROL.log
Wire-visible, real kernel (non-KASAN lab)the SYN-ACK on the wire carried the sprayed option block (42 04 be ef…) instead of the echoed timestamp; the kfree_rcu control stayed cleanevidence/race-stage1-wire-uaf.json, evidence/race-control-kfree_rcu.json

The dynamic leg is a purpose-built 7.0.14 guest (KASAN + a boot-parameter window stretch) with per-packet CPU steering: the retransmitted SYN is processed on one vCPU, the ACK/transfer on a second, and the victim's accept()+close() on a third, so the override is routine instead of accidental. The kernel itself reported:

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)

plus 30 reader-side READ-AFTER-FREE records (read 71–322 µs after the free, optlen=40, KASAN shadow 0xfb). The patched control (kfree_rcu, verified in the object file) ran the same race and hold: 0 KASAN, 0 read-after-free. That is the vulnerability, not a version guess.

Why a clean remote run is not a patch

The reader is not a long loop. tcp_v4_send_synack() loads ireq->ireq_opt and passes it to ip_build_and_send_pkt()/ip_options_build(), whose memcpy is the use-after-free read; the load and the read are a few instructions apart (tens to hundreds of nanoseconds). The free side — child destruction after the victim's accept()+close() — is much later: the measured close cycle alone is 61–92 µs, and the ACK→destruction latency adds the cross-CPU wakeup.

So the two events are not merely rare together; they are separated by ~90 µs by construction, and the read is over long before the free. The natural-timing experiment quantifies it: with the same instrumented kernel, no window stretching, ~140k race attempts and a concurrent half-open churn,

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

the free never once landed inside the reader's window. A second, stronger attempt used the lab's slab spray: 8,000 attempts each carrying 200 retransmitted SYNs (1.6M independent reader windows) against a pristine kernel whose reader vCPU was kept runnable and preempted by host CFS hogs - still zero SYN-ACKs carrying the spray. The reader vCPU is preempted about once per 5 ms of runtime; 2M windows of ~10 ns against 20-40 s of runtime is a handful of hits even under a perfectly uniform model, and the observed zero says the preemption points are not uniform in the guest instruction stream.

The wire proof therefore needs the reader to be delayed deterministically, which the lab does with a boot-parameter window stretch (reader_hold_us); on a real target only a hypervisor or scheduler stall inside those ~10 ns can do it. That is why the remote probe treats a positive as proof and a negative as a bound, never as "patched".

Download Tool