CVE-2019-13382:SnagIt本地提权漏洞分析

 

0x00 漏洞概要

每隔30-60秒,TechSmith Uploader Service(UploaderService.exe)就会检查C:\ProgramData\Techsmith\TechSmith Recorder\QueuedPresentations目录,查找其中是否存在*.xml格式的任何演示文件。如果找到匹配文件,该服务就会以SYSTEM权限将文件移动到C:\ProgramData\Techsmith\TechSmith Recorder\InvalidPresentations目录中。

由于低权限用户具备QueuedPresentations以及InvalidPresentations目录的完整控制权限,因此用户可以在QueuedPresentations目录中创建无效的演示文件,然后在InvalidPresentations目录中为该文件名设置一个符号链接,将其指向一个特权位置。

当该服务检查演示文件时,会将文件移出QueuedPresentations目录,并入InvalidPresentations目录中。执行该操作时,该服务会访问符号链接,将新的文件写入受保护的位置,这样低权限用户就能完全控制文件内容,将权限提升至NT AUTHORITY\SYSTEM

测试版本:Snagit 2019.1.2 Build 3596

测试系统:Windows 10 1803 x64

漏洞描述:SnagIt Relay Classic Recorder通过不安全文件移动操作导致存在本地提权(LPE)漏洞

 

0x01 漏洞分析及利用

在分析目标软件是否存在权限提升漏洞时,想寻找合适的切入点往往并不容易,因为其中涉及到大量源于以及漏洞类别。我通常会选择从基础点切入,然后逐步往复杂性方面发展。这个过程通常涉及到许多工具,比如PowerUp,该工具可以帮我们识别各种琐碎(但又常见)的错误配置情况。

如果没有找到有趣的信息,那么下一步通常是寻找逻辑漏洞,特别是能否滥用符号链接(symlink)/挂载点(mountpoint)/硬链接(hardlink)。为了快速识别能够利用的潜在链接类漏洞,我们需要准确找到OS上的某些位置,其中高权限进程(通常是SYSTEM权限)会与某个目录或者文件进行交互,而低权限用户具备该目录或者文件的完整控制权限。对于大多数逻辑漏洞而言,这个思路通常没问题,因为有趣的攻击路径通常与特权进程会使用低权限用户可控的资源密切相关。

在寻找这类漏洞时,我通常会使用Process Monitor,同时过滤SYSTEM进程以及通常容易被滥用的文件系统路径(比如C:\ProgramDataC:\Windows\Temp以及C:\Users\<username>\AppData)。过滤器规则如下图所示:

应用过滤器后,观察几分钟,我们可以看到UploaderService.exe会查询C:\ProgramData\Techsmith\TechSmith Recorder\QueuedPresentations目录,检查是否存在XML文件:

分析该目录的DACL,可以看到BUILTIN\Users具备写入权限:

这一点非常有趣,因为高权限SYSTEM进程(UploaderService.exe)正在查找该目录中的文件,而低权限用户却具备该目录的读写权限。了解这一点后,下一步就是为UploaderService.exe准备一个XML文件,看会出现什么情况。

与我们设想的一样,UploaderService.exe会检查C:\ProgramData\Techsmith\TechSmith Recorder\QueuedPresentations目录中是否存在XML文件,最终找到我们构造的文件:

下一个问题是,UploaderService.exe会如何处理我们的XML文件?该程序是否会读取文件内容,还是会执行其他操作?

继续观察Process Monitor的输出信息来解答我们这个问题。在测试环境中,UploaderService.exe会读取C:\ProgramData\Techsmith\TechSmith Recorder\QueuedPresentations中的XML文件,判断XML演示文件是否有效。由于我们只是在XML文件中echo了1这个字符,因此程序会判断1.xml不是有效的演示文件,并将其移动到C:\ProgramData\Techsmith\TechSmith Recorder\InvalidPresentations\1.xml

观察C:\ProgramData\Techsmith\TechSmith Recorder\InvalidPresentations目录,可以发现BUILTIN\Users同样具备读写权限:

此时,我们已经发现有个SYSTEM进程(UploaderService.exe)会在用户可控的目录中查找XML文件。发现目标文件后,该特权进程会将攻击者提供的XML文件从QueuedPresentations目录移动到InvalidPresentations目录中,同时保持原始的文件名。

