Platform: TryHackMe
Difficulty: Hard
Category: Active Directory
Skills Covered: Windows enumeration, SMB/LDAP enumeration, OSINT, SID brute-forcing, Kerberoasting, hash cracking, RDP, WinPEAS, PrintNightmare LPE, secretsdump, pass-the-hash, Evil-WinRM
Overview #
Enterprise is a hard difficulty Active Directory machine that simulates a realistic Windows domain environment. The intended path requires thorough enumeration across several services before any exploitation begins. There is no web vulnerability or low-hanging fruit. Gaining initial access depends on finding credentials exposed in a public Git repository through OSINT, and privilege escalation leverages the PrintNightmare local privilege escalation vulnerability against an unpatched Windows Server 2019 host.
The full attack chain:
- Enumerate exposed services — Kerberos, LDAP, SMB, RPC, and an Atlassian Bitbucket instance
- Exploit anonymous SMB and RPC access to build a domain user list via SID brute-forcing
- Identify a GitHub organisation linked from the Bitbucket instance
- Recover plaintext credentials from a developer’s Git commit history (
nik:ToastyBoi!) - Use those credentials to perform an authenticated Kerberoast and crack the service account hash (
bitbucket:littleredbucket) - RDP in as the
bitbucketservice account to obtain the user flag - Run WinPEAS and identify PrintNightmare (CVE-2021-1675) as viable local privilege escalation
- Execute the PrintNightmare LPE PoC to create a new local administrator account
- Dump local hashes with secretsdump and pass the Administrator NTLM hash via Evil-WinRM for the root flag
Reconnaissance #
Port Scanning #
Starting with a targeted Nmap scan across all relevant ports:
┌──(parallels㉿Kali)-[~/targets/enterprise]
└─$ cat scan.txt
# Nmap 7.99 scan initiated Tue Apr 14 23:20:30 2026 as: /usr/lib/nmap/nmap --privileged -vvv -p 53,80,88,139,135,389,445,464,593,636,3268,3269,3389,5985,7990,9389,47001,49664,49666,49667,49668,49672,49669,49671,49676,49698,49704,49855 -4 -A -oN scan.txt 10.64.185.202
Nmap scan report for 10.64.185.202
Host is up, received echo-reply ttl 126 (0.057s latency).
Scanned at 2026-04-14 23:20:30 EDT for 79s
PORT STATE SERVICE REASON VERSION
53/tcp open domain syn-ack ttl 126 Simple DNS Plus
80/tcp open http syn-ack ttl 126 Microsoft IIS httpd 10.0
|_http-server-header: Microsoft-IIS/10.0
|_http-title: Site doesn't have a title (text/html).
| http-methods:
| Supported Methods: OPTIONS TRACE GET HEAD POST
|_ Potentially risky methods: TRACE
88/tcp open kerberos-sec syn-ack ttl 126 Microsoft Windows Kerberos (server time: 2026-04-15 03:20:37Z)
135/tcp open msrpc syn-ack ttl 126 Microsoft Windows RPC
139/tcp open netbios-ssn syn-ack ttl 126 Microsoft Windows netbios-ssn
389/tcp open ldap syn-ack ttl 126 Microsoft Windows Active Directory LDAP (Domain: ENTERPRISE.THM, Site: Default-First-Site-Name)
445/tcp open microsoft-ds? syn-ack ttl 126
464/tcp open kpasswd5? syn-ack ttl 126
593/tcp open ncacn_http syn-ack ttl 126 Microsoft Windows RPC over HTTP 1.0
636/tcp open tcpwrapped syn-ack ttl 126
3268/tcp open ldap syn-ack ttl 126 Microsoft Windows Active Directory LDAP (Domain: ENTERPRISE.THM, Site: Default-First-Site-Name)
3269/tcp open tcpwrapped syn-ack ttl 126
3389/tcp open ms-wbt-server syn-ack ttl 126 Microsoft Terminal Services
|_ssl-date: 2026-04-15T03:21:47+00:00; 0s from scanner time.
| ssl-cert: Subject: commonName=LAB-DC.LAB.ENTERPRISE.THM
| Issuer: commonName=LAB-DC.LAB.ENTERPRISE.THM
|
| rdp-ntlm-info:
| Target_Name: LAB-ENTERPRISE
| NetBIOS_Domain_Name: LAB-ENTERPRISE
| NetBIOS_Computer_Name: LAB-DC
| DNS_Domain_Name: LAB.ENTERPRISE.THM
| DNS_Computer_Name: LAB-DC.LAB.ENTERPRISE.THM
| DNS_Tree_Name: ENTERPRISE.THM
| Product_Version: 10.0.17763
|_ System_Time: 2026-04-15T03:21:39+00:00
5985/tcp open http syn-ack ttl 126 Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-title: Not Found
|_http-server-header: Microsoft-HTTPAPI/2.0
7990/tcp open http syn-ack ttl 126 Microsoft IIS httpd 10.0
| http-methods:
| Supported Methods: OPTIONS TRACE GET HEAD POST
|_ Potentially risky methods: TRACE
|_http-server-header: Microsoft-IIS/10.0
|_http-title: Log in to continue - Log in with Atlassian account
9389/tcp open mc-nmf syn-ack ttl 126 .NET Message Framing
47001/tcp open http syn-ack ttl 126 Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
49664/tcp open msrpc syn-ack ttl 126 Microsoft Windows RPC
49666/tcp open msrpc syn-ack ttl 126 Microsoft Windows RPC
49667/tcp open msrpc syn-ack ttl 126 Microsoft Windows RPC
49668/tcp open ncacn_http syn-ack ttl 126 Microsoft Windows RPC over HTTP 1.0
49669/tcp open msrpc syn-ack ttl 126 Microsoft Windows RPC
49671/tcp open msrpc syn-ack ttl 126 Microsoft Windows RPC
49672/tcp open msrpc syn-ack ttl 126 Microsoft Windows RPC
49676/tcp open msrpc syn-ack ttl 126 Microsoft Windows RPC
49698/tcp open msrpc syn-ack ttl 126 Microsoft Windows RPC
49704/tcp open msrpc syn-ack ttl 126 Microsoft Windows RPC
49855/tcp open msrpc syn-ack ttl 126 Microsoft Windows RPCKey Observations:
- Domain Controller identified: LAB-DC.LAB.ENTERPRISE.THM (ENTERPRISE.THM forest)
- Full Active Directory service stack exposed: Kerberos (88), LDAP (389/3268), SMB (445), RPC (135/593)
- Windows Server 2019 (Build 17763) from the RDP NTLM banner
- WinRM on port 5985 — a potential remote management target if credentials are recovered
- Atlassian on port 7990 — non-standard, worth investigating
Enumeration #
Port 80 — IIS Web Server #
Browsing to the IIS instance on port 80 returns a static page stating “Enterprise Domain Controller. Keep Out!” No real application is hosted here.

