Vulnerability research

NetScaler: when handshake fragments overrun a buffer

A VPN gateway processes connection requests before an employee logs in. NetScaler CVE-2026-88772 fails at that stage: assembling fragments can copy more data than a buffer holds. Exploitation is confirmed. Older appliances with DTLS enabled need urgent patching and an investigation of their earlier exposure.

Warm-paper drawing of a gateway feeding paper fragments into a fixed-size sorting tray until they spill beyond its right boundary.
In this article

A company puts its VPN gateway on the internet so employees can connect securely from elsewhere. Before it checks an employee's identity, however, the gateway has work to do: receive packets, negotiate encryption and assemble handshake messages that arrive in pieces. The sender has not logged in yet. A flaw at this stage reaches the appliance before passwords and multifactor authentication can protect the login.

NetScaler CVE-2026-88772 sits in that assembly process. On September 27, Citrix confirmed exploitation and CISA added it to the Known Exploited Vulnerabilities catalog. A patch analysis published on the 29th explained the failure: after deciding that a message is complete, the program copies its stored contents into contiguous memory. That copy lacked a capacity bound. Passing the completeness check still left the subsequent write unsafe.

Our assessment is that internet-reachable DTLS services on older firmware warrant emergency patching. Strong passwords, login rate limits and MFA operate later in the process. Yesterday's 88771 log-command-injection investigation followed a background script; this vulnerability concerns the gateway's handling of network data in memory. Each needs its own exposure check.

1 The work that happens before login

DTLS provides encrypted communication over UDP. Packets can be lost or arrive out of order, and a long handshake message can be split into fragments. The receiver must remember which message each fragment belongs to and where it fits, then resume negotiation when the missing pieces arrive. The handshake format in RFC 6347 separates the complete message's length, its message_seq, the fragment's fragment_offset and its fragment_length. These fields answer different questions.

Consider an eight-byte message in two fragments: one covers positions zero through three, the other four through seven. The receiver can now determine whether all message bytes are present. An implementation may also retain record headers, internal buffer structures or other temporary contents. The message's logical length and the number of bytes stored in memory require separate accounting. Treating one as a guarantee about the other leaves the next copy exposed.

DTLS also has a cookie round trip: the server returns a value and asks the client to present it again. The protocol describes its purpose as checking that the sender can receive replies at that address, reducing resource exhaustion through spoofed source addresses. Someone who can send and receive packets can complete that exchange. Employee authentication still comes later. Exposure assessment needs to follow the packet's route to the service.

Citrix's security bulletin identifies enabled DTLS as the prerequisite, with DTLS enabled by default on VPN virtual servers. Searching configuration text for an explicit DTLS service can miss an ordinary SSL VPN virtual server that inherits this default. Dedicated DTLS virtual servers and load-balancing services also matter. Check the effective settings and network reachability of each virtual server.

2 A complete message can still overflow its destination

watchTowr compared 14.1-73.30 with 14.1-73.37: the nsppe Packet Engine combines linked NetScaler Buffers (NSBs) into a 0x8c00-byte buffer. Declared fragment lengths can diverge from retained NSB contents; the old loop lacked a remaining-capacity check for each copy. The patch adds that check. Citrix has not published source function names or line numbers. This explanation relies on the published comparison; SOSEC obtained no firmware and did not independently reproduce appliance code execution.

How does that gap arise? In the published example, the complete message declares 120 bytes and each fragment advances reassembly by one byte. Its NSB node retains substantially more record content. Once all 120 positions are covered, coalescing walks the chain and copies retained node contents. The copied total can therefore greatly exceed the declared 120-byte message. Track both the declared contribution to the message and the length the internal node eventually supplies to the copy.

0x8c00 is 35,840 in decimal. The capacity is substantial; the question is what guarantees that the total copied into it stays below that number. If fragment collection tracks progress using declared lengths while the later copy uses lengths retained in internal nodes, the two stages can assign different sizes to the same input. The first has already declared the message complete. The second keeps walking the chain and moving bytes.

