oplock对于利用TOCTOU的bug是很有用的,因为你可以通过锁定一个试图打开的文件或目录来轻松地赢得与进程的竞争。当然,它也有一些限制:你不能细粒度地 “放行 “一个访问(一旦锁被解除,所有待定的访问都会发生),而且它并不适用于所有类型的访问,但它通常非常有效。
SetOpLock工具可以让你创建这些锁,并阻止对文件或目录的访问,直到你按回车键释放锁。它让你在读、写和放行oplock之间进行选择。
同样,James将这一技术与之前的技术相结合,创造了一个强大的primitive,实现一些TOCTOU bug的利用:通过设置一个伪symlink(和之前一样),并在最终文件(symlink的目标)上放置一个oplock,我们可以在打开目标文件时改变symlink(即使目标文件被锁定,symlink也没有被锁定),并使其指向另一个目标文件。
在上述设置中,第一次访问文件C:\Dir/file.txt将打开C:\One/\foo.xxx,第二次访问将打开C:\Two/\bar.yyy。
BaitAndSwitch工具用独占的oplocks实现了这种技术,如果你需要读写锁,可以使用SetOpLock和CreateSymlink。
Exploitation strategies 一个典型的例子让我们考虑一下产品X的以下行为。
在C:\ProgramData\Product\Logs(具有默认/继承访问权的目录)中创建日志文件。
日志文件由特权(系统)和非特权(用户)进程创建/写入。
创建日志文件的过程设置了一个明确的ACL,这样每个用户都可以写入文件。
这就导致了可以被利用来创建具有任意内容任意文件的一个漏洞。
如果我们删除现有的日志文件,并将日志目录变成与C:\Windows\System32的连接点(由于继承了C:\ProgramData的访问权限),产品X的特权进程将在System32目录下创建日志。
我们也可以使用symlink技术转移一个特定的日志文件(如some.log),以攻击者选择的名称创建一个任意文件,如程序目录中的DLL。
因为特权进程也对日志文件设置了允许写入的ACL,所以我们也可以根据自己的喜好更改文件的内容。
这是一个在很多产品上都发现过的bug,大概是因为它是一个共同需求的简单实现(日志文件可被所有组件—用户和系统组件写入,所有组件的通用日志代码)。在过去一年多的时间里,我们看到了好几个这样的例子。
从任意文件写入到权限升级。在特权进程的上下文中,通过任意写入文件来获得代码执行的两种常用技术是:
至少有两种不太知名的技术。
控制内容这些技术需要对创建的文件内容进行控制:如果你可以劫持创建一个文件到任意位置,但无法控制该文件中的内容,那么它的作用就非常有限。在我们的例子bug中,我们有一个很好的ACL,由特权程序对生成的文件进行设置,但如果我们没有这个奢侈条件呢?
我们可以尝试针对其他操作。在我们的日志记录例子中,假设日志记录功能在日志达到一定大小的时候对文件进行移动,一个特权进程可能会移动或重命名日志文件(例如从abc.log到abc.old.log)。那么我们就可以利用符号链接来滥用这个操作。
在重命名/移动操作中,用指向我们的有效载荷(sh.dll)的伪链接替换源文件。
将目标文件替换为我们要创建或替换的文件的伪链接(这里是target.dll)
所以,当重命名操作发生时的布局是这样的。