对滥用Windows特权文件操作的研究(上)
导语:本文介绍了如何滥用Windows上的特权进程执行文件,来实现本地权限升级(从用户升级到管理员/系统权限)。除此之外,还介绍了利用这类漏洞的可用技术、工具和具体过程。
本文介绍了如何滥用Windows上的特权进程执行文件,来实现本地权限升级(从用户升级到管理员/系统权限)。除此之外,我还介绍了利用这类漏洞的可用技术、工具和具体过程。
特权文件操作漏洞
以高权限运行的进程会对所有进程中执行的文件执行操作,这意味着,当高权限进程在没有足够预防措施的情况下,可以访问用户控制的所有文件或目录。因此,从理论上说,这就是一个安全漏洞,因为恶意攻击者有可能会滥用该特权进程执行的操作,使特权文件做一些不应该做的事情。对于许多特权访问用户控制的资源的情况都是如此,文件只是一个简单的目标。
在渗透测试中,大家熟知的示例包括用户可写的服务可执行文件和DLL劫持漏洞,如果你对特权服务将执行的文件具有写入权限,或者对它将在其中查找DLL的目录具有写入权限,那么你可以在这个特权进程中执行有效载荷。不过,以上举例的这个漏洞已经众所周知了,除了偶尔的配置漏洞发生之外,一般的防护软件都可以对它进行预防了。
然而,其他文件系统操作的潜在滥用似乎不那么为人所知了,但同样和以上所说的漏洞一样危险。如果你可以让一个特权进程为你创建、复制、移动或删除任意文件,那么使用system函数来调用shell脚本的漏洞就离你不远了。
此外,由于这些都是逻辑漏洞,它们通常非常稳定(不涉及内存损坏),通常能够在代码重构中存活(只要文件操作逻辑不变),并且无论处理器体系结构如何,它们都以完全相同的方式被滥用。对攻击者来说,这些功能非常有价值。
漏洞的寻找过程
用户可写的位置
虽然大多数特权程序不会直接操作一些非特权用户的文件(有些例外,如AV),但许多程序会对可能位于用户可以操作的某个位置的文件执行操作。非特权用户在以下一些位置,是具有某种形式的写入权限的:
1.用户自己的文件和目录,包括其AppData和Temp文件夹,如果你足够幸运或运行AV,某些特权进程可能会使用;
2.公众用户的文件和目录:idem;
3.在C:\中创建的目录具有默认ACL(访问控制列表):默认情况下,在分区根目录中创建的目录具有允许用户写入的许可ACL;
4.具有默认ACL的C:\ ProgramData子目录:默认情况下,用户可以创建文件和目录,但不能修改现有文件和目录,这通常是第一个看的位置;
5. C:\ Windows \ Temp的子目录:默认情况下,用户可以创建文件和目录,但不能修改现有文件和目录,也不能读取其他用户创建的文件/访问目录。有意查看安装程序和准时运行的其他特权软件和脚本,而不检查预先存在的文件和目录;
你可以使用特定的工具和命令(例如SysInternals的AccessChk,icacls或PowerShell的Get-Acl)检查文件权限,也就可以使用浏览器的“安全”选项卡来检查文件权限,“高级”表单具有“有效访问”选项卡,允许列出特定帐户或组对其的访问权限该文件/目录(如AccessChk在命令行上执行)。下面的屏幕截图显示了在C:\ProgramData目录上授予用户组的(默认)访问权限:
寻找特权文件操作
要查找特权进程执行的文件操作的示例,我们可以简单地使用SysInternals的ProcMon,Procmon是微软出品用于监视Windows系统里程序的运行情况,监视内容包括该程序对注册表的写入、对文件的写入、网络的连接、进程和线程的调用情况,procmon是一款超强的系统监视软件。Procmon为感兴趣的进程过滤文件事件,当我们看到它访问用户可控制的文件和目录时,就可以检查该进程是否使用模拟客户端来实现这一点。
漏洞利用技术与工具
一旦我们发现在用户/用户可控制的文件和目录上,可以执行对一些文件的操作,我们就需要一种方法来劫持这些操作,进而实施攻击。
值得庆幸的是,James Forshaw (@tiraniddo )通过他在NTFS文件系统和Windows内部的开创性工作完成了所有繁重工作,他在众多文章中发表了其中的技术细节。他提出了几种滥用Windows文件系统和路径解析功能的技术(以下我会详细介绍),并在开源的symboliclink-test -tools toolkit和NtApiDotNet库中实现了这些技术。他的技术和工具包为许多测试人员(包括我自己)打开了一扇寻找这种类型的漏洞的门,让这些漏洞的利用成为可能。
NTFS 交叉
交叉是一个NTFS功能,它允许将目录设置为文件系统的安装点(mount point),就像Unix中的安装点一样,但是也可以设置为解析到另一个目录(在同一个或另一个文件系统上)。在本文在,我们可以把它们看作是一种只包含目录的符号交叉。
有趣的是,在大多数情况下,路径解析将遵循 交叉规则(除非明确设置参数以防止这种情况),因此在上面的设置中,尝试打开C:\ Dir \ file.txt的程序实际上将打开C:\ Other \ file.txt。
连接可以由非特权用户创建,由于它们可以跨卷工作,因此你也可以将C:\Dir“重定向”到D:\OtherDir。如果你具有对现有目录的写入权,则可以将其转换为 交叉,但必须为空。
NTFS交叉是用重解析点(reparse points)实现的,虽然内置工具不允许这样做,但是可以通过设置自定义重解析点的实现将它们解析为任意路径。CreateMountPoint工具允许你完成重解析点实现,对于常规 交叉,你还可以将mklink和PowerShell的New-Item与-Type Junction参数一起使用。
NTFS重解析点(Reparse Points)
随Windows 2000发布的NTFS版本5里最有趣的一个属性是引入了一些特殊的文件系统功能,并应用于特定的文件或目录上。这些特殊功能使NTFS文件系统更加强大和有扩展性。这个特性的实现基础叫做重解析点(reparse points)。
重解析点的使用源于一些应用程序想把一些特殊数据存储到特殊的地方——重解析点,然后由应用程序做上特殊的标记,只允许它使用。为此文件系统引入了一个应用程序相关的特殊过滤器(application-specific filter),并与重解析点的标记关联起来。多个应用程序可以把不同的数据存储到同一个重解析点文件里,只要使用不同的标记。微软保留了几个标记为自己使用。
现在我们假设用户打算访问一个有标记的重解析点文件。当文件系统打开文件时,发现有重解析点关联到这个文件,于是“重解析”这个打开文件请求,发现与应用程序相关联的可用过滤器,并与这个重解析点进行匹配,通过后就可以把重解析点的数据传送给这个过滤器了。过滤器于是可以把这些数据用于任何途径,依赖于应用程序最初的定义。这是一个非常灵活的系统:应用程序不需关心重解析点是如何工作的,重解析点的实现细节对于用户是完全透明的。你只需简单的放入和拿出数据,其余的事情都是自动完成,这使文件系统的功能大大增强了。
微软使用重解析点在Windows 2000里实现了如下的功能:
1. 符号链接(Symbolic Links):符号链接允许你创建一个指向其他地方某个文件的指针。NTFS并没有像UNIX文件系统那样实现“真正”的文件符号链接,但是从功能上重解析点完全可以模拟得一模一样。本质上,NTFS的符号链接就是一个重解析点,把对一个文件的访问转移到另一个文件身上。
2. 交叉点(Junction Points):交叉点和符号链接类似,只不过对象是目录而不是文件。
3.卷装载点(Volume Mount Points):卷装载点和前2者类似,只是更进一层:它能创建对整个卷的链接。比如,你可以为可移动硬盘或其他存储介质创建卷装载点,或者让本地的不同分区(C:,D:,E:等等)看起来就像在一个卷里一样。这对于那些大型的CD-ROM服务器非常有用,如果没有卷装载点,它们就只能为每张磁盘人工维护一个分区字母。
4.远程存储服务器(RSS:Remote Storage Server):Windows 2000的这个特性能利用一些规则来移除NTFS卷上不常用的文件,放到存档介质里(比如CD-RW或磁带)。当它把文件移出到“下线”或“半下线”的存储介质上时,RSS自动创建指向这个存档文件的重解析点,以备日后使用。
硬链接 (hard link)
我们都知道文件都有文件名与数据,这在 Linux 上被分成两个部分:用户数据 (user data) 与元数据 (metadata)。用户数据,即文件数据块 (data block),数据块是记录文件真实内容的地方;而元数据则是文件的附加属性,如文件大小、创建时间、所有者等信息。在 Linux 中,元数据中的 inode 号(inode 是文件元数据的一部分但其并不包含文件名,inode 号即索引节点号)才是文件的唯一标识而非文件名。文件名仅是为了方便人们的记忆和使用,系统或程序通过 inode 号寻找正确的文件数据块。
为解决文件的共享使用,Linux 系统引入了两种链接:硬链接 (hard link) 与软链接(又称符号链接,即 soft link 或 symbolic link)。链接为 Linux 系统解决了文件的共享使用,还带来了隐藏文件路径、增加权限安全及节省存储等好处。若一个 inode 号对应多个文件名,则称这些文件为硬链接。换言之,硬链接就是同一个文件使用了多个别名(见 图 2.hard link 就是 file 的一个别名,他们有共同的 inode)。硬链接可由命令 link 或 ln 创建。如下是对文件 oldfile 创建硬链接。
由于硬链接是有着相同 inode 号仅文件名不同的文件,因此硬链接存在以下几点特性:
· 文件有相同的 inode 及 data block;
· 只能对已存在的文件进行创建;
· 不能交叉文件系统进行硬链接的创建;
· 不能对目录进行创建,只可对文件创建;
删除一个硬链接文件并不影响其他有相同 inode 号的文件。
所以,非特权用户还可以创建硬链接,与Unix对应的硬链接一样,将作为现有文件的附加路径。它不能在目录上工作,也不能跨卷工作(对于硬链接来说没有意义)。
此外,内置工具不允许你创建到没有写入权限的文件的硬链接,但是实际的系统调用允许你使用打开供读取的文件来创建硬链接。使用symboliclink-test -tools中的CreateHardLink工具(或Ruben Boonen编写的这个PowerShell脚本)创建指向你没有写入权限的文件的硬链接。
注意,如果没有对文件的写入权限,就不能删除创建的链接。另外,这项技术在即将发布的Windows 10中得到了缓解。
本文我们对特权文件操作的原理和可能发生漏洞的地方,进行了理论上的分析。下文我们接着将对象管理器(ObjectManager)符号链接以及漏洞利用的示例和思路。
发表评论