Two independent checks make the error easier to follow. Coverage asks whether the required message bytes have arrived. Capacity asks whether the bytes about to be written will fit. Even a valid fragment needs the latter check; inconsistent input makes it especially important. The protocol also requires receivers to handle overlapping fragments caused by retransmission. Rejecting every overlap would break legitimate traffic.

The upper row checks fragment positions for completeness. The lower row checks actual bytes against fixed capacity. Remaining capacity must be checked before each copy.
Two checks examine the same data for different purposes. Tiles and boxes illustrate completeness and capacity; they do not represent packet counts, an appliance memory layout or proportional sizes.

What follows an out-of-bounds write depends on adjacent memory, control over the written bytes and the code that later consumes corrupted state. A crash is one possible outcome; Citrix also confirms remote code execution as an impact. Operators should preserve an unexpected restart for investigation, then correlate its time with connections, processes and file changes. A restart alone cannot establish that attacker code executed.

3 Protect every write

This independent model shows where a capacity check belongs. It handles integers only: no network requests and no NetScaler packets. Suppose a destination holds 64 bytes and a saved header takes eight. Every remaining chunk must fit in the space left. All lengths below are validated nonnegative integers:

def fits(capacity, header_size, chunks):
    if header_size > capacity:
        return False
    remaining = capacity - header_size
    for size in chunks:
        if size > remaining:
            return False
        remaining -= size
    return True

assert fits(64, 8, [20, 20, 16])
assert not fits(64, 8, [20, 20, 17])
assert not fits(64, 65, [])

The first case fills the destination exactly: 8 + 20 + 20 + 16 = 64. The second exceeds it by one byte and must be rejected before the third copy starts. In the third, even the header is too large and must be rejected first. SOSEC ran these three assertions locally; all passed. They validate this model's accounting. Appliance correctness still depends on the vendor implementation and appliance tests.

The order matters too: compare the next chunk with remaining space before subtracting. In low-level code with fixed-width integers, adding several external lengths before comparing the sum with capacity can overflow the sum itself. Implementers must also reject negative lengths, validate pointer ranges, release temporary state on failure and use the same length for both the check and the copy. Two independently chosen values can reopen the gap.

Regression tests should follow these relationships: valid single- and multi-fragment messages complete; an exact fit succeeds; one excess byte is rejected before a write; duplicate, reordered and overlapping fragments follow protocol rules; and an interrupted or rejected message leaves the next valid connection working. These cases explain what the repair protects. Sending a crash-triggering sample to a production gateway disrupts service without covering those different failure paths.

4 What to change on the gateway

Inventory customer-managed instances, including standby nodes and NetScaler instances used by Secure Private Access Hybrid. Citrix updates its managed cloud services. Prioritize older instances with reachable DTLS services. Temporarily disabling the relevant DTLS service or blocking its UDP entry point at a controlled network boundary reduces this vulnerability's exposure. Remote-access performance and availability may change; verify any transport fallback with the actual clients. The companion 88771 vulnerability still requires an upgrade.

On September 30, the official download page lists 14.1-73.37 and 13.1-64.24 for the ordinary release branches. Stay within the appropriate product line; ordinary packages cannot substitute for FIPS or NDcPP builds:

First fixed releases and current deployment choices by branch
BranchFirst fixedDeployment choice
ADC / Gateway 14.114.1-73.3714.1-73.37
ADC / Gateway 13.113.1-64.2313.1-64.24
ADC 14.1 FIPS14.1-73.37 FIPS14.1-73.37 FIPS in that branch
ADC 13.1 FIPS / NDcPP13.1-37.27913.1-37.279 for the matching FIPS / NDcPP line

Scoring and version databases deserve a careful read as well. At retrieval, NVD was Analyzed, with NIST assigning CVSS 3.1 at 8.1 and the NetScaler CNA assigning CVSS 4.0 at 9.5. Different scoring systems are not a single severity trend. NVD's machine-readable 14.1 FIPS range also included 14.1-73.37 as an affected endpoint, conflicting with the vendor bulletin and CNA repair boundary. This article follows the vendor package table for deployment and retains that discrepancy for reviewing scanner results. The state cutoff is September 30, 2026, 04:07 UTC.

