Share
## 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.*