# TryHackMe Operation Endgame—Writeup

Welcome back to my CTF writeup! In this post, I’ll take you through a detailed, step-by-step walkthrough of how I successfully pwned **Operation Endgame**, one of TryHackMe’s latest machines for March 2026. This challenge is all about **Active Directory (AD)**, so we’ll explore every angle—from enumeration and privilege escalation to domain exploitation. I’ll share every tool, technique, and thought process I used to go from initial access to full domain control. Whether you’re new to AD hacking or sharpening your pentesting skills, this writeup will guide you through the entire journey. Let’s dive in and take down this AD environment!

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2F0a83L4PR084edH1ns2BJ%2Fsource.gif?alt=media&#x26;token=05e4504c-0641-4562-9629-61455ee5c83d" alt=""><figcaption></figcaption></figure>

#### Intended Solution

We start by using **Nmap** to discover open ports and potential entry points.

`nmap -sV -sC 10.67.132.244`

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2FlYRqkQiAb6nHGLvwPGNt%2FScreenshot%20(1466).png?alt=media&#x26;token=8535fa94-f09d-4462-bef1-a30aba7c19e1" alt=""><figcaption></figcaption></figure>

From the port scan results, it’s evident that the target is operating as a Domain Controller (DC). This conclusion is supported by the presence of several key Active Directory services:

* **88** – Kerberos
* **389 / 636 / 3268 / 3269** – LDAP (including LDAPS and Global Catalog)
* **445** – SMB
* **53** – DNS

The combination of these services strongly indicates that we are dealing with an Active Directory environment.

We also identified the hostname as **AD** and the domain name as **thm.local**. To ensure proper name resolution, we added the following entry to our `/etc/hosts` file:

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2FDHjrTdvYzlalpMdS1yiS%2FScreenshot%20(1467).png?alt=media&#x26;token=9c36ece7-1b00-4456-8eb2-af42a330a976" alt=""><figcaption></figcaption></figure>

The next step is to verify whether the Guest account has access to the domain.\\

`nxc smb AD.thm.local -u 'guest' -p '' --shares`

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2FcNZ8VUUwr7MMmbW1ybO4%2FScreenshot%20(1468).png?alt=media&#x26;token=66d36758-475c-4b1c-8ecf-977bbd467a9c" alt=""><figcaption></figcaption></figure>

Using `nxc smb`, we confirmed that authentication with the Guest account is successful.

Additionally, the Guest account is able to bind to the LDAP service.

`nxc ldap AD.thm.local -u 'guest' -p ''`

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2FpCx2EjnISCFOqyuJwwDq%2FScreenshot%20(1471).png?alt=media&#x26;token=deafd5ed-69d2-4a4d-87fa-ec7a5e5d7fb5" alt=""><figcaption></figcaption></figure>

Since the Guest account has access to LDAP, we can leverage it to enumerate domain users, particularly those with Service Principal Names (SPNs) configured. Accounts with SPNs are considered **Kerberoastable**, meaning we can request service tickets (TGS) for them from the Key Distribution Center (KDC). These tickets are encrypted using the target account’s password hash, allowing us to extract them and perform offline password cracking.

This works because, in Active Directory environments, any authenticated domain user—including low-privileged accounts like Guest (if permitted)—can request service tickets for service accounts. The Kerberos protocol does not restrict who can request these tickets; it only verifies that the requester is authenticated. As a result, if weak passwords are used for service accounts, we may be able to crack the ticket offline and recover plaintext credentials, potentially leading to privilege escalation within the domain.

`nxc ldap AD.thm.local -u 'guest' -p '' --kerberoasting kerbs.txt`

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2FihCWCImia0jSndrQFNlm%2FScreenshot%20(1472).png?alt=media&#x26;token=d9fb7aae-8526-4948-b5e3-50ff0a14f5ed" alt=""><figcaption></figcaption></figure>

Using `nxc`, we identified a Kerberoastable account and successfully retrieved the TGS hash for the **cody\_roy** account.

Now we can crack it using `john`&#x20;

`john kerbs.txt --wordlist=/usr/share/wordlists/rockyou.txt`

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2FzJpjKbE2EIJKlC4jx9Ce%2FScreenshot%20(1475).png?alt=media&#x26;token=a5f6c275-3822-4e8c-a0bd-9c09ac293829" alt=""><figcaption></figcaption></figure>

