SolarWinds Serv-U CVE-2026-28318: KEV Denial of Service Vulnerability in Managed File Transfer
CISA added SolarWinds Serv-U CVE-2026-28318 to KEV on 2026-06-05, indicating active exploitation. The high-severity vulnerability allows remote, unauthenticated attackers to cause a Denial of Service (DoS) by sending specially crafted HTTP POST requests with a Content-Encoding: deflate header. SolarWinds has released version 15.5.4 Hotfix 1 to address the flaw.
On this page 0% read
Executive Summary
CISA added CVE-2026-28318 to the Known Exploited Vulnerabilities catalog on 2026-06-05, warning of active exploitation in the wild [Source 1]. The vulnerability affects SolarWinds Serv-U managed file transfer software. It is an uncontrolled resource consumption flaw (CWE-400) that allows a remote, unauthenticated attacker to cause a Denial of Service (DoS) condition by crashing the Serv-U service [Source 1] [Source 2].
The crash is triggered by sending a specially crafted HTTP POST request that includes the header Content-Encoding: deflate [Source 2] [Source 3]. SolarWinds released Serv-U version 15.5.4 Hotfix 1 to remediate the vulnerability [Source 2]. Administrators are strongly advised to patch their servers immediately or apply temporary mitigations such as blocking POST requests containing the Content-Encoding header or restricting access to trusted IP addresses [Source 2].
Key Facts
event_id: "solarwinds-serv-u-cve-2026-28318-kev"
cve: "CVE-2026-28318"
vendor: "SolarWinds"
product: "Serv-U"
kev_added: "2026-06-05"
kev_due: "2026-06-19"
cvss_v3: "7.5"
cwe: "CWE-400"
vulnerability: "uncontrolled resource consumption / remote denial of service"
patched_version: "15.5.4 Hotfix 1"
high_value_evidence:
- "Serv-U-StartupLog.txt (version check)"
- "WAF/HTTP access logs (POST requests with Content-Encoding: deflate)"
- "/var/log/syslog or Windows Event Log (Serv-U process crash/exit)"
Source Confidence & Evidence Mapping
- confirmed: CISA added CVE-2026-28318 to KEV on June 5, 2026, confirming evidence of active exploitation [Source 1].
- confirmed: SolarWinds published a trust center security advisory for CVE-2026-28318 detailing the
Content-Encoding: deflatevector and releasing version 15.5.4 Hotfix 1 as the minimum patched build [Source 2]. - confirmed: Industry advisories and analysis reports (e.g. BleepingComputer) verified the DoS behavior and provided recommended mitigations [Source 3].
- unknown: Public sources do not identify specific threat actor groups, campaign names, victim counts, or complete packet-level exploit payloads beyond the header manipulation.
Impact Determination
| Classification | Criteria | Required evidence | Handling decision |
|---|---|---|---|
| Confirmed compromise | System logs show frequent Serv-U crashes correlated with incoming POST requests containing Content-Encoding: deflate, or post-crash forensic review indicates active system tampering. | HTTP access/WAF logs, Serv-U process crash event IDs (e.g. Event ID 1000 on Windows or syslog segfaults on Linux), and file access logs. | Isolate the system, preserve log and registry evidence, perform memory forensics, and rotate all administrative and MFT user credentials. |
| Presumed exposed | Serv-U server is exposed to the internet and is running a version prior to 15.5.4 Hotfix 1. | Serv-U version extracted from Serv-U-StartupLog.txt, binary properties, or Windows Registry. | Apply Serv-U 15.5.4 Hotfix 1 immediately or implement temporary blocking mitigations at the WAF level. |
| Potentially exposed | Serv-U is present in the network asset inventory, but its version, patch level, and external exposure status are not yet verified. | CMDB assets, internal scanner logs, port scans. | Verify version and external exposure paths. |
| Not exposed | Serv-U is not deployed, or it is verified to be running version 15.5.4 Hotfix 1 or later with negative findings in crash and access logs. | Version status report, system uptime checks, and log audits. | Document version status, archive evidence, and continue routine monitoring. |
Timeline
- 2026-06-05: SolarWinds publishes security advisory for CVE-2026-28318, releasing Serv-U 15.5.4 Hotfix 1 [Source 2].
- 2026-06-05: CISA adds CVE-2026-28318 to the KEV Catalog [Source 1] [Source 3].
- 2026-06-06: Halting Problems releases this analysis and the corresponding local/log audit scripts.
- 2026-06-19: CISA BOD 22-01 remediation due date for federal civilian executive branch agencies [Source 1].
Technical Analysis
The vulnerability is rooted in how Serv-U processes compression headers in incoming HTTP requests. When an unauthenticated remote client sends an HTTP POST request containing Content-Encoding: deflate, the application attempts to decompress the payload. Due to improper resource limitation, this decompression process triggers uncontrolled CPU and memory consumption. As a result, the server runs out of memory or hangs, crashing the Serv-U service and causing a Denial of Service (DoS) for all connected file transfer users.
While DoS vulnerabilities are often deprioritized, file transfer systems like Serv-U represent a high-value entry point. Threat actors often leverage DoS attacks to disrupt operations, mask other malicious activities, or force services to reboot in vulnerable states to hijack configurations or access files.
Detection and Hunting
Script: Local and Log-Based Vulnerability Audit
The following Python script checks local Serv-U installation paths, registries, and log files for unpatched versions, system crash events, or HTTP access log entries that match the exploitation signature (POST requests utilizing deflate compression).
#!/usr/bin/env python3
"""Audit SolarWinds Serv-U CVE-2026-28318 exposure, log anomalies, and crash indicators."""
from __future__ import annotations
import argparse
import json
import os
import re
import sys
from pathlib import Path
CVE = "CVE-2026-28318"
MIN_PATCHED_VERSION = "15.5.4 Hotfix 1"
MIN_PATCHED_VERSION_TUPLE = (15, 5, 4, 1)
DEFAULT_STARTUP_LOGS = [
r"C:\ProgramData\RhinoSoft\Serv-U\Serv-U-StartupLog.txt",
r"C:\ProgramData\SolarWinds\Serv-U\Serv-U-StartupLog.txt",
"/usr/local/Serv-U/Serv-U-StartupLog.txt",
]
# SELECTORS to scan for in logs
SELECTORS = [
"CVE-2026-28318",
"deflate",
"Content-Encoding",
"Serv-U",
]
def parse_serv_u_version(version_str: str) -> tuple[int, int, int, int]:
"""Parse Serv-U version string into a comparable 4-tuple: (major, minor, patch, hotfix/build).
Handles formats like:
- "15.5.4 Hotfix 1" -> (15, 5, 4, 1)
- "15.5.4 HF 1" -> (15, 5, 4, 1)
- "15.5.4.123" -> (15, 5, 4, 123)
- "15.5.4" -> (15, 5, 4, 0)
- "15.5.3" -> (15, 5, 3, 0)
"""
v_norm = version_str.lower().strip()
# Replace "hotfix" or "hf" with a dot for easier regex grouping
v_norm = re.sub(r"\b(hotfix|hf)\s*([\d]+)", r".\2", v_norm)
digits = [int(x) for x in re.findall(r"\d+", v_norm)]
if not digits:
return (0, 0, 0, 0)
elif len(digits) == 1:
return (digits[0], 0, 0, 0)
elif len(digits) == 2:
return (digits[0], digits[1], 0, 0)
elif len(digits) == 3:
return (digits[0], digits[1], digits[2], 0)
else:
return (digits[0], digits[1], digits[2], digits[3])
def check_windows_registry() -> str | None:
"""Retrieve Serv-U version from Windows Registry if running on Windows."""
try:
import winreg
subkeys = [r"SOFTWARE\RhinoSoft\Serv-U", r"SOFTWARE\Wow6432Node\RhinoSoft\Serv-U"]
for subkey in subkeys:
try:
with winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, subkey) as key:
version, _ = winreg.QueryValueEx(key, "Version")
return str(version)
except OSError:
continue
except (ImportError, OSError):
pass
return None
def find_version_in_startup_log(log_path: Path) -> str | None:
"""Scan Serv-U-StartupLog.txt for Version strings."""
if not log_path.exists():
return None
try:
content = log_path.read_text(encoding="utf-8", errors="ignore")
# Match lines like "Version 15.5.4" or "Version 15.5.4 (15.5.4.202)" or "Version 15.5.4 Hotfix 1"
matches = re.findall(
r"Version\s+([\d\.]+(?:\s+(?:hotfix|hf)\s+\d+)?)",
content,
re.IGNORECASE
)
if matches:
# Return longest match as it is likely the most descriptive/precise version
return max(matches, key=len).strip()
except OSError:
pass
return None
def scan_access_log_for_deflate_post(log_path: Path) -> list[dict[str, object]]:
"""Scan HTTP access/WAF logs for POST requests with Content-Encoding: deflate."""
findings: list[dict[str, object]] = []
if not log_path.exists():
return findings
try:
with open(log_path, "r", encoding="utf-8", errors="ignore") as f:
for line_no, line in enumerate(f, start=1):
# Search for POST request indicators with 'deflate' and 'Content-Encoding'
lower_line = line.lower()
if "post" in lower_line and "deflate" in lower_line:
findings.append({
"file": str(log_path),
"line": line_no,
"evidence": line.strip()[:1000],
"reason": "Found POST request containing deflate compression indicator",
})
except OSError:
pass
return findings
def check_system_crashes() -> list[str]:
"""Check system logs for Serv-U service crashes (Windows Event Log or Linux systemd)."""
crashes = []
if sys.platform != "win32":
paths = ["/var/log/syslog", "/var/log/messages"]
for p in paths:
log_path = Path(p)
if log_path.exists():
try:
content = log_path.read_text(encoding="utf-8", errors="ignore")
matches = re.findall(r".*(serv-u|Serv-U).*segfault|crash|exited.*", content, re.IGNORECASE)
if matches:
crashes.append(f"Found Serv-U crash/segfault indicators in {p}")
except OSError:
pass
return crashes
def main() -> int:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument(
"--version",
help="Manually specify Serv-U version to audit (e.g. '15.5.4', '15.5.4 Hotfix 1')."
)
parser.add_argument(
"--startup-log",
type=Path,
help="Path to Serv-U-StartupLog.txt (auto-detects if omitted)."
)
parser.add_argument(
"--access-log",
type=Path,
help="Path to HTTP access/WAF log to scan for malicious POST deflate requests."
)
parser.add_argument(
"--output",
default="hp-serv-u-cve-2026-28318-audit.json",
help="JSON file path to save audit results."
)
parser.add_argument(
"--fail-on-open",
action="store_true",
help="Exit with code 2 if unpatched version or exploitation indicators are found."
)
args = parser.parse_args()
results: dict[str, object] = {
"cve": CVE,
"min_patched_version": MIN_PATCHED_VERSION,
"audited_version": None,
"is_vulnerable": None,
"version_source": None,
"log_findings": [],
"crash_findings": [],
}
# 1. Determine Version
version_str = args.version
version_source = "CLI Argument"
if not version_str and sys.platform == "win32":
version_str = check_windows_registry()
if version_str:
version_source = "Windows Registry"
if not version_str and args.startup_log:
version_str = find_version_in_startup_log(args.startup_log)
if version_str:
version_source = f"Startup Log ({args.startup_log})"
if not version_str:
for p in DEFAULT_STARTUP_LOGS:
path = Path(p)
if path.exists():
version_str = find_version_in_startup_log(path)
if version_str:
version_source = f"Auto-detected Startup Log ({p})"
break
# 2. Evaluate vulnerability status
if version_str:
results["audited_version"] = version_str
results["version_source"] = version_source
parsed_v = parse_serv_u_version(version_str)
is_vulnerable = parsed_v < MIN_PATCHED_VERSION_TUPLE
results["is_vulnerable"] = is_vulnerable
print(f"[+] Found Serv-U version: {version_str} via {version_source}")
if is_vulnerable:
print(f"[!] Serv-U version is below patched threshold ({MIN_PATCHED_VERSION}). System is VULNERABLE.")
else:
print(f"[+] Serv-U version is patched ({version_str} >= {MIN_PATCHED_VERSION}).")
else:
results["is_vulnerable"] = "Unknown (Version not detected)"
print("[-] Serv-U version could not be detected. Check paths or provide --version.")
# 3. Access/WAF Log Scan
if args.access_log:
print(f"[+] Scanning access log: {args.access_log}...")
hits = scan_access_log_for_deflate_post(args.access_log)
results["log_findings"] = hits
print(f"[+] Found {len(hits)} suspicious deflate POST request(s).")
for h in hits:
print(f" - Line {h['line']}: {h['evidence']}")
# 4. Local System Crash Scan
crash_logs = check_system_crashes()
results["crash_findings"] = crash_logs
if crash_logs:
print(f"[!] System crash indicators found:")
for crash in crash_logs:
print(f" - {crash}")
output_path = Path(args.output)
try:
output_path.write_text(json.dumps(results, indent=2, sort_keys=True), encoding="utf-8")
print(f"[+] Wrote audit results to {output_path.resolve()}")
except OSError as e:
print(f"[-] Failed to write JSON results to {args.output}: {e}", file=sys.stderr)
vulnerable_found = results["is_vulnerable"] is True
indicators_found = len(results["log_findings"]) > 0 or len(results["crash_findings"]) > 0
if args.fail_on_open and (vulnerable_found or indicators_found):
return 2
return 0
if __name__ == "__main__":
raise SystemExit(main())
Downstream Abuse Audits
A compromise or disruption of Serv-U can expose the host and its data to significant downstream risks:
- Configuration Disclosure: An attacker targeting a vulnerable Serv-U server might seek to download configuration files such as
Serv-U.Archive, theUsersdirectory, or server identities (Serv-UID.txt/ registry configurations). Although passwords inServ-U.Archiveare encrypted, exposure of the Server Identity allows offline decryption of user credentials, facilitating permanent unauthorized access. - Sensitive File Exposure: Since Serv-U hosts enterprise file transfer interfaces, a compromised server could allow malicious access to critical corporate files, source code, data backups, or keys stored in user folders.
- Cloud Credential Leakage: Serv-U setups integrated with cloud backends (such as AWS S3, Azure Blob, or Google Cloud Storage) might store access credentials or OIDC integration variables on the local system. Security teams must verify file permissions on any cloud storage backend scripts and configuration files.
Remediation
To secure your environment, apply the following steps:
- Upgrade Immediately: Apply the security update to Serv-U version 15.5.4 Hotfix 1 or newer.
- WAF Mitigations: If patching is delayed, configure WAF rules or reverse proxies to inspect HTTP POST requests. Drop any incoming POST requests containing the
Content-Encoding: deflateheader. - Access Control: Limit exposure by restricting access to the Serv-U HTTP/S portal to known, trusted source IP addresses.
- Credential Integrity: After patching, check system logs for prior crash patterns. If exploitation is suspected, rotate all Serv-U administrator passwords, user passwords, and audit the integrity of the configuration files (
Serv-U.Archive).
Machine-Readable Event Profile
{
"schema_version": "3.0",
"event_id": "solarwinds-serv-u-cve-2026-28318-kev",
"event_name": "SolarWinds Serv-U CVE-2026-28318 KEV Denial of Service Vulnerability",
"parent_campaign_id": "none",
"is_campaign_level": false,
"publication_state": "publish_ready",
"confidence": "high",
"confidence_reason": "CISA has added this CVE to the KEV catalog, confirming active exploitation in the wild. SolarWinds has released an advisory and a hotfix.",
"attack_types": ["Denial of Service", "Uncontrolled Resource Consumption"],
"sources": {
"direct": [
"https://www.solarwinds.com/trust-center/security-advisories/CVE-2026-28318"
],
"primary_research": [
"https://www.cisa.gov/known-exploited-vulnerabilities-catalog",
"https://www.bleepingcomputer.com/news/security/cisa-warns-of-actively-exploited-solarwinds-serv-u-dos-flaw/"
],
"correlated": []
},
"affected_assets": {
"ecosystems": ["SolarWinds Serv-U"],
"registries": [],
"packages": [],
"versions": ["prior to 15.5.4 Hotfix 1"],
"repositories": [],
"vendors": ["SolarWinds"],
"ci_cd_systems": [],
"container_images": [],
"developer_tools": [],
"credentials_at_risk": ["files stored in MFT directories"]
},
"timeline": {
"first_seen": "2026-06-05",
"malicious_publish_time": "unknown",
"discovery_time": "unknown",
"removal_time": "unknown",
"disclosure_time": "2026-06-05",
"patch_or_fix_time": "2026-06-05"
},
"artifact_analysis": {
"malicious_artifacts": [],
"execution_trigger": "remote unauthenticated HTTP POST request containing Content-Encoding: deflate header",
"payload_behavior": ["excessive CPU and memory utilization", "service crash"],
"provenance": {}
},
"iocs": {
"package_versions": [],
"files": ["Serv-U-StartupLog.txt"],
"hashes": [],
"domains": [],
"urls": [],
"ips": [],
"process_patterns": [],
"network_patterns": ["POST request with Content-Encoding: deflate"]
},
"detection": {
"lockfile_hunts": [],
"filesystem_hunts": [],
"process_hunts": [],
"network_hunts": ["detect HTTP POST requests with Content-Encoding: deflate"],
"ci_cd_hunts": [],
"registry_hunts": [],
"hunt_recipes": []
},
"open_questions": [],
"defender_takeaways": {
"detection": "Inspect WAF and HTTP reverse proxy logs for HTTP POST requests using deflate encoding.",
"hunting": "Audit local system crash logs for Serv-U process exits and check version banner in Serv-U-StartupLog.txt.",
"remediation": "Apply Serv-U 15.5.4 Hotfix 1 immediately.",
"prevention": "Configure WAF to block POST requests containing Content-Encoding header if not required by business operations."
},
"remediation_gates": {
"containment_complete": ["Block Content-Encoding: deflate headers", "Restrict network access to trusted IPs"],
"eradication_complete": ["Apply Serv-U 15.5.4 Hotfix 1"],
"recovery_complete": ["Restart Serv-U service", "Confirm normal operations"],
"closure_required": ["Confirm version is patched", "Complete negative log audit for deflate POST requests"]
}
}