HackTheBox : Forest

0liverFlow
11 min readAug 10, 2024

--

Forest

Forest is a windows Domain Controller (DC) with an Exchange Server installed on it. The DC is found to allow anonymous LDAP binds, which is used to enumerate domain objects. The password for a service account with Kerberos pre-authentication disabled can be cracked to gain a foothold. The service account is found to be a member of the Account Operators group, which can be used to add users to privileged Exchange groups. The Exchange group membership is leveraged to gain DCSync privileges on the domain and dump the NTLM hashes.

Reconnaissance

Nmap

Nmap scan
NSE scripts

RPC — TCP/135

Enumerating domain information

Domain information

Enumerating domain users

Domain users

Enumerating domain groups

Domain groups

Enumerating user information

Details of the administrator account

Enumerating domain password info

Password policy info

You could also use the following script to automate the enumeration phases performed above :

#!/bin/bash

# Enum users, groups, shares and the password policy
cmds=(enumdomusers enumdomgroups netshareenum getdompwinfo)

for cmd in ${cmds[@]}
do echo $cmd | awk '{print toupper($0)}'
echo "--------------------"
rpcclient -U '' -N forest.htb -c $cmd
echo
done
Enumerate users, groups, shares and password policy using customized script

LDAP — TCP/389

LDAP (Lightweight Directory Access Protocol) is a protocol that helps users find data about organizations, persons, and more.

It has two main goals: to store data in the LDAP directory and authenticate users to access the directory. It also provides the communication language that applications require to send and receive information from directory services. A directory service provides access to where information on organizations, individuals, and other data is located within a network. You can see it like a database for storing and maintaining information about users and resources. To interact with directory services, we will use ldap queries. These are commands used to retrieve information from a directory service.

LDAP offers two main authentication types :

  • Simple authentication : This requires only distinguished username and password. This authentication method is unsafe see that the user’s password is sent in cleartext.
  • SASL (Simple Authentication and Security Layer) : SASL binds an LDAP server to other authentication mechanisms, such as kerberos. The LDAP server sends the message in cleartext to other authorization services but attaches a security layer that protects the data.

Well, let’s get our hands dirty by enumerating ldap using a tool called ldapsearch. This opens a connection to an LDAP server, binds and performs a search using specified parameters.

Ldap enumeration with ldapsearch

Here is a quick explanation of the different flags :

  • -LL : used to control the format of the output.
  • -H : used to specify the LDAP uri
  • -x : used for simple authentication. In our scenario, we’re attempting an anonymous authentication.
  • -b : used to specify the basedn (base distinguished name) to start from.

As you can notice, ldap anonymous bind is allowed. This allows unauthenticated users to retrieve information from the domain, such as a complete listing of users, groups, computers, user account attributes, and the domain password policy. That said, let’s take a look at that :

Users enumeration

Great! We found 30 users. Let’s now enumerate the SMB server. Shall we ?

SMB — TCP/445

In this section, we are going to enumerate the SMB shares. For that, we will begin with shares enumeration :

Share enumeration
Supported SMB protocols
ms17–010 vuln check

Let’s now perform further enumeration using an amazing tool called enum4linux-ng which is a python implementation of the enum4linux ruby script.

By default, it will perform all simple enumeration (-A) if no option is provided. In more details, it will use RPC to get the users (-U) , groups (-G), shares (-S), password policy (-P), OS information (-O), printer information (-I), domain information (-L). It will also do an NetBIOS name lookup (-N).

Note : If you’re not interested in NetBIOS name lookup, but want to enumerate all the other information mentioned above, you can use the -As option.

Open ports and NetBIOS name lookup
SMB dialects and domain information
Users enumeration
Groups enumeration

You might not notice it, but enum4linux-ng returned 31 users during the users enumeration while ldapsearch returned 30 users.

After a quick comparison, I found that the missing user was svc-alfresco.

Therefore, I added him to the users.txt file created during the users enumeration with ldapsearch.

Now the question we should ask ourselves is : “How can we get an initial access to the domain environment using the information obtained during our enumeration phase ?”

Many attack vectors can be tried. Here are a few :

  • Perform a password spraying attack using a list of common/weak passwords.
  • Check if users used their username as their password
  • Perform an AS-Rep roasting attack

Knowing that we already have a list of valid domain users, we can try to perform an AS-Rep roasting attack.

AS-REP Roasting

To perform this attack, we can either use kerbrute or impacket-GetNPUsers :

AS-Rep roasting attack using kerbrute
AS-Rep roasting with impacket-GetNPUsers

Hash Type

Prior to crack the hash, we need to identify its type. For that, we can use a tool called name-that-hash :

Hash type

Cracking NT Hash

To crack the hash, you can either use John the Ripper or Hashcat. The choice is yours.

NT hash successfully cracked

Excellent! Let’s verify if we can get a shell on the target machine.

Initial Access

Authentication check
Bypassing the AMSI
User flag

Well, let’s now perform some local reconnaissance. Shall we ?

