
Safely detect whether a SolarWinds Serv-U host is vulnerable to CVE-2026-28318
A safe, non-destructive detector for CVE-2026-28318, an unauthenticated
denial-of-service in SolarWinds Serv-U <= 15.5.4.108. A single POST that carries
Content-Encoding: deflate and a body feeds that body to an in-memory deflate
decompressor (CZLibCompression) whose buffer management performs an invalid free(),
aborting the Serv-U service process. (CVSS 7.5, AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H,
CWE-763.)
This script does not crash the target. It answers one question per host: is the 15.5.4 HF1 fix missing? That is an exact proxy for whether the server is vulnerable to CVE-2026-28318.
Yes. This is the whole point of the tool, and it is safe to run against production:
deflate. deflate is the only Content-Encoding value that
starts the vulnerable decompressor. The script sends a single POST with a benign
Content-Encoding: identity and a short body, which never reaches the crashing code
path.15.5.4.125)
rejects any request that has a body and a non-empty Content-Encoding with
415 Unsupported Media Type. Vulnerable builds have no such gate and handle the
identity probe normally. So the verdict turns purely on the status code, and the
service is never destabilised.The script sends one safe POST to the site root and reads the status code:
The target is fingerprinted as Serv-U from the probe response's own Server header, so
no separate identification request is needed.
It proves the fix is missing; it does not crash the service to confirm. A
VULNERABLEverdict means the HF1 input-validation gate is absent, which is an exact proxy for this CVE. The script deliberately stops there rather than sending the crashingdeflatevalue.
# single host (scheme defaults to https://)
./cve_2026_28318_check.py 10.0.0.5
# explicit URL / port
./cve_2026_28318_check.py https://10.0.0.5:443
# several hosts at once
./cve_2026_28318_check.py host-a:443 host-b https://host-c
# scan a list, one target per line ('#' comments allowed), compact output
./cve_2026_28318_check.py -f targets.txt --brief
# machine-readable output for pipelines
./cve_2026_28318_check.py -f targets.txt --json > results.json
A vulnerable Serv-U server (the [!] marker and VULNERABLE render red on a TTY):
$ ./cve_2026_28318_check.py https://10.0.0.5
[!] https://10.0.0.5: VULNERABLE [missing-415-gate]
Serv-U returned 401 (not 415) to the identity probe, so the HF1 415 gate is ABSENT (build <= 15.5.4.108) and CVE-2026-28318 is unpatched. This proves the fix is missing; it does NOT crash the service. Apply 15.5.4 HF1 (build 15.5.4.125+).
A patched server returns PATCHED (the HF1 415 gate answered the identity probe):
$ ./cve_2026_28318_check.py https://10.0.0.6
[+] https://10.0.0.6: PATCHED [hf1-415-gate]
Serv-U returned 415 to the identity probe, so the 15.5.4 HF1 input-validation gate is present (build >= 15.5.4.125). Not vulnerable to CVE-2026-28318.
Scan a list, one aligned line per host (--brief). Exit status is 1 if any host is
VULNERABLE, else 0, which is handy in scripts:
$ ./cve_2026_28318_check.py -f targets.txt --brief; echo "exit: $?"
VULNERABLE https://10.0.0.5 missing-415-gate
PATCHED https://10.0.0.6 hf1-415-gate
NOT-SERV-U https://10.0.0.7 not-servu
ERROR https://10.0.0.8 no-response
exit: 1
Machine-readable output for pipelines (--json):
$ ./cve_2026_28318_check.py https://10.0.0.5 --json
[
{
"target": "https://10.0.0.5",
"verdict": "VULNERABLE",
"reason": "missing-415-gate",
"detail": "Serv-U returned 401 (not 415) to the identity probe, so the HF1 415 gate is ABSENT (build <= 15.5.4.108) and CVE-2026-28318 is unpatched. This proves the fix is missing; it does NOT crash the service. Apply 15.5.4 HF1 (build 15.5.4.125+)."
}
]
| Code | Meaning |
|---|---|
0 | No target was VULNERABLE |
1 | At least one target is VULNERABLE |
2 | Usage error (bad arguments / unreadable targets file) |
Server header (reported as NOT-SERV-U) or answer with its own 415 (a
possible false PATCHED). Point the tool directly at the Serv-U management interface
where you can.VULNERABLE verdict proves the HF1 input-validation fix is
absent; it does not demonstrate the crash (by design). That gate is an exact proxy for
this CVE.Upgrade to SolarWinds Serv-U 15.5.4 Hotfix 1 (build 15.5.4.125) or later, which adds
the input-validation gate that rejects a request carrying both a body and a non-empty
Content-Encoding. Until you can patch, restrict network access to the Serv-U service to
trusted sources.
This code is distributed under an MIT license.
Usage of this tool for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state, and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program.
identity probe response | Verdict | Meaning |
|---|
Serv-U Server header, status ≠ 415 (e.g. 401 / 404 / 200 / 302) | VULNERABLE [missing-415-gate] | The HF1 415 gate is absent, so build <= 15.5.4.108, CVE-2026-28318 unpatched. |
Serv-U Server header, status = 415 | PATCHED [hf1-415-gate] | HF1 input-validation gate present, so build >= 15.5.4.125. Not vulnerable. |
Responded, but no Serv-U Server header | NOT-SERV-U [not-servu] | Not a Serv-U server, or a proxy stripped the header. |
| No usable response / connection failure | ERROR [no-response] | No HTTP service reachable, filtered, TLS error, or timeout. |
| Flag | Description |
|---|
targets | One or more HOST[:PORT] or URL (scheme defaults to https://) |
-t, --target TARGET | Add a target (repeatable) |
-f, --file FILE | Read targets from a file (one per line; # comments) |
-b, --brief | Single aligned line per target, ideal for scanning many hosts |
--json | Emit structured JSON results |
--no-color | Disable coloured output (also honours NO_COLOR and non-TTY) |
--timeout SECS | Per-probe timeout (default: 10) |
-v, --verbose | Show the probe sent and the raw response headers |
| Verdict | Reason tag | Meaning |
|---|
VULNERABLE | missing-415-gate | Serv-U server with no HF1 415 gate, so build <= 15.5.4.108, CVE-2026-28318 unpatched. Patch immediately. |
PATCHED | hf1-415-gate | Serv-U server that answers the identity probe with 415, so the HF1 fix is present (build >= 15.5.4.125). |
NOT-SERV-U | not-servu | Responded, but no Serv-U Server header; not Serv-U, or a proxy stripped it. |
ERROR | no-response | No usable HTTP response (no service on that port, filtered, TLS error, or timeout). |
ERROR | bad-target | The target argument could not be parsed. |