Operation Endgame

This challenge will focus on exploiting an Active Directory environment. - by h4sh3m00

The following post by 0xb0b is licensed under CC BY 4.0arrow-up-right


Scenario

So, Operation Endgame was firing on all cylinders. Sneaky Viper, our black hat crew, had become the worst nightmare. After months of gathering information and carrying out operations, we found the way to their system, and boom: mission complete.

Summary

chevron-rightSummaryhashtag

In Operation Endgame we begin with only VPN access to a Windows Domain Controller in the thm.local domain and no valid credentials. While web enumeration yields nothing useful, we successfully authenticate to SMB as guest with a blank password and enumerate shares. Using RID brute-forcing over IPC$, we extract a list of valid domain usernames for further attacks.

With usernames in hand, we attempt AS-REP Roasting but fail to crack the hashes. Pivoting to Kerberoasting using the guest account, we retrieve a TGS for the user CODY_ROY and successfully crack it. Using the recovered credentials, we authenticate via SMB and RDP. BloodHound enumeration reveals no immediate path to Domain Admins through CODY_ROY, but a password spray using CODY_ROY's cracked password uncovers credential reuse by ZACHARY_HUNT. BloodHound analysis shows that ZACHARY_HUNT has GenericWrite over JERRI_LANCASTER, enabling a Targeted Kerberoast attack by adding an SPN to the account. We request and crack the TGS for JERRI_LANCASTER, gaining access to that account.

As JERRI_LANCASTER, we obtain access to the C:\Scripts directory and discover syncer.ps1, which contains credentials for SANFORD_DAUGHERTY, a Domain Admin. After authenticating via RDP and launching an elevated command prompt using Ctrl+Shift+Enter to bypass UAC restrictions, we obtain administrative privileges and retrieve the final flag from the Administrator’s desktop.

An unintended path also exists. BloodHound reveals that the GUESTS group has GenericWrite over the domain controller computer object. Using the guest account’s empty NTLM hash, we perform a Resource-Based Constrained Delegation (RBCD) attack, delegating control from CODY_ROY to AD$. With getST.py, we impersonate Administrator for the CIFS service and authenticate to SMB via Kerberos without a password. From there, we achieve full domain compromise and can directly add users to the Domain Admins group. Both paths ultimately demonstrate full Active Directory takeover from an initial anonymous SMB foothold.

Recon

We use rustscan -b 500 -a 10.113.179.210 -- -sC -sV -Pn to enumerate all TCP ports on the target machine, piping the discovered results into Nmap which runs default NSE scripts -sC, service and version detection -sV, and treats the host as online without ICMP echo -Pn.

A batch size of 500 trades speed for stability, the default 1500 balances both, while much larger sizes increase throughput but risk missed responses and instability.

The target machine is a domain controller AD.thm.local / thm.local with exposed services including DNS 53, Kerberos 88/464, LDAP/Global Catalog 389/636/3268/3269, and SMB 139/445 with message signing required. It runs Microsoft IIS 10.0 on ports 80 and 443, plus RDP 3389 with a valid AD certificate, RPC services 135, 593, 49664–49710 range, .NET Message Framing 9389, and Microsoft HTTPAPI 47001.

Since we don't have any credentials and couldn't find anything on the web server we try to authenticate as guest and anonymously against SMB. We can successfully authenticate ourselves as the user guest. Not only can we authenticate ourselves, we can also list shares, including the IPC$ share.

To further enumerate domain users, we perform a RID brute-force, since the IPC$ share is readable.

We then craft a users list with the follwing command. These users may be helpful later on.

We generate the hosts file entry like the following:

And add the following line to our /etc/hosts file.

Access as CODY_ROY

AS-REP Roastting

Now that we have some usernames, we can try AS-REP Roasting by requesting a Kerberos AS-REP response for accounts that do not require pre-authentication, allowing us to capture the encrypted response and crack it offline to recover the user's password.

We use NetExec for AS-REP Roasting and are able to extract the blob from several users.

But we aren't able to crack them...

Kerberaosting

Since we can authenticate as guest, we could also try kerberoasting

Unlike ASREProastingarrow-up-right, this attack can only be carried out with a prior foothold (valid domain credentials), except in the Kerberoasting without pre-authenticationarrow-up-right scenario.

We perform a Kerberoasting attack using the guest account and successfully retrieved the TGS ticket for the service account CODY_ROY using nxc ldap.

Next, we crack the hash.

We are able to authenticate against SMB on the domain controller with the credentials gathered.

We are also able to use RDP, but the environment seems to be restricted. We can't open the explorer or other apps on the target.

We still can still use WINDOWS+R to open the run prompt and execute a CMD shell.

At first glance, we don't find anything special on the target. In the C: directory, we find the Scripts folder. This could contain usable loot, but we don't have read permission as CODY_ROY.

We can't even view the permissions for the folder.

BloodHound Enumeration

With the credentials, we can now also enumerate the AD using BloodHound.

