A 22-year-old paper cut that keeps showing up on your quarterly scan report like an uninvited relative
Tenable plugin 12213 maps to CVE-2004-0230, the *Slipping in the Window* attack documented by Paul Watson in 2004. An off-path attacker who knows (or guesses) a TCP four-tuple — source/dest IP and port — can send a forged RST or SYN whose sequence number falls anywhere inside the receiver's window, killing the connection. The plugin fires against any host whose TCP stack accepts in-window RSTs without the stricter checks defined by RFC 5961 (challenge ACK, exact-match-only RST). Affected stacks are essentially every pre-2010 OS: legacy Windows (≤2003/XP SP2), older Linux (<2.6.36), older BSD, old Cisco IOS, JunOS, and a long tail of embedded/IoT/printer/UPS stacks that never got the RFC 5961 treatment.
Vendor severity MEDIUM is generous to the point of misleading on a modern fleet. The only impact is a *denial of service against an individual TCP connection* — not the host, not the service, not data. On any session protected by TLS, IPsec, or an application-layer keepalive/reconnect, the user sees a half-second hiccup. The plugin is famously noisy on long-lived BGP peerings (which is why TCP-MD5 / TCP-AO exist) and on legacy SCADA/serial-over-TCP gear. For a general enterprise fleet in 2026, this is backlog hygiene, not a patch event.
4 steps from start to impact.
Enumerate a target TCP four-tuple
- Visibility into who talks to whom (BGP looking-glass, passive DNS, partner directory)
- Off-path packet injection capability — ability to spoof the source IP toward the victim
- Most ISPs and cloud providers implement BCP38 ingress filtering, which drops spoofed-source packets at the edge
- Ephemeral ports are randomized on every modern stack (Linux, Windows ≥Vista, BSD)
Guess the ephemeral port
reset-tcp.c. ISN guessing is no longer required because RFC 793 only required the RST to fall in-window, not match exactly.- Asymmetric bandwidth toward the victim
- Sustained packet injection without rate-limiting upstream
- Carrier-grade NAT and stateful firewalls drop the forged packets if they don't match an existing state entry
- BGP sessions on routers worth attacking use TCP-MD5 (RFC 2385) or TCP-AO (RFC 5925) — RST is rejected without the shared secret
Land an in-window RST or SYN
- Target stack predates RFC 5961 or has it disabled
- Window is large enough that random sequence number hits within ~1-2 minutes
- Linux ≥2.6.36 (2010), Windows ≥7/2008R2, modern BSD all implement RFC 5961
- TLS, SSH, IPsec, and application reconnect logic mask the impact to the user
tcpExtTCPACKSkippedChallenge counter increments on Linux; almost never monitored.Impact — single-connection DoS
- Target is a long-lived TCP session whose drop matters (BGP, replication, SCADA)
- Every interesting protocol either auto-reconnects or is already cryptographically protected
The supporting signals.
| CVE | CVE-2004-0230 — Paul Watson, *Slipping in the Window: TCP Reset Attacks*, CanSecWest 2004 |
|---|---|
| Tenable plugin | 12213 — remote check, MEDIUM (CVSSv2 5.0) |
| In the wild | Not on CISA KEV. No active exploitation campaigns tracked. Historical noise against BGP peerings circa 2004–2008 before TCP-MD5 saturation. |
| EPSS | Effectively negligible (<0.5 percentile) — exploitation interest has been near zero for over a decade |
| CVSS vector | AV:N/AC:L/Au:N/C:N/I:N/A:P — network reachable, no auth, partial availability impact only. No confidentiality or integrity loss. |
| Public PoC | Watson's original reset-tcp.c, plus trivial scapy and hping3 one-liners. No weaponized framework module — Metasploit never shipped one because the payoff is too small. |
| Affected stacks | Pre-RFC 5961 TCP: legacy Windows (≤XP SP2 / 2003), Linux <2.6.36, older BSD, old Cisco IOS/JunOS, long tail of embedded gear, printers, UPS, SCADA serial-over-TCP gateways |
| Fix | RFC 5961 challenge ACK + exact-match RST. Shipped in Linux 2.6.36 (Oct 2010), Windows 7/2008R2, modern BSD, Cisco IOS 15.x, JunOS 10.x. For BGP specifically: TCP-MD5 (RFC 2385) or TCP-AO (RFC 5925). |
| Exposure data | Shodan/Censys show the affected stack signature still present on hundreds of thousands of embedded devices, but their TCP sessions are short-lived HTTP/HTTPS — exploitation provides no value |
| Reporter | Paul A. Watson (Terrapin Communications) — disclosure April 20, 2004 via NISCC / US-CERT VU#415294 |
noisgate verdict.
Maximum impact is a single TCP connection drop with no confidentiality or integrity loss, and every protocol where the drop would matter (BGP, IPsec, replication) has had cryptographic protection deployed for over a decade. The decisive factor is impact ceiling: this CVE simply cannot produce code execution, data disclosure, or host compromise under any deployment role.
Why this verdict
- Impact is bounded to availability of one TCP connection — CVSS A:P with C:N/I:N. No code execution, no data loss, no privilege gain is reachable from this primitive.
- Mitigations are 16 years deployed. RFC 5961 landed in Linux 2.6.36 (2010), Windows 7, and every mainstream BSD/router OS. A modern fleet baseline catches this finding only on legacy outliers.
- The only historically painful target — BGP — is already protected by TCP-MD5/TCP-AO on every serious peering. The plugin firing on a BGP router today is almost always a false-positive for the keyed sessions.
- Role multiplier — line-of-business server / workstation: chain succeeds in dropping one TLS/SSH session; user reconnects. Blast radius: zero beyond a UX hiccup.
- Role multiplier — domain controller / identity provider: RFC 5961-compliant stack on all supported Windows; chain fails. Even if it landed, LDAP/Kerberos clients reconnect transparently. Blast radius: nil.
- Role multiplier — BGP edge router: chain succeeds only if TCP-MD5/AO is NOT configured AND the peer IP/port is guessable AND BCP38 is absent upstream. Outcome is a route flap, not compromise. Blast radius: brief reachability gap, capped at one peering.
- Role multiplier — OT/SCADA serial-over-TCP gateway: chain can succeed against ancient stacks and the dropped session may cause an HMI alarm or process trip. This is the only role where impact escapes 'cosmetic,' and even there it remains DoS — no control-plane takeover. Verdict floor does NOT cross HIGH because there is no integrity or RCE primitive.
Why not higher?
MEDIUM would imply meaningful business risk; the bug's impact is capped at a single TCP connection reset against a shrinking population of pre-2010 stacks. There is no path to code execution, credential theft, or lateral movement. Even in the worst high-value role (OT gateway), the outcome stays in the availability column.
Why not lower?
IGNORE would be wrong for OT/ICS environments and a small set of legacy network gear where a connection drop has real operational consequence, and where BCP38 + TCP-MD5 may not be in place. The finding deserves backlog hygiene attention, not deletion.
What to do — in priority order.
- Enable TCP-MD5 or TCP-AO on every BGP peering — RFC 2385 / RFC 5925 reject any TCP segment not bearing the keyed digest, neutralizing this attack against the only deployment role where a connection reset has real business impact. Standard config on Cisco IOS/JunOS/Arista; no SLA — this should already be in place, audit by quarter-end.
- Verify RFC 5961 is enabled on Linux fleet — Confirm
net.ipv4.tcp_challenge_ack_limitis set (default since 2.6.36) and that no hardening profile has zeroed it. Push via Ansible/Puppet baseline. No mitigation SLA — fold into the next configuration baseline review. - Enforce BCP38 / uRPF at all internet edges — Drops spoofed-source packets before they reach internal stacks. Eliminates the off-path injection prerequisite for this and a dozen other spoofing-class attacks. Audit during your next firewall ruleset review.
- Inventory and isolate pre-2010 TCP stacks — Embedded gear, printers, UPS, SCADA gateways, legacy Windows. Place behind segmentation so the four-tuple is not reachable from untrusted networks. Tracked in the asset inventory program, not a CVE SLA.
- Suppress plugin 12213 on hosts confirmed RFC 5961-compliant — Tenable's plugin sometimes false-positives on stacks that ARE compliant but respond to crafted probes ambiguously. Document the suppression rationale per host class to keep the scan signal clean.
- TLS / SSH / IPsec on the connection — these protect payload but a TCP RST tears down the session before crypto matters; reconnect is the only mitigation at that layer (and it's enough for human-facing sessions)
- IDS RST-flood signatures — fire after the damage, generate alert fatigue, and offer no inline protection
- Patching the OS — there is no patch in 2026; the fix shipped a decade ago. If your stack lacks it, you have a vendor-support problem, not a patch problem
- Web Application Firewall — operates above TCP; cannot see or block spoofed RST/SYN packets
Crowdsourced verification payload.
Run on a representative Linux host as a regular user — no privileges needed for the sysctl read. Example: ./check-rfc5961.sh. For Windows hosts, the equivalent is verifying OS build ≥6.1 (Windows 7 / Server 2008 R2) — anything older is end-of-life and inherently vulnerable. Outputs VULNERABLE, PATCHED, or UNKNOWN.
#!/usr/bin/env bash
# noisgate verifier — CVE-2004-0230 / Tenable plugin 12213
# Checks for RFC 5961 (challenge ACK) support on a Linux host.
# Exit codes: 0=PATCHED, 1=VULNERABLE, 2=UNKNOWN
set -u
OS="$(uname -s)"
if [ "$OS" != "Linux" ]; then
echo "UNKNOWN: this verifier targets Linux. For Windows, confirm build >= 6.1 (Win7/2008R2)."
exit 2
fi
KVER="$(uname -r | awk -F. '{printf "%d%03d%03d\n", $1, $2, ($3+0)}')"
# RFC 5961 mitigations landed in 2.6.36
MIN="2006036"
if [ "$KVER" -lt "$MIN" ]; then
echo "VULNERABLE: kernel $(uname -r) predates RFC 5961 (need >= 2.6.36)"
exit 1
fi
# Confirm the challenge ACK limit sysctl exists and is non-zero
SCTL="/proc/sys/net/ipv4/tcp_challenge_ack_limit"
if [ ! -r "$SCTL" ]; then
echo "UNKNOWN: kernel new enough but $SCTL not readable"
exit 2
fi
LIM="$(cat "$SCTL" 2>/dev/null || echo 0)"
if [ "$LIM" -le 0 ]; then
echo "VULNERABLE: tcp_challenge_ack_limit=$LIM (mitigation disabled)"
exit 1
fi
# Optional: surface SACK / rst_in_window counters if available
if [ -r /proc/net/netstat ]; then
SKIP=$(awk '/TCPACKSkippedChallenge/{f=1; next} f{print $0; exit}' /proc/net/netstat 2>/dev/null || true)
[ -n "$SKIP" ] && echo " (info) TCPACKSkippedChallenge counter row: $SKIP"
fi
echo "PATCHED: kernel $(uname -r), tcp_challenge_ack_limit=$LIM (RFC 5961 active)"
exit 0
If you remember one thing.
Sources
- NVD — CVE-2004-0230
- Tenable plugin 12213
- US-CERT VU#415294 (TCP RST attack)
- RFC 5961 — Improving TCP's Robustness to Blind In-Window Attacks
- RFC 2385 — TCP MD5 Signature Option (BGP protection)
- RFC 5925 — TCP Authentication Option (TCP-AO)
- Watson, *Slipping in the Window* (CanSecWest 2004)
- CISA KEV catalog (not listed)
What defenders are saying.
Crowdsourced verification outputs.
Results submitted by users who ran the verification payload against their environment.