在2021年的BlackHat大会上,由Will Schroeder和Lee Christensen发布了关于Active Directory Certificate Services 利用白皮书《Certified Pre-Owned - Abusing Active Directory Certificate Services》,其中包含了大量的针对ADCS的攻击手法,通过对ADCS的攻击,将域渗透的攻击面扩展到了最大。尽管ADCS并不是默认安装在域环境中,但是在一些大型企业的域环境中却被广泛部署。
本文分为上中下三篇,重点介绍如何在域环境中使用ADCS技术攻击域控制器,以及如何利用对象ACL来维持更高的权限。同时,我们将深入探讨ADCS的基础架构、攻击面以及后利用。这些内容将通过实战演练的方式进行讲解。
1.什么是PKI?
公钥基础建设 (Public Key Infrastructure,简称PKI) 是一组由硬件、软件、参与者、管理者与流程组成的基础架构,其目的在于创造、管理、分配、使用、存储以及撤销数字证书。PKI依赖于经过身份验证的用户和受信任的资源之间的数字证书交换。可以使用证书来保护数据安全,并管理来自组织内外的用户和计算机的标识凭据。
2.什么是CA?
数字证书认证机构 (Certificate Authority,简称CA) 是负责签发证书、认证证书、管理已颁发证书的权威机构。它要制定政策和具体步骤来验证、识别用户身份,并对用户证书进行签名,以确保证书持有者的身份和公钥的拥有权。
3.什么是证书?
证书是一个小文件,此文件包含了公钥信息、拥有者身份信息、以及数字证书认证机构对这份文件的数字签名,以保证这个文件的整体内容正确无误。
拥有者凭此文件,可向电脑系统或者其他用户表明身份,从而获得对方的信任并授权访问或使用某些敏感的电脑服务。在证书注册过程中,客户端会生成公钥/私钥对,然后客户端将公钥发送到CA,而CA会确认客户端信息,用自己的私钥对其进行签名,随后再将包含客户端公钥的证书发送回客户端。
在概念上,证书相当于驾照,交警部门相当于CA。将身份信息与考核情况递交给交警部门,他们会给我们一个带有特有盖章的驾照,这样才可以开车上路。乘客会因为驾照而信任你的驾车技术,因为只有通过考核交警部门才会给你发驾照。如果严重违反了交通规则,你会被吊销驾照,不能开车载人。
4.什么是ADCS?
AD域作为当前企业的办公内网广泛应用的集权管理方案,其域控在AD域内扮演着“大脑”的角色,至关重要,而不少企业在会在安装AD域的同时安装ADCS证书服务器来管理证书,攻击者会针对ADCS来进行攻击从何获取域控权限,导致AD集权安全收到威胁。
5.搭建ADCS
搭建ADCS可参考文章https://learn.microsoft.com/zh-cn/windows-server/networking/core-network-guide/cncg/server-certs/install-the-certification-authority注意不要将证书服务器和域控搭建在一台主机上。
证书模板定义了用户和设备如何根据模板来请求和使用企业CA颁发的证书。例如你可以创建一个模板来提供文件加密或电子邮件签名功能。CA依赖于ADDS来存储配置的模板。注意,只有在使用企业CA时才可以使用证书模板,这意味着,在使用独立CA时,必须手动创建每个证书请求,并添加需要在证书中包含的必须信息。
CA针对用户和计算机提供了模板,可以向证书模板分配相应的权限,以定义可以管理模板的人员、可以执行注册或自动注册的人员,以及默认的有效期和续订期。可以通过复制预定义的证书模板来应用其他修改。
1.模板版本
Windows Server AD CS 中的 CA 支持四个版本的证书模板,它们具有以下功能差异:
可以使用certtmlp.msc打开证书模板控制台,使用certsrv.msv打开证书颁发机构。
其中版本架构就是我们上面所说的模板版本,预期用途就是这个证书模板申请之后用来干什么,例如可以客户端身份验证、服务器身份验证等,如果要设置模板特定用途可以右击模板属性在应用程序策略中添加或删除证书模板用途。
在证书模板属性中我们主要关注使用者名称、发布要求、扩展和安全。
2.使用者名称
使用者名称就是我们后面申请证书要用到的SAN(subjectAltname)来指定身份,如果设置了在请求中提供,可以在申请证书的时候为指定的人生成证书。
3.发布要求
在发布要求中主要关注是否勾选了CA证书管理程序批准。如果用户有注册权限,但是在证书模板中勾选了CA证书管理程序批准,那么只有等到CA管理员批准才能够申请证书。
4.扩展
扩展中主要关注在上面我们说到的应用程序策略(pKIExtendedKeyUsage)EKU,根据Specterops的研究,拥有以下的证书可用于kerberos身份认证。
PKINIT默认是不存在的,我们可以手动创建。
其中对象标识符如下所示
描述 对象描述符(OID)
客户端认证 1.3.6.1.5.5.7.3.2
PKINIT客户端认证 1.3.6.1.5.2.3.4
智能卡登录 1.3.6.1.4.1.311.20.2.2
任何目的 2.5.29.37.0
子CA (no EKUs)
5.安全
安全中我们主要关注Authenticated User组是否具有完全控制、写入和注册权限,如果拥有这些权限,则会造成一些安全问题。
三、如何注册证书?
1.证书注册流程
(1)客户端创建公钥和私钥
(2)客户端向企业 CA 服务器发送证书请求 (CSR)
(3)CA会判断,证书模板是否存在?证书模板是否允许 CSR 中的设置?用户是否允许注册证书?
(4)若符合上面条件CA 生成证书并使用 CA 私钥对其进行签名
2.手动申请证书
(1)客户端首先生成一个证书申请文件,我们可以通过openssl生成。
首先生成私钥
openssl genrsa -out server.key 1024
生成公钥
openssl rsa -in server.key -pubout -out public.key
(2)根据私钥生成证书申请文件CSR
openssl req -new -key server.key -out server.csr
(3)客户端把证书申请文件(CSR)发送给CA,然后选择一个证书模板。接着CA会判断证书模板是否存在,CSR请求的内容在模板中是否被允许使用,是否允许用户注册证书。注意此时我已经安装了证书web服务。
(4)CA用自己的私钥来签署证书,然后将其返回给客户端。
3.使用网页注册证书
在此之前我已经安装了证书Web服务,使用http://ip/certsrv/打开输入域账户密码
点击申请证书,高级证书申请
接着创建并向此CA提交一个申请
4.域内用户使用GUI请求证书
如果在域内则可以启动certmgr.msc来申请用户证书,或者使用certlm.msc申请计算机证书。
ADCS在ldap容器中位置位于
CN=Public Key Services,CN=Services,CN=Configuration,DC=
其中Certification Authorities存放了受信任的根证书,AIA为证书的授权信息访问,CDP为吊销发布点,certificate Templates 为证书模板,Enrollment Services为企业CA,OID为对象描述符。
PKINIT协议为kerberos 协议的一个扩展协议,可通过X.509证书来获取kerberos的TGT票据,PKINIT与kerberos差别主要在AS阶段,一种是基于对称密钥加密的认证方式,PKINIT是基于非对称密钥加密的认证方式,我们可以首先来看看正常kerberos的AS认证流程:
(1)当域内某个客户端用户Client访问域内的某个服务,于是输入用户名和密码,此时客户端本机的Kerberos服务会向KDC的AS认证服务发送一个AS_REQ认证请求。请求的凭据是Client的哈希值NTLM-Hash加密的时间戳以及Client-info、Server-info等数据,以及一些其他信息。
(2)当client发送身份信息给AS后,AS会先向活动目录AD请求,询问是否有此Client用户,如果有的话,就会取出它的 NTLM-Hash,并对 AS_REQ 请求中加密的时间戳进行解密,如果解密成功,则证明客户端提供的密码正确,如果时间戳在五分钟之内,则预认证成功。
然后 AS 会生成一个临时秘钥 Session-Key AS,并使用客户端 Client 的 NTLM-Hash 加密 Session-key AS 作为响应包的一部分内容。此Session-key AS用于确保客户端和TGS之间的通信安全。还有一部分内容就是TGT,使用KDC一个特定账户的NTLM-Hash, 对 Session-key AS、时间戳、Client-info 进行加密。这个特定账户就是创建域控时自动生成的 Krbtgt 用户,然后将这两部分以及 PAC 等信息回复给 Client,即 AS_REP 。PAC 中包含的是用户的 SID、用户所在的组等一些信息。
接着来看PKINIT的认证流程:
(1)client使用向CA申请的证书与client自己的私钥加密的时间戳发送给KDC。
(2)KDC 通过CA证书链验证client的身份,并获取到client证书里面的公钥,然后用公钥解密时间戳,并判断时间戳是否符合规定时间。
(3)若上述身份验证通过,并且时间戳符合规则则返回TGT与一个会话密钥(其中会话密钥使用下面两种算法生成)。
PKINIT 是不太常见的非对称密钥方法。客户端有一个公/私密钥对,并用他们的私钥对预验证数据进行加密,KDC 用客户端的公钥对其进行解密。KDC 还有一个公/私密钥对,允许使用以下两种方法之一交换会话密钥:
(1)Diffie-Hellman Key Delivery
该方法允许 KDC 和客户端安全地建立共享会话密钥,即使攻击者拥有客户端或 KDC 的私钥。会话密钥将存储在 TGT 的加密部分,它是用 Krbtgt 帐户的密钥(哈希)加密的。关于Diffie-Hellman,可参考这篇文章
https://www.liaoxuefeng.com/wiki/1252599548343744/1304227905273889
(2)Public Key Encryption Key Delivery
该方法使用 KDC 的私钥和客户端的公钥来封装由 KDC 生成的会话密钥。
具体流量方面的分析我会在后面的文章中介绍正常的kerberos与PKINIT之间的不同。
在2021年BlackHat发布的《Certified_Pre-Owned》白皮书中详细介绍了ADCS的滥用手法,下面针对不同的证书模板错误下导致域权限提升的攻击手法进行配置与分析。
1.ESC1
满足上面条件时,当攻击者在请求证书时可以通过
CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT字段来声明自己的身份,从而获取到伪造身份的证书。
使用certsrv.msc打开证书颁发机构,首先创建一个模板,右击证书模板 ->管理 -> 右击现有的证书模板 -> 复制模板,然后配置错误模板。
我们可以利用certify.exe find 来查看我们配置,发现我们的msPKI-Certificate-Name-Flag的属性值为ENROLLEE_SUPPLIES_SUBJECT,也就是可以指定使用者身份,即可以在请求中提供。
利用此模板来申请一个证书,此时我的账户名为test1,是一个域内本地管理员权限。
使用命令:
Certify.exe request /ca:DC03Server.lohack.cm\lohack-DC03Server-CA-2/template:ESC1 /altname:administrator
查看我们申请证书的使用者名称。
接着从-----BEGIN RSA PRIVATE KEY-----到-----END CERTIFICATE-----复制出来,保存为ESC1.pem,然后利用openssl来转换为ESC1.pfx,无需设置密码。
①key后缀的,只包含私钥
②crt/cer 后缀的,只包含公钥
③csr后缀的,证书申请文件,不包含公钥,也不包含私钥。没啥用
④pfx,pem,p12后缀的,包含公私钥,我们最喜欢的。
利用工具Rubeus.exe来申请我们所需要的TGT,此处的ESC1.pfx就是我们刚刚申请的证书,可以发现在我们申请证书之前,我们dir域控是不行的。
此时dir域控,可以发现成功dir。
此时查看凭据,存在cifs服务票据。
2.ESC2
同ESC1一样,生成模板,此时设置应用程序策略为空,也就是EKU为空或ANY EKU。
利用certify.exe find 命令来查看模板ESC2配置,可以发现msPKI-Certificate-Name-Flag为ENROLLEE_SUPPLIES_SUBJECT,pkiextendedkeyusage与mspki-certificafte-application-policy都为空。
此时利用certify生成证书
Certify.exe request /ca:DC03Server.lohack.cm\lohack-DC03Server-CA-2/template:ESC2 /altname:administrator
同ESC1一样生成pfx证书,然后利用rubues请求TGT票据,尝试列出域控目录
3.ESC3
模版一为颁发“注册代理”证书
模板二为允许使用“注册代理”证书去代表其他用户申请身份认证证书:
Certify.exe request /ca:DC03Server.lohack.cm\lohack-DC03Server-CA-2 /template:ESC3
Certify.exe request /ca:DC03Server.lohack.cm\lohack-DC03server-CA-2/template:ESC32 onbehalfof:lohack\administrator /enrollcert:ESC32
Rubeus.exe asktgt /user:administrator /certificate:ESC44.pfx /dc:10.10.21.2 /ptt
4.ESC4
证书模板是 AD 中的安全对象,这意味着它们具有安全描述符指定哪些 AD 主体对模板具有特定权限。如果模板具有允许非特权的AD主机编辑权限,那么此模板便可面临攻击。
如果攻击者对模板对象拥有writeProperty权限,可以修改模板AD对象属性,则可以将错误配置写到模板中,例如允许域成员在mspki-certificate-name-flag属性中启用CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT标志,则与ESC1具有相同的滥用场景。
下面配置模板
查看模板配置
接着使用admod修改mspki-certificate-name-flag
申请证书
最后可通过证书申请并导入票据