为什么这个过程比较有趣?这意味着我们在文件移动操作中,有机会通过符号链接对特权文件执行写入操作。具体步骤如下:

  • 在创建C:\ProgramData\Techsmith\TechSmith Recorder\InvalidPresentations\1.xml上创建符号链接,指向C:\Windows\System32\ualapi.dll
    • 需要注意的是,C:\Windows\System32\ualapi.dll并不存在,这是我们准备以SYSTEM权限执行的一个DLL
    • 由于当前进程具备SYSTEM权限,因此能够对该文件执行写入操作
  • 构造一个C:\ProgramData\Techsmith\TechSmith Recorder\QueuedPresentations\1.xml文件
  • UploaderService.exe检查C:\ProgramData\Techsmith\TechSmith Recorder\QueuedPresentations目录中是否存在XML文件时,会发现1.xml并将其移动到C:\ProgramData\Techsmith\TechSmith Recorder\InvalidPresentations\1.xml。在执行该操作时,目标程序会使用我们构造的符号链接,因此实际上会将文件移动到C:\Windows\System32\ualapi.dll,同时保持原始的DACL信息。

从理论上讲,这个操作应该能够成功,我们可以来试一下。在符号链接方面,我使用了James ForshawSymbolic Link Testing Tools中提供的CreateSymlink.exe工具。我们需要做的就是在C:\ProgramData\Techsmith\TechSmith Recorder\InvalidPresentations\1.xml上设置符号链接,指向C:\Windows\System32\ualapi.dll,然后创建C:\ProgramData\Techsmith\TechSmith Recorder\QueuedPresentations\1.xml

创建符号链接以及XML文件后,我们可以等待60秒,等UploaderService.exe检查QueuedPresentations目录。当目标程序执行该操作时,会发现我们的1.xml文件,尝试将其移动到C:\ProgramDataTechSmithTechSmith RecorderInvalidPresentations1.xml,然而在该过程中,因为存在符号链接,程序实际上写入的是C:\Windows\System32\ualapi.dll

可以发现系统中的确出现了C:\Windows\System32\ualapi.dll

这一点的确很好,但正常情况下,新创建的ualapi.dll应该会直接继承父目录(C:\Windows\System32)的权限,阻止低权限用户执行写入操作。我一开始也是这么想的(在检查该文件的DACL信息前),然而UploaderService.exe使用的是MoveFileW()。根据官方文档,MoveFileW()在同一个卷上移动文件时,会保持原始的DACL。

虽然官方没有明确说明,但可以推测的是,如果文件没有跨卷移动,那么DACL就会保持不变。这意味着当UploaderService.exe访问到C:\ProgramData\TechSmith\TechSmith Recorder\InvalidPresentations\1.xml上的符号链接时,就会尝试将原始文件移动到C:\Windows\System32\ualapi.dll,同时保持与1.xml相同的DACL。由于该文件由低权限用户创建,因此根据DACL,低权限用户为文件所有者,具备FullControl权限:

此时,我们已经生成了C:\Windows\System32\ualapi.dll,并且低权限用户具备该文件写入权限。这意味着我们可以将新创建的ualapi.dll替换成我们自己选择的payload,这里我们选择让payload在加载时执行cmd.exe

现在payload的路径为C:\Windows\System32\ualapi.dll,当spooler服务启动时就会加载这个DLL。就PoC而言,剩下的只需要重启主机以便重启spooler服务即可。此外,我们还可以使用CollectorService,在不重启主机的情况下加载这个DLL。由于这只是一个PoC,剩下的工作就留给大家来完成。

主机重启后,spoolsv.exe会以SYSTEM权限从C:\Windows\System32\ualapi.dll加载我们的payload,帮助我们实现权限提升。

漏洞利用过程可参考此处视频

SnagIt在versions 2019.1.3、2018.2.4以及13.1.7中修复了这个漏洞,对应的编号为CVE-2019-13382。官方引入的补丁在移动文件时会调用_time64,同时也会检查重解析点(FSCTL_GET_REPARSE_POINT)。如果存在重解析点,则执行移除重解析点操作。

 

0x02 时间线

2019年6月19日:与Capital Group的安全测试团队共同确认漏洞
2019年6月20日:开始与Capital Group处理漏洞联合披露事宜。在支持案例中请求TechSmith安全团队提供联系信息
2019年6月21日:分配新的案例,表示可以上传漏洞详细信息,将其转发给安全团队
2019年6月21日:将完整报告、PoC代码和演示视频上传到支持案例
2019年6月25日:TechSmith证实该漏洞存在并提供了临时补救建议,要求在公开披露之前告知对方
2019年6月25日:告知TechSmith我们会在首次提交报告后的90天公开披露漏洞信息,如果需要可以考虑延期
2019年7月2日:TechSmith表示已完成修复版本,将在7月底之前部署,询问我们是否需要验证补丁
2019年7月2日:告知TechSmith我们需要验证补丁
2019年7月3日:TechSmith为我们提供修复版
2019年7月9日:测试SnagIt后,我们认为补丁可以缓解问题,并通知对方
2019年7月23日:官方发布补丁发布,漏洞报告案例公开披露

(完)