Nuclei Scan #
Running a Nuclei scan across the target to surface any automated findings in the background:
┌──(parallels㉿Kali)-[~/targets/enterprise]
└─$ nuclei -target http://10.64.185.202/ -fr
__ _
____ __ _______/ /__ (_)
/ __ \/ / / / ___/ / _ \/ /
/ / / / /_/ / /__/ / __/ /
/_/ /_/\__,_/\___/_/\___/_/ v3.7.1
projectdiscovery.io
[INF] Current nuclei version: v3.7.1 (latest)
[INF] Current nuclei-templates version: v10.4.1 (latest)
[INF] Targets loaded for current scan: 1
[INF] Using Interactsh Server: oast.live
[waf-detect:modsecurity] [http] [info] http://10.64.185.202/
[rdp-detect] [javascript] [info] 10.64.185.202:3389
[ldap-metadata] [javascript] [info] 10.64.185.202:389 ["BaseDN: dc=389","DnsHostName: LAB-DC.LAB.ENTERPRISE.THM","DefaultNamingContext: DC=LAB,DC=ENTERPRISE,DC=THM","DomainFunctionality: 7","ForestFunctionality: 7","DomainControllerFunctionality: 7"]
[ldap-default-login] [javascript] [info] 10.64.185.202:389 [passwords="admin",usernames="admin"]
[ldap-anonymous-login-detect] [javascript] [medium] 10.64.185.202:389
[smb2-capabilities] [javascript] [info] 10.64.185.202:445 ["["DFSSupport","LargeMTU","Leasing"]"]
[smb2-server-time] [javascript] [info] 10.64.185.202:445 ["SystemTime: 2026-04-15T03:30:48.000Z ServerStartTime: 2009-04-22T19:24:48.000Z"]
[smb-version-detect:smb-version] [javascript] [info] 10.64.185.202:445 ["SMB 2.1"]
[smb-enum-domains] [javascript] [info] 10.64.185.202:445 ["DomainName: LAB.ENTERPRISE.THM"]
[smb-enum] [javascript] [info] 10.64.185.202:445 ["DNSComputerNamen: LAB-DC.LAB.ENTERPRISE.THM","DNSComputerName: LAB-DC.LAB.ENTERPRISE.THM","ForestName: ENTERPRISE.THM","OSVersion: 10.0.17763","NetBIOSComputerName: LAB-DC","NetBIOSDomainName: LAB-ENTERPRISE"]
[smb-os-detect] [javascript] [info] 10.64.185.202:445 ["Windows Server 2019, Version 1809"]
[rdp-detection:win2016] [tcp] [info] 10.64.185.202:3389
[smb-anonymous-access] [javascript] [high] 10.64.185.202:445
[smb-shares] [javascript] [low] 10.64.185.202:445 ["[ADMIN$ C$ Docs IPC$ NETLOGON SYSVOL Users]"] [passwords="password",usernames=" "]
[INF] Scan completed in 1m. 31 matches found.Two high-value findings stand out: anonymous SMB access and anonymous LDAP bind. These are immediate pivots.
SMB Anonymous Access #
Listing shares anonymously to clarify what is accessible:
smbclient -L //10.64.185.202/ -U ""
The share list reveals: ADMIN$, C$, Docs, IPC$, NETLOGON, SYSVOL, Users. Attempting to connect to each, Docs and Users are accessible without credentials.

