代码编织梦想

文章前言

我喜欢的一件事是当我认为我很好地理解了一个话题,然后有人证明我完全错了。当James Forshaw发表一篇关于Kerberos中继的博客时,或多或少发生了这种情况,这反驳了我几年前不能中继Kerberos的结论. James表明有一些技巧可以使Windows对不同的服务主体名称(SPN)进行身份验证,而不是通常从客户端连接到的主机名派生的名称,这意味着Kerberos并不像我假设的那样完全防中继。这促使我研究了一些替代的滥用路径,包括我几年前研究过但永远无法工作的东西:中继DNS身份验证。当您能够使用mitm6通过 DHCPv6欺骗来欺骗DNS服务器时,这一点尤其重要。在这种情况下,您可以让受害机器使用Kerberos及其机器帐户可靠地向您进行身份验证,此身份验证可以中继到任何不强制完整性的服务,例如:基于Active Directory证书服务(AD CS)http(s)的注册,AD CS中继,与使用mitm6中继WPAD身份验证相比,此技术更快、更可靠且侵入性更小,但当然需要使用AD CS,这篇博客描述了这项技术的背景以及我对krbrelayx所做的更改,以支持这次真正的Kerberos中继。

基于DNS的Kerberos

如果您熟悉Kerberos,您就会知道DNS是拥有有效的Kerberos基础架构的关键组件,但是您知道Active Directory中的DNS还支持使用Kerberos在DNS 上进行身份验证的操作吗?这是"ynamic Update"操作的一部分,用于使具有动态地址的网络客户端的DNS记录与其当前IP地址保持同步,下图显示了动态更新过程中涉及的步骤

步骤如下(按照上面的数据包从上到下),在此交换中客户端是Windows 10工作站,服务器是具有DNS角色的域控制器

  • 客户端查询其名称的授权开始(SOA)记录,该名称指示哪个服务器对客户端所在的域具有权威性

  • 服务器使用授权的DNS服务器进行响应,在本例中为DC icorp-dc.internal.corp

  • 客户端尝试使用他们在区域中的名称对A记录进行动态更新internal.corp

  • 服务器拒绝此动态更新,因为未提供身份验证

  • 客户端使用TKEY查询来协商经过身份验证的查询的密钥

  • 服务器回答TKEY资源记录,完成身份验证

  • 客户端再次发送动态更新,但现在附有一条TSIG记录,该记录是使用在步骤 5 和 6 中建立的密钥的签名

  • 服务器确认动态更新,新的DNS记录现已到位

让我们仔细看看第5步和第6步,TKEY查询实际上是通过TCP发送的,因为它比UDP允许的最大512字节大很多,这主要是因为相当大的TKE 附加记录,其中包含我们经常看到的用于Kerberos身份验证的结构:

事实证明此查询包含完整的GSSAPI和SPNEGO结构,其中包含Kerberos AP-REQ,这本质上是对服务的正常Kerberos身份验证流程,回复再次包含一个 GSSAPI和SPNEGO结构,指示认证成功,并使用AP-REP回复。此AP-REP包含一个新的会话密钥,客户端可以使用该密钥通过TSIG记录签署其DNS查询,请注意encAPRepPart通常使用只有客户端和服务器知道的会话密钥进行加密,但是因为我将测试域中各种系统的Kerberos密钥加载到Wireshark 接受的密钥表中,我们可以解密整个交换以查看它包含

此流程的概念相当简单(实际实现并非如此),客户端使用Kerberos进行身份验证并安全地交换会话密钥,然后使用该会话密钥签署进一步的更新查询。服务器可以存储密钥和经过身份验证的用户/计算机,并以经过身份验证的方式处理更新,而不必将身份验证绑定到特定的TCP套接字,因为以后的查询可能通过UDP发送

滥用DNS身份验证

如果我们能够拦截DNS查询,就有可能欺骗受害客户端向我们发送真实DNS 服务器的Kerberos票证,这种拦截可以在默认的Windows配置中由同一 (V)LAN中的任何系统使用mitm6完成,mitm6将自己宣传为DNS服务器,这意味着受害者将发送SOA到我们的假服务器,如果我们拒绝他们的动态更新,则使用Kerberos进行身份验证,现在这有点棘手,通常DNS服务器角色将在域控制器上运行,因此DNS服务的服务票证已经适用于在DC上运行的服务,因为它们使用相同的帐户,我们可以更改票证中的服务名称,这意味着我们可以将此票证中继到例如LDAP,但是如果我们仔细查看TKEY查询中的身份验证器,我们会看到设置了请求完整性(签名)的标志

