AndreiG6/cpanel-cve-2026-41940-ioc
GitHub: AndreiG6/cpanel-cve-2026-41940-ioc
针对 CVE-2026-41940 cPanel/WHM 身份验证绕过漏洞的 IOC 检测脚本,修复了上游脚本误报问题并增加了多源日志交叉关联分析与三级严重性评估。
Stars: 3 | Forks: 0
# CVE-2026-41940 IOC 扫描器
用于检测影响 11.40 之后所有 cPanel 版本的 cPanel/WHM 身份验证绕过漏洞 (CVE-2026-41940) 的检测脚本。
这是对[上游 cPanel 检测脚本](https://support.cpanel.net/hc/en-us/articles/40073787579671)的重写版本,修复了误报问题并增加了日志关联分析。
## 功能说明
扫描 `/var/cpanel/sessions/raw/` 目录,查找显示被利用换行符注入迹象的 session 文件,然后将可疑 IP 和 session token 与 cPanel 的访问/登录/错误日志进行交叉比对。同时也会扫描 access_log 以检测 session 文件已过期或被清除的历史利用行为。
## 相对于上游脚本的修复与改进
1. **移除了有缺陷的多行 `pass` 正则表达式**,该正则会对生产环境中每一个经过身份验证的 session 产生误报(该正则匹配任何 `pass=` 字段后跟另一行的内容,而这匹配了所有的 session 文件)。
2. **泛化了注入检测**,改为检测 `method=badpass origin + 任何 post-auth 属性`,而不是要求严格的 `token_denied + cp_security_token` 组合。这可以捕获省略了 `token_denied` 的 PoC 变体。
3. **三级严重性评估**,基于观察到的结果而非二值化的标志:
- **CRITICAL** — 注入的 token 在 access_log 中存在 2xx/3xx 状态码(利用成功),或者在 session 过期后在 access_log 中发现了历史利用行为
- **HIGH** — 注入写入成功,但 token 从未出现在 access_log 中(已暂存,仍可能被使用)
- **MEDIUM** — token 曾被尝试使用,但所有请求均返回 4xx/5xx 状态码(服务器已拦截)
4. **分级修复指导** — CRITICAL/HIGH 级别触发完整的应急响应;仅包含 MEDIUM 级别则表示服务器成功防御,仅需执行较轻量的清理步骤。
5. **通过 cpsessid 和 IP 进行交叉比对**,从 access_log 中收集使用注入 token 的相关记录,可捕获攻击者在注入后的 IP 切换行为。
6. **仅 access_log 检测** — 通过将失败的登录尝试(`POST /login/?login_only=1` -> 401)与随后来自同一 IP 的成功 cpsess token 使用情况进行关联分析,捕获 session 文件已过期或被清除情况下的利用行为。
7. **`--extended` 模式**,用于跨其他日志源进行更深入的扫描。
## 快速运行(无需克隆仓库)
```
# Bash — 适用于所有平台,无 dependencies
bash <(curl -fsSL https://raw.githubusercontent.com/AndreiG6/cpanel-cve-2026-41940-ioc/main/ioc.sh)
# Python — 在大型 session dirs 上更快,支持 --json
curl -fsSLo /tmp/ioc.py https://raw.githubusercontent.com/AndreiG6/cpanel-cve-2026-41940-ioc/main/ioc.py
python3 /tmp/ioc.py
# Extended scan(任一 variant)
bash <(curl -fsSL https://raw.githubusercontent.com/AndreiG6/cpanel-cve-2026-41940-ioc/main/ioc.sh) --extended
python3 /tmp/ioc.py --extended
# 运行后检查 exit code($? = 0 无异常,1 发现 IOCs,2 环境 error)
echo $?
```
## JSON 输出(仅限 Python 版本)
Python 版本支持 `--json` 参数以提供结构化输出,您可以通过管道将其传递给 `jq`,接入 SIEM,或进行程序化处理。
```
# 完整 JSON output
python3 ioc.py --json
# 仅 summary counts
python3 ioc.py --json | jq '.counts'
# 列出所有 CRITICAL findings
python3 ioc.py --json | jq '[.findings[] | select(.severity == "CRITICAL")]'
# 提取唯一的 attacker IPs
python3 ioc.py --json | jq '.suspect_ips[]'
# 显示 findings 及其 source IPs(用于 firewall blocklists)
python3 ioc.py --json | jq '[.findings[] | {severity, source_ip, token: .cp_security_token}]'
# 获取所有成功使用 token 的 IPs(用于立即 blocking)
python3 ioc.py --json | jq '[.findings[] | select(.severity == "CRITICAL") | .source_ip] | unique'
# 为特定 IP 提供 cross-ref data
python3 ioc.py --json | jq '.cross_ref[.suspect_ips[0]]'
```
JSON 结构示例:
```
{
"findings": [
{
"severity": "CRITICAL",
"file": "/var/cpanel/sessions/raw/:Q3f8Ag2epeBuTaIZ",
"verdict": "Injected token used successfully (2xx/3xx in access_log)",
"origin": "address=203.0.113.50,app=whostmgrd,method=badpass",
"source_ip": "203.0.113.50",
"user": "root",
"hasroot": "1",
"tfa_verified": "0",
"cp_security_token": "/cpsess04396539398",
"token_denied": "1",
"successful_internal_auth_with_timestamp": "9999999999",
"token_hits": [
"203.0.113.50 - root [04/30/2026:12:12:01 -0000] \"GET /cpsess04396539398/json-api/version HTTP/1.1\" 200 0 ..."
]
},
{
"severity": "MEDIUM",
"file": "/var/cpanel/sessions/raw/:2TDiaHwh_r8qOH5y",
"verdict": "Injection landed; token was tried but BLOCKED (all 4xx/5xx)",
"source_ip": "198.51.100.23",
"cp_security_token": "/cpsess5637704041",
"token_hits": [
"198.51.100.23 - root [04/30/2026:04:08:09 -0000] \"GET /cpsess5637704041/json-api/version HTTP/1.1\" 403 0 ..."
]
},
{
"severity": "CRITICAL",
"file": null,
"verdict": "Injected cpsess token used with 2xx/3xx after failed login; session expired or purged",
"source_ip": "203.0.113.99",
"cp_security_token": "/cpsess8705792557",
"token_hits": ["..."]
}
],
"counts": {"critical": 2, "high": 15, "medium": 71, "warning": 0},
"suspect_ips": ["203.0.113.50", "198.51.100.23", "203.0.113.99"],
"suspect_ips_omitted": 0,
"cross_ref": {
"203.0.113.50": {
"cpanel_access_log": ["...last 5 lines..."],
"cpanel_login_log": ["..."]
}
},
"advisory": "https://support.cpanel.net/hc/en-us/articles/40073787579671"
}
```
## 使用方法(本地副本)
```
git clone https://github.com/AndreiG6/cpanel-cve-2026-41940-ioc.git
cd cpanel-cve-2026-41940-ioc
# Bash variant
bash ioc.sh # default (CRITICAL/HIGH expanded, MEDIUM/WARNING counts only)
bash ioc.sh -v # verbose (expand all findings)
bash ioc.sh --extended # verbose + deeper logs + all IPs in cross-ref
# Python variant(相同 detection logic,速度更快,结构化 output)
python3 ioc.py # default (same collapse behavior as bash)
python3 ioc.py -v # verbose
python3 ioc.py --extended # verbose + deeper logs
python3 ioc.py --json # structured JSON (always includes all findings)
```
必须在目标 cPanel 服务器上以 root 身份运行。Python 版本需要 Python 3.6+(CentOS 7 / CloudLinux 7+ 自带)。
## 退出代码
| 代码 | 含义 |
|------|---------|
| 0 | 未发现指标 |
| 1 | 检测到 IOC |
| 2 | 环境错误(非 cPanel 服务器) |
## 参考信息
- [cPanel 公告](https://support.cpanel.net/hc/en-us/articles/40073787579671)
- CVE-2026-41940:通过 cPanel session 处理中的换行符注入实现身份验证绕过
## 许可证
MIT
标签:CISA项目, cPanel, CVE-2026-41940, IOC扫描, Shell脚本, Web安全, WHM, 会话注入, 子域名变形, 应急处置, 应用安全, 日志关联分析, 红队与蓝队, 蓝队分析, 误报修复, 身份验证绕过