The Users share exposes the domain users directory. Browsing it, only LAB-ADMIN and Default are accessible and neither contains anything notable. However, the share enumeration itself surfaces some usernames to start the user list:
LAB-ADMIN
atlbitbucket
bitbucket
Administrator
RPC Enumeration — SID Brute-Forcing #
rpcdump over anonymous authentication returns over 600 registered RPC endpoints, confirming the null session is fully functional.

Direct user enumeration via enumdomusers was blocked, so I fell back to SID brute-forcing using Impacket’s lookupsid.py. This technique uses the known domain SID to iterate through relative identifiers (RIDs) and resolve each to a domain principal.

After cleaning the output, the full domain user list was:
Administrator
Guest
krbtgt
atlbitbucket
LAB-DC$
DnsAdmins
ENTERPRISE$
bitbucket
nik
replication
spooks
korone
banana
Cake
contractor-temp
varg
joiner
LAB-ADMINKerberos Pre-Authentication Checks #
With the user list, I ran two standard Kerberos attacks against it.
Kerbrute — which showed only atlbitbucket existed in this context, looking back im honestly not sure why:

AS-REP Roasting — checking for accounts with pre-authentication disabled (which would allow offline hash cracking without credentials):

No accounts were AS-REP roastable. Both password-protected files found in the Docs share were encrypted and inaccessible without their passwords.


