CVE-2022-34718 — EvilESP: Windows TCP/IP IPsec ESP OOB Write RCE

Last updated: 2026-04-19
Severity: Critical (CVSS 9.8)
Component: tcpip.sys
Bug Class: OOB Write (single byte, remote, kernel-mode)
Privilege Escalation: Remote Unauthenticated → SYSTEM (RCE theoretical; DoS demonstrated)
Patch: September 2022 Patch Tuesday (KB5017315 and related)
Related: Tcpip Stack, Pool Internals, Primitives, Reversing

Vulnerability Summary

CVE-2022-34718 (“EvilESP”) is a critical zero-click remote kernel vulnerability in tcpip.sys. An unauthenticated attacker with an established IPsec Security Association can send a crafted IPv6 packet containing a Fragment Extension Header embedded inside an IPsec ESP payload to trigger a single-byte out-of-bounds write into the NetIoProtocolHeader2 kernel pool object. The written offset is > 0x38 and the written value (0x2c) is controlled via the ESP tail’s Next Header field. Reliable remote DoS was demonstrated; RCE paths were outlined but not publicly completed at time of disclosure.

Prerequisites:

  • Target has IPv6 enabled (default on Windows 7+)
  • Target has IPsec configured and a Security Association established with the attacker
  • SA can be established via: domain environment with group policy, pre-shared key (PSK), or certificate-based auth — requires two IP security policies with mutual authentication

Root Cause Analysis

Two patched functions in tcpip.sys

BinDiff analysis of sequential pre/post-patch builds revealed two modified functions:

1. Ipv6pReassembleDatagram — incorrect memory offset calculation
When reassembling an IPv6 fragmented datagram that was delivered through an IPsec ESP payload, the offset into the NetIoProtocolHeader2 pool object is computed as:

offset = sizeof(Payload Data) + sizeof(Padding) + sizeof(Padding Length)

Due to a missing bounds check, this offset can be larger than the object’s size (> 0x38), placing the write past the end of the allocated object into adjacent pool memory.

2. ESP extension header type gate — patch discards malformed packets early
The patch adds a check: if the IPv6 extension header type embedded in the ESP tail structure is ≤ 0x2c, discard the packet before reassembly. This blocks the three extension headers that exploit the bug:

Extension HeaderNext Header Value
Hop-by-Hop Options0x00
Routing Header0x2b
Fragment Header0x2c ← exploit vector

The OOB Write Primitive

Target object:  NetIoProtocolHeader2 (kernel paged pool)
Write offset:   > 0x38 (controllable via packet crafting)
Write value:    0x2c (IPv6 Fragment Header type — Next Header field value)
Write size:     1 byte

The value 0x2c (= IPv6 Fragment Extension Header type) comes from the Next Header field in the ESP tail structure. Corrupting even one byte of the NetIoProtocolHeader2 object at a random offset > 0x38 does not cause an immediate crash, but reliable BSOD is achievable by:

  1. Additional headers in fragmented message — insert extra extension headers to push the offset further and corrupt more critical bytes of adjacent objects
  2. Repeated pings after initial corruption — spray the pool and trigger crash through accumulated corruption

IPsec ESP Protocol Background

ESP (Encapsulating Security Payload, RFC 4303) is an IPsec protocol that encrypts/authenticates network traffic between two hosts sharing a Security Association (SA). An SA is a unidirectional set of cryptographic parameters (algorithm, key, SPI) negotiated via IKEv1/IKEv2 or manual configuration. The SA requirement is the main exploitation prerequisite: without it, tcpip.sys drops ESP packets before any parsing occurs.

ESP packet structure relevant to the bug:

