开卷有益 · 不求甚解
虽然这不是我花费太多时间的事情,但找到一种绕过 UAC 的新方法总是很有趣。在阅读Rubeus工具的一些功能时,我意识到有一种可能的方法可以滥用 Kerberos 绕过 UAC,至少在加入域的系统上很好。目前还不清楚这是否已经记录在案,这篇文章似乎讨论了类似的事情,但依赖于从另一个系统绕过 UAC,但我将要描述的内容在本地工作。即使在我不确定它是否已被记录在幕后它是如何工作的之前,它已被描述为一种技术。
让我们从系统如何防止您绕过最无意义的安全功能开始。默认情况下,如果用户是本地管理员,LSASS 将过滤任何网络身份验证令牌以删除管理员权限。但是有一个重要的例外,如果用户是域用户和本地管理员,则 LSASS 将允许网络身份验证使用完整的管理员令牌。如果说您使用Kerberos
在本地进行身份验证,这将是一个问题。这不是微不足道的 UAC 绕过吗?只需以域用户身份向本地服务进行身份验证,您就会获得绕过过滤的网络令牌?
不,Kerberos
具有特定的附加功能来阻止这种攻击媒介。如果我是慈善机构,我会说这种行为也确保了一定程度的安全。如果您没有以管理员令牌的身份运行,那么访问 SMB 环回接口不应突然授予您管理员权限,通过该权限您可能会意外破坏您的系统。
早在去年 1 月,我就阅读了 Microsoft 的 Steve Syfuhs的一篇文章,内容是Kerberos
如何防止这种本地 UAC 绕过。TL;DR; 当用户想要获得服务的Kerberos
票证时,LSASS 将向 KDC 发送 TGS-REQ 请求。在请求中,它将嵌入一些表明用户是本地用户的安全信息。此信息将嵌入到生成的工单中。
当该票证用于对同一系统进行身份验证时,Kerberos
可以提取信息并查看它是否与它知道的信息匹配。如果是这样,它将获取该信息并意识到用户没有被提升并适当地过滤令牌。不幸的是,尽管很喜欢史蒂夫的帖子,但这篇文章对细节特别轻。我想我必须自己追踪它是如何工作的。让我们转储Kerberos
票证的内容,看看我们是否可以看到票证信息:
我已经突出显示了两个感兴趣的条目,KERB-AD-RESTRICTION-ENTRY和KERB-LOCAL条目。当然,我没有猜到这些名称,这些名称都记录在 Microsoft Kerberos 协议扩展 ( MS-KILE ) 规范中。KERB_AD_RESTRICTION_ENTRY 显然
是最有趣的,它包含“LimitedToken”
和“Medium Integrity Level”
这两个作品。
当通过 SSPI 接受来自网络客户端 的 Kerberos AP-REQ时,LSASS 中的 Kerberos 模块将调用 LSA 函数``LsaISetSupplementalTokenInfo
以将来自 KERB-AD-RESTRICTION-ENTRY
的信息应用到令牌(如果需要)。相关代码大致如下:
我已经强调了这个函数中的三个主要检查,第一个比较KERB-AD-RESTRICTION-ENTRY的``MachineID
字段 是否与存储在 LSASS 中的匹配。如果是,则设置bLoopback
标志。然后它检查 AFAIK 未记录的 LSA 标志以过滤所有网络令牌,此时它将检查 LimitedToken
标志并相应地设置 bFilterToken
标志。此过滤模式默认为关闭,因此通常不会设置bFilterToken 。
最后,代码查询当前创建的令牌 SID 并检查以下任何一项是否为真:
NtProductLanManNt
,实际上对应一个域控制器。如果任何一个为真,那么只要令牌信息既不是环回也不是强制过滤,该函数将返回成功并且不会进行过滤。因此,在默认安装中,无论机器 ID 是否匹配,都不会过滤域用户。
对于完整性级别,如果正在进行过滤,那么它将被丢弃到 KERB-AD-RESTRICTION-ENTRY
身份验证数据中的值。但是,它不会将完整性级别提高到默认创建的令牌之上,因此不能滥用它来获取系统完整性。
注意Kerberos
将 首先使用 AP-REQ 中的票证中的 KERB-AD-RESTRICTION-ENTRY
身份验证数据调用LsaISetSupplementalTokenInfo 。
如果它不存在,那么它将尝试使用来自身份验证器的条目来调用它。如果票证或身份验证器都没有条目,则永远不会调用它。我们如何删除这些值?
好的,我们怎么能滥用它来绕过 UAC?假设你被认证为域用户,最有趣的滥用它的方法是让机器 ID 检查失败。我们将如何做到这一点?LsapGlobalMachineID 值是 LSASS 启动时生成的随机值。
我们可以滥用这样一个事实,即如果您查询用户的本地 Kerberos 票证缓存,即使您不是管理员,它也会返回服务票证的会话密钥(默认情况下它不会返回 TGT 会话密钥)。
因此,一种方法是为本地系统生成服务票证,将生成的KRB-CRED
保存到磁盘,重新启动系统以使 LSASS 重新初始化,然后在返回系统时重新加载票证。此票证现在将具有不同的机器 ID,因此Kerberos
将忽略限制条目。您可以使用内置klist
和Rubeus
使用以下命令来完成:
PS> klist 获取 RPC/$env:COMPUTERNAME
PS> Rubeus.exe /dump /server:$env:COMPUTERNAME /nowrap
... 将 base64 票证复制到文件中。然后重启:
PS> Rubeus.exe ptt /ticket:<BASE64 TICKET>
您可以使用Kerberos身份验证通过命名管道或使用``RPC/HOSTNAME
SPN的 TCP 访问 SCM 。请注意,SCM 的 Win32 API 始终使用协商
身份验证,这会在工作中引发扳手,但还有其他 RPC 客户端;-) 虽然 LSASS 会在 AP-REQ 中向身份验证器添加一个有效的限制条目,但它不会被使用因为票证中的那个会先被使用,由于机器ID不同而无法申请。
另一种方法是生成我们自己的票证,但我们不需要凭据吗?我相信 Benjamin Delpy发现了一个技巧并将其放入kekeo
中,它允许您滥用无约束委托来获取具有会话密钥的本地 TGT。使用此 TGT,您可以生成自己的服务票证,因此您可以执行以下操作:
KERB-AD-RESTRICTION-ENTRY
但填写一个伪造的机器 ID。最终,这是一个合理数量的 UAC 绕过代码,至少与刚刚更改环境变量相比。但是,您可能可以使用kekeo
和Rubeus
等现有工具将其组合在一起,但我不会发布一个交钥匙工具来做到这一点,您需要自己做 :-)
KERB-LOCAL
的目的是什么?这是一种重用本地用户凭据的方式,这类似于 NTLM 环回,其中 LSASS 能够确定调用实际上来自本地经过身份验证的用户并使用他们的交互式令牌。可以根据 Kerberos 包中的已知凭据列表检查票证和身份验证器中传递的值,如果匹配,则将使用现有令牌。
这不会总是消除基于 KERB-AD-RESTRICTION-ENTRY
值过滤令牌的需要吗?由于它的设计方式,这种行为似乎很少使用。首先,它仅在接受服务器使用Negotiate包时才有效,如果直接使用``Kerberos
包则不起作用(有点......)。这通常不是障碍,因为大多数本地服务都使用Negotiate
来方便。
真正的问题是,作为一个规则,如果您使用与本地计算机协商
作为客户端,它将选择 NTLM 作为默认值。这将使用 NTLM 而不是 Kerberos 中已内置的环回,因此不会使用此功能。请注意,即使在域网络上全局禁用 NTLM,它仍然适用于本地环回身份验证。我猜KERB-LOCAL
是为了与 NTLM 进行功能对等而添加的。
回到博客开头的格式化票证,KERB-LOCAL
值是什么意思?它可以解压成两个 64 位值,0x17E3303CE60 和 0x3976FC25。第一个值是LSASS 堆中KERB_CREDENTIAL
结构的堆地址!!第二个值是创建 KERB-LOCAL 结构时的票数。
幸运的是 LSSAS 不只是取消引用凭证指针,它必须在有效凭证结构列表中。但是这个值没有被蒙蔽或引用随机生成的值这一事实似乎是一个错误,因为堆地址很容易暴力破解。当然不是那么简单,Kerberos
确实会验证票证的 PAC 中的 SID 是否与凭据中的 SID 匹配,因此您不能只是欺骗 SYSTEM 会话,但是,我将把它作为一个想法继续下去和。
希望这能让您更深入地了解此功能的工作原理,并为您尝试以新的方式绕过 UAC 带来一些乐趣。
更新:这个简单的 C++ 文件可用于修改 Win32 SCM API 以使用 Kerberos 进行本地身份验证。链接: https://gist.github.com/tyranid/c24cfd1bd141d14d4925043ee7e03c82
近期阅读文章
,质量尚可的,大部分较新,但也可能有老文章。开卷有益,不求甚解
,不需面面俱到,能学到一个小技巧就赚了。译文仅供参考
,具体内容表达以及含义, 以原文为准
(译文来自自动翻译)尽量阅读原文
。(点击原文跳转)每日早读
基本自动化发布(不定期删除),这是一项测试
最新动态: Follow Me
微信/微博:
red4blue
公众号/知乎:
blueteams