moscowchill/ADCSAudit
GitHub: moscowchill/ADCSAudit
一个单文件、零依赖的只读 PowerShell 脚本,用于在域内快速审计 AD CS 的 ESC 系列权限提升配置错误。
Stars: 0 | Forks: 0
# ADCSAudit



`ADCSAudit` 会对证书模板、企业 CA 和域控制器进行枚举,然后标记出由 SpecterOps 的 *Certified Pre-Owned* 研究所普及的标准“ESC”权限提升路径。它**仅进行枚举**——绝不会请求证书,也绝对不会进行任何更改。
## 为什么会有这个工具
现有的 AD CS 工具非常出色,但每一个在部署时都会带来成本,这在加固过的管理服务器上显得很不方便:
| 工具 | 在受限主机上的阻力 |
|------|-------------------------------|
| **Certipy** | Python + impacket —— 你必须安装 Python 运行时或远程运行它。 |
| **Certify** | 编译好的 C# 二进制文件 —— 会落地到磁盘 / 面临 AMSI / EDR 检测风险。 |
| **PSPKIAudit** | 是 PowerShell 工具,但需要先安装 `PSPKI` 模块。 |
| **Locksmith** | 成熟的 PowerShell 工具,但你需要从 PSGallery 安装 / 导入模块。 |
有时你只是想要**一个 `.ps1` 脚本,可以直接粘贴到你现有的 PowerShell 会话中**,在你已有的管理服务器上运行——无需安装、无需联网、无需在磁盘上留下二进制文件,也不会让 EDR 将其标记为已知的攻击工具。这就是这个脚本的全部意义所在:
- **单文件。** 复制过去,运行。搞定。
- **零依赖。** 仅使用 `System.DirectoryServices` 和 `certutil.exe`——这两者内置于每一台加入域的 Windows 主机中。不需要 `ActiveDirectory` RSAT 模块。
- **只读。** 它只读取 AD 对象和 CA 的注册表值。它不会进行任何更改。
- **实时 SID + 嵌套组解析。** 它能解析出*实际*可以进行注册的主体,包括通过嵌套组成员身份(`LDAP_MATCHING_RULE_IN_CHAIN`)可达的主体——这是离线模板导出无法告诉你的。
它**并不**打算取代 Certipy 或 Locksmith。它是在无法落地工具时,你运行的轻量级“第一眼”检查。关于何时选择何种工具,请参阅下方的[对比](#comparison)。
## 检查内容
**证书模板**
| ESC | 检查项 |
|-----|-------|
| **ESC1** | 注册者提供主体 + client-auth EKU,且可被低权限主体注册 |
| **ESC2** | Any-Purpose(或无)EKU,且可被低权限主体注册 |
| **ESC3** | Certificate Request Agent EKU,且可被低权限主体注册 |
| **ESC4** | 低权限主体拥有或对模板具有写入/控制权限 |
| **ESC9** | client-auth 模板上设置了 `CT_FLAG_NO_SECURITY_EXTENSION` |
| **ESC13** | 模板的颁发策略链接到某个组 (`msDS-OIDToGroupLink`) |
| **ESC15** | 带有注册者提供主体的 Schema v1 模板 (CVE-2024-49019) |
**证书颁发机构**
| ESC | 检查项 |
|-----|-------|
| **ESC6** | 启用了 `EDITF_ATTRIBUTESUBJECTALTNAME2`(任何注册者都可以指定 SAN) |
| **ESC7** | 低权限主体拥有 `ManageCA` / `ManageCertificates` 权限 |
| **ESC8** | HTTP(S) web enrollment 端点可达(NTLM relay 攻击面) |
| **ESC11** | 未强制要求 ICPR (RPC) 请求加密 |
| **ESC16** | CA 上的安全扩展被全局禁用 |
**域控制器**
| ESC | 检查项 |
|-----|-------|
| **ESC10** | 弱证书映射 (`SCHANNEL\CertificateMappingMethods`, `Kdc\StrongCertificateBindingEnforcement`) |
它还会显示**非默认的模板所有者**(委派控制 = 潜在的 ESC4),并打印每个模板的完整注册权限情况。
### 威胁模型
当**低权限主体**(`Everyone`、`Anonymous`、`Authenticated Users`、`BUILTIN\Users`、`Domain Users`、`Domain Computers`、`Domain Guests`)可以直接或通过嵌套组成员身份触及该路径时,就会产生一条发现。这与 Certipy 的 `find -vulnerable` 推理暴露面的方式一致。
## 使用方法
```
# 从包含脚本的文件夹中,在已加入域的主机上
powershell -ExecutionPolicy Bypass -File .\Invoke-ADCSAudit.ps1
# 仅显示有 findings 的对象
.\Invoke-ADCSAudit.ps1 -VulnerableOnly
# 在网络中保持静默(无 /certsrv 探测,无 DC 远程注册表)
.\Invoke-ADCSAudit.ps1 -SkipWebEnrollment -SkipDCChecks
```
| 参数 | 效果 |
|-----------|--------|
| `-OutputDir ` | 报告写入的目录(默认为 `.\ADCSAudit_`) |
| `-VulnerableOnly` | 仅打印至少有一项发现的模板/CA |
| `-SkipCAConfig` | 跳过对每个 CA 的 `certutil` 查询(ESC6/7/11/16) |
| `-SkipWebEnrollment` | 跳过 HTTP(S) `/certsrv` 探测(ESC8) |
| `-SkipDCChecks` | 跳过针对 DC 的远程注册表 ESC10 检查 |
### 输出
带有颜色的控制台摘要,以及在输出目录中生成机器可读的文件:
```
findings.csv # every finding (ESC, severity, object, detail, principals)
findings.json # same, as JSON
templates.csv # full per-template matrix (flags, EKUs, owner, enrollers)
cas.csv # per-CA results
```
## 环境要求
- Windows PowerShell **5.1+**(Windows 自带版本;PowerShell 7 也可以)
- 以**域用户**身份运行——这对于所有的模板检查已经足够
- 对于 **ESC7**(CA 安全),你至少需要对 CA 具有**读取**权限;如果被拒绝,检查会优雅降级
- ESC8 需要向 CA 发起出站 HTTP(S) 请求;ESC10 使用针对 DC 的远程注册表——使用 `-Skip*` 开关可以保持静默
## 对比
| | **ADCSAudit** | Certipy | Certify | PSPKIAudit | Locksmith |
|---|:---:|:---:|:---:|:---:|:---:|
| 语言 / 运行时 | PowerShell | Python | C# (.NET) | PowerShell | PowerShell |
| 安装占用 | **单个 `.ps1`** | python+impacket | 落地二进制文件 | `PSPKI` 模块 | PSGallery 模块 |
| 需要 RSAT / 模块 | **否** | 不适用 | 不适用 | 是 (PSPKI) | 导入模块 |
| 枚举 | ✅ | ✅ | ✅ | ✅ | ✅ |
| **漏洞利用** (请求/伪造证书) | ❌ | ✅ | ✅ | ❌ | ❌ |
| **修复** (修复模式) | ❌ | ❌ | ❌ | ❌ | ✅ |
| 离线解析 (注册表/BOF) | ❌ | ✅ (`parse`) | ❌ | ❌ | ❌ |
| 无需落地二进制文件即可从 Windows 运行 | ✅ | ❌ | ❌ | ✅ | ✅ |
| 默认只读 | ✅ | 不适用 | 不适用 | ✅ | ✅ (审计模式) |
**何时使用何种工具**
- **当你想在一台无法(或不愿意)安装模块或落地二进制文件的主机上,对环境进行快速、无依赖的读取时,选择 `ADCSAudit`。**
- **当你需要实际*证明*可利用性(请求/伪造证书、relay、离线解析注册表导出)时,请使用 [Certipy](https://github.com/ly4k/Certipy)。**
- **当你想要一个成熟的审计工具,并且还能为你*修复*这些发现时,请使用 [Locksmith](https://github.com/TrimarcJake/Locksmith)。**
- **如果你已经习惯了 GhostPack/SpecterOps 的工作流,请使用 [Certify](https://github.com/GhostPack/Certify) / [PSPKIAudit](https://github.com/GhostPack/PSPKIAudit)。**
这些工具是互补的。一个常见的流程是:使用 `ADCSAudit` 进行快速分诊 → 使用 Certipy 将确认的路径武器化 → 使用 Locksmith 进行修复。
## 局限性
- **仅进行枚举。** 它能识别错误配置;但不会请求证书或证明可利用性。请使用 Certipy/Certify 进行确认。
- **ESC7** 需要对 CA 的配置注册表具有读取权限。
- **ESC13** 检测涵盖了 OID→组链接;但完整的 ESC13 可利用性还取决于其他因素。
- 它会在许多 CA 上标记 **ESC11**,因为默认情况下请求加密是关闭的——这与 Certipy 的模型一致,但除非攻击链的其余部分也能对上,否则请将其视为信息参考。
- 它不能替代上面更成熟的工具;它只是方便的第一遍检查。
## 工作原理(写给好奇者)
- 模板和 CA 是从 **Configuration 分区**(`CN=Public Key Services,CN=Services,CN=Configuration,...`)通过 `System.DirectoryServices.DirectorySearcher` 读取的,并通过适当的 `SecurityMasks` 请求 `nTSecurityDescriptor`。
- 每个模板的 DACL 都使用 `ActiveDirectorySecurity` 进行解析,将对象 ACE 映射到 **Enroll**(`0e10c968-78fb-11d2-90d4-00c04f79dc55`)和 **All-Extended-Rights** GUID。复合权限通过 `.HasFlag()` 进行测试(而不是按位 AND),因此仅仅拥有*读取*权限的主体绝不会因此被误认为拥有*写入*权限。
- CA 端的标志(`EditFlags`、`InterfaceFlags`、`DisableExtensionList`、`Security`)来自于 `certutil -getreg`;CA 安全描述符使用 `RawSecurityDescriptor` 解析,并映射到 `ManageCA`/`ManageCertificates`。
- ESC10 通过远程注册表服务从每个 DC 读取 `SCHANNEL` / `Kdc` 注册表值。
## 法律 / 授权使用
此工具旨在对你拥有或获得明确书面授权进行测试的环境进行**授权的安全评估**。它是只读的,但在运行之前,你有责任确保已获得授权。作者对滥用行为不承担任何责任。
## 致谢
- ESC 分类法:**[Certified Pre-Owned](https://posts.specterops.io/certified-pre-owned-d95910965cd2)** — Will Schroeder & Lee Christensen (SpecterOps)。
- 灵感来源于 [Certipy](https://github.com/ly4k/Certipy)、[Certify](https://github.com/GhostPack/Certify)、[PSPKIAudit](https://github.com/GhostPack/PSPKIAudit) 和 [Locksmith](https://github.com/TrimarcJake/Locksmith)。
## 许可证
[MIT](LICENSE)
标签:AD CS, AI合规, IPv6, Libemu, log2timeline, PowerShell, 协议分析, 权限提升, 足迹探测, 配置核查