diff --git a/data.json b/data.json index 120b23fd..46488280 100644 --- a/data.json +++ b/data.json @@ -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 未授权任意文件读取分析:一个末尾斜杠打穿的满分漏洞" } \ No newline at end of file diff --git a/doc/2026-09/GitLab CVE-2026-85706 未授权任意文件读取分析:一个末尾斜杠打穿的满分漏洞.md b/doc/2026-09/GitLab CVE-2026-85706 未授权任意文件读取分析:一个末尾斜杠打穿的满分漏洞.md new file mode 100644 index 00000000..43ff5b2d --- /dev/null +++ b/doc/2026-09/GitLab CVE-2026-85706 未授权任意文件读取分析:一个末尾斜杠打穿的满分漏洞.md @@ -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 漏洞概述 + +
项目
内容
CVE 编号
CVE-2026-85706
漏洞类型
路径遍历 / 未授权任意文件读取
CVSS 评分
10.0(CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:N)
影响组件
Repository Commits API(GitLab CE/EE)
影响版本
18.7 ≤ v < 19.1.8;19.2 ≤ v < 19.2.6;19.3 ≤ v < 19.3.2
修复版本
19.1.8 / 19.2.6 / 19.3.2
报告者
s3ntago(HackerOne)
在野利用
已观测到探测与利用,CISA KEV 收录
+ +时间线: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/ + +**免责声明** +:本文仅用于安全研究与学习,未经授权不得用于任何非法渗透测试活动。 + + diff --git a/doc/2026-09/被改写的系统服务:IDM 内核驱动 CVE-2026-90493 提权.md b/doc/2026-09/被改写的系统服务:IDM 内核驱动 CVE-2026-90493 提权.md new file mode 100644 index 00000000..e2db3ba2 --- /dev/null +++ b/doc/2026-09/被改写的系统服务:IDM 内核驱动 CVE-2026-90493 提权.md @@ -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 +。 + +四个子命令的功能划分如下: +
子命令
功能
0x0C
查询值
0x0D
创建缺失的键路径并写入值
0x0E
删除值
0x0F
删除值,并在键为空时删除键
+处理函数内部会从用户输入中解出"注册表相对路径 + 值名"两部分。根前缀由请求包里的 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 仓库提供一个批处理脚本,把整条链压缩成六个动作。此处按动作意图逐步说明,不逐行复制脚本原文。 +
步骤
动作
改动前的值
改动后的值
1
查询目标服务的 ImagePath
%SystemRoot%\system32\svchost.exe -k netsvcs -p
未改动,仅作记录
2
改写 ImagePath
同上
攻击者二进制路径,类型 REG_EXPAND_SZ
3
改写启动类型
0x3(手动)
0x2(自动)
4
改写服务类型
0x20(共享进程)
0x10(独立进程)
5
替换 RequiredPrivileges 列表
三项
二十八项
6
启动该服务
未启动
调用服务启动命令拉起
+目标服务是 Windows 内置的 Natural Authentication。第三、四步的改动意图值得单独说明:启动类型从手动改为自动,是为了不依赖人工触发;服务类型从共享进程改为独立进程,是因为载荷是一个独立可执行文件,而不是由 svchost 托管的动态库,服务控制管理器需要按独立进程方式加载它。 + +第五步是整个链条里最能说明隐患深度的一处。被替换的 RequiredPrivileges 列表包含二十八项特权,其中包括: +- SeTcbPrivilege +(作为可信计算基础的一部分行动) + +- SeDebugPrivilege +(调试其他进程) + +- SeLoadDriverPrivilege +(加载与卸载设备驱动) + +- SeBackupPrivilege + 与 SeRestorePrivilege +(备份与还原文件,可绕过 ACL) + +- SeImpersonatePrivilege + 与 SeAssignPrimaryTokenPrivilege +(模拟与分配令牌) + +这一组权限的组合在 Windows 权限体系中处于顶端。**换句话说,这条链不但把身份从普通用户换成了 LocalSystem,还顺手给新身份配足了二十八项特权,其中任何一项单独拿出来都足以支撑后续操作。** +### 4.2 为什么挑中这个系统服务 + +PoC 仓库里附了一份 backup.reg +,用于在使用后恢复原始配置。从这份备份文件可以完整读出 Natural Authentication 服务的原始定义,也就能看出选择它的理由。原始定义中的关键字段如下: +
字段
原始值
ImagePath
%SystemRoot%\system32\svchost.exe -k netsvcs -p
ObjectName
LocalSystem
RequiredPrivileges
SeTcbPrivilege、SeChangeNotifyPrivilege、SeSystemEnvironmentPrivilege
Start
3(手动)
Type
0x20(共享进程)
DependOnService
RpcSs、ProfSvc、Schedule
服务 DLL
%SystemRoot%\System32\NaturalAuth.dll
+这份原始定义里有三个特征同时成立,构成了挑选依据。 + +一是身份。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 日,报告、源码与预编译文件在同一次提交里一起公开。此后厂商的发布节奏没有变化: +
日期
版本
更新日志要点
2026-07-22
6.43 Build 7
修复部分网站不显示下载面板
2026-08-08
6.43 Build 8
修复部分文件下载 403 错误
2026-08-20
6.43 Build 10
修复部分文件下载 403 错误
+三个版本的更新日志都只涉及下载功能。**需要把表述的边界写清:从更新日志未提及这一点,只能推出"厂商未公开说明已修复",不能反推"这三个版本仍然受影响",也不能推"厂商已修复但选择不公告"。** + 最新版本当前是否仍存在该缺陷,公开信息未说明,这是本编号最大的开放问题。 +### 5.2 同一产品历史漏洞的形态变化 + +IDM 历史上有过若干编号,把可检索到的几条按时间排列,可以看出形态的变化: +
编号
年份
类型
评分
CVE-2008-4508
2008
边界内操作限制不当
7.8
CVE-2010-0995
2010
栈缓冲区溢出(FTP URI)
9.3
CVE-2020-23060
2021
栈缓冲区溢出(导入导出功能)
7.1
CVE-2020-28964
2021
栈缓冲区溢出(搜索功能)
6.7
CVE-2025-56231
2025
证书校验缺失(更新保护绕过)
9.1
CVE-2026-90493
2026
内核驱动访问控制缺失
9.3
+前四条全部是内存破坏类问题,落点在用户态组件。**本次是该产品在可检索记录里的第一个内核驱动层面的编号,而且不是内存破坏,是权限逻辑缺陷。** + +这个转变对防御方的含义是反向的:内存破坏类漏洞需要绕过地址随机化、控制流保护、堆保护等一整套缓解机制,利用难度随系统版本上升;而授权逻辑缺陷不需要绕过任何缓解机制,它只是"本该拒绝的请求被接受了"。**从防御角度看,缺陷类型向逻辑层迁移,通常意味着利用门槛下降而不是上升。** +### 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。来源标识为  +cna@vuldb.com,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** + + +![](https://mmbiz.qpic.cn/mmbiz_jpg/zNsFJyIuL0EFxsuoyKmkibHsLIdGGLyCzC4dmiaW5T6fmc3MprPDhaQCo4CdT45fhmLIXgZD33K4OtOjDYQJYmeh6ibOIO7tru1x752ova5uZM/640?wx_fmt=jpeg&from=appmsg "") + + +公众号内容都来自国外等平台- 搜索的内容通过结合编写 -  + + 提供整洁 - 广告已关 + +公众号 |  +AnQuan7 (Ots安全) +