编写Windows文件系统驱动程序很难
@jonasLyk的一条推文让我想起了几个月前在NTFS中发现的一个漏洞,我已经验证该漏洞在Windows 10 2004中仍然存在。虽然这个漏洞不能直接用于绕过安全机制,但它可能被用作攻击链的一部分。NTFS很好地展示了在Windows上编写文件系统驱动程序的复杂性,因此随着时间的推移出现这么多奇怪的边缘情况也就不足为奇了。
这个问题涉及创建新目录时的默认安全描述符(SD)分配。如果你了解Windows安全描述符,就会知道可以通过CONTAINER_INHERIT_ACE
和/或OBJECT_INHERIT_ACE
ACE标志来指定继承规则。这些标志表示当新条目是目录或文件时,ACE是否应该从父目录继承。让我们看看NTFS用于为新文件分配安全性的代码,看看你能否发现这个bug?
代码使用SeAssignSecurityEx
基于父SD和调用者的任何显式SD来创建新SD。为了使继承工作,你不能指定显式SD,所以我们可以忽略这一点。SeAssignSecurityEx
是否应用目录或文件的继承规则取决于IsDirectoryObject参数的值。如果向NtCreateFile传递了FILE_DIRECTORY_FILE选项标志,则此参数设置为TRUE。这看起来没问题,如果你不指定FILE_DIRECTORY_FILE标志,就无法创建目录;如果不指定标志,默认情况下将创建文件。
但等等,这根本不正确。如果你指定名称格式为ABC::$INDEX_ALLOCATION,那么无论你指定什么标志,NTFS都会创建一个目录。因此,这个bug是:如果你使用$INDEX_ALLOCATION技巧创建目录,那么新的SD将像文件而不是目录一样继承。我们可以在命令提示符下验证这种行为。
|
|
首先我们创建目录ABC并授予两个ACE:一个用于INTERACTIVE组将在目录上继承,另一个用于NETWORK将在文件上继承。
|
|
然后我们使用$INDEX_ALLOCATION技巧创建子目录XYZ。我们可以确定它起作用了,因为当CMD尝试将"Hello"写入目录对象时,它会打印"Incorrect function"。
|
|
转储XYZ子目录的SD,我们看到ACE是基于它作为文件而不是目录继承的,因为我们可以看到NETWORK的ACE而不是INTERACTIVE的ACE。最后我们列出ABC以确认它确实是一个目录。
|
|
这有用吗?老实说可能没有。我能想象的唯一场景是,如果你可以向系统服务指定一个路径,该服务在继承文件访问会授予权限而继承目录访问不会的位置创建文件。这将允许你创建一个可以控制的目录,但老实说这似乎有点牵强。如果有人能想到这个的好用途,请让我或Microsoft知道 :-)
尽管如此,有趣的是这是另一个$INDEX_ALLOCATION在确定对象是目录还是文件时未正确验证的情况。另一个很好的例子是CVE-2018-1036,你只能使用FILE_ADD_FILE权限创建新目录。为什么在使用流类型时自动创建目录的设计决策尚不清楚。我想我们可能永远不会知道。