Port 7990 — Atlassian #
The Altlassian instance presents a standard login page.

Notably, a banner message states the organisation is migrating to GitHub. Searching for the organisation name on GitHub leads to the enterprise-thm organisation.

Credential Discovery via OSINT #
GitHub Repository Analysis #
Reviewing the enterprise-thm GitHub organisation reveals a contributor nik who was one of the users already in our list. The organisation has a PowerShell repository with two commits: an initial commit and a follow-up update.

Inspecting the initial commit, nik hardcoded credentials directly into the script:

The follow-up commit removed the credentials, but Git’s version history retains every previous state permanently. Since the repository was never made private, the exposed credentials remain publicly visible in the commit diff.


Recovered credentials:
nik:ToastyBoi!Testing these credentials for RDP access confirms nik lacks remote desktop permissions. However, valid domain credentials are enough to perform authenticated enumeration against Active Directory.
Initial Access #
Authenticated Kerberoasting #
With nik’s credentials, I queried Active Directory all user accounts to create a truly valid user list, then attempted to kerberoast these users with niks credentials

The bitbucket account has a registered SPN, making it Kerberoastable. Requesting its service ticket and attempting to crack the encrypted portion offline:

The hash cracked successfully:

bitbucket:littleredbucketRDP as bitbucket — User Flag #
bitbucket has remote desktop access. Connecting via RDP:

The user flag is present on the desktop.
Privilege Escalation #
WinPEAS — CVE Discovery #
Running WinPEAS against the host identifies multiple unpatched vulnerabilities. The most relevant is CVE-2021-1675, a local privilege escalation variant of the PrintNightmare vulnerability affecting the Windows Print Spooler service.

PrintNightmare LPE (CVE-2021-1675) #
CVE-2021-1675 allows a low-privileged user to add a malicious printer driver via the Print Spooler service, which executes with SYSTEM privileges. Caleb Stewart’s PoC implements this as a local privilege escalation that creates a new local administrator account.
Using the PoC from https://github.com/calebstewart/CVE-2021-1675:

The exploit completes and a new local administrator account is created.
Dumping Hashes and Pass-the-Hash #
With local admin access, I used Impacket’s secretsdump.py to extract the local SAM database and recover the Administrator NTLM hash:

Rather than cracking the hash, I passed it directly to Evil-WinRM to authenticate as Administrator over WinRM (port 5985):

The root flag is retrieved.
Key Takeaways #
Hints are huge In CTF challenges like this, little side comments in weird places are never not important. A simple hint like “migrating to github” was all i needed to know to search online. The critical foothold here came from a developer’s Git commit history, not from exploiting a service vulnerability. Credentials committed to version control persist indefinitely in the diff history even after removal. Organisations migrating between source control platforms should treat the transition as a credential hygiene event and audit all repository history before making repositories public.
Anonymous SMB and RPC is a joke Null session enumeration allowed full domain user list recovery via SID brute-forcing without a single valid credential. Restricting anonymous access to SMB and RPC is a baseline hardening requirement for any domain controller.
Kerberoasting vulnerable accounts is quick and easy. Once nik’s credentials were recovered, Kerberoasting was a single command. Service accounts with weak passwords and registered SPNs are a persistent problem in AD environments. Kerberoastable accounts should use long, randomly generated passwords (25+ characters) or be migrated to Group Managed Service Accounts (gMSA), which rotate automatically.
Unpatched Print Spooler vulnerabilities remain prevalent. PrintNightmare (CVE-2021-1675 / CVE-2021-34527) was patched in mid-2021, but unpatched systems remain common in enterprise environments. The Print Spooler service should be disabled on hosts that do not require printing functionality — particularly servers and domain controllers.
Pass-the-hash eliminates the need to crack strong passwords. Once local admin access was achieved, the Administrator hash was immediately usable for lateral movement via PtH. Enabling Protected Users security group membership and Credential Guard limits the viability of hash-based attacks in modern AD environments.