CODY_ROY has some interesting permissions. As part of the EVERYONE group, the user has GenericWrite Permission on various users, which would allow us to perform a shadow credential attack or a targeted kerberoast attack on each of those users. But at first glance, those users do not have any interesting permissions or group memberships.

The user CODY_ROY is also not part of a special group. We seem to have reached a dead end here.

We can identify the following users as domain administrators:

If we look at the shortest path to domain admins, we find that the user guest has exceptional permissions. That allow us to escalate to the domain administrators.

When we look at the guest user's Outbound Object Control, we see that we essentially have a GenericWrite on all users, but also on the domain controller machine. We will look at this path last, as I believe it is an untintended path. I had chosen this path for the original release of the challenge some time ago. It was part of a CTF held by THM at DEFCON 32.

Intendend Path

Access as ZACHARY_HUNT

From our previous enumeration, we were able to create a user list and crack a password of CODY_ROY from the TGS blob. If we didn't have the guest user with the aformentioned permisssion, how could we proceed?

Next, we could look at the password policy and, perform a password spray with all usernames = password or with classic passwords like Winter2026. However, this lock the accounts.

We'll try a password spray with the password of CODY_ROY, even though it doesn't look like it's being used by anyone else.

And we have a hit. ZACHARY_HUNT is also using that password.

We test the credentials using NetExec. We successfully authenticated and can list the shares.

We review our bloodhound data again and inspect what the user has for groups or permissions. ZACHARY_HUNT has GenericWrite permissions over JERRI_LANCASTER.

The user JERRI_LANCASTER is member of the READER ADMINS group. Let's see what we can do with that.

Access as JERRI_LANCASTER

Since we have a GenericWrite permission as ZACHARY_HUNT over JERRI_LANCASTER er try to perfom a targeted Kerberoast attack. In the hope to retrieve a crackable TGS. A shadow credential attack for now is less helpful because this will give us a hash and we only have RDP in place to connect requiring a password.

See below links for further reading

This abuse can be carried out when controlling an object that has a GenericAll, GenericWrite, WriteProperty or Validated-SPN over the target. A member of the Account Operatorarrow-up-right group usually has those permissions.

The attacker can add an SPN (ServicePrincipalName) to that account. Once the account has an SPN, it becomes vulnerable to Kerberoastingarrow-up-right. This technique is called Targeted Kerberoasting.

To perform the TargetedKerberoast we will use the following tool:

We run the following command and are able to get the Kerberos 5, etype 23, TGS-REP blob of the JERRI_LANCASTER user.

We use hashcat to crack the blob and are able to retrieve the password of JERRI_LANCASTER.

We test the credentials using NetExec. We successfully authenticated and can list the shares.

As JERRI_LANCASTER, we authenticate via RDP. Still the environment is restricted like for all other users. But we spawn a CMD shell.

And now we are able to read the C:\Scripts directory. It includes a syncer.ps1 which has the credentials of SANFORD_DAUGHERTY.

Shell as SANFORD_DAUGHERTY

Recalling our BloodHound data we know that this user is a Domain Admin.

We connect via RDP with the credentials gathered. Run a CMD shell...

... and we do not have the privileges. We did not start it in the context of an Administrator.

If instead of hitting enter in the RUN command prompt and issue the following combination from CTRL SHIFT ENTER to spawn a CMD shell as administrator. The UAC prompt pops up. We confirm...

... and retrieve an administrator shell.

We find the final flag at C:\Users\Administrator\Desktop.

Unintended Path

We noticed that the GUESTS group has a generic write permission on the computer object AD.THM.LOCAL. We had something similar back then in the Ledger room.

Recalling: We found this path by Shortest Path to Domain Admins

This allows us a Resource-Based Constrained Delegation attack on the domain controller.

The rbcd.py script requires a password

Empty password hash for guest: 31D6CFE0D16AE931B73C59D7E0C089C0

With the follwing rbcd.py command we perform a Resource-Based Constrained Delegation attack in the THM.LOCAL domain by authenticating as the guest account using the empty NTLM hash 31D6CFE0D16AE931B73C59D7E0C089C0 to modify the AD$ computer object so that the machine account CODY_ROY is allowed to delegate to it, enabling potential privilege escalation via Kerberos delegation abuse.

Next, we use getST.py to authenticate as the CODY_ROY account with its password, request a Kerberos service ticket for the SPN cifs/AD.THM.LOCAL, and impersonate the Administrator user via delegation, effectively obtaining a service ticket that allows access to the CIFS service on AD.THM.LOCAL as Administrator.

We set the KRB5CCNAME environment variable to use the Kerberos ticket cache file Administrator@cifs_AD.THM.LOCAL@THM.LOCAL.ccache we received.

Next we connect to the SMB service using Kerberos authentication -k without supplying a password -no-pass as Administrator. From there we can exfiltrate the file.

From here, we can now create new users and assign admin permissions. In this example, we have made CODY_ROY the domain administrator.

Last updated

Was this helpful?