ESP Header:
  [SPI (4)] [Seq# (4)]
ESP Payload:
  [Payload Data — contains embedded IPv6 packet with Fragment Header]
ESP Trailer:
  [Padding (0-255 bytes)] [Padding Length (1)] [Next Header (1)] ← 0x2c here
ICV (optional):
  [Integrity Check Value — aligned on 4-byte boundary per RFC]

The padding requirement (ICV must be 4-byte aligned per RFC) means the Padding Length field can be crafted to control the offset calculation.


Exploitation Technique

Stage 1: Establish Security Association

Attacker configures IPsec SA with the target using PSK or domain policy. Both endpoints need matching IP security policies with mutual authentication.

Stage 2: Send Malicious ESP Packet

Craft an IPv6 ESP packet containing:

  • An IPv6 Fragment Header (type 0x2c) embedded in the payload
  • ESP tail Next Header = 0x2c
  • Padding tuned to control sizeof(Payload Data) + sizeof(Padding) + sizeof(Padding Length) > 0x38

Send to target. tcpip.sys decrypts the ESP payload, then processes the embedded IPv6 extension headers including the Fragment Header, triggering Ipv6pReassembleDatagram with the corrupted offset calculation.

Stage 3: NetIoProtocolHeader2 Corruption

The 1-byte OOB write at offset > 0x38 lands in NetIoProtocolHeader2 or an adjacent pool object. Immediate crash is not guaranteed — the byte at that position may be padding. Reliability techniques:

# Conceptual: additional extension headers increase offset
# Each extension header adds to sizeof(Payload Data) path
# Craft: Fragment Header + N×RoutingHeaders inside ESP payload
# → offset grows to corrupt critical fields of adjacent object

Exploit Primitives (Theoretical RCE Paths)

IBM X-Force outlined two paths from OOB write to RCE:

Path 1: NetIoProtocolHeader2 → AAR/AAW
Study the NetIoProtocolHeader2 structure layout. If the 1-byte write at offset > 0x38 can land on a length field, pointer low byte, or function pointer, it can be converted into an arbitrary read/write primitive.

Path 2: Adjacent object corruption
Use pool grooming to place a controlled kernel object adjacent to NetIoProtocolHeader2 in the paged pool. Corrupt a single critical byte (e.g., a refcount, size field, or pointer LSB) in that adjacent object to gain a stronger primitive. See Pool Internals for grooming strategies.

PoC Implementation Approach

IBM X-Force used an NDIS protocol driver to construct and send raw IPv6+ESP packets with full control over all header fields — bypassing the socket API’s inability to craft raw IPsec payloads. Scapy with raw socket mode is a secondary approach for crafting the outer packet structure.


Key Primitives Used

  • OOB write: 1 byte at controllable offset > 0x38, value = 0x2c, into NetIoProtocolHeader2 pool object
  • Pool position control: Adjacent object grooming via paged pool spray (path to RCE)
  • Remote vector: No local access required — exploitable over network

Mitigations Bypassed

  • No authentication required: Exploitable pre-auth (SA establishment is a network operation, not OS login)
  • Windows Firewall: tcpip.sys processes ESP packets below the firewall layer — firewall cannot filter this
  • KASLR: Not bypassed in DoS demo; required for full RCE — would need kernel leak or predictable pool layout

Proof-of-Concept Notes

  • chompie1337 (@chompie1337) demonstrated remote DoS via crafted IPv6/ESP packet
  • PoC video: https://twitter.com/chompie1337/status/1583666434668101637
  • Numen Cyber Labs published independent PoC restoration: https://www.numencyber.com/tcp-ip-vulnerability-cve-2022-34718-poc-restoration-and-analysis/
  • PoC requires: NDIS driver or low-level raw packet sender; established IPsec SA with PSK; IPv6 reachability
  • Full RCE PoC: not publicly released as of 2026-04

Patch Analysis

Methodology (IBM X-Force):

  1. Obtained pre-patch and post-patch tcpip.sys from Winbindex (https://winbindex.m417z.com/?file=tcpip.sys) — sequential builds to minimize noise
  2. Loaded both binaries in Ghidra; applied PDB files from Microsoft Symbol Server → all functions named
  3. Exported both binaries in BinExport format using the BinExport Ghidra extension
  4. Loaded into BinDiff → matched functions by name (symbol info available) → identified two modified functions

Key insight from patch diff:
The patch prohibits ESP from carrying IPv6 extension headers with type ≤ 0x2c. This is the minimal fix — the check is added at the ESP parsing layer before reassembly is triggered. The underlying offset calculation bug in Ipv6pReassembleDatagram is also fixed independently.

Patch analysis workflow note:
Using Ghidra+BinExport+BinDiff is a valid alternative to the IDA-based workflow (see Reversing). When PDB symbols are available, all functions match by name and BinDiff’s structural algorithms are less important — focus directly on the matched-but-changed function list.


References

  • chompie1337 (IBM X-Force), “Dissecting and Exploiting TCP/IP RCE Vulnerability ‘EvilESP’”, IBM Security Intelligence / IBM Think, 2023 — https://www.ibm.com/think/x-force/dissecting-exploiting-tcp-ip-rce-vulnerability-evilesp
  • chompie1337, Twitter PoC demo: https://twitter.com/chompie1337/status/1583666434668101637
  • Numen Cyber Labs, “TCP/IP Vulnerability CVE-2022-34718 PoC Restoration and Analysis”, 2022 — https://www.numencyber.com/tcp-ip-vulnerability-cve-2022-34718-poc-restoration-and-analysis/
  • Microsoft MSRC Advisory: https://msrc.microsoft.com/update-guide/en-US/vulnerability/CVE-2022-34718
  • RFC 4303 — IP Encapsulating Security Payload (ESP)