Skip to content
KitploitKITPLOIT
ToolsBlog
Submit
ToolsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

··Feeds·Contact·Privacy·© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
servu-cve-2026-28318-poc — SolarWinds Serv-U CVE-2026-28318: unauthenticated Content-Encoding: deflate crash. Root-cause analysis (invalid free of an interior pointer -> heap corruption) + DoS-only PoC. Fixed in 15.5.4 Hotfix 1. | Kitploit
Tools/GitHubGitHub/eaea0001/servu-cve-2026-28318-poc
Memory ForensicsVulnerability AnalysisExploitationPenetration TestingBinary Analysis
GitHubeaea0001/servu-cve-2026-28318-poc

servu-cve-2026-28318-poc

SolarWinds Serv-U CVE-2026-28318: unauthenticated Content-Encoding: deflate crash. Root-cause analysis (invalid free of an interior pointer -> heap corruption) + DoS-only PoC. Fixed in 15.5.4 Hotfix 1.

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share
View Repository
12 months agoNot yet reviewed

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

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:

root@kitploit:~
1. inflate bodyPtr[0..bodyLen]  -> grows an accumulator buffer `acc`   (stock zlib, bounded, correct)
2. free(*bodyPtr)                <-- *bodyPtr is an INTERIOR pointer into the receive buffer
3. *bodyPtr = acc                // replace compressed body with decompressed buffer
4. *bodyLen = total

Step 2 is the bug. *bodyPtr is not an independently-allocated block: it points to the request body inside the single HTTP receive buffer, i.e. receive_buffer + header_length. Freeing an interior (and 16-byte-misaligned) pointer makes the allocator parse an attacker-influenced region as a heap chunk header → heap metadata corruption → 0xC0000374.

What was ruled out (so you don't chase the wrong thing)

Both of the "obvious" hypotheses are wrong, verified at runtime:

  • Not an inflate/decompression overflow. The decompressor is stock zlib1.dll!inflate and honors avail_out on every call (observed across 100+ chunks; zero out-of-bounds writes).
  • Not an accumulator overflow. The growing output buffer is allocated as prev_total + produced + 1 each round and written exactly that much — tight, no overflow.

The corruption is solely the invalid free() in step 2.


Evidence

Captured at runtime (Frida) against Serv-U 15.5.4.108 while sending a Content-Encoding: deflate request whose body decompresses to "A" * 8192:

  • The freed pointer is …ce — mod 16 == 14. Heap allocation bases are 16-byte aligned, so this is not an allocation base; it is an interior pointer.
  • The 48 bytes before the freed pointer are the HTTP header tail, ending in \r\n\r\n:
    root@kitploit:~
    …tream\r\nContent-Length: 26\r\nConnection: close\r\n\r\n
    
  • The bytes at the freed pointer are a raw deflate stream (ed c1 01 0d 00 …).
  • Crash signature: faulting module ntdll.dll, exception 0xC0000374 (STATUS_HEAP_CORRUPTION), with the call originating from the free in the RhinoNET.dll deflate handler. The last heap operation before the crash is exactly this free(bodyPtr).
  • Size-independence: a body that decompresses to only ~4 KB (compressed ≈ a few dozen bytes) crashes identically; working-set memory does not grow.

Severity

  • Confirmed: reliable unauthenticated remote crash of the Serv-U service (DoS). The service may auto-restart, but repeated requests keep it down and can exhaust Windows service-recovery.
  • Beyond DoS — unproven. The freed "chunk header" overlaps attacker-controlled HTTP header bytes, which is in principle a stronger primitive than a plain DoS. However, on modern Windows (Segment Heap) the invalid free fast-fails (0xC0000374) in our testing, and we did not achieve code execution. Treat this as pre-auth heap-corruption DoS with a memory-safety root cause; do not assume RCE.

Reproduce

Requires Python 3 (standard library only). Point it at a Serv-U HTTP listener you are authorized to test. On Windows it uses one Get-NetTCPConnection call to read the listener PID and the Application event log to confirm the heap-corruption crash.

root@kitploit:~
python poc_verify.py                       # default 127.0.0.1:80, tiny packet, 1 shot
python poc_verify.py --host <ip> --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:

root@kitploit:~
POST / HTTP/1.1
Host: <target>
Content-Encoding: deflate
Content-Type: application/octet-stream
Content-Length: <n>
Connection: close

<raw-deflate body — even a few dozen bytes is enough>

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:
    root@kitploit:~
    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.

Download Tool
ProductSolarWinds Serv-U (FTP / MFT / File Server)
Vulnerable15.5.4 and earlier in that branch without Hotfix 1 (analysis done on build 15.5.4.108)
FixedServ-U 15.5.4 Hotfix 1 (released 2026-06-04)
VectorUnauthenticated, network (HTTP/HTTPS management/web port)
Public classCWE-400 Uncontrolled Resource Consumption · DoS · CVSS 7.5 · CISA KEV
Actual classCWE-763 Release of Invalid Pointer / CWE-590 Free of Memory not on the Heap → heap corruption