OBJ_DONT_REPARSE is (mostly) Useless.
延续上一篇博客的主题,我认为将两个额外的OBJECT_ATTRIBUTE标志记录为缓解符号链接攻击的方法是很棒的。虽然OBJ_IGNORE_IMPERSONATED_DEVICEMAP非常有用,但另一个标志OBJ_DONT_REPARSE却不是,至少在保护文件系统访问方面不是。
引用文档,OBJ_DONT_REPARSE执行以下操作:
“如果设置此标志,在解析关联对象的名称时不会跟随任何重解析点。如果遇到任何重解析,尝试将失败并返回STATUS_REPARSE_POINT_ENCOUNTERED结果。这可用于确定对象的路径中是否有任何重解析点,在安全场景中。”
这看起来非常明确,如果遇到任何重解析点,名称解析就会停止并返回STATUS_REPARSE_POINT_ENCOUNTERED。让我们在PS中尝试打开notepad可执行文件。
PS> Get-NtFile ??\c:\windows\notepad.exe -ObjectAttributes DontReparse Get-NtFile : (0xC000050B) - 对象管理器在检索对象时遇到了重解析点。
这并不符合你的预期,访问notepad应该没有重解析点,那么出了什么问题?你假设文档指的是NTFS重解析点,而它实际上指的是所有重解析点。C:驱动器符号链接仍然是一个重解析点,只是针对对象管理器。因此,仅使用此对象属性标志访问驱动器路径就会失败。不过,这确实意味着它也可以保护你免受注册表符号链接的攻击,因为那也使用重解析点。
我假设这个标志根本不是为文件访问引入的,而是为命名内核对象引入的,在这些对象中遇到符号链接通常问题不大。与OBJ_IGNORE_IMPERSONATED_DEVICEMAP不同,我无法 pinpoint 这个标志关联的具体漏洞,所以我不能确定它被引入的原因。尽管如此,这有点烦人,特别是考虑到有一个IO管理器特定的标志IO_STOP_ON_SYMLINK,它可以做你想要的事情来避免文件系统符号链接,但只能在内核模式下通过IoCreateFileEx访问。
并不是说这个标志完全防止了对象管理器重定向攻击。例如,它不能防止滥用影子目录,这些目录可用于重定向路径查找。
PS> $d = Get-NtDirectory \Device PS> $x = New-NtDirectory \BaseNamedObjects\ABC -ShadowDirectory $d PS> $f = Get-NtFile \BaseNamedObjects\ABC\HarddiskVolume3\windows\notepad.exe -ObjectAttributes DontReparse PS> $f.FullPath \Device\HarddiskVolume3\Windows\notepad.exe
好吧…