
Citrix NetScaler CVE-2026-88772 — DTLS preauth memory overflow
watchTowr Labs reverse-engineers CVE-2026-88772, a preauth DTLS memory overflow in Citrix NetScaler ADC/Gateway's nsppe binary, exploited in the wild as a zero-day and fixed in Citrix bulletin CTX697096. The writeup walks through patch diffing between build 14.1-73.30 and 14.1-73.37, crafting malicious DTLS handshake fragments that trick NetScaler's reassembly logic into copying about 174KB of NSB chain data into a 35,840-byte scratch buffer, and the full exploitation path from crash to a fake-vtable hijack, ROP-based mprotect call, and shellcode execution, plus a public detection artefact generator.
What it is
watchTowr Labs' exploitation walkthrough for CVE-2026-88772, a preauth DTLS buffer overflow in the nsppe binary of Citrix NetScaler ADC/Gateway. The bug requires DTLS enabled on a VPN virtual server (the default, unless an admin set -dtls OFF) and was exploited in the wild as a zero-day before the fix shipped in bulletin CTX697096.
How it works
DTLS handshake fragments carry two size fields: length (total message size) and fragment_length (bytes this record contributes). NetScaler's reassembly logic trusts fragment_length to decide how much of a record to keep, but allocates a full NSB (NetScaler Buffer) per record regardless. The attacker crafts 120 records, each claiming fragment_length=1 toward a 120-byte handshake message, but each record actually carries ~1,447–1,459 bytes padded via a second, "hidden" handshake header that only exists to satisfy per-record size accounting. Once all 120 offsets (0–119) arrive, NSPPE marks the message reassembled — but the NSB chain still holds the full ~174KB of data, not 120 bytes. The copy routine then memcpy's the entire chain into a fixed 0x8c00-byte (35,840-byte) scratch buffer in nsppe's .bss, with no bounds check, producing a ~137,825-byte overflow into adjacent writable data.
flowchart TD
A[120 DTLS records, each fragment_length=1] --> B[NSPPE marks 120-byte message complete]
B --> C[NSB chain actually holds ~174KB]
C --> D[memcpy into 35,840-byte scratch buffer]
D --> E[~137,825-byte overflow past buffer]
E --> F[Overwrite global list pointer]
F --> G[Overwrite fake vtable object]
G --> H[Hijack virtual call -> ROP: mprotect RWX page]
H --> I[Shellcode execution]From the crash, the authors repair an overwritten global list pointer (a constant, 0x357f820 in their build) to survive the first segfault, then corrupt an adjacent object at 0x355c800 to fake its method table and hijack a virtual call made by a periodic background-thread routine. Because NX is enabled and the binary has no PIE/RELRO/stack canary, they chain a ROP sequence (pop rdi/rsi/rdx; ret into mprotect) to mark a page RWX, then return into shellcode on that page.
Preconditions / Affected
- DTLS enabled on a NetScaler VPN virtual server (default unless explicitly disabled).
- Vulnerable through build 14.1-73.30; fixed in 14.1-73.37 (also 13.1-64.23, 14.1-FIPS 73.37, 13.1-FIPS/NDcPP 37.279).
- No PIE, no RELRO, no stack canary on the vulnerable binary — these absent mitigations are what make the ROP chain and address reuse practical, per the writeup.
What to do
- Patch to the fixed builds listed above.
- Where patching is delayed, note that disabling DTLS (
-dtls OFF) on VPN virtual servers removes the attack surface described here (default is DTLS enabled). - Use watchTowr's public Detection Artefact Generator (
watchTowr-vs-Citrix-Netscaler-CVE-2026-88772.py, linked on their GitHub) to test exposure; it drives a cookie-validated DTLS handshake and sends the 120 crafted records.
Caveats
The exact hijacked-object offsets, the vtable constant, and the global list pointer value (0x357f820) are specific to the authors' tested build (14.1-73.30) and may shift across versions/builds — the page presents this as their own verified chain, not a guaranteed-universal offset.
Organisations named here
- CTX697096
- Sina Kheirkhah
CVEs named here
- CVE-2026-88772
Technologies named here
- watchTowr Platform
- Citrix NetScaler ADC
- Citrix NetScaler gateway
- Detection Artefact Generator
- GDB
- Citrix NetScaler
Techniques named here
- DTLS handshake fragment reassembly confusion
- Hidden handshake header size-accounting bypass
- DTLS cookie exchange bypass to preauth state
- Global pointer corruption and fake object/vtable hijack
- ROP chain to bypass NX via mprotect
- Patch diffing
Related in Offensive Security