这将自动触发LDAP签名,这会使整个攻击失败,因为如果没有在每条消息上提供有效的加密签名,之后我们就无法与LDAP交互,我们无法生成此签名,因为我们转发了身份验证并且实际上并不拥有解密服务票证和提取会话密钥所需的Kerberos密钥

这最初让我碰壁有两个原因:

  • 当时没有任何已知的默认高价值服务会接受设置了完整性标志的身份验证,但不会在协议级别强制执行它

  • 客户端专门请求他们在其Kerberos票证请求中使用的SPN中的"dns"服务类,此SPN仅在实际的DNS服务器上设置,因此要中继到的合法主机的数量非常少

在阅读了James的博客后重温这一点,我意识到这些都不是当今知识的问题:

  • 由于AD CS研究是由Lee Christensen和Will Schroeder发表的,我们有一个高价值的端点,它存在于大多数AD环境中,并为受害者提供代码执行可能性,如我在上一篇关于AD CS中继的博客中所述

  • 正如James在他的博客中所描述的,许多服务类实际上会隐式映射到 HOST 类,事实证明,这包括DNS,因此当我们的受害者请求DNS服务的票证时,这实际上适用于具有HOST SPN的任何帐户,这是默认在域中的所有计算机帐户上设置的,因此可以针对在这些帐户下运行的任何服务

解决了这两个问题后,没有什么能真正阻止我们将我们在假DNS服务器上收到的Kerberos身份验证转发到AD CS,完成后我们可以为我们转发的计算机帐户申请证书,并使用我在之前的博客中谈到NT哈希恢复技术或S4U2Self 技巧,使用这些技术,我们可以SYSTEM访问受害计算机,这有效地使其成为可靠的RCE,只要AD CS http端点可用于中继

对krbrelayx和mitm6的更改

最初krbrelayx并不是真正的中继工具,相反它通过使用不受约束的委派配置(系统)帐户来捕获Kerberos TGT,并且以与ntlmrelayx相同的方式使用这些 TGT可以使用传入的NTLM身份验证,由于现在有一个实际中继Kerberos身份验证的用例,因此我更新了krbrelayx中的功能,使其可以在中继模式下运行,而不是在无约束委托模式下运行,如果您未指定任何可用于从传入的 Kerberos身份验证中提取信息的NT散列或AES密钥,它实际上将默认为此模式,简而言之,krbrelayx现在可用于中继Kerberos身份验证,但仅支持中继到HTTP和LDAP,至于mitm6,我添加了指定中继目标的选项,当受害者询问SOA记录时,这将是权威名称服务器响应中的主机名,这将使受害者为我们的目标服务而不是合法的DNS服务器请求Kerberos服务票证

需要注意的一点是,当目标AD CS服务器不是受害者用于Kerberos操作的DC 时,这种方法效果最好,如果它们位于同一主机上(例如在较小的或实验室环境中),同时针对KDC和AD CS服务器的服务器,可能会导致受害者将其 Kerberos票证请求(TGS-REQ)发送给您而不是DC,虽然您可以代理此流量,但这超出了本项目的范围,您最终可能无法获得任何身份验证数据

我们必须克服最后一个障碍,Kerberos AP-REQ实际上并没有告诉我们哪个用户在进行身份验证,这仅在Authenticator的加密部分中指定,所以我们不知道哪个用户或机器帐户正在向我们进行身份验证,幸运的是这在默认的AD CS模板方案中并不重要,因为它们允许将任何名称指定为CN,并且无论如何它都会被Active Directory中的名称覆盖,然而为了获得最佳结果,我建议您使用mitm6将攻击范围限定在一个主机上,并--victim在krbrelayx中指定该主机名,以便正确填写字段

攻击示例

让我们看看这在实践中的样子,首先我们设置krbrelayx,将AD CS主机(在我的实验室中adscert.internal.corp)指定为目标,并将接口的IPv4地址指定为绑定DNS服务器的接口,这可以防止与通常在例如:Ubuntu上侦听环回适配器的DNS服务器发生冲突

