1. 补丁分析
观察 bindiff 下的差异流程图:
差异主要包括两部分:
-
将以前的 MsiGetFileAttributes() 调用 封装到 IsJunctionFolder() 函数里,用以判断是否是连接目录,实际效果是一样的。
-
在 CreateFolder() 之后,又调用了一次 IsJunctionFolder() 函数,新增了一处判断是否是连接目录的点。
那么该补丁的作用点就是 CreatFolder() 后面跟着的 IsJunctionFolder() 函数,这说明在CVE-2018-8339 漏洞中, CreatFolder() 所处的分支会出现目录连接。我们需要理解 CreateFolder() 在什么情况下被调用。
2. GetBackupFolder 分析
借助 Process Monitor 和 xp 源码,我们可以整理出 GetBackupFolder() 的流程图如下:
可以看到, CreateFolder() 会在两种情况下被调用:
-
一开始 C://Config.msi 就不存在,所以调用 CreateFolder() 创建文件夹。
-
一开始 C://Config.msi 存在,但是 是连接目录,所以被删除后,需要调用 CreateFolder() 重新创建。
尝试通过条件竞争的方式,在 CreateFolder() 之前创建我们的 C://Config.msi 目录。但发现一旦创建成功,CreateFolder() 就会返回一个错误值(非1),导致 GetBackupFolder() 直接结束,整个安装也随之结束。
继续研究 CreateFolder() 的逻辑:
CreateFolder() 在函数一开始,就会调用 CMsiPath::EnsureExists() 以确保 C://Config.msi 目录存在。
EnsureExists() 首先判断目标目录是否存在,如果存在 则直接返回,返回值为0;如果不存在,则调用 CreateDirectory() 创建目录,只有在确实创建的情况下,会返回0,并将输入参数里的 *pcCreatedFolders 加1,以表示确实创建了。
当 EnsureExists() 返回0, 且 *pcCreatedFolders 不为0的情况下,CreateFolder() 才会继续运行下去,修改该文件夹的安全描述符,并最终返回1,GetBackupFolder() 才会继续运行下去。
而当我们通过条件竞争 在 CreateFolder() 之前创建 C://Config.msi ,会导致 EnsureExists() 返回时, *pcCreatedFolders 为0,导致 CreateFolder() 返回一个错误值,导致 GetBackupFolder() 直接结束。
3. 漏洞思路
如果不能在CreateFolder() 之前创建 C://Config.msi ,那么条件竞争的窗口在哪里?
CreateFolder() 通过 EnsureExists() 创建文件夹,如果创建成功,就会调用 NtSetSecurityObject() 修改文件对象的安全描述符,以保证普通用户无权访问。通过调试发现,虽然该文件夹是以 System 权限创建,拥有者是 system,但由于使用了默认安全描述符,普通用户仍然可以对其进行修改。所以我们的竞争窗口 就是在 EnsureExists() 创建文件夹之后, NtSetSecurityObject() 修改安全描述符之前。
如何保证竞争时机?
James Forshaw 在15年提供了一组符号连接工具(https://github.com/googleprojectzero/symboliclink-testing-tools),其中的 SetOpLock 可用于下文件锁,当目标文件被执行文件流操作时,就会调用我们设定的锁回调函数。
经过测试,通过给 EnsureExists() 创建的 C://Config.msi 下文件锁,我们可以在其被执行 NtSetSecurityObject() 断下来,执行我们的回调函数。在回调函数里,我们可以通过CreateFile() 打开该目录文件对象的句柄,并在NtSetSecurityObject() 之后,通过 CreateMountPoint() 创建 C://Config.msi 的目录连接。一旦创建目录连接成功,我们就回到了 CVE-2018-0868 的利用思路上。仍然是移动装有真 rbs 脚本的目录,并在原位置创建一个同名目录(里面包含伪造的rbs脚本),以保证 C://Config.msi 目录连接 指向我们新创建的伪造目录。
这是一个正经的公众号;drop database;在这里,你可以看到最新的漏洞复现,最全的修复方案以及最特殊的利用技巧。
点击上方蓝字关注我们!
原文始发于微信公众号(肚子好饿啊早知道不做安全了):Windows Installer CVE-2018-8339 漏洞分析
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论