BishopFox/CVE-2026-28318-check
GitHub: BishopFox/CVE-2026-28318-check
一个安全、非破坏性的 SolarWinds Serv-U 拒绝服务漏洞(CVE-2026-28318)检测脚本,通过差异化的 HTTP 状态码判断目标是否缺失补丁。
Stars: 1 | Forks: 0
# SolarWinds Serv-U 未授权拒绝服务:安全检测脚本
一个针对 **CVE-2026-28318**(**SolarWinds Serv-U `<= 15.5.4.108`** 中的未授权拒绝服务漏洞)的安全、**非破坏性**检测脚本。发送一个携带 `Content-Encoding: deflate` 和请求体的 POST 请求,会将该请求体提供给内存中的 deflate 解压器(`CZLibCompression`),其缓冲区管理会执行无效的 `free()`,导致 Serv-U 服务进程中止。(CVSS 7.5, `AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H`,CWE-763。)
此脚本**不会导致目标崩溃。** 它针对每个主机只回答一个问题:**是否缺失了 15.5.4 HF1 补丁?** 这是判断服务器是否易受 CVE-2026-28318 攻击的精确依据。
## 运行安全吗?
是的。这是该工具的核心目的,它完全可以安全地在生产环境中运行:
- **它从不发送 `deflate`。** `deflate` 是触发易受攻击解压器的*唯一* `Content-Encoding` 值。该脚本仅发送一个带有良性 `Content-Encoding: identity` 和短请求体的 POST 请求,该请求永远不会触达导致崩溃的代码路径。
- **这是一种差异检查,而非漏洞利用。** HF1 补丁(版本 `15.5.4.125`)会通过 **`415 Unsupported Media Type`** 拒绝*任何*同时带有请求体和非空 `Content-Encoding` 的请求。易受攻击的版本没有此拦截机制,会正常处理 `identity` 探测。因此,判定结果完全取决于状态码,服务绝对不会受到破坏。
- **这是预认证且只读的。** 仅需一个请求,无需登录,不会改变目标状态。
## 工作原理
该脚本向站点根目录发送一个安全的 POST 请求并读取状态码:
| `identity` 探测响应 | 判定结果 | 含义 |
|---|---|---|
| `Serv-U` Server 头,状态 **≠ 415**(例如 401 / 404 / 200 / 302) | `VULNERABLE` `[missing-415-gate]` | 缺失 HF1 415 拦截机制,因此版本为 `<= 15.5.4.108`,未修复 CVE-2026-28318。 |
| `Serv-U` Server 头,状态 **= 415** | `PATCHED` `[hf1-415-gate]` | 存在 HF1 输入验证拦截机制,因此版本为 `>= 15.5.4.125`。不易受攻击。 |
| 有响应,但没有 `Serv-U` Server 头 | `NOT-SERV-U` `[not-servu]` | 不是 Serv-U 服务器,或代理剥离了该头。 |
| 没有可用的响应/连接失败 | `ERROR` `[no-response]` | 没有 HTTP 服务可达、被过滤、TLS 错误或超时。 |
目标是通过探测响应自身的 `Server` 头进行指纹识别的,因此无需单独的识别请求。
## 环境要求
- Python 3.7+,仅使用标准库,无第三方依赖包。
## 用法
```
# 单个 host (scheme 默认为 https://)
./cve_2026_28318_check.py 10.0.0.5
# 显式 URL / port
./cve_2026_28318_check.py https://10.0.0.5:443
# 一次扫描多个 host
./cve_2026_28318_check.py host-a:443 host-b https://host-c
# 扫描列表,每行一个 target ('#' 注释被允许),紧凑输出
./cve_2026_28318_check.py -f targets.txt --brief
# 用于 pipeline 的机器可读输出
./cve_2026_28318_check.py -f targets.txt --json > results.json
```
### 选项
| 参数 | 描述 |
|---|---|
| `targets` | 一个或多个 `HOST[:PORT]` 或 URL(默认协议为 `https://`) |
| `-t, --target TARGET` | 添加目标(可重复使用) |
| `-f, --file FILE` | 从文件读取目标(每行一个;支持 `#` 注释) |
| `-b, --brief` | 每个目标输出单行对齐内容,适合扫描大量主机 |
| `--json` | 输出结构化的 JSON 结果 |
| `--no-color` | 禁用彩色输出(同时也遵循 `NO_COLOR` 环境变量和非 TTY 环境) |
| `--timeout SECS` | 每次探测的超时时间(默认:10) |
| `-v, --verbose` | 显示发送的探测请求和原始响应头 |
### 示例
**易受攻击的 Serv-U 服务器**(`[!]` 标记和 `VULNERABLE` 在 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+).
```
**已修补的服务器**返回 `PATCHED`(HF1 415 拦截机制响应了 identity 探测):
```
$ ./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.
```
**扫描列表,每个主机输出单行对齐内容**(`--brief`)。如果任何主机为 `VULNERABLE`,退出状态为 `1`,否则为 `0`,这在脚本中非常实用:
```
$ ./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
```
**用于自动化管道的机器可读输出**(`--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+)."
}
]
```
## 判定结果
| 判定结果 | 原因标签 | 含义 |
|---|---|---|
| `VULNERABLE` | `missing-415-gate` | 没有 HF1 415 拦截机制的 Serv-U 服务器,因此版本为 `<= 15.5.4.108`,未修复 CVE-2026-28318。**请立即修补。** |
| `PATCHED` | `hf1-415-gate` | 响应 identity 探测返回 `415` 的 Serv-U 服务器,说明已包含 HF1 补丁(版本 `>= 15.5.4.125`)。 |
| `NOT-SERV-U` | `not-servu` | 有响应,但没有 `Serv-U` Server 头;不是 Serv-U,或被代理剥离。 |
| `ERROR` | `no-response` | 没有可用的 HTTP 响应(该端口无服务、被过滤、TLS 错误或超时)。 |
| `ERROR` | `bad-target` | 无法解析目标参数。 |
## 退出代码
| 代码 | 含义 |
|---|---|
| `0` | 没有目标被标记为 `VULNERABLE` |
| `1` | 至少有一个目标被标记为 `VULNERABLE` |
| `2` | 使用错误(参数错误/目标文件无法读取) |
## 局限性
- **代理 / TLS 终结。** Serv-U 前面的反向代理或负载均衡器可能会剥离 `Server` 头(报告为 `NOT-SERV-U`),或者以其自身的 `415` 进行响应(可能导致误报为 `PATCHED`)。请尽可能将工具直接指向 Serv-U 管理界面。
- **这不是崩溃测试。** `VULNERABLE` 判定证明缺失了 HF1 输入验证修复;(根据设计)它不会演示崩溃。该拦截机制是判断此 CVE 的精确依据。
- **不验证 TLS。** Serv-U 管理界面通常使用自签名证书,因此该脚本不验证证书。它仅确认可达性并读取状态,仅此而已。
- **仅反映可达性。** 结果仅反映服务器从您运行它的网络位置返回的内容。
## 修复建议
升级到 **SolarWinds Serv-U 15.5.4 Hotfix 1(版本 `15.5.4.125`)** 或更高版本,该版本添加了输入验证拦截机制,可拒绝同时携带请求体和非空 `Content-Encoding` 的请求。在修补之前,请将对 Serv-U 服务的网络访问限制为受信任的来源。
## 许可证
此代码在 [MIT 许可证](LICENSE)下发布。
## 法律免责声明
未经双方事先同意,使用此工具攻击目标是非法的。遵守所有适用的地方、州和联邦法律是最终用户的责任。开发者不承担任何责任,也不对任何因滥用本程序或由此造成的损害负责。
## 另请参阅
- [NVD: CVE-2026-28318](https://nvd.nist.gov/vuln/detail/CVE-2026-28318)
- [MITRE: CVE-2026-28318](https://www.cve.org/CVERecord?id=CVE-2026-28318)
标签:CVE-2026-28318, PoC, SolarWinds, 密码管理, 暴力破解