-
-
[翻译]Windows授权指南
-
发表于: 2023-9-24 15:27 5878
-
原文标题:A Windows Authorization Guide
原文链接:https://csandker.io/2018/06/14/AWindowsAuthorizationGuide.html
与Linux相比,Windows的授权过程相当复杂,并涉及许多参与者和对象。因此,有许多术语和缩写需要了解,才能理解和跟进该主题。为了对本指南涵盖的内容有一个概念,可以查看以下术语和缩写的概述:
面对这些缩略词的困扰,我认为最好的方法是直接深入其中,并交叉参考所有新术语。对于以下所有内容(以及一般情况),请注意有一个Windows安全术语表,您可以用来查找以下使用的任何缩略词或术语。
基本访问检查
从最简单的情景开始:您登录到Windows系统并想要打开一个文件。是谁决定您是否有权限访问以及如何做出这个决定呢?
作为参考,我们来回顾一下在Unix系统上如何做出这个决定。在Unix系统上,您的用户具有用户ID和组ID,而访问目标(在这种情况下就是文件)具有相关的访问权限列表,可能是这样的:
1 | - rwxr - xr - - 1 root root 2048 Jun 13 10 : 00 file .txt |
与Unix操作系统不同,Windows操作系统的授权决策过程相对复杂。许多参与者和对象涉及其中。以下是关于Windows授权过程的介绍:
简单来说,当用户登录到Windows计算机(无论是本地用户还是域用户)时,将为该用户创建一个访问令牌(Access Token)。准确地说,这个访问令牌是为用户的登录线程创建的。
当已登录用户尝试打开一个文件时,会生成一个访问请求,指定用户希望对该文件执行的操作(访问权限)。在我们的情况下,用户只想读取文件,这对应于GENERIC_READ访问权限。有一组不同的访问权限,它们实际上只是表示为位掩码的数字,用作全局参考,以清楚地定义用户请求执行的操作。最重要的访问权限是通用访问权限(Generic Access Rights)和标准访问权限(Standard Access Rights)。
用户的访问请求由名为安全参考监视器(Security Reference Monitor,SRM)的Windows组件处理。安全参考监视器接收请求的访问权限以及用户的访问令牌,并将这些信息与所请求文件的定义访问权限进行比较,这些权限组合在一个称为安全描述符(Security Descriptor)的结构中。
需要注意的是,每个安全对象(包括文件、目录、注册表键和其他许多内容)都有一个安全描述符。安全描述符定义了为对象分配的访问权限和其他安全属性。
让我们将其分解为关键要点:
每个用户登录线程都有一个访问令牌。
(理解为:每个用户都被分配了一个访问令牌)执行所需的操作(例如打开文件)通过访问权限来表示,例如GENERIC_READ。
每个安全对象都有一个安全描述符,该描述符定义了谁可以在该对象上执行什么操作。
**安全参考监视器(SRM)**是负责评估是否应该授予某个进程对所请求的对象的所请求访问权限的软件组件。
在SRM中,授予或拒绝访问的关键函数称为SEAcessCheck。
如果你喜欢对事物进行可视化表示,可以参考以下图片,以了解刚刚介绍的内容:
(这张图片是基于James Forshaw在他2015年的BlackHat演讲中使用的图)
现在,已经介绍了Windows世界中访问检查的基本概念,让我们更深入地了解各个组件。
安全描述符、DACL和SACL
本节将详细介绍上图中显示的所有者检查和DACL检查。
如前所述,每个安全对象都有一个安全描述符。
安全描述符定义了一个对象结构,用于记录引用对象所属的所有者和组,以及为哪些操作授予(或拒绝)访问权限。
为了了解其外观,下面的屏幕截图显示了正在运行的explorer.exe进程的安全描述符(作为内核对象):
在这里,最基本的部分是所有者和组字段,它们由安全标识符(SID)表示。在Windows世界中,SID只是用于标识安全主体(例如用户、组等)的唯一字符串。SID由三个块组成:
- 第一部分 - 总是以"S"开头 - 描述了组,例如域Everyone(S-1-1-0)、Anonymous(S-1-5-7)、Authenticated Users(S-1-5-11),可以在注册表中查找已知SID。
- 第二部分是唯一的域ID(也存在于每个默认的工作组)(S-1-5-21),例如S-1-5-21-2884053423-3431565070-78458365-…。
- 最后一部分被称为相对ID(RID),它描述了安全组内的用户组,例如内置的管理员组(S-1-5-32-544)或内置的Guests组(S-1-5-32-546)或者著名的默认Admin帐户(我通常将其称为RID-500 Admin)(S-1-5-21-2884053423-3431565070-78458365-500)。请注意,前两个组位于同一个安全组(S-1-5-32-…),而RID-500管理员位于域安全组中。
现在回到上面的示例:所有者设置为SID S-1-5-21-…..-1001,这是我当前用户的唯一值,组设置为SID S-1-5-21-…-513,这是域用户组的SID。
您可以在注册表中查找这些SID以获取已知SID的信息。
除了explorer.exe进程的所有者和组之外,上述显示的安全描述符还包含两个列表,即自主访问控制列表(DACL)和系统访问控制列表(SACL):
DACL是由安全描述符的所有者控制的列表,指定特定用户或组对对象的访问权限。
SACL是由系统管理员控制的列表,其中包含两种类型的控制项:
- SACL保存了MANDATORY_INTEGRITY_LABEL(稍后详细介绍);
- SACL保存用于生成审计消息的控制项(我们现在忽略这部分)。
对于SACL,只需记住MANDATORY_INTEGRITY_LABEL存储在其中(我们暂时忽略其他部分)即可。
DACL是用于授权过程的重要控制列表。请查看上面的屏幕截图,可以看到所呈现的DACL实际上包含三个访问控制项(ACEs)。对于这三个ACEs,设置了以下重要字段:
- SID:SID定义了ACE适用的安全主体(用户或组)。
S-1-5-21-…..-1001引用了一个特定的域用户。
S-1-5-18引用本地系统帐户。 - Mask:访问掩码是一个数字值,类似于多个访问权限(例如GENERIC_READ)的组合(加法)。访问掩码是在Microsoft Docs中描述的数据结构。
文档 - AceType:AceType定义了对于给定的安全主体(SID)和给定的访问掩码,是否应该允许或拒绝访问。
在上面的示例中,给出了三个AceType为ACCESS_ALLOWED_ACE_TYPE的ACEs,这意味着如果安全参考监视器(SCM)在任何这些ACEs中找到与请求用户的匹配访问掩码,将授予访问权限。
在这部分中,重要的要点是:
安全参考监视器(SCM)将检查所请求对象的安全描述符,并遍历安全描述符的DACL中的每个ACE,检查请求用户(通过其SID和请求的访问权限,例如GENERIC_READ)是否与ACE中的访问掩码匹配。如果找到匹配项,则该ACE的AceType将决定是否授予或拒绝访问权限。
关于空DACL的注意事项:
如果安全描述符的DACL设置为NULL
,即安全描述符没有DACL,则向每个人授予完全访问权限。
如果安全描述符的DACL为empty
(即存在DACL,但不包含任何ACE),则不授予对该对象的访问权限。
还缺少的最后一部分信息是请求用户的身份。安全参考监视器从给定的用户访问令牌中获取请求用户的身份。关于该令牌的详细信息将在后面给出,现在只需知道该令牌包含请求用户的SID以及用户组的SID即可。
好的,现在让我们将SeAccessCheck的完整流程放入整体图像中:
在完整性级别检查(IL-Check)之后(将在以下部分中描述),安全参考监视器(SRM)查询所请求对象的安全描述符以获取以下信息:
- 谁是所请求对象的所有者?
→ 如果请求用户是所请求对象的所有者:授予访问权限 - 如果请求用户不是所有者,则遍历安全描述符的DACL中的所有ACE,并确定:
- ACE是否适用于请求用户,通过比较ACE的SID与用户的SID和用户的组SID?
- 访问掩码是否包含请求的访问权限,例如访问掩码是否包含GENERIC_READ访问权限?
- 访问类型是设置为允许访问还是设置为拒绝访问?
- 如果有任何ACCESS_DENIED_ACE_TYPE与用户和请求的访问权限匹配:
拒绝访问
- 如果没有ACCESS_DENIED_ACE_TYPE,但有一个ACCESS_ALLOWED_ACE_TYPE与用户和请求的访问权限匹配:
授予访问权限
除了所有者和DACL检查之外,还有一个要理解SeAccessCheck的要素缺失,那就是完整性级别检查(IL-Check)。让我们深入了解一下。
完整性级别检查/强制完整性控制(MIC)
本节将阐明上图中显示的完整性级别检查。
完整性级别检查旨在执行另一个Windows控制层,称为强制完整性控制(MIC)。
强制完整性控制(Mandatory Integrity Control,MIC)提供了一种控制对可安全对象的访问的机制。这种机制是在自主访问控制之外的一种机制,并在对对象的自主访问控制列表(DACL)进行访问检查之前进行评估。
来源:强制完整性控制(Mandatory Integrity Control)
现在你脑海中应该出现的第一个问题是:为什么我们需要MIC?我们有DACL检查,这基本上是在Unix系统中进行的相同检查——这不应该足够吗?
对这个问题的答案是:是的,DACL检查是授权检查的核心,绝大多数访问请求将根据DACL检查来授予或拒绝。MIC只是微软在Windows Vista中添加的另一层,与用户访问控制(UAC)一起使用,以获得更精细的控制,并防止受损的进程访问敏感资源。
这是对一个简单问题的非常抽象的答案,但下面对MIC和UAC的介绍将希望能更多地解释这个问题。
每个安全对象都在其SACL中设置了一个MANDATORY_INTEGRITY_LABEL。这个标签将四个可能的完整性级别(IL)之一分配给对象(如Windows完整性机制设计中定义的):
- 低(SECURITY_MANDATORY_LOW_RID 0x00001000)
- 中等(SECURITY_MANDATORY_MEDIUM_RID 0x00002000)
- 高(SECURITY_MANDATORY_HIGH_RID 0X00003000)
- 系统(SECURITY_MANDATORY_SYSTEM_RID 0x00004000)
这些完整性级别标记了分配给安全对象的“安全保护”程度。
“默认情况下,所有对象都被分配了中等完整性标签。”
作为例子,回顾一下之前的安全描述符的屏幕截图,注意到这个对象(explorer.exe进程)的安全描述符具有以下MANDATORY_INTEGRITY_LABEL:SID:S-1-16-8192
快速查阅“熟知的SID注册表”可以得知,这个SID描述了“中等强制级别”(对所有对象来说是默认的)。
»要点«:
完整性标签的整个目的是防止较低级别的完整性进程访问较高级别的完整性对象。
另一个例子:启动Internet Explorer时,会生成一个低完整性级别的IE进程(参见下面的屏幕截图)。这个低级别的IE进程是用户用于浏览互联网的进程。
如果这个进程受到攻击,例如利用IE/Flash等漏洞,该进程将无法访问用户的文档,因为这些文档是用默认的中等完整性级别标签创建的(而IE进程正在以低完整性运行)。
这是完整性级别检查开始有意义的时候。想象一下没有强制完整性控制(MIC)的情况下被入侵的IE。IE进程是由已登录用户启动的,因此属于已登录用户拥有。DACL检查将允许被入侵的IE进程访问用户的资源。
通过执行完整性级别检查,被入侵的IE进程将被拒绝访问用户资源。
那么我是不是在说,当具有较低完整性级别的进程尝试访问具有较高完整性级别的资源时,访问通常会被拒绝?当然不是,为什么会那么简单呢...
在完整性级别检查过程中,SRM将请求进程的完整性级别与请求的对象的完整性级别进行比较,并根据为该对象定义的完整性级别策略决定是否进行DACL检查或拒绝访问。
对象的完整性级别策略基于以下三个定义的状态(如SYSTEM_MANDATORY_LABEL_ACE Structure中定义):
- SYSTEM_MANDATORY_LABEL_NO_WRITE_UP(0x1)
- SYSTEM_MANDATORY_LABEL_NO_READ_UP(0x2)
- SYSTEM_MANDATORY_LABEL_NO_EXECUTE_UP(0x4)
再次参考前一节中给出的运行中的explorer.exe的安全描述符。注意到SACL ACE SYSTEM_MANDATORY_LABEL_ACE_TYPE的访问掩码设置为0x00000003,这意味着该完整性策略拒绝具有低于中等完整性级别的进程的读取和写入访问尝试,而该对象的完整性级别为中等。
这就是完整性级别检查的故事。
再次参考初始图表,并确保现在一切都清楚明白。
特权
引入特权的最好方式是使用官方MSDN的解释:
特权是帐户(如用户或组帐户)在本地计算机上执行各种与系统相关的操作的权利,例如关闭系统、加载设备驱动程序或更改系统时间。特权与访问权限在两个方面不同:
- 特权控制对系统资源和与系统相关的任务的访问,而访问权限控制对可安全对象的访问。
- 系统管理员将特权分配给用户和组帐户,而系统根据对象的DACL中所授予的
ACE的访问权限来授予或拒绝对可安全对象的访问。
每个系统都有一个帐户数据库,用于存储用户和组帐户所拥有的特权。当用户登录时,系统会生成一个访问令牌,其中包含用户的特权列表,包括授予用户或用户所属的组的特权。请注意,这些特权仅适用于本地计算机;域帐户在不同计算机上可能具有不同的特权。
来源:https://msdn.microsoft.com/en-us/library/windows/desktop/aa379306(v=vs.85).aspx
要枚举您的用户拥有的特权,只需运行以下命令并在输出结果的末尾找到特权列表:
1 | C:> whoami / all |
请注意,在以“以管理员身份运行”的方式启动的命令提示符中运行该命令后,特权会展开显示:
要交叉检查或查找您拥有的特权,您可以使用以下的MSDN资源:
https://msdn.microsoft.com/en-us/library/windows/desktop/bb530716(v=vs.85).aspx
UAC
用户访问控制(User Access Control,UAC)的唯一目的是对管理员执行进行更细粒度的控制,并防止管理员在不需要时使用其管理员执行权限。
回顾一下介绍中的内容,通过登录到您的Windows计算机,您的登录线程被分配了一个用户访问令牌,所有由该用户启动的子进程都将继承此令牌。对于非管理员用户,这是一个中等完整性令牌,具有默认特权。
在Windows Vista之前,管理员用户获得一个具有所有管理员特权的高完整性令牌,并且每个启动的子进程都会继承此令牌。这意味着由管理员用户生成的所有进程都将以高特权运行,即使该进程不需要这些高特权(例如,由管理员启动的explorer.exe将以高完整性令牌和完整的管理员特权运行,而不需要这些特权)。UAC的引入就是为了解决这个问题。
»注意:以下所有解释都假设UAC已启用,并且我们讨论的管理员用户不是本地RID-500er管理员(我们稍后讲到这种特殊情况)。
自从Windows Vista引入UAC以来,当管理员登录时,将创建两个访问令牌:
- 完整的管理员令牌,通常称为“非过滤令牌”或“完整令牌”,具有高完整性级别(IL)和所有管理员特权。
- 过滤的管理员令牌,通常称为“标准令牌”或“受限令牌”,具有中等完整性级别(IL)和较少的特权。
这两个令牌在内核中相互关联,因此如果需要,执行线程可以访问这两个令牌。
现在,如果管理员用户登录到他的帐户并启动cmd.exe,该进程将使用过滤的中等完整性令牌(请记住:UAC已启用,用户不是RID-500管理员)生成。因此,不会将高访问特权授予不需要这些特权的进程。
但是,如果管理员用户需要使用完整的管理员特权运行进程,他可以使用完整的管理员令牌请求操作系统提升此进程的特权,这就是“以管理员身份运行”按钮。这将导致突出显示的“同意”提示弹出(C:\ Windows \ System32 \ consent.exe),如下面的屏幕截图所示:
通过接受此同意提示,系统将使用完整的管理员特权创建提升的进程(在本例中为cmd.exe),如下面的屏幕截图所示:
左侧显示了管理员在没有提升权限的情况下启动的cmd.exe进程(注意,conhost.exe是由cmd.exe创建的子进程),右侧显示了通过点击“以管理员身份运行”启动的提升的cmd.exe进程。
还可以比较这些进程的完整性级别和特权,以确定哪个是哪个。
对于RID-500er本地管理员的UAC设置
以上所有解释仅适用于不是RID-500er本地管理员的本地或域管理员。每个Windows安装都带有一个本地管理员帐户(默认情况下禁用),可以通过相对标识符(RID)为500(SID:S-1-5-21-DomainID-500)来识别。
对于RID-500本地管理员,情况有所不同,该帐户默认情况下未启用UAC。
这意味着,如果您使用RID-500er本地管理员帐户登录到Windows计算机,您将立即被分配一个高特权的完整访问令牌(而不是获取“过滤”中等完整性令牌)。如果您使用RID-500本地管理员运行cmd.exe(或其他任何程序),即使没有指定“以管理员身份运行”,cmd.exe也将以完全的管理员特权和高完整性级别生成(因为您只获得了一个cmd.exe进程可以继承的完整令牌)。如果您使用RID-500er本地管理员点击“以管理员身份运行”,则不会显示同意提示。
默认情况下,RID-500er管理员未启用UAC,但可以通过将以下注册表键设置为“1”来启用:
1 | HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\FilterAdministratorToken |
如下面的屏幕截图所示,在此示例中,FilterAdminstratorToken已设置为“1”,这将使RID-500er管理员参与UAC(因此之前提到的所有规则也适用于该用户)。
禁用非RID-500er管理员的UAC
默认情况下,RID-500er管理员未参与UAC,但所有其他管理员(即属于管理组的本地或域用户)均参与UAC。
现在,RID-500er管理员用户可以参与UAC,非RID-500er管理员也可以通过将LocalAccountTokenFilterPolicy设置为“1”来取消参与UAC。
1 | HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\LocalAccountTokenFilterPolicy |
默认情况下,此注册表键未设置,因此如果缺少此键,则所有非RID-500er帐户都参与UAC:
UAC和远程访问
上述所有内容适用于本地访问,即您的用户在本地登录计算机并执行进程。现在,在远程访问中还有另一个情况。
简而言之:对于远程访问(例如通过wmic),域管理员将获得完整的高完整性访问令牌,但本地的非RID-500er管理员只会获得中等完整性受限令牌。
1)本地管理员(非RID-500er)的远程访问
来源:https://support.microsoft.com/en-us/help/951016/description-of-user-account-control-and-remote-restrictions-in-windows
当一个属于目标远程计算机本地管理员组的用户建立远程管理连接时,他们不会以完整的管理员身份连接。用户在远程计算机上没有提升权限的可能性,并且用户无法执行管理员任务。如果用户想使用安全账户管理器(SAM)帐户管理工作站,用户必须通过远程协助或远程桌面与要管理的计算机进行交互登录。
域管理员远程访问
当一个拥有域用户账户的用户远程登录到Windows Vista计算机时,如果该用户是管理员组的成员,该域用户将在远程计算机上以完整的管理员访问令牌运行,并且对于该会话,远程计算机上的用户的UAC将被禁用。
» 对UAC的这一添加适用于远程管理访问,这不会影响远程桌面连接(被认为是本地登录)。
UAC和哈希传递(Pass-the-Hash)
现在让我们面对以下问题:
问:以下账户尝试通过pth攻击(pass-the-hash)(使用psexec或wmic)使用默认设置建立与计算机的远程连接。
谁将能够建立成功的远程连接,为什么?
a) 本地的‘Administrator’ - SID:S-1-5-21DomainID-500
b) 本地用户‘LocalAdm’,他是本地管理员组的成员(SID:S-1-5-32-544)
c) 域用户‘Lab\Frank’,他是一个没有管理员特权的标准域用户
d) 域用户‘Lab\Bob’,他是域管理员组的成员
请注意,远程访问需要启动高特权进程,并且请考虑到没有办法远程提升特权。
——– 包含答案 ——–
答案:a)和d)是正确的。
以下是原因:
a) - 本地的RID-500管理员默认情况下没有启用UAC。RID-500管理员默认会接收到完整的访问令牌,因此可以建立远程连接。
b) - 非RID-500的本地管理员已经启用了UAC,但是并没有接收到完整的访问令牌。
具体情况如下:非RID-500的管理员尝试登录并获得了一个标准/中间的访问令牌。远程连接访问需要启动完整访问令牌的管理员访问进程,而该用户没有这个权限(他/她只获得了中间访问令牌),因此他的连接将被拒绝。
c) - 与非RID-500的本地管理员情况相同。他/她获得了一个标准(中间)的访问令牌,因此被拒绝。
d) - 域管理员已经启用了UAC,但会自动提升权限。这是远程访问与本地访问的例外情况。
具体情况如下:域管理员尝试登录时,会自动接收到一个完整/管理员访问令牌(而不是标准/中间访问令牌),因此可以获得远程Shell。
如果您还感兴趣,我还建议阅读harmj0y关于“Pass-the-Hash Is Dead: Long Live LocalAccountTokenFilterPolicy”的博文:https://www.harmj0y.net/blog/redteaming/pass-the-hash-is-dead-long-live-localaccounttokenfilterpolicy/
额外提示:如前所述,UAC的远程规则不适用于远程桌面连接。因此,如果您的用户是远程桌面用户组的一部分,您也可以通过远程桌面进行传递哈希攻击,具体描述可参考这里:https://www.kali.org/penetration-testing/passing-hash-remote-desktop/
访问令牌(Access Tokens)
到目前为止,在讨论基本访问检查或UAC时,介绍了用户的“访问令牌”。这些访问令牌包含有关当前用户和用户组的信息,并且例如由安全参考监视器(Security Reference Monitor,SRM)用于确定谁正在请求访问。
这些令牌对于访问检查非常重要,并且在某些特定的权限提升攻击中也发挥作用。因此,值得更仔细地了解访问令牌。
首先,只有两种类型的令牌:
- 主令牌(Primary Tokens):分配给进程的令牌。
- 模拟令牌(Impersonation Tokens):分配给线程的令牌。
只有这两种类型的令牌。"Filtered tokens"、"Restricted Tokens"、"Full Tokens"、"Admin Tokens"或者一般来说的"Access Tokens"只是用来描述令牌的名称,但所有这些都是模拟令牌。
主令牌和模拟令牌都包含以下主要字段:
- 用户SID(User SID):用户的SID(模拟令牌)或创建进程的用户的SID(主令牌)。
- 组SID(Group SIDs):对应用户(用户SID)的组SID。
- 登录SID(Logon SID):标识当前登录会话。
- 特权(Privileges):用户(模拟令牌或进程)拥有的特权列表。
- 主组SID(Primary Group SID):标识被模拟用户的主组(模拟令牌),例如“Domain Users”。
- 默认DACL(Default DACL):当用户在未指定安全描述符的情况下创建安全对象时,系统使用的默认DACL(类似于Linux的umask)。
- 类型(Type):令牌是主令牌还是模拟令牌的信息。
- 模拟级别(Impersonation Level):允许的模拟程度(级别)。
- 完整性级别(Integrity Level):完整性级别的SID。
- ...
将令牌传递给SRM以确定进程是否可以访问对象,因此如果您能够获得高特权令牌,就可以提升特权。
为了对令牌有实际操作经验,James Forshaw开发了一个很好的工具Token Viewer(包含在Sandbox-AttackSurface-Analysis-Tools)中),如下所示:
在右侧窗口中显示了一个进程列表。其中一个高完整性级别的cmd.exe进程的令牌被打开,并显示在左侧窗口中。请注意,令牌类型是主令牌(因为它是一个进程),完整性级别(IL)设置为高(因为该cmd.exe进程作为管理员启动的提升进程)。
请记住,每个进程都有一个分配给它的令牌,而该令牌始终是一个主令牌。
现在让我们转向线程。请记住,从介绍中可以知道,一旦用户登录,用户将被分配一个令牌,更准确地说,用户的登录线程将被分配一个模拟令牌。进程只能拥有一个主令牌,但线程可以同时拥有一个模拟令牌和一个主令牌,在这种情况下,模拟令牌将始终优先于主令牌。(是的,我知道,当微软命名事物时有点糟糕)
下面是一个模拟令牌的示例:
请注意,令牌类型现在显示为“模拟”,并且现在“模拟级别”字段也设置为“模拟”。模拟级别是一个重要的字段,它影响着一个令牌是否可以被模拟(在下一节中将详细介绍)。
到目前为止,一切都很好。关键要点是,对于进程和线程,只有两种类型的令牌。
模拟
模拟过程在Windows授权过程中非常重要,经常被使用。为了理解为什么会使用模拟,我们首先必须退后一步:
想象一下,用户想要删除一个远程文件共享中的文件。现在,托管文件的服务器需要确定用户是否被允许这样做。服务器无法访问用户的访问令牌,因为该令牌在远程服务器的内存中不可访问(令牌存储在请求删除文件的用户的计算机上)。服务器可以从Active Directory(AD)查询用户的账户和组信息,并手动检查用户是否被允许删除文件,但这个任务既繁琐又容易出错。因此,另一种方法被实现并称为“模拟”。
基本思想是服务器简单地假装成请求的用户,并像用户一样执行请求的动作。因此,服务器会复制用户的模拟令牌,并使用该复制的令牌请求动作(例如删除文件)(就像服务器是用户一样)。
模拟是一项强大的功能,它使进程能够假扮成其他人。
好吧,百万美元的点子:我只需模拟一个高权限用户的令牌,就能立即提升特权!...这个想法很好,但显然并不那么简单。有两个障碍:
a)并非每个模拟令牌都可以用于执行动作
b)您需要特殊权限才能“模拟”一个令牌(从技术上讲,这意味着复制一个令牌)
第一个障碍是并非每个令牌实际上都是“有价值的”。这意味着每个模拟令牌都有一个名为“模拟级别”的属性,可以具有以下值之一:
- 匿名级别 - 服务器可以模拟客户端,但令牌不包含有关客户端的任何信息。匿名级别仅支持进程间通信(例如命名管道)。所有其他传输都会自动提升到“识别级别”。
- 识别级别 - 这是默认级别。服务器可以获取客户端的身份以进行ACL检查。您可以使用该令牌读取有关模拟用户的信息或检查资源的ACL,但实际上无法访问该资源(读取/写入/执行)。
- 模拟级别 - 服务器可以模拟客户端的安全上下文以访问本地资源。如果服务器是本地的,它可以访问本地和网络资源。如果服务器是远程的,它只能访问与服务器相同机器上的资源。
- 委派级别 - 最高权限的模拟级别。服务器可以模拟客户端的安全上下文以访问本地或远程资源。
因此,您需要一个模拟级别或委派级别的模拟令牌才能真正执行任何操作(下一节将详细介绍)。
在您面前的第二个障碍是,您需要特殊权限才能复制(模拟)另一个令牌。这个特殊权限是TOKEN_DUPLICATE(如访问令牌对象的访问权限中所指定的)。
情节转折在于,如果您没有持有这个权限,您复制(模拟)令牌的请求不会被拒绝,您仍然会得到一个复制的令牌,但其模拟级别较低。
复制/模拟另一个令牌的流程如下所示:
特权提升使用识别令牌
前面的部分描述了获取识别令牌相当容易。
为了再次强调这一点,我在我的Windows机器上激活了本地管理员账户,并使用了Forshaw的Token Viewer工具来模拟管理员的模拟令牌(有关更多详细信息,请查看他2015年的BlackHat演讲)。
我使用标准非管理员用户运行了这个工具,但仍然获得了管理员的令牌。这感觉很奇怪,但根据前面介绍的对重复令牌进行访问检查的情况,这一切都是正常的。
请注意,我只获得了一个识别模拟令牌。
凭借这个令牌,我应该无法做太多事情,尤其是无法执行管理任务或访问受保护的资源...
...除非当然有些程序员忘记检查用于授权检查的模拟级别。James Forshaw发现在一些Windows组件中出现了这种情况,导致了CVE-2015-0002的发生,例如在这个PoC中所示。
我强烈建议您回顾一下James 2015年的BlackHat演讲,以了解这个漏洞的全部影响和应用,但基本上是这样的:某个Windows组件进行了访问检查,以验证提交的模拟令牌是否属于管理员,但该组件只检查了模拟类型和相关组,并完全忽略了模拟级别,这导致任何能够提交具有管理员组的高完整性识别令牌的用户都可以获得访问权限...这是一个令人惊讶的发现!
泄漏令牌的特权提升
Forshaw发现的另一个特权提升漏洞被称为“泄漏令牌”。这种漏洞的基本思想如下:
内核代码可以访问任何类型的令牌以进行读取和操作。那么,如果你找到了一个Windows内核组件,它只是将它访问过的令牌返回给用户怎么办?!
听起来这似乎太明显了,这是有缺陷的,但Forshaw发现了一个未记录的win32k系统调用存在,它将先前使用过的令牌直接返回给用户。
这个漏洞存在于Windows剪贴板的内核代码中(用于复制+粘贴)。因此,一旦管理员复制了一些东西(例如从编辑器中复制的文本),任何用户都可以调用未记录的函数NtUserGetClipboardToken,并获取先前使用过的管理员访问令牌。
这个问题由Forshaw在CVE-2015-0087中提出。
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
赞赏
- Android主流的污点分析工具 1535
- [翻译]“过滤-静音”操作:调查EDR内部通信 12034
- [翻译]Windows授权指南 5879
- [翻译]利用Android WebView漏洞 7896
- [翻译]伪造调用堆栈以混淆EDR 11404