HackTheBox : 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
RPC — TCP/135
Enumerating domain information
Enumerating domain users
Enumerating domain groups
Enumerating user information
Enumerating domain password 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
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.
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 :
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 :
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.
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 :
Hash Type
Prior to crack the hash, we need to identify its type. For that, we can use a tool called name-that-hash :
Cracking NT Hash
To crack the hash, you can either use John the Ripper or Hashcat. The choice is yours.
Excellent! Let’s verify if we can get a shell on the target machine.
Initial Access
Well, let’s now perform some local reconnaissance. Shall we ?
Once done, let’s perform a password spraying attack to check if svc-alfresco’s password was reused by other users :
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.
Let’s download the collected information on our attacker machine :
Let’s upload the collected domain 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
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
Interesting! Seems that the Administrator has a session on the FOREST machine. Let’s check what this means :
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 .
$pass = convertto-securestring 'P4ssw0rd!' -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential('haxor', $pass)
New-PSDrive -Name privesc -PSProvider FileSystem -Credential $cred -Root \\10.10.14.13\toolkit
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
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 :
Knowing DNS is running internally, we can perform a nslookup to get the IP address corresponding to the exchange server :
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 :
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.
To avoid entering manually the commands, I created a powershell script that automates the entire process :
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 :
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.
Resources
https://book.hacktricks.xyz/network-services-pentesting/pentesting-smb/rpcclient-enumeration
https://www.hackingarticles.in/active-directory-enumeration-rpcclient/
https://www.redhat.com/en/topics/security/what-is-ldap-authentication
https://blog.netwrix.com/2024/02/19/ldap-vs-active-directory/
https://www.netwrix.com/ldap_reconnaissance_active_directory.html
https://github.com/BloodHoundAD/BloodHound/tree/master/Collectors
https://book.hacktricks.xyz/windows-hardening/active-directory-methodology/bloodhound
https://bloodhound.readthedocs.io/en/latest/data-analysis/edges.html#genericall
https://bloodhound.readthedocs.io/en/latest/data-analysis/edges.html#writedacl
https://github.com/0liverFlow/CTF-Tools/blob/main/AD/DCSyncExploiter.ps1
https://msrc.microsoft.com/update-guide/en-US/advisory/CVE-2020-1472
https://www.crowdstrike.com/blog/cve-2020-1472-zerologon-security-advisory/
Contact
GitHub : https://github.com/0liverFlow