对滥用Windows特权文件操作的研究(下)
导语:上文我们对特权文件操作的原理和可能发生漏洞的地方,进行了理论上的分析。本文我们接着将对象管理器(ObjectManager)符号链接以及漏洞利用的示例和思路。
上文我们对特权文件操作的原理和可能发生漏洞的地方,进行了理论上的分析。本文我们接着将对象管理器(ObjectManager)符号链接以及漏洞利用的示例和思路。
对象管理器(ObjectManager)符号链接
对象管理器是一个执行体的子系统,所有其他的执行体子系统,特别是系统调用必须通过它来获得对WindowsNT资源的访问,这使得对象管理器成为资源管理的基础设施。对象管理器用来避免在其他子系统中管理资源带来的冗余与不安全。在对象管理器视角,每个资源都是一个对象,不论是物理资源(如文件系统或外设),还是逻辑资源(如一个互斥锁)。
虽然NTFS确实提供了文件系统符号链接,但是在Windows上,没有特权的用户不能在文件系统上创建符号链接。因为,它需要SeCreateSymbolicLinkPrivilege (创建符号链接权限),默认情况下只向管理员授予权限。
然而,无此特权的用户可以在Windows的对象管理器中创建符号链接,顾名思义,它可以管理诸如进程,部分和文件之类的对象。对象管理器使用符号链接,例如用于与相应设备相关联的驱动器字母和命名管道。用户可以在诸如\RPC CONTROL\之类的可写对象目录中创建对象符号链接,这些符号链接可以指向任意路径(包括文件系统上的路径),不管该路径当前是否存在。
当对象符号链接与NTFS交叉结合使用时,对象符号链接特别有趣。实际上,作为一个非特权用户,我们可以用对象管理器符号链接将一个安装点链接到\RPC Control\目录。
这给了我们一些行为有点像文件系统符号链接的东西,在上图中,C:\Dir\file.txt可以被解析为C:\Other\stuff.any。它们当然不是完全等同的,但在很多情况下,这足以滥用程序。
你可以使用CreateMountPoint和CreateDosDeviceSymlink分别执行这些步骤,但是CreateSymlink工具只会在一个方便的命令中实现了这项技术。
机会锁(opportunistic locks)
CIFS(通用Internet文件系统)中引入了一叫做opportunistic locks的锁,简称oplocks。 客户端可以锁定一个文件,但是这个锁可以随时被服务器撤消,oplocks的目的是让客户端上的文件缓存更加安全。
简而言之,机会锁就是是一个可以放在文件上的锁,当其他进程想要访问该文件时,它可以得到通知,同时延迟这些进程的访问,以便锁定进程可以在解除锁之前让文件处于适当的状态。最初设计的目的是让用户通过SMB缓存客户端-服务器文件访问,进而通过调用文件句柄上的特定控制代码在本地放置机会锁。
这对于利用TOCTOU漏洞非常有用,因为你可以通过锁定进程试图打开的文件或目录轻松赢得与进程的竞争。当然,它也有一些限制,比如你不能只允许一个访问(所有等待中的访问将在锁被解除后同时发生),并且它不适用于所有类型的访问。TOCTOU是time-of-check-to-time-of-use的缩写; TOCTTOU可发音为TOCK too。TOCTOU是指计算机系统的资料与权限等状态的检查与使用之间,因为某特定状态在这段时间已改变所产生的软件漏洞。
SetOpLock工具允许你创建这些锁,如果用命令“SET OPLOCK”锁定了一个本地用户,则所有的本地用户都会被锁定,并阻止对文件或目录的访问,直到你按Enter键释放锁为止。
James再次将这种技术与之前的技术相结合,创建了一个强大的原语,可以缓解对某些TOCTOU漏洞的利用:通过设置伪符号链接(如前所述),并在最终文件(符号链接的目标)上放置一个机会锁,我们可以在打开目标文件时更改符号链接(即使目标文件被锁定,符号链接也没有),让它指向另一个目标文件。
在上面显示的设置中,对文件C:\Dir\file.txt的第一次访问将打开C:\One\foo.xxx,第二次访问将打开C:\Two\bar.yyy。
BaitAndSwitch工具使用独占的机会锁实现此技术,如果你需要读取或写入锁,则可以使用SetOpLock和CreateSymlink。
以产品X为例,具体说明一下漏洞的利用
产品X具有以下行为:
1.在C:\ProgramData\Product\Logs(具有默认/继承访问权限的目录)中创建日志文件;
2.日志文件由特权(系统)和非特权(用户)进程创建/写入;
3.创建日志文件的过程设置了一个明显的ACL,这样每个人都可以写入文件;
这些行为足以导致了一个漏洞,黑客们可以利用这个漏洞创建包含任意内容的任意文件。
如果我们删除现有的日志文件, 并将日志目录转换为与C:\Windows\System32进行交叉,则产品X的特权的过程将创建System32系统的日志目录(多亏了从C:\ProgramData继承的访问权限)。
我们也可以使用符号链接技术来劫持一个特定的日志文件(如some.log),以创建一个具有攻击者选择的名称的任意文件,例如,程序目录中的DLL。
因为特权进程还在日志文件上设置了一个许可的ACL,所以我们还可以根据自己的喜好更改文件的内容。
以下是在几个产品上发现的同一个漏洞,可能是因为它是一个普通需求的简单实现(所有组件都可以写的日志文件——用户和系统组件,所有组件的公共日志代码)。在过去的一年里,我们看到了该漏洞存在于以下几个产品中:
· 在Rylance Hanson发现的Cylance产品中;
· 在Ben Turner发现的Symantec / Altiris代理中
· 在McAfee Endpoint Security中(已修补)
· 在Mark Barnes发现的NVIDIA GeForce Experience和Intel Driver&Support Assistant中
· 在Pulse Secure VPN客户端(未打补丁)中;
在具有任意文件写入特权的进程上下文中获取代码执行
在具有任意文件写入特权的进程上下文中获取代码执行的两种常用技术是:
1.DLL劫持:在特权进程将加载DLL的位置(在应用程序的目录、System32、Windows或系统的%PATH%上的其他目录中)创建DLL。它需要一种方法(重新)启动特权进程来加载有效载荷,,以及DLL将在被劫持之前加载的位置。
2.覆盖:替换将让我们代码执行的现有二进制/脚本/配置文件/等,除了要求(重新)启动进程外,它还需要文件写入操作以允许覆盖现有文件(另外目标文件不应被锁定),并且通常只特定于给定的服务/应用程序。
至少有两种鲜为人知的技术:
1. 使用C:\Windows\System32\ Wow64Log.dll在特权32位进程中加载64位DLL。默认情况下,此DLL不存在(至少在消费者版本上),并且在所有32位进程中被加载。但是,DLL不能一直使用来自Kernel32的导入,因此它必须只使用NTDLL API,当然,这只有在你有一个有趣的(特权的)32位进程注入时才有效,这个技巧是由George Nicolaou发现的。
2.使用“诊断中心标准收集器服务(Diagnostics Hub Standard Collector Service)”:这项技术是由James Forshaw发现的,他在这篇博客文章中详细解释了这项技术,并发表了一个利用该漏洞的示例。简而言之,该技术可以让DiagHub服务(作为系统运行)以DLL的形式加载System32中的任何扩展名的文件。因此,如果你可以在System32中创建一个带有有效载荷的test.log文件(当然,文件的内容必须是一个可用的DLL),只需使用此技术将该DLL加载到特权服务中。然而,这项技术会在即将发布的Windows 10中被限制。
控制内容
以上这些技术需要对创建的文件的内容进行控制,因为如果你可以将文件的创建劫持到任意位置,但是无法控制文件中的内容,那么它的攻击性则非常有限。在本文的漏洞示例中,我们有一个由特权程序在生成的文件上设置的很好的ACL,但是如果没有这条件怎么办?
我们可以尝试针对其他操作,在本文的日志示例中,假设日志功能在日志达到特定大小时轮换日志,则特权进程可能会移动或重命名日志文件(例如,从abc.log改变为abc.old.log)。然后我们可以使用符号链接滥用此操作:
1.通过经过伪造的符号链接将重命名/移动操作中的源文件替换为我们的有效载荷(sh.dll);
2.通过经过伪造的符号链接将目标文件替换为我们要创建或替换的文件(本文用的是target.dll);
因此,重命名操作发生时的布局如下所示:
当特权进程试图将abc.log移动或重命名为abc.old.log时,它实际上会将用户拥有的文件sh.dll移动或重命名为target.dll,以将我们的有效载荷放在要执行的正确位置。
因此,我们可以控制的特权文件移动/重命名/复制操作都是非常有趣的原语:
1.受控移动或重命名为我们提供任意文件写入;
2.完全受控(源和目标)副本也是如此;
3.在复制操作中,我们控制源文件,但不控制目标文件,这样就可以读取任意的文件(如果目标位置是用户可读的);
4.一个我们控制源文件而不是目标文件的移动/重命名操作,该操作可以让我们删除任意一个文件;
注意:
1.覆盖目标的能力取决于执行操作的进程所使用的选项;
2.如果目标文件已经存在,我们还可以使用硬链接代替伪符号链接;
3.滥用任意文件读取的常见方法是获取SAM,SECURITY和SYSTEM配置单元以转储SAM数据库和缓存凭据;
利用权限升级删除任意文件
以上我们讨论了利用权限升级可以写入任意文件,那么可以删除任意文件吗?除了具有明显的DoS潜力外,我们有时可以滥用EoP的任意文件删除漏洞删除以下文件来:
1.是否位于可以写入的位置,即使不能覆盖现有的位置,比如C:\ProgramData;
2.稍后将用于特权进程的读取或写入操作(无论是我们用于删除的相同进程还是不同的进程);
例如,如果我们知道如何触发从C:\ ProgramData \ Product \ foo到C:\ ProgramData \ Product \ bar的移动/重命名,但这些文件已经存在且我们没有写入权限,那么我们就可以使用任意文件删除漏洞来删除foo和bar,并自己重新创建它们。我们可以使用以前的技术来滥用写入操作(如果产品目录现在是空的,则使用伪符号链接,否则使用硬链接)并完成链接。
利用滥用 Windows 特权文件操作的漏洞来绕过杀毒软件的检测
绕过杀毒软件的检测是这类漏洞的主要目标,因为具有高度特权的软件是不受这类漏洞限制的。它们一旦躲开追踪,就可以操纵一切文件了,包括用户拥有的文件。执行扫描、删除和恢复的特权进程有时会欺骗我们执行有趣的文件操作,从而将防御组件变成摆设。
利用杀毒软件的隔离和恢复功能
隔离和恢复功能特别有趣,尤其是当它们可以由非特权用户触发时(有时不在UI中,但可以通过COM劫持访问),触发隔离(或删除)的最简单方法当然是将已知的检测到的文件(如EICAR)放入文件系统中。
有趣的是,有些杀毒软件会在删除检测到的文件前执行特权操作,例如:
1.在同一目录中创建/删除临时文件;
2.将受感染的文件复制或移动到用户可写的位置;
3.将受感染的文件复制或移动到用户可读的隔离位置(如果你利用此文件,请注意不要破坏SAM文件);
临时和隔离文件有时会进行编码或填充,如果你想查看算法(读取结果文件),那么在启动IDA/Ghidra之前最好检查Hexacorn的DeXRAY。
如果非特权用户可以触发恢复过程,则恢复过程是另一个示例或特权文件写漏洞。要控制内容,要么在删除或恢复期间查找潜在的TOCTOU,要么将载荷设置为“恶意”,以便首先对其进行隔离。
移动文件删除/隔离
如果杀毒软件在检测和删除/隔离(TOCTOU)期间没有锁定(或以其他方式阻止访问)被检测到的文件,则我们可以使用一个有趣的交叉技巧来替换它的父目录(检测之后,删除之前)。如果我们想要删除一些一些我们无权访问的文件(例如,C:\ Windows \ System32 \ license.rtf),我们可以这样做:
1.在我们创建的目录中删除EICAR(或任何可检测文件),其名称与目标文件相同,例如C:\Temp\Test\ lic.rtf;
2.等待杀毒软件检测到它;
3.删除或重命名父目录C:\Temp\Test;
4.用交叉把它换成C:\Windows\System32;
5.杀毒软件删除已经被解析成C:\Windows\System32\licence.rtf的C:\Temp\Test\licence.rtf;
正确的方法是使用机会锁,但是在实践中并不总是那么容易实现,因为文件在被删除之前可以被访问很多次。一种快速且简单的方法是简单地在目录旁边创建交叉,并进行一个循环,不断地交换这两个目录。根据杀毒软件检索删除路径和删除文件的方式,我们可能有一个删除该交叉的机会。目前,该方法已经在几款杀毒软件产品上起了作用。
滥用Windows特权文件操作的漏洞已经被发现
去年年初,在常见的软件产品中发现了以下这样的漏洞,目前它们硬件被报告给各自的供应商,其中一些供应商已经发布了补丁。下表总结了我们发现的漏洞及其当前的状态。
注意:缺少的产品名称和额外的细节将在修复时发布,这样做是为了避免漏洞发生野外利用。
目前,以下3个漏洞的详细信息已经被公开了:
发表评论