svc-alfresco privileges
svc-alfresco account information

Once done, let’s perform a password spraying attack to check if svc-alfresco’s password was reused by other users :

Password spraying

Unfortunately, that’s not the case.

Post-compromission enumeration & attacks

Well, let’s first collect the domain information using sharphound, then visualize it with bloodhound.

Python web server
Downloading SharpHound
Collecting domain information

Let’s download the collected information on our attacker machine :

Downloading the collected information on the attacker machine

Let’s upload the collected domain data in bloodhound :

Uploading data in bloodhound

Fantastic! We can now use the prebuilt analytic queries to check the different attack paths that we can take to compromise high value targets.

Here are the queries, I executed :

Find all Kerberoastable Accounts

Find all Kerberoastable Accounts

As you can see, except the krbtgt account (which is normal), there is no other kerberoastable account.

Shortest Paths to Domain Admins from Owned Principals

Shortest Paths to Domain Admins from Owned Principals

Interesting! Seems that the Administrator has a session on the FOREST machine. Let’s check what this means :

HasSession Explanation

To abuse that we can either try to dump the administrator’s credentials or perform a token impersonation attack. Nonetheless, to dump the credentials we must have administrative access on the compromised host which is not the case in our scenario.

Well, let’s check if we can escalate our privileges by trying to look for privesc vectors using winpeas.

First let’s transfer winpeas to the target system :

impacket-smbserver -smb2support -user haxor -password P4ssw0rd! toolkit .
Launching SMB Server
$pass = convertto-securestring 'P4ssw0rd!' -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential('haxor', $pass)
Creating PS credential
New-PSDrive -Name privesc -PSProvider FileSystem -Credential $cred -Root \\10.10.14.13\toolkit
Connecting to SMB share
Accessing the SMB share
Winpeas execution
Autologon credentials and password policy

Sad to say but I found nothing really interesting that could help me to either move laterally or escalate my privileges.

Let’s keep on with our attack paths enumeration using bloodhound :

Shortest path from owned principals

Shortest Path From Owned Principals

Based on the graph above, there is a new machine EXCH01.HTB.LOCAL.

However, we don’t know its IP address. Therefore we need to perform a name resolution. Knowing that DNS is open internally, we can use nslookup to resolve the machine name :

DNS

Knowing DNS is running internally, we can perform a nslookup to get the IP address corresponding to the exchange server :

Name Resolution

Another piece of information that we can retrieve from the graph is that svc-alfresco is part of the Account Operators group.

Let’s check if there is an existing path from that group to the domain admins group :

Path from Account Operators to Domain Admins

Awesome! We got two paths.

We will try to exploit this path : Account Operators -> Exchange Windows Permissions -> HTB.LOCAL -> Domain Admins.

As we can see, the members of the Account Operators group have GenericAll ACE for the group Exchange Windows Permissions. This ACE allows the trustee (members of the Account Operators) to have full complete control over the object. For example, they can add an AD object to the target group.

Moreover, the Exchange Windows Permissions group have WriteDacl ACE on the domain HTB.LOCAL. This means that we can grant ourselves any privilege we want on the object. For instance, we can grant ourselves DCSync privileges. Sounds pretty cool, right ?

That said, to exploit these ACEs, we will first add our user to the Exchange Windows Permissions group, then we will grant him DCSync privileges which he will then use to dump the secrets from the domain.

Let’s walk the talk. Shall we ?

Here, we are going to use the Remote Server Administration Tools (RSAT) for Windows which include some useful Active Directory tools.

Downloading powershell script to exploit ACEs

To avoid entering manually the commands, I created a powershell script that automates the entire process :

Exploiting ACEs
Dumping domain controller’s secrets
Testing each hash with its corresponding username
Getting a remote shell
Root flag

Last but not least, I didn’t want to end this CTF without checking at least one of the dangerous vulnerabilities on Active Directory which is zerologon :

Vulnerable to zerologon

You might not believe it but the target is vulnerable which means that an attacker can be Domain Admin without any valid credentials. All he needs is to be in the internal network. You can find more details here.

Findings and Recommendations

1/ To get our initial access, we performed an AS-Rep roasting attack against an account that used a weak password. Normally, this should not work see that kerberos pre-authentication is required by default. Refer here for mitigation.

2/ Furthermore, to get Domain Admin we took advantage of over permissive rights. We recommend removing the user svc-alfresco from the Account Operators group.

3/ Last but not least, we noticed insufficient patching. Indeed, the Domain Control was vulnerable to a critical vulnerability that allows an attacker to become Domain Admin with no valid credentials. Refer here to patch that.

Wrapping Up

That’s it guys. Congrats on having made it so far 👏.

I hope you enjoyed the writeup.

If so, do not forget to click on the little clap icon below and subscribe to my newsletter to keep up with my latest articles.

--

--

0liverFlow
0liverFlow

Written by 0liverFlow

Pentester | Enjoy breaking and building stuffs

No responses yet