Hack The Box — Forest Write-up. Forest is a Hack The Box machine marked…
By: Gabriel Pirjolescu
Tags: Penetration Testing, Windows, Active Directory, Hackthebox

Forest is a Hack The Box machine marked as easy with a difficulty score of 5.6 out of 10. It features an Active Directory Domain Controller with full functionalities. The initial foothold phase requires mainly enumeration and understanding of Kerberos attacks. For the privilege escalation we will have to enumerate the Active Directory paths and abuse ACLs rights.

Initial Foothold

Before starting the actual exploration on the machine, it’s best to add the mapping from the hostname of the machine to the IP address to the /etc/hosts file so that it automatically resolves the IP from the hostname.

/etc/hosts

Now we need to find the services running on the machine by scanning the ports. First, we will run a full-range TCP port scan to find the open ports. The -p- parameter stands for the whole range of ports, while -oN will write the normal output to a file.

TCP scan for the full range of ports.

Next, we will take the open ports and run a more thorough scan on them. The parameter -sC makes use of nmap’s standard enumeration scripts and -sV enumerates also the standard version of the service running on a port. It is clear from the open ports that the machine is Windows domain controller since most of the services are the one used in an Active Directory setting such as Kerberos, MSRPC, SMB and DNS.

Enumerating the open ports using standard scripts

A good starting point in enumerating Windows systems is the enum4linux tool. It has several important features such as user listing, share enumeration, identifying the remote OS and listing group membership information. In our case, it managed to find users, password policy information, groups and domain group membership. The most important information provided was the list of usernames. To get the list of users a technique called RID cycling was used which leverages a so-called null session attack. A null session is an unauthenticated (actually authenticated with an anonymous user) connection to the IPC$ share. After establishing the connection, one can find out the SID/GUID of the domain. Finally, with the GUID the attacker can cycle through the whole range of possible RIDs, enumerating all the accounts in the domain.

A list of users enumerated by the enum4linux tool

After several unsuccessful tries of establishing a foothold, I have tried a Kerberos attack called AS-REP roasting, which abuses user accounts that don’t require Kerberos preauthentication. Usually, when a user initiates a TGT request, it has to supply a timestamp encrypted with that user’s hashed password. The Key Distribution Center then decrypts the timestamp to verify if the subject making the request really is that user, and then returns the response and continues with normal authentication procedures. The problem is that the response’s encrypted part is signed with the client key. Therefore, if preauthentication is not enabled, an attacker can send a request for that user which doesn’t have preauthentication enabled and received the encrypted response which can be cracked offline. In our case, we use the lists of users to try the attack for each one of them by using the following command.

GetNPUsers.py htb.local/ -dc-ip 10.10.10.161 -usersfile usernames.txt -format john -outputfile hashes.asreproast john --wordlist=/usr/share/wordlists/rockyou.txt hashes.asreproast

The attack successfully returned the encrypted response for a service account named svc-alfresco . Then, john was used to crack it.

hashes.asreproast

Having the credentials for the svc-alfresco user, the next step was to connect to the machine. Usually, the service account is not allowed to connect to the machine interactively. To bypass this, I have used the Windows Remote Management protocol, which is an implementation of WS-Management Protocol. This is a protocol used by hardware and operating systems from different vendors to interoperate. Evil-WinRM is the perfect tool for this since it has powerful features such as loading Powershell scripts, DLLs and C# assemblies in memory memory combined with upload and download file functionalities.

Privilege escalation

Knowing that the machine is a Domain Controller, my intuition was that another Active Directory attack will be needed for the privilege escalation. In our case, the setup is made up of only one machine. However, manually enumerating and discovering paths in a vast AD environment would be painfully slow. Bloodhound was created exactly for this reason. It uses graph theory to reveal hidden relationships in an AD environment. Bloodhound uses the Neo4j graph database technology that can easily discover relationships and calculate shortest paths between nodes and it is written in JavaScript as a standalone desktop application. To gather the data an ingestor called SharpHound is used. It has two different variants, one written in Powershell and the second one is a compiled C# binary.

The SharpHound ingestor

In my previous experience, I have learned that invoking Powershell directly from Evil-WinRM prevents the output of errors. Therefore I first started a Powershell remote shell, imported the model and then ran it. The documentation for the parameters used by Invoke-Bloodhound can be found here. As we can see from the image, SharpHound creates a zip file with some JSONs inside. The zip file can be dragged-and-dropped in the Bloodhound interface.

The BloodHound interface

Another tool that can be used in combination with BloodHound is aclpwn. It identifies and exploits ACL-based privilege escalation paths. The arguments needed are the source (the user that’s been compromised already) and the destination (it can be a user or a domain). In our case, we want to get from user svc-alfresco to the htb.local domain. As you can see it found two ACL attack paths. An Access Control List (ACL) is a set of rules in a domain which can be configured for either an object or an Organizational Unit (OU). All objects inside the OU will inherit the ACLs that determine how they can interact in between them (an object can be anything — a user, a group, a machine, etc).

Running aclpwn

What happens in our case is that in both cases the user wants to achieve WriteDacl permissions on the domain object. WriteDacl provides the ability to modify security on an object which can lead to Full Control of the object. By default, the user in Exchange Windows Permission group can do this. The next step down the chain is to GenericAll , which means that an object has “The right to create or delete children, delete a subtree, read and write properties, examine children and the object itself, add and remove the object from the directory, and read or write with an extended right” of another object. The next steps are MemberOf , which means a group is a member of another group.

In case you were wondering why do we need WriteDacl permissions on the domain, the answer is to grant DCSync privileges. DCSync right allows an attacker to simulate the behaviour of a Domain Controller and it has two stages:

Discover the Domain Controller in the provided domain Request the Domain Controller to replicate the user credentials

The attack can be performed either over the network by using the Impacket secretsdump.py script or by dropping mimikatz on the target. I have chosen the latter option. Finally, I have used a Pass-The-Hash attack to login as the Administrator user by using the hash extracted with mimikatz.

Performing a DCSync attack using mimikatz

Pass-The-Hash using wmiexec.py

Prevention and detection

The first step in preventing such an attack would be not leaving unneeded ports open. Besides, an Intrusion Prevention/Detection System can be installed to alert and defend from most attacks described here.

Following, to prevent RID cycling one can disable SID enumeration by disallowing the enumeration of SAM accounts and shares and also disallowing anonymous SIDs and name translation. Also, anonymous login to IPC$ can be disabled. An easy way to defend from AS-REP roasting is to make sure Kerberos preauthentication is enabled.

Another thing to keep in mind is that service accounts such as svc-alfredo are not supposed to perform interactive logins and perform commands. Therefore, alerts can be set up for such activities. It is easy to detect when scripts or binaries such as SharpHound.ps1 and mimikatz.exe are dropped on the disk by checking the hash. However, some techniques allow them to be run in-memory. To detect this, deep packet inspection can be enabled to detect them before reaching the host.

To defend against ACL attacks the one should take the stand of the attacker and audit the policies. A good thing is to restrict permission delegation so that admins on the hosts are not also domain admins. ACL changes need to be monitored and system access control lists (SACLs) can be used to monitor and alert when objects in ACLs are accessed or modified.

Contact

If you would like to get in touch you can contact me on one of the following platforms: