Forest started with Windows enumeration using SMB and LDAP queries that lead to leveraging a lingering service account with PRE_AUTH disabled for user access. Once on the machine, we were able to abuse the existing Active Directory entitlements to create a malicious user entry with the rights to perform a DCSync using Mimikatz to acquire the Administrator's hash, finally using it to execute a pass-the-hash escalation to Administrator.
Despite the chronological time of this writeup being released, Forest was one of the first HTB machines where I really had a chance to dig into AD/Kerberos from a Windows and offensive tools perspective. There were definitely some roadbumps throughout the process, but looking back on it now that I have completed a few more of these types of machines I realize Forest was indeed a great introduction to the technology stack.
Let us kick this off with an NMAP scan to see what we are working with.
Side comment: Going back through my notes makes me realize how much I've learned from a process standpoint. Today, if I would have seen the above and immediately would have gone for an LDAP root-dse query followed up by enumerating users from that angle. I will leave the details of how that can be done out for now as I will address it in coming writeups.
We needed to continue our enumeration. I tried a few different things like SMB enumeration, NMAP scripts, and enum4linux. They all "worked" but I feel in this particular case enum4linux provided the most relevant data.
With this we have a few user accounts to play with. Let us see what we can do with them.
Time to go a bit into Kerberos theory. If we follow the diagram I whipped up below we can follow the three steps of accessing a Kerberized service: AS -> TGT -> TGS.
To understand the next step and why we chose a certain script within impacket, let us add one extra detail to this background authentication flow - kerberos pre-authentication. LDAPwiki does a great job of explaining firstly what it is and then what can happen when it is not set.
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.
That last part is exactly what we are interested in. If there are accounts that have pre_auth explicitly disabled we would be able to request a TGT as that user and then pass the encrypted data to our favorite JTR/Hashcat. Impacket has a very useful script for exactly this - GetNPUsers.py.
Excellent! Looks like we were able to capture a request for the account svc_alfresco. If we take a quick peek at the captured hash...
For no other reason than "because" I felt like using Hashcat at this particular point. If we run this hash through hashcat with the trusty rockyou.txt wordlist.
We now have a user and password credential set! Perfect! Let us log in and see if we can get to our first flag.
User down, time to move on to Administrator.
Now that we have user access, let's see how we can escalate our entitlements. Since this is a Windows/Active Directory based machine we can use tooling like Bloodhound to check on combined entitlements that can be used to help our efforts out. I focused on using the python version as I found it easier and more stable to work with rather than running on the host locally and passing the result files back over to our own machine.
Starting our ne04j and bloodhound instances locally we can then import these result files. First we trace down what entitlements our svc-alfresco service account has, then secondly show the relationships our end-goal Administrator has.
So what does this mean? Took me awhile to understand what angle we wanted to achieve here. It essentially boils down to we have the ability, to give ourselves the ability, to trigger a DCSync between the EXCH01.htb.local and FOREST.htb.local, which should provide us the Administrator (or any account for that matter) password hash.
The theory behind the approach can be seen this github repo and has a few other related escalation approaches worth reading up on. First up, we need to ensure we are added to the Exchange Windows Permissions Group which grants up writeDACL on the domain object itself. Again here, knowing what I know now I would have just leveraged svc-alfresco and added that account the group, but for my lack of understanding I first created a new user, TEST3, to which I then added to the proper groups.
With our user created and in the right group, we still had one last step to prepare before we could execute the dcsync exploit. The theory behind the approach can be seen this article and elaborates that we should need DS-Replication-Get-Changes-All. Let's add that to our new TEST3 user.
A quick relog to apply the changes and now we should be ready to kick off the dcsync. Despite many options available I ended up loading mimikatz to the host to run the attack locally.
Beautiful, we have our Administrator hash. All that is left is to kick off a pass-the-hash to start a session as Administrator.
Last step, let's get root.txt.
And just like that Forest is complete. Thanks folks until next time.
Looking back on my notes and approach here I definitely see how while this machine was overall simplistic, it highlighted my lack of knowledge on these topics. In future machines of this nature I would generally try and focus on a few different things.
Keep things simple and use what is present - Instead of creating a new account which can leave incriminating logs and evidence, I should have leverage the svc-alfresco account more.
Avoid uploading files - Similarly instead of sending executables and result files back and forth between hosts I could have tried focusing on remote possibilities.
Overall, it got me to the same conclusion, but the point of going through these exercises is to improve our overall knowledge and thinking processes. This machine definitely achieved that goal.
Follow me and let me know what you think of this article on twitter!