This is the official write-up for the hard-rated “Triathlon” lab that I was invited to create for Hack Smarter’s new lab platform, available at courses.hacksmarter.org. Although I didn’t have to “solve” this lab (as the creator), I am documenting the process I would have used to find all information in this write-up WITHOUT including any flags, in the spirit of the game. However, following this process exactly should result in a full compromise of the target network.
If you’d prefer a more visual format, my YouTube video for this lab features a couple of Easter Eggs and information about the “lore” of the lab and the creation process.
Initial Scanning and Enumeration #
My first step is to confirm that each machine is alive and responding. Since the machines may not all respond to pings, I moved on to a quick nmap scan of each:
Ports look to be standard for Windows machines, with one domain controller and two other servers. Since we are operating in a Windows environment, we will populate our /etc/hosts file, as we will likely be interacting with Kerberos, which prefers NetBIOS names over IP addresses. We can find these hostnames (unauthenticated) using netexec:
Now we can populate our /etc/hosts file using these hostnames. I prefer to use the format
After confirming that there are no non-standard ports or services, we can proceed to domain enumeration.
Finding Valid Users #
Reading the lab premise, we see that we only have access to the VPN, but no other information. This means that we don’t have any credentials or usernames to attack. The only information that we have is that we have been contracted by “an elite triathlon team from the United States.”
We won’t find any information on the machines until we have credentialed access, but the information we have about the organization allows us to begin gathering OSINT about the target.
Following the first search engine result leads us to a page with a “Meet the Team” link that may yield some potential usernames:
This page has the names of several athletes, which we can use to create a wordlist of potential usernames.
This page lists nine athletes, which we will collate into a list of potential users:
Next, we can use popular open source tools like username-anarchy or UserlistGenerator to turn these first and last names into common username formats:
We can use kerbrute to test whether any of the created usernames is valid in the “tri.lab” domain:
Initial Access #
Most Active Directory hacking checklists will likely tell you that if you have valid usernames but no passwords, one of the first things to try is ASREP-roasting. We can test this using GetNPUsers.py:
However, this hash does not (and is not intended to) crack:
However, there is a less common technique that we can use here. Although we don’t have credentials to query the users with SPNs from the directory, if we have a user (like the “t.spivey” user) that does not require Kerberos pre-authentication, we can use this account to request a service ticket (ST) for a known account without having to supply any credentials. GetUserSPNs.py implements this using the -no-preauth flag:
This hash will crack, albeit with mutations. I used the “best66” hashcat rule, but others will likely work also.
We can confirm this password’s validity using netexec:
Lateral Movement #
There is a 2025 CVE that I was unaware of while creating this lab, so it is not patched. See if you can find it, but I will not be demonstrating it in my official walkthrough 😅
Now that we have a domain user, we can attempt to move laterally to gain more access to the environment. Although enumerating SMB shares does not yield any helpful information, we do have write permissions on a file share on the “SWIM-SRV” machine:
We can attempt to use this access to coerce authentication using an LNK file attack or a similar method. We can set up a malicious LNK file using netexec’s “slinky” module and catching authentication using a tool like responder:
However, this hash also does not (and is not intended to) crack:
However, since SMB signing is not enabled on SWIM-SRV or BIKE-SRV, we can attempt to relay authentication from the “e.ackerlund” account on SWIM-SRV to the BIKE-SRV machine and see if this account has any permissions. We can use netexec to create a list of relay targets:
After adjusting our /etc/responder/Responder.conf file (we will need to disable conflicting listeners to avoid error output), we can use ntlmrelayx.py to relay authentication. As it turns out, the “e.ackerlund” account is an administrator on BIKE-SRV, so ntlmrelayx will dump the hashes from the machine’s Security Account Manager (SAM):
impacket-ntlmrelayx -tf targets.txt -smb2support, for reference.
We can confirm the hash for the local “Administrator” account is valid using netexec:
We can use administrative credentials to extract secrets using secretsdump.py:
This hash will crack using only a standard wordlist:
We can confirm this password, revealing that the “m.pearson” account is an administrator on SWIM-SRV:
Domain Escalation #
Now that we have administrative access on both of the auxiliary servers, the only thing left to do is find a way onto the domain controller. With administrative access on a few machines, we may be able to access a Certificate Authority (CA) and abuse our permissions to escalate ourselves in the domain.
We can see that SWIM-SRV hosts tri-CA, the CA for tri.lab. Because we have control of an administrator for this server (the “m.pearson” account), there are two intended routes from here: ESC7 via the local Administrators group or a Golden Certificate attack.
First, we will need to find a suitable target. We can check bloodhound-ce for Domain Admins:
It looks like the “j.reed” account we observed earlier has an admin account called “j.reed_adm” that we can target for the next steps.
Golden Certificate Attack #
Because we have full control over the server where the CA is running via membership in the local Administrators group, we can back up the CA’s certificate, allowing us to forge certificates (offline) on behalf of arbitrary principals:
We can now use certipy to authenticate with this certificate, gaining a TGT that we can use for domain authentication:
ESC7 Exploitation #
As a member of the local Administrators group, we are automatically granted the ManageCA right and the ManageCertificates right on the CA. However, Certipy will not detect that the local Administrators group has these permissions, so we will have to rely upon the knowledge that these permissions are inherently granted to this group. Because of these permissions, we will be able to use one of the ESC7 escalation methods to gain Kerberos tickets for arbitrary principals via a certificate created using the “SubCA” certificate template.
We’ll first request a certificate using the SubCA template targeting the “j.reed_adm” user:
This request fails as expected, as the SubCA template is not enrollable by users not in the Domain Admins group or higher. However, because we have elevated rights on the CA, we can approve our own request and retrieve the certificate:
We can successfully authenticate with our certificate and get a TGT, granting us full access as a Domain Admin:
Lab Objective #
Using our administrative rights on the domain controller, we can perform a DCSync, granting us the NTLM hashes of the “krbtgt” account, the target for this lab:
Thank you to Tyler at Hack Smarter for inviting me to create this lab - I had a lot of fun building and testing this one. Looking forward to the possibility of publishing something I’ll think up in the future!