Let's try login to RDP using `cody_roy's` credentials

While exploring the system, I found a `C:\Scripts` directory; however, `cody_roy` seems to have restricted access rights.

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2FhOJyvs6tu8wgXsFIUEIZ%2FScreenshot%20(1479).png?alt=media&#x26;token=0777bc71-6058-48eb-8c5c-8ed7bb36c0b9" alt=""><figcaption></figcaption></figure>

To explore more further, with `cody_roy’s` credentials obtained, we can proceed to enumerate the Active Directory environment using `BloodHound`.

`bloodhound-python -u 'cody_roy@thm.local' -p 'REDACTED' -dc AD.thm.local -d thm.local -ns 10.65.190.173 --dns-timeout 10 --zip --dns-tcp -c All`

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2F1JAZSVQwv52SzChSoziP%2FScreenshot%20(1523).png?alt=media&#x26;token=4581236e-221e-4e31-a899-4a02e75c19f1" alt=""><figcaption></figcaption></figure>

(The target IP address changed because I restarted the machine instance due to connectivity issues.)

Now let's start using `BloodHound`!

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2FwHPkGnOpcQc3lR9ATG2i%2FScreenshot%20(1484).png?alt=media&#x26;token=3bb691e7-99ab-4a79-a1ab-21435670e873" alt=""><figcaption></figcaption></figure>

The `cody_roy` account possesses some notable permissions. As a member of the **EVERYONE** group, the user has **GenericWrite** rights over multiple domain users. This level of access enables us to potentially carry out attacks such as a **Shadow Credentials** abuse or a **targeted Kerberoasting** attack against those accounts.

However, upon initial inspection, the affected users do not appear to hold any privileged roles or significant group memberships that would immediately lead to escalation.

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2FHtmQcthOeQUgRj5C6Ulr%2FScreenshot%20(1488).png?alt=media&#x26;token=90fb17bd-ede3-4675-afef-6fea636b9fe3" alt=""><figcaption></figcaption></figure>

Since `cody_roy` is not a member of any elevated groups, further privilege escalation from this account appears limited.

However, since we have recovered a valid password, we can perform a password spraying attack hoping whether other accounts are reusing the same credentials.

We will use `nxc` again to enumerate all the users:

`nxc ldap AD.thm.local -u 'cody_roy' -p 'REDACTED' --users`

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2FyqLVbfbnnIBERsG4z6Bw%2FScreenshot%20(1490).png?alt=media&#x26;token=ecd45096-6cb4-4f72-bb48-dcbb1838bb8a" alt=""><figcaption></figcaption></figure>

After that, I dumped everything into a `.txt` file and filtered it down to just the usernames.

`awk '{print $5}' usernames.txt > clean_usernames.txt`

The command `awk '{print $5}' usernames.txt > clean_usernames.txt` uses **AWK**, a text-processing utility, to extract the fifth column from each line of the file `usernames.txt`. In AWK, `$5` refers to the fifth whitespace-separated field in every line. The command processes the input file line by line, prints only the fifth field, and then redirects (`>`) the output into a new file called `clean_usernames.txt`. As a result, the new file will contain only the values from the fifth column—which are the usernames—listed line by line.

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2FE5mR51wRqRh7olt4nnHq%2FScreenshot%20(1494).png?alt=media&#x26;token=f3320208-f095-4722-a9af-ada11ff47950" alt=""><figcaption></figcaption></figure>

We then used `nxc` once more, leveraging the compiled user list and the recovered password to conduct a password spraying attack.

`nxc smb AD.thm.local -u clean_usernames.txt -p 'REDACTED' --continue-on-success`&#x20;

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2FyweGOMalYlkQuKd1GRJo%2FScreenshot%20(1495).png?alt=media&#x26;token=b9574d96-3a53-48dd-999d-413f3cba472e" alt=""><figcaption></figcaption></figure>

We discovered that the `zachary_hunt` account is using the same password.

Let's check the permission of `zachary_hunt` in BloodHound:

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2FLLHNKlwUjnGp5NkNBQPj%2FScreenshot%20(1500).png?alt=media&#x26;token=70cd1396-50cc-4c98-9d12-7173cdcefec2" alt=""><figcaption></figcaption></figure>

From further enumeration, we observed that this account has **GenericWrite** privileges over the **jerri\_lancaster** user. This permission can be abused to conduct a targeted Kerberoasting attack. By leveraging our write access, we can temporarily assign a malicious SPN to the target account and then request a service ticket for it. Once the ticket is obtained, we can extract the hash and proceed with offline password cracking, following the standard Kerberoasting process.

We leveraged `targetedKerberoast` to request a service ticket and extract the hash for `jerri_lancaster`.

`./targetedKerberoast.py -v -d 'thm.local' -u 'ZACHARY_HUNT' -p 'REDACTED' --dc-host AD.thm.local --request-user JERRI_LANCASTER`

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2F6JNVopjQ70fN0iebuwxY%2FScreenshot%20(1501).png?alt=media&#x26;token=526fcb32-d24b-419c-99a6-97cdef4ea985" alt=""><figcaption></figcaption></figure>

Now let's crack it using `john` :

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2Fg2cA3OHKJJ05rJQf1Tic%2FScreenshot%20(1503).png?alt=media&#x26;token=c32d42f0-e0ef-488c-80b9-d2993eed7ae5" alt=""><figcaption></figcaption></figure>

Now let's analyze `jerri_lancaster` in BloodHound:

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2FaEnc2yXHcJUJrPbxXtAT%2FScreenshot%20(1506).png?alt=media&#x26;token=11d5f0ce-affc-4e19-8810-bfbb020acdf1" alt=""><figcaption></figcaption></figure>

Analyzing the account in BloodHound reveals that `jerri_lancaster` belongs to the **Remote Desktop Users** group.

At this stage, we can leverage the compromised `jerri_lancaster` account to log in through RDP with `xfreerdp3`.

`xfreerdp3 /v:AD.thm.local /u:'JERRI_LANCASTER' /p:'REDACTED' /dynamic-resolution /clipboard /cert:ignore`

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2F2zvKkaXP7Tv5vZYHNp6S%2FScreenshot%20(1508).png?alt=media&#x26;token=87a51be2-1d04-4435-a2db-90f7e60d99aa" alt=""><figcaption></figcaption></figure>

Now we sucessfully access the windows server:

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2FVwxx7Xect4cOBcnjDlOV%2FScreenshot%20(1509).png?alt=media&#x26;token=0ecb23c3-eefc-42f4-baf5-861456da1a2b" alt=""><figcaption></figcaption></figure>

We’ve successfully accessed the `C:\Scripts` directory. Inside, we found a PowerShell script—let’s examine its contents.

`more syncer.ps1`

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2FkpJZrolEVDrj7Mlj45cV%2FScreenshot%20(1510).png?alt=media&#x26;token=b1c22112-5c28-4947-8ec7-3d4466fcbe62" alt=""><figcaption></figcaption></figure>

Upon reviewing the script, we discovered that it contains credentials for the `sanford_daugherty` user.

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2FsCP45scNIt9uWmHtePGD%2FScreenshot%20(1513).png?alt=media&#x26;token=d2ba203e-70d1-4e52-ac75-8ee4251f2b2a" alt=""><figcaption></figcaption></figure>

That's it! Now we can use `impacket-smbexec`  to spawn a shell as `SYSTEM` .

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2FYzf0G0yL90Bpkrx5tRZm%2FScreenshot%20(1516).png?alt=media&#x26;token=88aa3ee7-0c8f-4cdf-8ac3-832e43f80291" alt=""><figcaption></figcaption></figure>

With `SYSTEM` privileges acquired, we can now locate and read the flag.

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2FSuBi6ddiVGIHunpy4YEK%2FScreenshot%20(1518).png?alt=media&#x26;token=f167823a-fd94-47f0-932d-66d4f6dc79d7" alt=""><figcaption></figcaption></figure>

#### Unintended Solution

By analyzing the BloodHound data collected earlier, we observed that the **Guest** account has several assigned permissions. Most notably, it possesses **GenericWrite** rights over the Domain Controller, which is particularly significant.

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2FTMZte0pAaHEAbkyuBiin%2FScreenshot%20(1527).png?alt=media&#x26;token=e95a480c-ee05-4da0-ab0d-5ae024023483" alt=""><figcaption></figcaption></figure>

With **GenericWrite** access over the Domain Controller object, we can abuse this privilege by modifying the `msDS-AllowedToActOnBehalfOfOtherIdentity` attribute. This attribute controls **Resource-Based Constrained Delegation (RBCD)**, a feature in Active Directory that allows one account to impersonate users when accessing a specific resource. By altering this attribute, we can configure the Domain Controller to trust an account we control, effectively allowing us to impersonate privileged users—such as a Domain Admin—when authenticating to the DC.

To successfully perform this attack, we need an account that has a **Service Principal Name (SPN)** set and that we fully control. Typically, attackers create a new computer account for this purpose because computer accounts automatically have SPNs configured by default. However, in our case, this extra step is unnecessary. From our earlier Kerberoasting phase, we already identified that the **cody\_roy** account has an SPN configured, and we successfully recovered its password. Since we control this account and it already satisfies the SPN requirement, we can directly use it to carry out the RBCD attack without creating a new machine account.

This significantly simplifies the exploitation process and moves us one step closer to full domain compromise.

`impacket-rbcd THM.LOCAL/guest -no-pass -dc-ip 10.66.129.137 -delegate-to AD$ -delegate-from CODY_ROY -action write -hashes :31D6CFE0D16AE931B73C59D7E0C089C0`

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2FTslH5joJCY8OuTU8X9UL%2FScreenshot%20(1528).png?alt=media&#x26;token=cbd539e5-7068-44ba-b6ef-e0672f53ebcb" alt=""><figcaption></figcaption></figure>

We executed a Resource-Based Constrained Delegation attack within the **THM.LOCAL** domain. We authenticated as the **Guest** account using the well-known empty NTLM hash `31D6CFE0D16AE931B73C59D7E0C089C0`. This allowed us to modify the **AD$** computer object, configuring it to trust the `cody_roy` account for delegation.

As a result, the `cody_roy` account is now permitted to impersonate users when accessing the Domain Controller via Kerberos delegation mechanisms. This misconfiguration opens the door to privilege escalation, as we can potentially impersonate a highly privileged user—such as a Domain Administrator—and obtain elevated access within the domain.

Next, we utilized `impacket-getST` to authenticate as the `cody_roy` account using its recovered password. Through this tool, we requested a Kerberos service ticket for the SPN `cifs/AD.THM.LOCAL` while leveraging delegation to impersonate the **Administrator** account.

`impacket-getST -spn "cifs/AD.thm.local" -k -no-pass "THM.LOCAL/CODY_ROY:MK0)mko0" -impersonate "Administrator"`

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2FGX6lcyNURw1xuWBrVNNv%2FScreenshot%20(1531).png?alt=media&#x26;token=25263f70-8c87-4838-b01e-a0d37094523a" alt=""><figcaption></figcaption></figure>

As a result, we obtained a service ticket that grants us access to the CIFS service on `AD.THM.LOCAL` with the privileges of the **Administrator** user, effectively allowing us to operate with elevated domain-level access.

We configured the `KRB5CCNAME` environment variable to point to the Kerberos ticket cache file `Administrator@cifs_AD.THM.LOCAL@THM.LOCAL.ccache` that we previously obtained.

`export KRB5CCNAME=Administrator@cifs_AD.THM.LOCAL@THM.LOCAL.ccache`&#x20;

Using the acquired ticket alongside `impacket-smbexec`, we successfully spawned a shell running as SYSTEM on the Domain Controller.

<figure><img src="https://271954773-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FYsivTjPn2jLXI0ZgVqeF%2Fuploads%2FzvtiRmQwQ9yBdRGisjyw%2FScreenshot%20(1534).png?alt=media&#x26;token=b34fa469-9182-4c3b-9408-0c00e4c782b5" alt=""><figcaption></figcaption></figure>

From an initial low-privileged **Guest** account, we systematically enumerated the Active Directory environment and uncovered multiple misconfigurations. We leveraged LDAP access to identify Kerberoastable accounts, cracked weak credentials through offline password attacks, and abused password reuse via spraying.

From there, we escalated by exploiting **GenericWrite** permissions to perform a targeted Kerberoasting attack, pivoted through RDP access, and extracted additional credentials from a poorly secured PowerShell script.

But the real breakthrough came when we identified **GenericWrite** permissions over the Domain Controller itself. By abusing **Resource-Based Constrained Delegation (RBCD)**, we modified the `msDS-AllowedToActOnBehalfOfOtherIdentity` attribute, leveraged Kerberos delegation (S4U), impersonated the **Administrator**, and ultimately obtained a SYSTEM shell on the Domain Controller.

This machine was a perfect demonstration of how small misconfigurations in Active Directory — such as weak passwords, excessive write permissions, and improper delegation settings — can chain together into full domain compromise. Operation Endgame truly lived up to its name. From Guest to Domain Controller — complete takeover.&#x20;

Until the next machine.