sudo krbrelayx.py --target http://adscert.internal.corp/certsrv/ -ip 192.168.111.80 --victim icorp-w10.internal.corp --adcs --template Machine

然后我们设置mitm6,使用AD CS主机的名称作为中继目标:

sudo mitm6 --domain internal.corp --host-allowlist icorp-w10.internal.corp --relay adscert.internal.corp -v

我们等待受害者获得IPv6地址并连接到我们的恶意服务器:

屏幕截图显示受害者试图更新他们的DNS记录,由于缺乏身份验证,我们拒绝这样做,身份验证通过TCP发送到krbrelayx的DNS服务器,后者接受并转发到AD CS:

在线上我们看到了预期的流程

  • 受害者(192.168.111.73)查询其主机名的SOA记录

  • 我们指出我们的流氓DNS服务器是权威名称服务器,受害者将向其发送动态更新查询

  • 该查询被mitm6拒绝,这将向受害者表明他们需要对他们的查询进行身份验证

  • 客户端与KDC对话以获取我们指定的服务的Kerberos票证

  • 客户端与krbrelayx建立TCP连接并发送包含Kerberos票证的TKEY查询

  • 票证被转发到AD CS主机,从而导致我们的身份验证成功并颁发证书

有了这个证书我们可以使用PKINITtools(或Windows上的Rubeus)使用 Kerberos进行身份验证并模拟域管理员来访问我们的受害者(在本例中icorp-w10)

python gettgtpkinit.py -pfx-base64 MIIRFQIBA..cut...lODSghScECP5hGFE3PXoz internal.corp/icorp-w10$ icorp-w10.ccache

使用smbclient.py我们可以列出C$驱动器以证明我们具有管理员访问权限

防御措施

此技术滥用Windows和Active Directory中的不安全默认设置,这里的主要问题是Windows对IPv6的偏好,以及AD CS Web应用程序的安全默认设置不好,这些可以通过以下方式缓解

缓解mitm6

mitm6滥用了这样一个事实,即即使在仅IPv4的环境中,Windows也会查询 IPv6地址,如果您在内部不使用IPv6,则阻止mitm6的最安全方法是通过组策略在Windows防火墙中阻止DHCPv6流量和传入路由器广告,完全禁用 IPv6可能会产生不必要的副作用,将以下预定义规则设置为阻止而不是允许可防止攻击起作用:

  • (入站)核心网络 - IPv6 的动态主机配置协议(DHCPV6-In)

  • (入站)核心网络 - 路由器广告 (ICMPv6-In)

  • (出站)核心网络 - IPv6 的动态主机配置协议(DHCPV6-Out)

减轻对AD CS的中继

默认CertSrv站点不使用TLS,在启用进一步保护之前应首先强制执行,使用有效证书启用TLS后,在IIS中启用身份验证的扩展保护将防止中继攻击,这应该在提供此服务的所有单个CA服务器上的AD CS的所有基于Web的注册功能上启用

相关工具

本博客中提到的所有工具都可以作为 GitHub 上的开源工具获得。

  • mitm6 https://github.com/dirkjanm/mitm6

  • krbrelayx https://github.com/dirkjanm/krbrelayx

  • PKINITtools https://github.com/dirkjanm/PKINITtools

感谢本博客中提到的所有人以及我之前关于这些主题的帖子,感谢他们对研究和工具的贡献

关于kali linux 中的攻击总结01 ---arp毒化和dns欺骗_zhaotiannuo_1998的博客-爱代码爱编程

声明:此文章只做实验研究学习,请勿违法犯罪。 实验环境: 一台kali linux 和一台Windows7 两台都在一个网段,互相能ping通 Windows7能上网 开始实验: 先看一下windows7是否能够正常访问网

NTLM 中继攻击的几种非主流玩法-爱代码爱编程

在企业组织中的常见的一种安全风险是凭证重用,当攻击者攻击 NT LAN Manager 身份验证协议(以下简称 NTLM 身份验证)时就会出现这样的风险,而这个协议通常会在 微软的 活动目录 中默认启用。   NTLM 认证中的不安全性已经被安全研究人员发现超过15年了。该协议可以被滥用,通过一个称为“中继”的过程劫持受害者的会话,该过程通过将受害者的