# CVE-2026-50518 — Windows DHCP Server `dhcpssvc.dll` Punycode DNS-Name Conversion Heap Overflow (Unauthenticated RCE)

---

## Summary

| | |
|---|---|
| **Product** | Windows — `dhcpssvc.dll` (DHCP Server Service) |
| **CVE ID** | CVE-2026-50518 |
| **Impact** | Remote Code Execution (unauthenticated, network) |
| **MSRC severity** | Critical |
| **CVSS** | 9.8 — `CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H` |
| **CWE** | CWE-122: Heap-based Buffer Overflow |
| **Delivery** | Network — crafted DHCP traffic to the server (no authentication) |
| **KB / Fixed build (diffed lineage, Server 2016)** | KB5099535 — `dhcpssvc.dll` 10.0.14393.9339 |
| **Other affected SKUs** | Windows Server 2019 (KB5099538), 2022 (KB5099540), **2025** (KB5099536, `10.0.26100.33158`), 2012/2012 R2 |
| **Patch Date** | July 14, 2026 (2026-Jul) |
| **Pre-patch binary** | `dhcpssvc.dll` 10.0.14393.8781 (KB5094122) — SHA256 `262b5fe4ace7165fd6d24c3cc7e6fb09673d000c0fbf7ec023149aa3312ac313` |
| **Post-patch binary** | `dhcpssvc.dll` 10.0.14393.9339 (KB5099535) — SHA256 `c8a2b60dda941eb8ce58b5ef5bdb340d0818aebc3397696911b50a00000adad2` |
| **Feature flag** | `Feature_2907675961` (name-conversion path); broader DHCP option-parsing hardening under `Feature_661624120` — **CFR-gated** |
| **Exploitability** | Exploitation More Likely; not publicly disclosed; not exploited (per MSRC) |

> Lineage note: this diff is the **Server 2016 (build 14393)** pair `.8781 → .9339`
> (KB5099535) — winbindex indexes it, whereas the Server 2025 (`26100.33158`, KB5099536)
> build is not indexed. The same fix ships across the affected DHCP-Server SKUs.

---

## Product Description

`dhcpssvc.dll` implements the **Windows DHCP Server Service**. It parses DHCP options
from client packets, including options that carry **DNS names** (e.g. the client FQDN
option / domain search list). Names arrive in wire/punycode form and are converted to
Unicode by `DhcpGetUnicodeNameFromWirePunycodeName`, which walks the name label-by-label,
calling `ConvertPunycodeToUnicode` into a fixed destination buffer.

---

## Vulnerability Summary

`DhcpGetUnicodeNameFromWirePunycodeName` converts a wire/punycode DNS name into a fixed
**512-byte (0x200) destination buffer**, advancing through the name's labels. Pre-patch,
the **remaining-space accounting was incorrect** — the running size was recomputed as
`remaining = remaining + (remaining >> 1) * -2 + 2` rather than being properly decremented
by each converted label — so a crafted name with enough/long labels could drive the
cumulative Unicode output **past the end of the destination buffer**, a heap-based buffer
overflow (CWE-122). Because the DHCP Server processes **attacker-supplied packets over the
network without authentication** (`AV:N`, `PR:N`), the overflow is a remote code-execution
primitive (Microsoft rates it **Critical, 9.8**).

---

## Prerequisites and Constraints

- Network, unauthenticated (`AV:N`, `AC:L`, `PR:N`, `UI:N`) against a Windows DHCP Server.
- Send a DHCP packet whose DNS-name option (FQDN / domain search list) contains a
  crafted punycode name that overflows the 512-byte conversion buffer.
- Result: the punycode→Unicode conversion writes past the heap buffer.

---

## Vulnerability Details

### Root Cause

The destination-buffer remaining-space tracking in the multi-label punycode→Unicode name
conversion was miscomputed, so cumulative writes across labels could exceed the fixed
512-byte buffer.

### The patch (confirmed — diff, .8781 → .9339)

`DhcpGetUnicodeNameFromWirePunycodeName` (function ratio 0.69) is reworked, gated behind
the CFR feature flag, to track the remaining input and output space correctly and to
check the conversion result before advancing:

```c
// DhcpGetUnicodeNameFromWirePunycodeName (10.0.14393.9339) — PATCHED (from the diff)
size = 0x200;                                   // 512-byte dest buffer
...
remaining_wchars = size >> 1;                   // remaining output capacity (chars)
rc = ConvertPunycodeToUnicode((LPCSTR)(label + 1), label_len, dst);
if (rc != 0) { ... handle error ... }           // *** check conversion result ***
input_remaining = (input_remaining - 1) - label_len;   // decrement input by this label
dst = dst + remaining_wchars;                    // advance dest by converted length
// (pre-patch instead did: remaining = remaining + (remaining>>1)*-2 + 2  — wrong accounting)
```

With the input/output space decremented correctly per label and the conversion return
value checked, the accumulated Unicode output can no longer exceed the destination buffer,
closing the heap overflow. (The surrounding DHCP option-parsing routines —
`DhcpParseOptionV6`, `DhcpParseRegistryOption`, `DhcpGetOptionV6ByOptClass`,
`AddVendorOptDefsFunc*` — are hardened in the same update under `Feature_661624120`.)

### Patch Completeness Assessment

**CFR-gated.** The corrected conversion runs only when the flag is enabled; the original
accounting still ships when disabled. Given unauthenticated network RCE against DHCP
servers, apply the July 2026 update for your Server SKU (KB5099535 / KB5099536 / KB5099538
/ KB5099540) and restrict DHCP (UDP 67) exposure regardless.

---

## Detection Guidance

**Behavioural.** Heap corruption / crashes in the DHCP Server service
(`dhcpssvc!DhcpGetUnicodeNameFromWirePunycodeName` / `DhcpParseOptionV6`) on
unpatched/flag-disabled builds, correlated with DHCP packets carrying unusually long or
malformed DNS-name (FQDN / domain-search) options. Monitor DHCP server process health;
restrict DHCP to trusted network segments.

**Config.** The fix is CFR-gated — confirm the DHCP name-conversion feature flag is enabled.

---

## References

- MSRC advisory — CVE-2026-50518 (Windows DHCP Server Service Remote Code Execution), released 2026-07-14, KB5099535 (Server 2016) and per-SKU KBs.
- Full binary diff: `/data/patch_diffs/dhcpssvc_dll-cve-2026-50518-ghidriff.md`
