哈喽哈喽各位小伙伴好久不见啊,今天周五,发个存货准备下班跑路了
公开exp:https://www.exploit-db.com/exploits/46916
1. 漏洞思路
在分析 CVE-2018-8339 时其实就可以看到另一处漏洞 或者说另一种利用方式。CVE-2018-8339 的竞争窗口出现在 NtSetSecurityObject() 上。除了 CreateFolder() 里会调用 NtSetSecurityObject() 函数,当一开始就存在 Config.msi ,且是一个正常目录时,GetBackupFolder() 也会调用 NtSetSecurityObject() 修改其安全描述符,以保证普通用户无权访问。那么在这种情况下,在 NtSetSecurityObject() 前是否有竞争窗口呢?答案是:有。并且 CVE-2018-8339 的补丁无法起作用。
与 CVE-2018-8339 唯一不同的是,我们需要在一开始就创建一个正常的 C://Config.msi 文件夹。然后是相同的下文件锁,创建目录连接等。
2. exp 流程
-
对 C:Config.msi 等创建文件锁,以保证在 NtSetSecurityObject() 时断下来。
-
安装会自动回滚的msi包。
-
在锁回调函数里 createfile 打开 C:Config.msi,获得读/写权限句柄。
-
在主线处里使用句柄,调用 CreateMountPoint() 循环尝试创建 Config.msi 的目录连接。
-
一旦目录连接创建成功,在连接目标目录里循环 findfile, 找到 rbs 脚本的名字。
-
然后移动 C:Junction (即 连接目标目录),然后在原位置创建一个伪造目录和伪造脚本。
-
然后 msiexec.exe 会以 system 权限运行 rbs 脚本。
注意:该exp会导致生成一个隐藏的高权限的 Config.msi,无法简单删除。可以通过 执行一次 msi 安装来清除。
3. 补丁分析
使用bindiff 进行差异比较,有2个函数不同:
CMsiExecute::Rollback()
CMsiExecute::GenerateRollbackScriptName()
GenerateRollbackScriptName() 正如其名,用于生成回滚脚本名称。该函数直接调用前面提到的 GetBackupFolder() ,得到类似 C://Config.msi 的目录后,借助 TempFileName() 函数,直接生成一个空回滚脚本,并设置其安全描述符。
对比补丁前后的f5 结果:
可以看到,补丁版本在创建完 rbs 脚本,会对目录调用一次 HasJunction() ,以判断是否是连接目录。这样如果我们在 GetBackupFolder() 期间借助漏洞创建目录连接,那么在 GenerateRollbackScriptName() 这里会被检测到。
CMsiExecute::Rollback() 函数是正式执行安装回滚的函数,补丁版本会在回滚开始前,调用 HasJunction() 判断 回滚脚本目录 是否是目录连接。感觉这处补丁是为了加一层保险。
这是一个正经的公众号;drop database;在这里,你可以看到最新的漏洞复现,最全的修复方案以及最特殊的利用技巧。
点击上方蓝字关注我们!
原文始发于微信公众号(肚子好饿啊早知道不做安全了):浅分析一下 Microsoft Windows Installer 输入验证错误漏洞
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论