The extra 13.1 build matters. Citrix's supplemental guidance documents cyclic reboots in 13.1-64.23 when variables are configured; affected deployments should use 13.1-64.24. The read-only show ns variable command checks that condition. Upgrades also require signed SAML assertions, so confirm the identity provider's configuration before changing the gateway. The 15.1 Technology Preview remained vulnerable at the cutoff, and Citrix does not permit its production use.

Verify recovery with normal business traffic: check the running build on every node, HA status and intended DTLS settings, then complete an authorized login and application session while checking stability and logs. Keep necessary temporary restrictions until those checks finish. If the upgrade fails, keep unpatched nodes isolated. For ordinary 13.1 deployments, our rollback choice also remains 13.1-64.24 to avoid reintroducing the known reboot issue. Other branches must stay at or above their first-fixed release. If an operational emergency requires booting older firmware, keep it isolated while the incident owner decides how to restore service.

5 Investigate the time before the patch

Confirmed exploitation adds another obligation: determine whether someone entered during the exposure window. Citrix's suspected-compromise guide calls for preserving time information, logs and relevant instance or disk evidence, followed by isolation, investigation and rebuilding. Collecting a Packet Engine core causes a warm restart and disconnects SSH; account for its effects on evidence and service before proceeding. Preserve external syslog records too.

Signs of compromise widen recovery to identities and connected systems: investigate related authentication services, revoke exposed credentials, certificates and private keys, rebuild from trusted media, then restore a reliable pre-compromise configuration and rotate secrets. Citrix's IOC checks can assist, with coverage changing as detection logic evolves. A clean result leaves unrepresented attacker behavior to investigate. Record the detection version and time to make the result interpretable.

The engineering lesson is specific. Establishing that a message is complete finishes one part of protocol handling. Moving it into another storage representation requires a fresh capacity check against the bytes actually written. For an administrator on call, closure is equally concrete: the gateway runs repaired firmware, and someone owns the investigation of its earlier exposure. Once legitimate access works again, the response can begin to wind down on that basis.

Research basis

Research basisReviewed vendor guidance, current releases, CNA, NVD and change history, KEV and DTLS semantics. Appliance internals rely on the researcher's published firmware comparison; no firmware was obtained or appliance exploit reproduced. Only an offline capacity model was run. Sources checked through 2026-09-30 04:07 UTC.

SourceCitrix, CISA, NVD, RFC 6347 and watchTowr

Evidence confidence High

6Evidence and sources

6.1Sources and material

  1. Citrix: prerequisites and fixed releases, CTX697096https://support.citrix.com/external/article/CTX697096
  2. watchTowr: September 29 DTLS overflow and firmware patch analysishttps://labs.watchtowr.com/here-we-go-again-citrix-netscaler-dtls-preauth-memory-overflow-cve-2026-88772/
  3. RFC 6347: DTLS handshake, cookies and fragmentationhttps://www.rfc-editor.org/rfc/rfc6347.html#section-4.2
  4. Citrix: current NetScaler download brancheshttps://www.citrix.com/downloads/citrix-adc/
  5. Citrix: configuration, IOCs, 13.1 upgrade and SAML guidancehttps://community.citrix.com/techzone-blogs/110_security-updates/netscaler-adc-and-netscaler-gateway-security-bulletin-for-cve-2026-88771-through-cve-2026-88778/
  6. Citrix: evidence preservation, isolation and recovery after suspected compromisehttps://support.citrix.com/external/article/CTX694799/steps-to-take-if-netscaler-adc-is-suspec.html
  7. CISA: live KEV cataloghttps://www.cisa.gov/sites/default/files/feeds/known_exploited_vulnerabilities.json
  8. NetScaler CNA: original CVE-2026-88772 recordhttps://cveawg.mitre.org/api/cve/CVE-2026-88772
  9. NVD: independent score, product matching and change historyhttps://nvd.nist.gov/vuln/detail/CVE-2026-88772