## https://sploitus.com/exploit?id=CE83283F-0225-5C27-B272-334E3A273C9A
# CVE-2026-28318 โ SolarWinds Serv-U "Content-Encoding: deflate" pre-auth crash
> **Root-cause analysis + DoS proof-of-concept.**
> The public advisory classifies this as an unauthenticated *denial-of-service / uncontrolled
> resource consumption*. Binary analysis shows the underlying defect is **memory-safety**: an
> **invalid `free()` of an interior pointer** in the HTTP `deflate` decode path, which corrupts
> the process heap (`STATUS_HEAP_CORRUPTION`, `0xC0000374`). It is **not** a decompression bomb,
> and the crash is **independent of the decompressed size**.
---
## โ ๏ธ Disclaimer / scope
- This is **defensive security research** for an **already-patched, publicly-disclosed** vulnerability
(fix shipped **2026-06-04** in Serv-U 15.5.4 Hotfix 1; listed in **CISA KEV**).
- The PoC here only **crashes** a Serv-U instance you **own or are explicitly authorized to test**.
It is **DoS-only** โ no remote code execution is included or demonstrated (see *Severity*).
- Use it to **validate patch status and detection** on your own systems. Do not point it at systems
you do not control. You are responsible for complying with applicable law.
---
## Affected / Fixed
| | |
|---|---|
| Product | SolarWinds Serv-U (FTP / MFT / File Server) |
| Vulnerable | 15.5.4 and earlier in that branch **without** Hotfix 1 (analysis done on build **15.5.4.108**) |
| Fixed | **Serv-U 15.5.4 Hotfix 1** (released 2026-06-04) |
| Vector | Unauthenticated, network (HTTP/HTTPS management/web port) |
| Public class | CWE-400 Uncontrolled Resource Consumption ยท DoS ยท CVSS 7.5 ยท CISA KEV |
| Actual class | **CWE-763 Release of Invalid Pointer / CWE-590 Free of Memory not on the Heap** โ heap corruption |
> Affects only the HTTP/HTTPS listener (the web/management path). FTP/FTPS/SFTP are not on this code path.
---
## TL;DR
Any HTTP request carrying `Content-Encoding: deflate` **with a valid deflate body** crashes the
service. The handler decompresses the body, then **frees the pointer to the *compressed* body** and
swaps in the decompressed buffer โ but that pointer is an **interior pointer into the HTTP receive
buffer** (it points at the body, immediately after the `\r\n\r\n`), **not a heap allocation base**.
Calling `free()` on a non-base, unaligned pointer corrupts the heap and the process dies.
Because the bug is in *how the body pointer is freed* โ not in *how much* data is produced โ even a
~25-byte compressed body (that decompresses to a few KB) reliably crashes it. Memory usage does not
grow; it is not a "zip/deflate bomb."
---
## Root cause
The deflate-decode routine lives in `RhinoNET.dll` (Serv-U's network library) and is reached from the
HTTP receive path (`ProcessReceive`) once the header parser sets the "deflate" flag on seeing
`Content-Encoding: deflate`.
Simplified, the routine is called as `decode(this, &bodyPtr, &bodyLen)` and does:
```
1. inflate bodyPtr[0..bodyLen] -> grows an accumulator buffer `acc` (stock zlib, bounded, correct)
2. free(*bodyPtr) --port 80
python poc_verify.py --big # body decompresses to 8192 bytes
python poc_verify.py --shots 3
python poc_verify.py --no-events # skip event-log check (no privileges needed)
```
The PoC builds a minimal request:
```
POST / HTTP/1.1
Host:
Content-Encoding: deflate
Content-Type: application/octet-stream
Content-Length:
Connection: close
```
It reports **PASS** if the service crashed (listener PID changed / `0xC0000374` event appeared) and
**FAIL** if it survived (already patched, not affected, or the body was not processed as deflate).
---
## Mitigation
1. **Apply Serv-U 15.5.4 Hotfix 1** (or later).
2. **Interim:** in front of Serv-U, strip or reject inbound `Content-Encoding` on the HTTP/HTTPS
listener, e.g. on a reverse proxy:
```nginx
if ($http_content_encoding) { return 400; }
```
3. Restrict network exposure of the Serv-U web/management port.
---
## Methodology (how this was analyzed)
- Static: parameterized PE disassembly of `RhinoNET.dll` / `Serv-U.exe` (image base `0x180000000`) to
map the receive โ header-parse โ deflate-decode path and locate the erroneous `free`.
- Dynamic: Frida instrumentation of the live service โ hooking the decompressor to prove `zlib`
honors `avail_out`, tracing every `alloc`/`free`/`memcpy` of the decode call to disk, and a process
exception handler to capture the faulting instruction and the `0xC0000374` stack at the moment of
corruption. The interior-pointer free was then confirmed by dumping the bytes around the freed
pointer (HTTP header tail + raw-deflate body, 16-byte-misaligned).
Offsets referenced in analysis are specific to build 15.5.4.108 and will differ across builds.
---
## References
- SolarWinds โ Serv-U 15.5.4 Hotfix 1 release notes
- NVD โ CVE-2026-28318
- CISA KEV catalog โ CVE-2026-28318
---
*Published as defensive research after vendor patch availability. PoC is DoS-only and intended for
authorized testing.*