mirror of
https://github.com/gelusus/wxvl.git
synced 2026-10-27 19:10:56 +00:00
正在获取URL...
chainreactors: 16 个URL BruceFeIix: 20 个URL Doonsec: 37 个URL 总共去重后: 41 个URL 被改写的系统服务:IDM 内核驱动 CVE-2026-90493 提权、GitLab CVE-2026-85706 未授权任意文件读取分析:一个末尾斜杠打穿的满分漏洞、
This commit is contained in:
1 parent
6af024ed4b
commit
ae3afdc06e
3 files changed
+506
-1
No files matched your search
@@ -26782,5 +26782,7 @@
|
||||
"https://mp.weixin.qq.com/s/wyz2F_7Q8OrcUl_V8ObEsQ": "Fortinet 特权访问代理漏洞:任意网站都能接管你的代理和屏幕",
|
||||
"https://mp.weixin.qq.com/s/B2edlxX9t3rWMb__CcLPVA": "19.9 美元路由拆到 RCE:Dbit N300 UART + Boa 溢出(CVE-2026-20374)",
|
||||
"https://mp.weixin.qq.com/s/J7BBAqVBqEAcgKW0Rf5mUQ": "暗网惊现macOS 0day本地提权exp:兼容Big Sur到26.5",
|
||||
"https://mp.weixin.qq.com/s/gBv4VTbLKQt-UFbv44Li1w": "黑客可将存在漏洞的 LiteLLM AI 网关转化为获取 root 权限和窃取云凭证的途径"
|
||||
"https://mp.weixin.qq.com/s/gBv4VTbLKQt-UFbv44Li1w": "黑客可将存在漏洞的 LiteLLM AI 网关转化为获取 root 权限和窃取云凭证的途径",
|
||||
"https://mp.weixin.qq.com/s/HikwWitv49UYV9hO1h-4hw": "被改写的系统服务:IDM 内核驱动 CVE-2026-90493 提权",
|
||||
"https://mp.weixin.qq.com/s/bxDoc8f55krA-cR3urfIIg": "GitLab CVE-2026-85706 未授权任意文件读取分析:一个末尾斜杠打穿的满分漏洞"
|
||||
}
|
||||
@@ -0,0 +1,160 @@
|
||||
# GitLab CVE-2026-85706 未授权任意文件读取分析:一个末尾斜杠打穿的满分漏洞
|
||||
原创 Kratos
|
||||
Kratos Kratos Sec 2026-09-13 06:10
|
||||
|
||||
# GitLab CVE-2026-85706 未授权任意文件读取分析:一个末尾斜杠打穿的满分漏洞
|
||||
|
||||
9 月 10 日 GitLab 发布例行补丁,其中 CVE-2026-85706 拿到了 CVSS 10.0 满分:未授权、单个 HTTP 请求、读取服务器任意文件。watchTowr 的蜜网在补丁发布次日就观测到了探测流量,CISA 已将其列入 KEV 目录。这篇把原理、复现、利用限制、自查和修复讲清楚,重点说一个被多数预警稿忽略的问题:它到底能不能真的"读任意文件"。
|
||||
## 0x0 漏洞概述
|
||||
|
||||
<table><thead><tr><th style="color: rgb(102, 102, 102);font-size: 16px;line-height: 1.5em;letter-spacing: 0em;text-align: left;font-weight: bold;background: none left top / auto no-repeat scroll padding-box border-box rgb(240, 240, 240);height: auto;border-style: solid;border-width: 1px;border-color: rgba(204, 204, 204, 0.4);border-radius: 0px;padding: 5px 10px;min-width: 85px;"><section><span leaf="">项目</span></section></th><th style="color: rgb(102, 102, 102);font-size: 16px;line-height: 1.5em;letter-spacing: 0em;text-align: left;font-weight: bold;background: none left top / auto no-repeat scroll padding-box border-box rgb(240, 240, 240);height: auto;border-style: solid;border-width: 1px;border-color: rgba(204, 204, 204, 0.4);border-radius: 0px;padding: 5px 10px;min-width: 85px;"><section><span leaf="">内容</span></section></th></tr></thead><tbody><tr style="color: rgb(102, 102, 102);background-attachment: scroll;background-clip: border-box;background-color: rgb(255, 255, 255);background-image: none;background-origin: padding-box;background-position-x: left;background-position-y: top;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;"><td style="padding-top: 5px;padding-right: 10px;padding-bottom: 5px;padding-left: 10px;min-width: 85px;border-top-style: solid;border-bottom-style: solid;border-left-style: solid;border-right-style: solid;border-top-width: 1px;border-bottom-width: 1px;border-left-width: 1px;border-right-width: 1px;border-top-color: rgba(204, 204, 204, 0.4);border-bottom-color: rgba(204, 204, 204, 0.4);border-left-color: rgba(204, 204, 204, 0.4);border-right-color: rgba(204, 204, 204, 0.4);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;"><section><span leaf="">CVE 编号</span></section></td><td style="padding-top: 5px;padding-right: 10px;padding-bottom: 5px;padding-left: 10px;min-width: 85px;border-top-style: solid;border-bottom-style: solid;border-left-style: solid;border-right-style: solid;border-top-width: 1px;border-bottom-width: 1px;border-left-width: 1px;border-right-width: 1px;border-top-color: rgba(204, 204, 204, 0.4);border-bottom-color: rgba(204, 204, 204, 0.4);border-left-color: rgba(204, 204, 204, 0.4);border-right-color: rgba(204, 204, 204, 0.4);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;"><section><span leaf="">CVE-2026-85706</span></section></td></tr><tr style="color: rgb(102, 102, 102);background-attachment: scroll;background-clip: border-box;background-color: rgb(248, 248, 248);background-image: none;background-origin: padding-box;background-position-x: left;background-position-y: top;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;"><td style="padding-top: 5px;padding-right: 10px;padding-bottom: 5px;padding-left: 10px;min-width: 85px;border-top-style: solid;border-bottom-style: solid;border-left-style: solid;border-right-style: solid;border-top-width: 1px;border-bottom-width: 1px;border-left-width: 1px;border-right-width: 1px;border-top-color: rgba(204, 204, 204, 0.4);border-bottom-color: rgba(204, 204, 204, 0.4);border-left-color: rgba(204, 204, 204, 0.4);border-right-color: rgba(204, 204, 204, 0.4);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;"><section><span leaf="">漏洞类型</span></section></td><td style="padding-top: 5px;padding-right: 10px;padding-bottom: 5px;padding-left: 10px;min-width: 85px;border-top-style: solid;border-bottom-style: solid;border-left-style: solid;border-right-style: solid;border-top-width: 1px;border-bottom-width: 1px;border-left-width: 1px;border-right-width: 1px;border-top-color: rgba(204, 204, 204, 0.4);border-bottom-color: rgba(204, 204, 204, 0.4);border-left-color: rgba(204, 204, 204, 0.4);border-right-color: rgba(204, 204, 204, 0.4);border-top-left-radius: 0px;border-top-right-radius: 0px;border-bottom-right-radius: 0px;border-bottom-left-radius: 0px;"><section><span leaf="">路径遍历 / 未授权任意文件读取</span></section></td></tr><tr style="color: rgb(102, 102, 102);background-attachment: scroll;background-clip: border-box;background-color: rgb(255, 255, 255);background-image: none;background-origin: padding-box;background-position-x: left;background-position-y: top;background-repeat: no-repeat;background-size: auto;width: auto;height: auto;"><td style="padding-top: 5px;padding-right: 10px;padding-bottom: 5px;padding-left: 10px;min-width: 85px;border-top-style: solid;border-bottom-style: solid;border-left-style: solid;border-right-style: solid;border-top-width: 1px;border-bottom-width: 1px;border-left-width: 1px;border-right-width: 1px;border-top-color: rgba(204, 204, 204, 0.4);border-bottom-color: rgba(204, 204, 204, 0.4);border-left-color: rgba(204, 204, 204, 0.4);border-right-color: rgba(204, 204, 204, 0.4);border-top-left-radius: 0px;bordeLine truncated
|
||||
|
||||
时间线:9 月 10 日官方发补丁,9 月 11 日 watchTowr 蜜网捕获行为探测、vulhub 提交完整复现环境(pull 800),9 月 12 日起公开复现文章扩散。从补丁到武器化的间隔不到 48 小时。
|
||||
|
||||
GitLab 自建实例上沉淀的是源代码、CI/CD 流水线凭据、云密钥、内网拓扑,这类入口一旦失守暴露的不是单个应用,而是整个研发体系。所以它值 10 分。
|
||||
## 0x1 原理:四个缺陷叠出来的满分
|
||||
|
||||
这个漏洞不是单点失误,是四个环节各自"差一点"叠出来的。单独看每一个都算不上致命,串起来就是未授权任意文件读取。
|
||||
|
||||
**第一层:末尾斜杠造成路由歧义。**
|
||||
GitLab 的架构里 Workhorse 是前置代理,大文件上传由它一手处理,它内部有一条严格锚定的上传路由,匹配 /repository/commits
|
||||
(无末尾斜杠)。攻击者在路径末尾多加一个斜杠变成 /repository/commits/
|
||||
,Workhorse 的锚定匹配失败,认为这不是上传请求,原样转发给后端 Rails;而 Rails 的路由不区分这个斜杠,依然把它分发到 Repository Commits API。同一个 URL,两边的理解不一致,边界就这么被让出来了。
|
||||
|
||||
**第二层:Workhorse 的内部 JWT 照常注入。**
|
||||
Rails 侧的接口有 require_gitlab_workhorse!
|
||||
防线,本意是"只接受来自 Workhorse 的请求"。问题在于 Workhorse 转发所有代理请求时都会附带内部 JWT,不管请求是不是它主动处理过的。于是这道防线照常放行,攻击者构造的原始表单参数不经重写直达 Rails。
|
||||
|
||||
**第三层:认证顺序反了。**
|
||||
目标接口不是没有认证,而是认证做晚了。请求进来后先做项目读授权,然后就去读文件,用户认证在文件读取完成之后才调用。文件内容已经进了内存,认证拦得住后续流程,拦不住已经发生的读取。
|
||||
|
||||
**第四层:File.read 无路径约束。**
|
||||
服务端直接信任请求侧传入的文件元数据(file.path
|
||||
),据此读取本地文件,没有任何路径限制。这里甚至不需要经典的 ../
|
||||
遍历,直接给绝对路径就行。
|
||||
|
||||
**回显机制是个意外之喜。**
|
||||
就算读完文件,内容怎么带出来?这里靠 Rack 的表单解析报错:整份文件内容被当作表单字符串解析,遇到非法百分号编码(%
|
||||
后面不是两个十六进制字符)时,Rack 抛出的异常消息会把出错的那段内容写进 HTTP 400 响应体。文件内容就这样从错误信息里漏了出来。
|
||||
## 0x2 复现
|
||||
|
||||
vulhub 已提供完整环境和 PoC(github.com/vulhub/vulhub/pull/800
|
||||
),基于官方 Docker 镜像 19.3.1 可稳定复现,升到 19.3.2 后同样请求被认证直接阻断。
|
||||
|
||||
**Step 1:匿名拿一个公开项目 ID**
|
||||
```
|
||||
curl -s "http://target/api/v4/projects?visibility=public&simple=true&per_page=100"
|
||||
|
||||
```
|
||||
|
||||
利用前提是目标实例上存在至少一个公开项目,这个接口匿名可查。
|
||||
|
||||
**Step 2:触发文件读取**
|
||||
```
|
||||
curl -i -X POST "http://target/api/v4/projects/{id}/repository/commits/" \
|
||||
-H "Content-Type: application/x-www-form-urlencoded" \
|
||||
--data-urlencode "file=" \
|
||||
--data-urlencode "file.path=/var/opt/gitlab/gitlab-rails/etc/gitlab.yml" \
|
||||
--data-urlencode "file.size=1"
|
||||
|
||||
```
|
||||
|
||||
两个细节:URL 末尾的斜杠不能省,省了就进了 Workhorse 的正常上传链路;file.path
|
||||
直接给绝对路径。
|
||||
|
||||
选 gitlab.yml
|
||||
做默认目标是有讲究的:这份文件由 Omnibus 自动生成,内容里必然含有带 %
|
||||
的序列,必定触发 Rack 解析报错回显。响应 400,错误信息里能看到文件内容片段。
|
||||
## 0x3 冷静一下:它到底能读什么
|
||||
|
||||
大量预警稿标题写"任意文件读取",实际利用是有条件的。把限制说清楚,排查时才不会误判风险面。
|
||||
|
||||
**文件总是被读,但内容不一定回显。**
|
||||
回显依赖非法百分号编码触发 Rack 报错。内容规整的纯文本(比如 /etc/passwd
|
||||
)被读了,但响应可能只有一个 401,什么都带不出来。能稳定回显的是那些天然含 %
|
||||
序列的文件:gitlab.yml
|
||||
、redis.conf
|
||||
这类。
|
||||
|
||||
**回显是截断的。**
|
||||
Rack 2.2.23 的表单解析按 &
|
||||
和 ;
|
||||
切分参数。整份文件被当作表单字符串,错误信息只包含非法 %
|
||||
所在的那一段。拿 invalid %-encoding BEFORE_AMP&AFTER_AMP
|
||||
做实验,&
|
||||
之后的内容直接丢弃。也就是说,凭据如果排在截断点之后,泄露不出来。
|
||||
|
||||
**大小有上限。**
|
||||
Rack 默认解析上限 4MB(RACK_QUERY_PARSER_BYTESIZE_LIMIT=4194304
|
||||
),超出的文件不走回显。
|
||||
|
||||
**权限跟着 git 服务账号走。**
|
||||
底层是 git 对目标文件做 stat 和 read,读不到的照样读不到。
|
||||
|
||||
但这些限制挡不住它成为 10 分漏洞。一方面 gitlab.yml
|
||||
这个必中目标恰恰是整台服务器最要命的文件:数据库连接串、Redis 配置、secret_key
|
||||
/otp_key
|
||||
、SMTP、LDAP/SSO、对象存储密钥全在里面。secret_key
|
||||
拿到就可以伪造 Rails 会话 Cookie 直接接管管理员,Redis 凭据可以接着打内网。另一方面,即便内容回显不出来,400/401/500 的响应差异也足够做存在性探测,攻击者可以借此摸清服务器文件布局、权限边界和运行环境,为下一步铺路。
|
||||
## 0x4 自查:判断自己有没有中招
|
||||
|
||||
**先确认版本。**
|
||||
影响范围是 18.7 ≤ v < 19.1.8、19.2 ≤ v < 19.2.6、19.3 ≤ v < 19.3.2。管理后台 Help 页或 cat /opt/gitlab/version-manifest.txt
|
||||
可查。GitLab.com 和 GitLab Dedicated 用户无需动作。
|
||||
|
||||
**再翻日志。**
|
||||
在网关、Workhorse、NGINX 访问日志里找这类特征:
|
||||
- POST /api/v4/projects/{id}/repository/commits/
|
||||
,注意末尾斜杠,这是最硬的指纹;
|
||||
|
||||
- 请求体里带 file.path
|
||||
参数且值为绝对路径;
|
||||
|
||||
- 请求头无 Authorization
|
||||
/ PRIVATE-TOKEN
|
||||
;
|
||||
|
||||
- 响应码 400 且响应体里出现本不该出现在 API 报错里的文件内容片段。
|
||||
|
||||
WAF 可以加一条临时规则:拦截路径匹配 ^/api/v4/projects/[^/]+/repository/commits/
|
||||
的 POST 请求。
|
||||
|
||||
**重点排查公网实例。**
|
||||
暴露在互联网上的自建 GitLab 风险最高,回溯窗口建议覆盖 9 月 10 日补丁发布之前的时段,漏洞在补丁公开前就存在。
|
||||
## 0x5 修复与应急
|
||||
|
||||
**升级是唯一彻底手段。**
|
||||
19.3.2 / 19.2.6 / 19.1.8 三选一,按当前版本线对号入座。官方修复 commit 为 0d9ce3e758a85f0690be751e213625f7902c0361
|
||||
。注意两点:本批补丁含数据库迁移,单节点实例升级过程会停机,多节点按零停机流程走;19.3.2 带 post-deploy 迁移,升级后留意完成状态。
|
||||
|
||||
**暂时无法升级的:**
|
||||
把 GitLab Web 与 API 入口收敛到可信网段或 VPN 之后,禁止公网直连;对未登录状态下访问仓库提交类接口的请求启用监控告警。
|
||||
|
||||
**确认或怀疑已中招的,升级只是第一步。**
|
||||
假设 gitlab.yml
|
||||
已泄露,按清单轮换:数据库密码、Redis 密码、实例加密密钥(secret_key
|
||||
等)、对象存储密钥、SMTP 凭据,以及所有集成配置里的第三方 token。同时核查高级搜索、对象存储、镜像库有没有被读取或篡改的痕迹。
|
||||
## 0x6 同批补丁里的其他角色
|
||||
|
||||
这次补丁日一共修了十几个洞,除了主角之外值得留意的:
|
||||
- **CVE-2026-87719(9.9,EE)**
|
||||
:GraphQL 订阅序列化器反序列化缺陷,有 Duo Chat 权限的用户可绕过对象访问控制,拿到 Advanced Search 实例配置和敏感凭据。对启用了高级搜索的企业,等于把全实例代码检索能力交给了普通账号。和 85706 组合使用时危害放大。
|
||||
|
||||
- **CVE-2026-88765(8.5,EE)**
|
||||
:Unicode 转换缓冲区溢出,导入恶意构造的 Git 项目导出可 RCE,影响版本追溯到 12.3。
|
||||
|
||||
- **CVE-2026-79708(8.5)**
|
||||
:Developer 角色可借策略测试流水线读取受保护 CI/CD 变量。
|
||||
|
||||
- **CVE-2026-78252(8.2)**
|
||||
:Markdown JSON 表格渲染器 XSS,影响版本追溯到 15.3。
|
||||
|
||||
一次升级全部解决,没有理由只修主角。
|
||||
|
||||
**参考**
|
||||
- https://docs.gitlab.com/releases/patches/patch-release-gitlab-19-3-2-released/
|
||||
|
||||
**免责声明**
|
||||
:本文仅用于安全研究与学习,未经授权不得用于任何非法渗透测试活动。
|
||||
|
||||
|
||||
@@ -0,0 +1,343 @@
|
||||
# 被改写的系统服务:IDM 内核驱动 CVE-2026-90493 提权
|
||||
Ots安全 2026-09-13 05:45
|
||||
|
||||
**威胁简报**
|
||||
|
||||
|
||||
**恶意软件**
|
||||
|
||||
|
||||
**漏洞攻击**
|
||||
|
||||
## 前言
|
||||
|
||||
2026 年 9 月 13 日凌晨,VulDB 作为 CNA 发布了一个编号,把一款装机量以亿计的下载工具推到了本地提权的名单上。编号是 CVE-2026-90493,产品是 Internet Download Manager,问题出在它随包安装的一个内核驱动 idmwfp.sys
|
||||
上。
|
||||
|
||||
这件事的特殊之处不在漏洞本身的形态,而在围绕它的一组反差。同一个编号,VulDB 给 9.3 分并标为 CRITICAL,NVD 用自己的向量算出来是 8.5 分并标为 HIGH。CVE 记录写的影响范围截止到 6.42 Build 63,而厂商官方更新页在同一时期已经发到 6.43 Build 10。漏洞报告在 7 月 15 日就把完整源码和预编译二进制放上了 GitHub,厂商在随后一个月里连发三个版本,更新日志里一个字都没提驱动安全。
|
||||
|
||||
而整条提权链,被写成了一段六行的批处理脚本。
|
||||
## 一、先看问题:一个 9.3 分与一个 8.5 分
|
||||
### 1.1 编号、定性与三个判断位
|
||||
|
||||
CVE-2026-90493 的官方标题是 Tonec Internet Download Manager Kernel Driver idmwfp.sys access control。受影响组件定性为内核驱动,攻击向量为本地,权限前置为低权限。
|
||||
|
||||
CVE 记录里有一句必须原样读出的话:**"The exploit is now public and may be used."**
|
||||
这是 CNA 对利用状态的白纸黑字判断。向量里的 E:P
|
||||
项与之一致,表示存在概念验证代码。同一段描述里还有另一句,同样需要原样读:**"The vendor was contacted early about this disclosure but did not respond in any way."**
|
||||
|
||||
CVE 记录中的三个常用判断位在这条编号上全部是"无":没有进 CISA KEV,没有公开的野外利用报告,NVD 状态停在 Received
|
||||
。前两项容易理解,第三项需要单独说明,因为它决定了这个编号现在的可信度结构。
|
||||
### 1.2 NVD 的状态停在 Received
|
||||
|
||||
NVD 记录里两个字段值得单独看:vulnStatus
|
||||
是 Received
|
||||
,configurations
|
||||
是 null。
|
||||
|
||||
configurations
|
||||
为 null 意味着 NVD 还没有生成 CPE 匹配规则,也就是说所有引用这个编号的工具都还没有拿到"NVD 认可的受影响版本判据"。Received
|
||||
是 NVD 处理流程中较早的状态,比 Awaiting Enrichment
|
||||
更靠前,只表示记录已收到、尚未进入分析。
|
||||
|
||||
由此可以推出一个对使用者的实际含义:目前能查到的全部分数与分类,源头都是 VulDB 一家。Rapid7、InfoSecCenter 这些数据库页面显示的 8.8、9.3,逐条追下去都会回到 cna@vuldb.com
|
||||
这个来源。这不是说数据有问题,而是说**这个编号还没有经过第二家独立机构的评分复核,把它当成定论使用需要留一层余地**
|
||||
。
|
||||
## 二、影响范围
|
||||
### 2.1 这台机器装过 IDM
|
||||
|
||||
第一个条件不需要额外动作。idmwfp.sys
|
||||
不是可选组件,IDM 常规安装就会把它落到 C:\Windows\System32\drivers\
|
||||
下,并创建名为 IDMWFP
|
||||
的服务加载它。文件属性里的描述是 Internet Download Manager WFP Driver,签名方为 Tonec Inc.。
|
||||
|
||||
驱动的用途与它的名字一致。WFP 是 Windows 过滤平台的缩写,这个驱动参与网络流量处理。公开的社区实测记录显示,驱动启用后由 System 进程打开一个监听 127.0.0.1:1001
|
||||
的本地 HTTP 服务,IDM 的浏览器扩展通过这个端点与主程序通信,新建下载任务。这也解释了它为什么会提供注册表读写接口,因为它需要为 IDM 读写自身配置。
|
||||
|
||||
含义是清晰的:**攻击面随常规安装一起落地,不需要用户额外开启任何功能,也不存在"只装了但没用"的豁免情形**
|
||||
。驱动一旦加载,设备接口就在那里。
|
||||
### 2.2 驱动当前是否处于加载状态
|
||||
|
||||
第二个开关比第一个更容易变动。驱动由服务加载,服务名为 IDMWFP
|
||||
,可以用系统的服务查询工具确认当前状态。若服务被手动停止、驱动文件被清理工具删除、或系统做过卸载残留清理,攻击面就随之消失。
|
||||
|
||||
这里有一个容易误判的地方:IDM 主程序是否正在运行与攻击面无关。驱动由服务控制管理器加载,不依赖用户是否打开了下载界面。**判断依据应该是服务与驱动文件的存在状态,而不是任务栏里有没有 IDM 的图标。**
|
||||
### 2.3 只需要一个普通账号
|
||||
|
||||
PoC 报告列出的前置条件只有两项:本地已认证用户权限,以及能够打开设备接口 \\.\IDMWFP
|
||||
。
|
||||
|
||||
明确不需要的条件同样要列清:不需要管理员权限,不需要 SeRestorePrivilege
|
||||
,不需要 SeLoadDriverPrivilege
|
||||
,不需要调试权限,不需要交互式用户确认。
|
||||
|
||||
这与设备对象的安全描述符直接相关。报告的反编译结论是,驱动在 DriverEntry
|
||||
里创建设备对象时套用了 D:P(A;;GA;;;AU)
|
||||
。这串描述符的含义是:AU
|
||||
代表 Authenticated Users,即所有已认证用户;GA
|
||||
代表 GENERIC_ALL,即完全访问权。**所有已认证用户对该设备拥有完全访问权,这是整个链条的第一块基石,也是这份描述符把门槛从管理员降到了普通账号的原因。**
|
||||
### 2.4 没有可以关掉的配置项
|
||||
|
||||
多数产品漏洞可以通过调整配置来收窄暴露面,这个编号是例外。报告的第五节逐条列出了驱动缺失的三类校验,其中一类正是"没有把操作限定到调用者自己的 HKCU 映射"。也就是说,不存在一个"打开安全模式"或"限制为本用户"的开关可以把它关小。
|
||||
|
||||
因此准确的影响范围表述应该是四个开关的合取:**装了 IDM、驱动处于加载状态、本机存在任意一个普通本地账号。三个条件同时成立时,该账号即具备提升到系统级执行的通路。**
|
||||
环境里有几个普通账号不影响判断,因为攻击者只需要其中一个。
|
||||
## 三、原因导致:三道没做的校验
|
||||
### 3.1 一块对所有认证用户敞开的设备
|
||||
|
||||
根因需要两个条件同时成立,这个驱动两者都满足,所以两组问题要分开看。
|
||||
|
||||
第一组是设备侧。D:P(A;;GA;;;AU)
|
||||
让任何已认证用户都能拿到设备的完整访问权,于是任何普通本地用户都可以向 \\.\IDMWFP
|
||||
发送 DeviceIoControl
|
||||
请求。报告把这个条件列为漏洞成立的第一项前提。
|
||||
|
||||
需要说明的是,安全描述符过宽本身通常不足以构成高危问题,因为驱动可以在请求处理阶段补上调用者校验。这个驱动的问题恰恰在于它没有补,这就是第二组问题。
|
||||
### 3.2 一个内核注册表代理
|
||||
|
||||
分发函数是 IRP_MJ_DEVICE_CONTROL
|
||||
的处理例程,报告给出的地址是 sub_14000E9E0
|
||||
。其中 IOCTL 0x12C028
|
||||
走注册表操作路径,请求的第一个字节作为子命令选择器,0x0C
|
||||
到 0x0F
|
||||
四个子命令全部进入同一个处理函数 sub_140005B90
|
||||
。
|
||||
|
||||
四个子命令的功能划分如下:
|
||||
<table><thead><tr><th data-colwidth="119" style="border: 1px solid rgb(201, 201, 201);padding: 6px 12px;background: rgb(242, 242, 242);font-weight: 600;"><section><span leaf="">子命令</span></section></th><th data-colwidth="260" style="border: 1px solid rgb(201, 201, 201);padding: 6px 12px;background: rgb(242, 242, 242);font-weight: 600;"><section><span leaf="">功能</span></section></th></tr></thead><tbody><tr><td data-colwidth="119" style="border: 1px solid rgb(201, 201, 201);padding: 6px 12px;"><section><span leaf=""><span textstyle="" style="font-size: 16px;">0x0C</span></span></section></td><td data-colwidth="260" style="border: 1px solid rgb(201, 201, 201);padding: 6px 12px;"><section><span leaf=""><span textstyle="" style="font-size: 16px;">查询值</span></span></section></td></tr><tr><td data-colwidth="119" style="border: 1px solid rgb(201, 201, 201);padding: 6px 12px;"><section><span leaf=""><span textstyle="" style="font-size: 16px;">0x0D</span></span></section></td><td data-colwidth="260" style="border: 1px solid rgb(201, 201, 201);padding: 6px 12px;"><section><span leaf=""><span textstyle="" style="font-size: 16px;">创建缺失的键路径并写入值</span></span></section></td></tr><tr><td data-colwidth="119" style="border: 1px solid rgb(201, 201, 201);padding: 6px 12px;"><section><span leaf=""><span textstyle="" style="font-size: 16px;">0x0E</span></span></section></td><td data-colwidth="260" style="border: 1px solid rgb(201, 201, 201);padding: 6px 12px;"><section><span leaf=""><span textstyle="" style="font-size: 16px;">删除值</span></span></section></td></tr><tr><td data-colwidth="119" style="border: 1px solid rgb(201, 201, 201);padding: 6px 12px;"><section><span leaf=""><span textstyle="" style="font-size: 16px;">0x0F</span></span></section></td><td data-colwidth="260" style="border: 1px solid rgb(201, 201, 201);padding: 6px 12px;"><section><span leaf=""><span textstyle="" style="font-size: 16px;">删除值,并在键为空时删除键</span></span></section></td></tr></tbody></table>
|
||||
处理函数内部会从用户输入中解出"注册表相对路径 + 值名"两部分。根前缀由请求包里的 flags
|
||||
字段低位决定:flags & 0x1
|
||||
映射到 \REGISTRY\MACHINE\
|
||||
,flags & 0x2
|
||||
映射到 \REGISTRY\USER\
|
||||
。路径字符串在驱动内解码后,于路径末尾的反斜杠处切分成键路径与值名。
|
||||
|
||||
完成这些解析之后,处理函数直接调用一组内核注册表 API:ZwOpenKey
|
||||
、ZwCreateKey
|
||||
、ZwDeleteValueKey
|
||||
、ZwDeleteKey
|
||||
、ZwQueryValueKey
|
||||
、ZwSetValueKey
|
||||
。
|
||||
|
||||
调用链到这一步就没有别的了。**这组 API 的能力上限,就是这套接口的能力上限,而中间的约束环节全部缺失。**
|
||||
### 3.3 缺失的三道校验
|
||||
|
||||
报告第五节用三个"没有"概括了根因,逐条抄录:
|
||||
1. 驱动没有限制路径必须位于 IDM 自有命名空间下
|
||||
|
||||
1. 驱动没有校验调用者是否应当有权访问目标键
|
||||
|
||||
1. 驱动没有把操作限定到当前用户自己的 HKCU 映射
|
||||
|
||||
三道校验缺任何一道都会削弱防护,三道全缺的结果是接口性质发生变化。它不再是一个服务 IDM 自身配置的私有接口,而变成了一个由内核驱动代理执行的、面向任意已认证用户开放的注册表操作原语。
|
||||
|
||||
**用一句话概括这个错误的性质:把一个内核级的高权限能力包装成了用户可调用的代理,却没有在代理层恢复任何权限判断。**
|
||||
这也是为什么提交记录里的标题用的是 Exposed IOCTL with Insufficient Access Control 这个表述,而非泛泛的"权限检查缺失"。
|
||||
### 3.4 请求包与私有编码
|
||||
|
||||
四个子命令共用一个输入结构。报告给出的定义如下,此处仅用于说明协议形态:
|
||||
|
||||
```
|
||||
typedefstructIDMWFP_REG_CMD {
|
||||
uint8_t subcmd; /* 0x0C / 0x0D / 0x0E / 0x0F */
|
||||
uint8_t mode;
|
||||
uint16_t reserved0;
|
||||
uint32_t flags; /* bit0 = HKLM, bit1 = HKU */
|
||||
uint16_t path_offset;
|
||||
uint16_t path_wchars;
|
||||
uint16_t data_offset;
|
||||
uint16_t data_size;
|
||||
uint16_t value_type;
|
||||
uint8_t seed0;
|
||||
uint8_t seed1;
|
||||
} IDMWFP_REG_CMD;
|
||||
```
|
||||
|
||||
|
||||
从结构字段可以看出攻击者能完全控制的内容:注册表根、相对键路径、值名、值类型、值内容。四项全部来自用户输入,驱动侧只做解码与转发。
|
||||
|
||||
PoC 源码里还出现了成对的 encode_value_transport
|
||||
与 decode_value_transport
|
||||
函数,用于处理数据字段的字节变换,路径字段则单独走一套 UTF-16 展开逻辑。这说明接口使用的是私有编码而非明文协议。
|
||||
|
||||
需要把这一点的安全含义讲清:私有编码提高了构造请求的逆向成本,但它不构成安全边界。编码是公开算法,PoC 已经完整实现并随仓库发布。**把不公开的编码格式当作防护手段,在攻击者拿到一份反编译结果之后就不再成立。**
|
||||
### 3.5 证据边界说明
|
||||
|
||||
本节的全部机制描述来自两个来源:PoC 报告对驱动二进制的反编译结论,以及 PoC 在实机上的行为观测。
|
||||
|
||||
厂商没有发布任何安全公告,也没有发布补丁,因此**不存在可以逐行阅读的补丁差异文件**
|
||||
。这一点与闭源内核组件的一贯处境相同,需要在正文与参考章各标注一次,避免读者把反编译推断误当作补丁代码阅读。
|
||||
## 四、漏洞触发:六行批处理写完的提权链
|
||||
### 4.1 PoC 脚本的六步
|
||||
|
||||
PoC 仓库提供一个批处理脚本,把整条链压缩成六个动作。此处按动作意图逐步说明,不逐行复制脚本原文。
|
||||
<table><thead><tr style="box-sizing: border-box;"><th data-colwidth="61" style="box-sizing: border-box;border: 1px solid rgb(233, 233, 231);padding: 6px 12px;"><section><span leaf="">步骤</span></section></th><th data-colwidth="117" style="box-sizing: border-box;border: 1px solid rgb(233, 233, 231);padding: 6px 12px;"><section><span leaf="">动作</span></section></th><th data-colwidth="156" style="box-sizing: border-box;border: 1px solid rgb(233, 233, 231);padding: 6px 12px;"><section><span leaf="">改动前的值</span></section></th><th data-colwidth="166" style="box-sizing: border-box;border: 1px solid rgb(233, 233, 231);padding: 6px 12px;"><section><span leaf="">改动后的值</span></section></th></tr></thead><tbody><tr style="box-sizing: border-box;"><td data-colwidth="61" style="box-sizing: border-box;border: 1px solid rgb(233, 233, 231);padding: 6px 12px;"><section><span leaf=""><span textstyle="" style="font-size: 14px;">1</span></span></section></td><td data-colwidth="117" style="box-sizing: border-box;border: 1px solid rgb(233, 233, 231);padding: 6px 12px;"><section><span leaf=""><span textstyle="" style="font-size: 14px;">查询目标服务的 ImagePath</span></span></section></td><td data-colwidth="156" style="box-sizing: border-box;border: 1px solid rgb(233, 233, 231);padding: 6px 12px;"><code style="box-sizing: border-box;font-family: "JetBrains Mono", "SF Mono", "Cascadia Code", Menlo, Consolas, "Fira Code", "Source Code Pro", "DejaVu Sans Mono", "Liberation Mono", "Ubuntu Mono", "Noto Sans Mono", "PingFang SC", "Hiragino Sans GB", monospace, "SoloMD CJK", "Apple Color Emoji", "Segoe UI Emoji";font-size: 0.9em;background: none 0% 0% / auto repeat scroll padding-box border-box rgb(240, 238, 232);padding: 0.15em 0.4em;border-radius: 4px;"><span leaf=""><span textstyle="" style="font-size: 14px;">%SystemRoot%\system32\svchost.exe -k netsvcs -p</span></span></code></td><td data-colwidth="166" style="box-sizing: border-box;border: 1px solid rgb(233, 233, 231);padding: 6px 12px;"><section><span leaf=""><span textstyle="" style="font-size: 14px;">未改动,仅作记录</span></span></section></td></tr><tr style="box-sizing: border-box;"><td data-colwidth="61" style="box-sizing: border-box;border: 1px solid rgb(233, 233, 231);padding: 6px 12px;"><section><span leaf=""><span textstyle="" style="font-size: 14px;">2</span></span></section></td><td data-colwidth="117" style="box-sizing: border-box;border: 1px solid rgb(233, 233, 231);padding: 6px 12px;"><section><span leaf=""><span textstyle="" style="font-size: 14px;">改写 ImagePath</span></span></section></td><td data-colwidth="156" style="box-sizing: border-box;border: 1px solid rgb(233, 233, 231);padding: 6px 12px;"><section><span leaf=""><span textstyle="" style="font-size: 14px;">同上</span></span></section></td><td data-colwidth="166" style="box-sizing: border-box;border: 1px solid rgb(233, 233, 231);padding: 6px 12px;"><section><span leaf=""><span textstyle="" style="font-size: 14px;">攻击者二进制路径,类型 REG_EXPAND_SZ</span></span></section></td></tr><tr style="box-sizing: border-box;"><td data-colwidth="61" style="box-sizing: border-box;border: 1px solid rgb(233, 233, 231);padding: 6px 12px;"><section><span leaf=""><span textstyle="" style="font-size: 14px;">3</span></span></section></td><td data-colwidth="117" style="box-sizing: border-box;border: 1px solid rgb(233, 233, 231);padding: 6px 12px;"><section><span leaf=""><span textstyle="" style="font-size: 14px;">改写启动类型</span></span></section></td><td data-colwidth="156" style="box-sizing: border-box;border: 1px solid rgb(233, 233, 231);padding: 6px 12px;"><section><span leaf=""><span textstyle="" style="font-size: 14px;">0x3(手动)</span></span></section></td><td data-colwidth="166" style="box-sizing: border-box;border: 1px solid rgb(233, 233, 231);padding: 6px 12px;"><section><span leaf=""><span textstyle="" style="font-size: 14px;">0x2(自动)</span></span></section></td></tr><tr style="box-sizing: border-box;"><td data-colwidth="61" style="box-sizing: border-box;border: 1px solid rgb(233, 233, 231);padding: 6px 12px;"><section><span leaf=""><span textstyle="" style="font-size: 14px;">4</span></span></section></td><td data-colwidth="117" style="box-sizing: border-box;border: 1px solid rgb(233, 233, 231);padding: 6px 12px;"><section><span leaf=""><span textstyle="" style="font-size: 14px;">改写服务类型</span></span></section></td><td data-colwidth="156" style="box-sizing: border-box;border: 1px solid rgb(233, 233, 231);padding: 6px 12px;"><section><span leaf=""><span textstyle="" style="font-size: 14px;">0x20(共享进程)</span></span></section></td><td data-colwidth="166" style="box-sizing: border-box;border: 1px solid rgb(233, 233, 231);padding: 6px 12px;"><section><span leaf=""><span textstyle="" style="font-size: 14px;">0x1Line truncated
|
||||
目标服务是 Windows 内置的 Natural Authentication。第三、四步的改动意图值得单独说明:启动类型从手动改为自动,是为了不依赖人工触发;服务类型从共享进程改为独立进程,是因为载荷是一个独立可执行文件,而不是由 svchost 托管的动态库,服务控制管理器需要按独立进程方式加载它。
|
||||
|
||||
第五步是整个链条里最能说明隐患深度的一处。被替换的 RequiredPrivileges 列表包含二十八项特权,其中包括:
|
||||
- SeTcbPrivilege
|
||||
(作为可信计算基础的一部分行动)
|
||||
|
||||
- SeDebugPrivilege
|
||||
(调试其他进程)
|
||||
|
||||
- SeLoadDriverPrivilege
|
||||
(加载与卸载设备驱动)
|
||||
|
||||
- SeBackupPrivilege
|
||||
与 SeRestorePrivilege
|
||||
(备份与还原文件,可绕过 ACL)
|
||||
|
||||
- SeImpersonatePrivilege
|
||||
与 SeAssignPrimaryTokenPrivilege
|
||||
(模拟与分配令牌)
|
||||
|
||||
这一组权限的组合在 Windows 权限体系中处于顶端。**换句话说,这条链不但把身份从普通用户换成了 LocalSystem,还顺手给新身份配足了二十八项特权,其中任何一项单独拿出来都足以支撑后续操作。**
|
||||
### 4.2 为什么挑中这个系统服务
|
||||
|
||||
PoC 仓库里附了一份 backup.reg
|
||||
,用于在使用后恢复原始配置。从这份备份文件可以完整读出 Natural Authentication 服务的原始定义,也就能看出选择它的理由。原始定义中的关键字段如下:
|
||||
<table><thead><tr style="box-sizing: border-box;"><th data-colwidth="149" style="box-sizing: border-box;border: 1px solid rgb(233, 233, 231);padding: 6px 12px;"><section><span leaf="">字段</span></section></th><th data-colwidth="400" style="box-sizing: border-box;border: 1px solid rgb(233, 233, 231);padding: 6px 12px;"><section><span leaf="">原始值</span></section></th></tr></thead><tbody><tr style="box-sizing: border-box;"><td data-colwidth="149" style="box-sizing: border-box;border: 1px solid rgb(233, 233, 231);padding: 6px 12px;"><section><span leaf=""><span textstyle="" style="font-size: 14px;">ImagePath</span></span></section></td><td data-colwidth="400" style="box-sizing: border-box;border: 1px solid rgb(233, 233, 231);padding: 6px 12px;"><code style="box-sizing: border-box;font-family: "JetBrains Mono", "SF Mono", "Cascadia Code", Menlo, Consolas, "Fira Code", "Source Code Pro", "DejaVu Sans Mono", "Liberation Mono", "Ubuntu Mono", "Noto Sans Mono", "PingFang SC", "Hiragino Sans GB", monospace, "SoloMD CJK", "Apple Color Emoji", "Segoe UI Emoji";font-size: 0.9em;background: none 0% 0% / auto repeat scroll padding-box border-box rgb(240, 238, 232);padding: 0.15em 0.4em;border-radius: 4px;"><span leaf=""><span textstyle="" style="font-size: 14px;">%SystemRoot%\system32\svchost.exe -k netsvcs -p</span></span></code></td></tr><tr style="box-sizing: border-box;"><td data-colwidth="149" style="box-sizing: border-box;border: 1px solid rgb(233, 233, 231);padding: 6px 12px;"><section><span leaf=""><span textstyle="" style="font-size: 14px;">ObjectName</span></span></section></td><td data-colwidth="400" style="box-sizing: border-box;border: 1px solid rgb(233, 233, 231);padding: 6px 12px;"><section><span leaf=""><span textstyle="" style="font-size: 14px;">LocalSystem</span></span></section></td></tr><tr style="box-sizing: border-box;"><td data-colwidth="149" style="box-sizing: border-box;border: 1px solid rgb(233, 233, 231);padding: 6px 12px;"><section><span leaf=""><span textstyle="" style="font-size: 14px;">RequiredPrivileges</span></span></section></td><td data-colwidth="400" style="box-sizing: border-box;border: 1px solid rgb(233, 233, 231);padding: 6px 12px;"><section><span leaf=""><span textstyle="" style="font-size: 14px;">SeTcbPrivilege、SeChangeNotifyPrivilege、SeSystemEnvironmentPrivilege</span></span></section></td></tr><tr style="box-sizing: border-box;"><td data-colwidth="149" style="box-sizing: border-box;border: 1px solid rgb(233, 233, 231);padding: 6px 12px;"><section><span leaf=""><span textstyle="" style="font-size: 14px;">Start</span></span></section></td><td data-colwidth="400" style="box-sizing: border-box;border: 1px solid rgb(233, 233, 231);padding: 6px 12px;"><section><span leaf=""><span textstyle="" style="font-size: 14px;">3(手动)</span></span></section></td></tr><tr style="box-sizing: border-box;"><td data-colwidth="149" style="box-sizing: border-box;border: 1px solid rgb(233, 233, 231);padding: 6px 12px;"><section><span leaf=""><span textstyle="" style="font-size: 14px;">Type</span></span></section></td><td data-colwidth="400" style="box-sizing: border-box;border: 1px solid rgb(233, 233, 231);padding: 6px 12px;"><section><span leaf=""><span textstyle="" style="font-size: 14px;">0x20(共享进程)</span></span></section></td></tr><tr style="box-sizing: border-box;"><td data-colwidth="149" style="box-sizing: border-box;border: 1px solid rgb(233, 233, 231);padding: 6px 12px;"><section><span leaf=""><span textstyle="" style="font-size: 14px;">DependOnService</span></span></section></td><td data-colwidth="400" style="box-sizing: border-box;border: 1px solid rgb(233, 233, 231);padding: 6px 12px;"><section><span leaf=""><span textstyle="" style="font-size: 14px;">RpcSs、ProfSvc、Schedule</span></span></section></td></tr><tr style="box-sizing: border-box;"><td data-colwidth="149" style="box-sizing: border-box;border: 1px solid rgb(233, 233, 231);padding: 6px 12px;"><section><span leaf=""><span textstyle="" style="font-size: 14px;">服务 DLL</span></span></section></td><td data-colwidth="400" style="box-sizing: border-box;border: 1px solid rgb(233, 233, 231);padding: 6px 12px;"><code style="box-sizing: border-box;font-family: "JetBrains Mono", "SF Mono", "Cascadia Code", Menlo, Consolas, "Fira Code", "Source Code Pro", "DejaVu Sans Mono", "Liberation Mono", "Ubuntu Mono", "Noto Sans Mono", "PingFang SC", "Hiragino Sans GB", monospace, "SoloMD CJK", "Apple Color Emoji", "Segoe UI Emoji";font-size: 0.9em;background: none 0% 0% / auto repeat scroll padding-box border-box rgb(240, 238, 232);padding: 0.15em 0.4em;border-radius: 4px;"><span leaf=""><span textstyle="" style="font-size: 14px;">%SystemRoot%\System32\NaturalAuth.dll</span></span></code></td></trLine truncated
|
||||
这份原始定义里有三个特征同时成立,构成了挑选依据。
|
||||
|
||||
一是身份。ObjectName 为 LocalSystem,服务本体以内核级身份运行。二是权限。它的 RequiredPrivileges 里原本就含 SeTcbPrivilege
|
||||
,这一组权限通常只授予 SYSTEM 与极少数系统组件,被借用的服务自带这个起点。三是触发方式。备份文件中存在 TriggerInfo 子键,记录了触发 GUID、触发类型等字段,说明这是一个触发启动型服务,不需要等待系统重启就能被拉起。
|
||||
|
||||
backup.reg
|
||||
这份文件本身也透露了一条信息。它把整棵服务注册表子树完整备份下来,说明 PoC 具备用后恢复原配置的能力。**这类"改完再复原"的设计在真实攻击中常用于降低被发现的概率,它不改变漏洞的技术性质,但改变攻击者的时序选择。**
|
||||
### 4.3 载荷侧的动作
|
||||
|
||||
PoC 的载荷是一个标准的 Windows 服务程序:通过 StartServiceCtrlDispatcherA
|
||||
注册入口,通过 RegisterServiceCtrlHandlerA
|
||||
注册控制处理器,服务名硬编码为与目标服务相同的名称。这一设计是为了让服务控制管理器在启动它时能够正常握手。
|
||||
|
||||
提权成功后的动作是 StartProcessAsSystemInActiveSession
|
||||
,参数为目标程序路径与窗口标题,指向系统目录下的命令解释器。这个调用的作用是把进程从会话 0 拉到当前活动交互会话。
|
||||
|
||||
这一步解决的是一个实际问题。服务由服务控制管理器在会话 0 启动,即使身份是 SYSTEM,进程也处在一个没有交互桌面的会话里,用户看不到窗口。要在当前登录会话里拿到可交互的系统级命令行,就需要跨会话启动进程。PoC 仓库里单独提供了 create_process_as_user.hpp
|
||||
这一文件,篇幅约十五 KB,承担的就是这部分工作。
|
||||
|
||||
报告中还提到一段与载荷行为相关的观察:脚本触发后,载荷可能在不同的 Windows 会话中启动,因此即使执行成功,程序窗口也可能不出现在当前交互桌面上。这种情况下仍可在任务管理器里观察进程,例如一个以 SYSTEM 用户运行的命令解释器实例。**这句话是报告里对端到端效果唯一的间接描述,它不等价于一张提权成功的截图,这一点在用词上需要区分。**
|
||||
### 4.4 已动态验证的六项行为
|
||||
|
||||
报告第六节列出了作者实际验证过的行为,共六项:0x0D
|
||||
向测试路径写入 REG_DWORD;0x0C
|
||||
读回;0x0E
|
||||
删除该值;0x0F
|
||||
删除空键;0x0D
|
||||
写入 REG_EXPAND_SZ;0x0C
|
||||
读回并正确重建字符串内容。
|
||||
|
||||
作者对这六项结果的解释是:接口不是理论上的"可能写入",而是已经实证可稳定用于通用注册表操作。
|
||||
|
||||
需要把验证范围讲准。**六项验证覆盖的是注册表操作原语本身,即读写删三类动作都能按预期工作;它不包含端到端拿到系统级命令行的完整记录。**
|
||||
完整链具备工程实现这一点,依据是仓库里的载荷源码与批处理脚本,而非一份提权成功的日志。区分这两者,是因为前者决定了漏洞的定性,后者决定了攻击者在具体环境里的成功率。
|
||||
### 4.5 关于是否需要重启
|
||||
|
||||
PoC 脚本的末行直接调用服务启动命令拉起目标服务,设计意图是不依赖重启。
|
||||
|
||||
这里存在一个公开材料没有说明的环节:普通本地用户是否默认持有该服务的启动权限。CVE 记录与 PoC 报告都没有给出这一项的实测结果,服务安全描述符的原始内容虽然在备份文件里,但报告没有对其做权限解读。
|
||||
|
||||
可以确定的替代路径是:脚本第三步已把启动类型写成自动(0x2)。因此如果启动命令被拒绝,已落盘的配置会在系统下次启动时生效,触发目标服务的加载。**两条路径最终指向同一个结果,差异只在时间。把"免重启"当作无条件结论是不严谨的,严谨的表述是"脚本尝试立即触发,失败时由自动启动配置在重启后兜底"。**
|
||||
## 五、补丁分析:没有补丁可分析
|
||||
### 5.1 厂商在 PoC 公开后又发了三个版本
|
||||
|
||||
这一节没有补丁差异可读,但有一条同样有信息量的时间线。
|
||||
|
||||
PoC 仓库的初始提交日期是 2026 年 7 月 15 日,报告、源码与预编译文件在同一次提交里一起公开。此后厂商的发布节奏没有变化:
|
||||
<table><thead><tr style="box-sizing: border-box;"><th data-colwidth="128" style="box-sizing: border-box;border: 1px solid rgb(233, 233, 231);padding: 6px 12px;"><section><span leaf="">日期</span></section></th><th data-colwidth="155" style="box-sizing: border-box;border: 1px solid rgb(233, 233, 231);padding: 6px 12px;"><section><span leaf="">版本</span></section></th><th data-colwidth="250" style="box-sizing: border-box;border: 1px solid rgb(233, 233, 231);padding: 6px 12px;"><section><span leaf="">更新日志要点</span></section></th></tr></thead><tbody><tr style="box-sizing: border-box;"><td data-colwidth="128" style="box-sizing: border-box;border: 1px solid rgb(233, 233, 231);padding: 6px 12px;"><section><span leaf=""><span textstyle="" style="font-size: 14px;">2026-07-22</span></span></section></td><td data-colwidth="155" style="box-sizing: border-box;border: 1px solid rgb(233, 233, 231);padding: 6px 12px;"><section><span leaf=""><span textstyle="" style="font-size: 14px;">6.43 Build 7</span></span></section></td><td data-colwidth="250" style="box-sizing: border-box;border: 1px solid rgb(233, 233, 231);padding: 6px 12px;"><section><span leaf=""><span textstyle="" style="font-size: 14px;">修复部分网站不显示下载面板</span></span></section></td></tr><tr style="box-sizing: border-box;"><td data-colwidth="128" style="box-sizing: border-box;border: 1px solid rgb(233, 233, 231);padding: 6px 12px;"><section><span leaf=""><span textstyle="" style="font-size: 14px;">2026-08-08</span></span></section></td><td data-colwidth="155" style="box-sizing: border-box;border: 1px solid rgb(233, 233, 231);padding: 6px 12px;"><section><span leaf=""><span textstyle="" style="font-size: 14px;">6.43 Build 8</span></span></section></td><td data-colwidth="250" style="box-sizing: border-box;border: 1px solid rgb(233, 233, 231);padding: 6px 12px;"><section><span leaf=""><span textstyle="" style="font-size: 14px;">修复部分文件下载 403 错误</span></span></section></td></tr><tr style="box-sizing: border-box;"><td data-colwidth="128" style="box-sizing: border-box;border: 1px solid rgb(233, 233, 231);padding: 6px 12px;"><section><span leaf=""><span textstyle="" style="font-size: 14px;">2026-08-20</span></span></section></td><td data-colwidth="155" style="box-sizing: border-box;border: 1px solid rgb(233, 233, 231);padding: 6px 12px;"><section><span leaf=""><span textstyle="" style="font-size: 14px;">6.43 Build 10</span></span></section></td><td data-colwidth="250" style="box-sizing: border-box;border: 1px solid rgb(233, 233, 231);padding: 6px 12px;"><section><span leaf=""><span textstyle="" style="font-size: 14px;">修复部分文件下载 403 错误</span></span></section></td></tr></tbody></table>
|
||||
三个版本的更新日志都只涉及下载功能。**需要把表述的边界写清:从更新日志未提及这一点,只能推出"厂商未公开说明已修复",不能反推"这三个版本仍然受影响",也不能推"厂商已修复但选择不公告"。**
|
||||
最新版本当前是否仍存在该缺陷,公开信息未说明,这是本编号最大的开放问题。
|
||||
### 5.2 同一产品历史漏洞的形态变化
|
||||
|
||||
IDM 历史上有过若干编号,把可检索到的几条按时间排列,可以看出形态的变化:
|
||||
<table><thead><tr style="box-sizing: border-box;"><th data-colwidth="133" style="box-sizing: border-box;border: 1px solid rgb(233, 233, 231);padding: 6px 12px;"><section><span leaf="">编号</span></section></th><th data-colwidth="73" style="box-sizing: border-box;border: 1px solid rgb(233, 233, 231);padding: 6px 12px;"><section><span leaf="">年份</span></section></th><th data-colwidth="182" style="box-sizing: border-box;border: 1px solid rgb(233, 233, 231);padding: 6px 12px;"><section><span leaf="">类型</span></section></th><th data-colwidth="77" style="box-sizing: border-box;border: 1px solid rgb(233, 233, 231);padding: 6px 12px;"><section><span leaf="">评分</span></section></th></tr></thead><tbody><tr style="box-sizing: border-box;"><td data-colwidth="133" style="box-sizing: border-box;border: 1px solid rgb(233, 233, 231);padding: 6px 12px;"><section><span leaf=""><span textstyle="" style="font-size: 14px;">CVE-2008-4508</span></span></section></td><td data-colwidth="73" style="box-sizing: border-box;border: 1px solid rgb(233, 233, 231);padding: 6px 12px;"><section><span leaf=""><span textstyle="" style="font-size: 14px;">2008</span></span></section></td><td data-colwidth="182" style="box-sizing: border-box;border: 1px solid rgb(233, 233, 231);padding: 6px 12px;"><section><span leaf=""><span textstyle="" style="font-size: 14px;">边界内操作限制不当</span></span></section></td><td data-colwidth="77" style="box-sizing: border-box;border: 1px solid rgb(233, 233, 231);padding: 6px 12px;"><section><span leaf=""><span textstyle="" style="font-size: 14px;">7.8</span></span></section></td></tr><tr style="box-sizing: border-box;"><td data-colwidth="133" style="box-sizing: border-box;border: 1px solid rgb(233, 233, 231);padding: 6px 12px;"><section><span leaf=""><span textstyle="" style="font-size: 14px;">CVE-2010-0995</span></span></section></td><td data-colwidth="73" style="box-sizing: border-box;border: 1px solid rgb(233, 233, 231);padding: 6px 12px;"><section><span leaf=""><span textstyle="" style="font-size: 14px;">2010</span></span></section></td><td data-colwidth="182" style="box-sizing: border-box;border: 1px solid rgb(233, 233, 231);padding: 6px 12px;"><section><span leaf=""><span textstyle="" style="font-size: 14px;">栈缓冲区溢出(FTP URI)</span></span></section></td><td data-colwidth="77" style="box-sizing: border-box;border: 1px solid rgb(233, 233, 231);padding: 6px 12px;"><section><span leaf=""><span textstyle="" style="font-size: 14px;">9.3</span></span></section></td></tr><tr style="box-sizing: border-box;"><td data-colwidth="133" style="box-sizing: border-box;border: 1px solid rgb(233, 233, 231);padding: 6px 12px;"><section><span leaf=""><span textstyle="" style="font-size: 14px;">CVE-2020-23060</span></span></section></td><td data-colwidth="73" style="box-sizing: border-box;border: 1px solid rgb(233, 233, 231);padding: 6px 12px;"><section><span leaf=""><span textstyle="" style="font-size: 14px;">2021</span></span></section></td><td data-colwidth="182" style="box-sizing: border-box;border: 1px solid rgb(233, 233, 231);padding: 6px 12px;"><section><span leaf=""><span textstyle="" style="font-size: 14px;">栈缓冲区溢出(导入导出功能)</span></span></section></td><td data-colwidth="77" style="box-sizing: border-box;border: 1px solid rgb(233, 233, 231);padding: 6px 12px;"><section><span leaf=""><span textstyle="" style="font-size: 14px;">7.1</span></span></section></td></tr><tr style="box-sizing: border-box;"><td data-colwidth="133" style="box-sizing: border-box;border: 1px solid rgb(233, 233, 231);padding: 6px 12px;"><section><span leaf=""><span textstyle="" style="font-size: 14px;">CVE-2020-28964</span></span></section></td><td data-colwidth="73" style="box-sizing: border-box;border: 1px solid rgb(233, 233, 231);padding: 6px 12px;"><section><span leaf=""><span textstyle="" style="font-size: 14px;">2021</span></span></section></td><td data-colwidth="182" style="box-sizing: border-box;border: 1px solid rgb(233, 233, 231);padding: 6px 12px;"><section><span leaf=""><span textstyle="" style="font-size: 14px;">栈缓冲区溢出(搜索功能)</span></span></section></td><td data-colwidth="77" style="box-sizing: border-box;border: 1px solid rgb(233, 233, 231);padding: 6px 12px;"><section><span leaf=""><span textstyle="" style="font-size: 14px;">6.7</span></span></section></td></tr><tr style="box-sizing: border-box;"><td data-colwidth="133" style="box-sizing: border-box;border: 1px solid rgb(233, 233, 231);padding: 6px 12px;"><section><span leaf=""><span textstyle="" style="font-size: 14px;">CVE-2025-56231</span></span></section></td><td data-colwidth="73" style="box-sizing: border-box;border: 1px solid rgb(233, 233, 231);padding: 6px 12px;"><section><span leaf=""><span textstyle="" style="font-size: 14px;">2025</span></span></section></td><td data-colwidth="182" style="box-sizing: border-box;border: 1px solid rgb(233, 233, 231);padding: 6px 12px;"><section><span leafLine truncated
|
||||
前四条全部是内存破坏类问题,落点在用户态组件。**本次是该产品在可检索记录里的第一个内核驱动层面的编号,而且不是内存破坏,是权限逻辑缺陷。**
|
||||
|
||||
这个转变对防御方的含义是反向的:内存破坏类漏洞需要绕过地址随机化、控制流保护、堆保护等一整套缓解机制,利用难度随系统版本上升;而授权逻辑缺陷不需要绕过任何缓解机制,它只是"本该拒绝的请求被接受了"。**从防御角度看,缺陷类型向逻辑层迁移,通常意味着利用门槛下降而不是上升。**
|
||||
### 5.3 更新通路本身出过问题
|
||||
|
||||
前表中 2025 年 11 月的那条编号值得单独看。CVE-2025-56231 的定性是证书校验缺失,描述里明确了后果是允许攻击者绕过更新保护,评分 9.1。
|
||||
|
||||
这条编号与本次的关系需要写清:**当前厂商没有发布修复,所以它暂时不构成叠加风险**
|
||||
,因为没有可投毒的修复包可以下发。但它影响一个判断前提。当"升级到最新版"被当作唯一处置手段时,这条历史记录说明该产品的更新通路曾经出现过校验缺陷,把自动更新当作可信修复渠道需要保留质疑。
|
||||
### 5.4 这类问题的标准修复路径
|
||||
|
||||
虽然厂商没有发布补丁,这类缺陷的修复方向在 CWE 体系里有明确表述。报告建议的映射是 CWE-862(授权缺失)与 CWE-732(关键资源权限分配不当),CVE 记录实际采纳的是 CWE-266(权限分配不当)与 CWE-284(访问控制不当)。
|
||||
|
||||
而 VulDB 提交记录的标题用的是另一个概念:CWE-782,Exposed IOCTL with Insufficient Access Control。**这个分类反而没有被写进 CVE 记录的 CWE 字段,但它才是这类问题的专有类别。**
|
||||
|
||||
CWE-782 的官方描述针对的正是"产品实现了一个本应受限的 IOCTL,却没有正确实施访问控制"这一形态,其描述里特别点出一句与本案高度吻合的话:开发者常常假定 IOCTL 只会被受信任的进程访问,因此对传入数据很少或没有校验,从而暴露了在攻击者无法直接调用该 IOCTL 时根本不可达的弱点。
|
||||
|
||||
该条目的官方缓解建议有三处,与本案根因逐项对应:
|
||||
1. 为设备对象设置正确的安全描述符,限制哪些用户组可以打开设备句柄
|
||||
|
||||
1. 在 IOCTL 处理例程内校验调用者身份与特权,而不是依赖调用者的自觉
|
||||
|
||||
1. 最小化暴露面,只开放必需的功能,并在访问控制到位的前提下仍然校验全部输入参数
|
||||
|
||||
本案在这三处全部缺失:安全描述符给了所有认证用户完全访问权,处理例程不做调用者校验,功能上一口气开放了四个子命令覆盖读写删。**用 CWE-782 去描述它比用 CWE-284 更准确,原因是前者直接指向了缺陷的构造方式而非后果。**
|
||||
## 六、结束语
|
||||
|
||||
这个编号在 2026 年的漏洞清单里不算最显眼的一个。没有在野利用报告,没有进 CISA KEV,NVD 状态还停在上游。但它的结构值得留意。
|
||||
|
||||
它把缺陷放在了最难修补的位置。设备对象的安全描述符与 IOCTL 处理例程的鉴权逻辑,都在内核驱动里,而这是一个随常规安装落地的闭源组件。用户能做的只有卸载或停用,没有中间档位。
|
||||
|
||||
它也把厂商侧的处置空白暴露得很完整。报告在 7 月 15 日公开,源码与二进制一起给出;厂商在一个月内发布了三个版本,更新日志里没有一行相关文字;CVE 记录对厂商的表述是收到披露但未作任何回应。这是公开披露机制在商业闭源软件上的一次典型落空。
|
||||
|
||||
对使用者而言,这一类漏洞提醒的是一件更基础的事:**装机量本身不是安全信号。一个天天在用的工具,可以同时携带一个对所有本地用户敞开的内核级写注册表能力,而这个能力与它的核心功能并无必要关联。**
|
||||
判断一个组件的风险,看的是它请求了多少权限,而不是它在桌面上看起来多普通。
|
||||
|
||||
在厂商给出修复之前,本编号只有降级与隔离两种处置。也唯有把"随包安装的内核组件"纳入资产清点、把服务配置基线纳入持续监控,才能在下一个同类编号出现时提前知道自己的机器是否在范围内。
|
||||
## 七、参考
|
||||
1. CVE 记录 CVE-2026-90493。CNA 为 VulDB,CWE-266 与 CWE-284,四个版本的 CVSS 评分与向量逐项列明。
|
||||
|
||||
1. NVD 记录 CVE-2026-90493。来源标识为
|
||||
[email protected],vulnStatus 为 Received,configurations 字段为 null,cvssMetricV40 给 8.5。
|
||||
|
||||
1. PoC 仓库 IDM_LPE_PoC,作者 KnCRJVirX,初始提交日期 2026-07-15。含 readme.md、report_en.md、report_cn.md、poc.bat、backup.reg、预编译二进制与源码目录 src。
|
||||
|
||||
1. PoC 报告正文 report_en.md(13,568 字节)。机制描述、根因分类建议、六项动态验证行为、四条安全建议均出自该文件。
|
||||
|
||||
1. PoC 载荷源码 main.cpp 与 create_process_as_user.hpp。服务注册方式与跨会话启动实现出自这两个文件。
|
||||
|
||||
1. PoC 注册表操作源码 idmwfp_reg_demo.cpp(29,350 字节)。IOCTL 编号常量、请求包构造与传输编码函数出自该文件。
|
||||
|
||||
1. 厂商官方更新页,Tonec Inc. 的 Internet Download Manager news 页。版本序列与各版本更新日志逐条取自该页,页面共记录 376 条版本条目。
|
||||
|
||||
1. 驱动文件信息,idmwfp.sys 的产品名 Internet Download Manager WFP Driver 与签名方 Tonec Inc. 出自公开文件信息库条目。
|
||||
|
||||
1. 社区实测记录,关于 IDMWFP 服务与本地 127.0.0.1:1001 端点关系的技术讨论帖,用于说明驱动用途。
|
||||
|
||||
**证实状态说明**
|
||||
:厂商未发布安全公告,未发布补丁,因此本文第三节的机制描述来自 PoC 报告对驱动的反编译结论与实机行为观测,**不属于补丁代码阅读**
|
||||
。第一节中 CVSS 4.0 的两处分值差异,只能从公开字段观察到向量补充项的差异,具体计算口径差异公开信息未说明。最新版本 6.43 Build 10 是否已修复该缺陷,公开信息未说明。PoC 所称 2023 年 11 月之后版本均可使用的说法,报告未列出实测版本清单,属报告方陈述。
|
||||
|
||||
```
|
||||
https://www.cve.org/CVERecord?id=CVE-2026-90493
|
||||
https://nvd.nist.gov/vuln/detail/CVE-2026-90493
|
||||
https://services.nvd.nist.gov/rest/json/cves/2.0?cveId=CVE-2026-90493
|
||||
https://github.com/KnCRJVirX/IDM_LPE_PoC
|
||||
https://github.com/KnCRJVirX/IDM_LPE_PoC/blob/main/report_en.md
|
||||
https://github.com/KnCRJVirX/IDM_LPE_PoC/blob/main/poc/backup.reg
|
||||
https://vuldb.com/vuln/403081
|
||||
https://vuldb.com/submit/891910
|
||||
https://www.internetdownloadmanager.com/news.html
|
||||
https://cwe.mitre.org/data/definitions/782.html
|
||||
```
|
||||
|
||||
|
||||
**END**
|
||||
|
||||
|
||||

|
||||
|
||||
|
||||
公众号内容都来自国外等平台- 搜索的内容通过结合编写 -
|
||||
|
||||
提供整洁 - 广告已关
|
||||
|
||||
公众号 |
|
||||
AnQuan7 (Ots安全)
|
||||
|
||||
Reference in new issue
Block a user