The Most Dangerous User Right You (Probably) Have Never Heard Of

I find Windows user rights pretty interesting. Separate from machine/domain object DACLs, user rights govern things like “by what method can specific users log into a particular system” and are managed under User Rights Assignment in Group Policy. Sidenote: I recently integrated privilege enumeration into PowerUp in the Get-ProcessTokenPrivilege function, with -Special returning ‘privileged’ privileges.

SeEnableDelegationPrivilege

One user right I overlooked, until Ben Campbell’s post on constrained delegation, was SeEnableDelegationPrivilege. This right governs whether a user account can “Enable computer and user accounts to be trusted for delegation.” Part of the reason I overlooked it is stated right in the documentation: “There is no reason to assign this user right to anyone on member servers and workstations that belong to a domain because it has no meaning in those contexts; it is only relevant on domain controllers and stand-alone computers.” So this right applies to the domain, not the local domain-joined machine.

Ben explained how SeEnableDelegationPrivilege factors into constrained delegation. This was a missing piece of the whole puzzle for me. We both first thought that this right only governed the modification of the TRUSTED_FOR_DELEGATION and TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION flags- this would have opened up a nifty attack that Ben outlined. Unfortunately for us attackers, it appears that this right also controls the modification of the msDS-AllowedToDelegateTo property, which contains the targets for constrained delegation. If this is unclear, check out the post from last week for more background on constrained delegation.

TL;DR we can’t modify delegation specific user account control settings NOR the msDS-AllowedToDelegateTo field for targets (even if we have full control of the object) if we don’t have the SeEnableDelegationPrivilege right:

Now the question is: how can we determine which users have this right in the domain? Since SeEnableDelegationPrivilege is applicable only on a domain controller itself, we need to check if any group policy object applied to a domain controller modifies the user right assignments for that given DC. In most cases, this will be the “Default Domain Controllers Policy” (GUID = {6AC1786C-016F-11D2-945F-00C04FB984F9}). This is exactly what the Get-DomainPolicy -Source DC PowerView function will do:

So by default only members of BUILTIN\Administrators (i.e. Domain Admins/Enterprise Admins/etc.) have the right to modify these delegation settings. But what happens if we can edit this GPO, or any other GPO applied to the domain controller?

Why Care

There are a million ways to backdoor Active Directory given sufficient rights (make that a million and one : ). Sean Metcalf calls these “Sneaky Active Directory Persistence Tricks“. Some of these involve ACL backdoors, something I’ve covered some in the past. Other approaches might require maliciously editing GPOs. Still others could involve editing user objects. The SeEnableDelegationPrivilege approach is a bit of everything above.

TL;DR: if we control an object that has SeEnableDelegationPrivilege in the domain, AND said object has GenericAll/GenericWrite rights over any other user object in the domain, we can compromise the domain at will, indefinitely.

Given elevated domain rights OR edit rights to the default domain controller GPO (something @_wald0, @cptjesus, and I are currently working on for BloodHound) for just a few minutes, you can make a single modification to the given GPO to implement this backdoor. This GPO is located at \\DOMAIN\sysvol\testlab.local\Policies\{6AC1786C-016F-11D2-945F-00C04fB984F9}\MACHINE\Microsoft\Windows NT\SecEdit\GptTmpl.inf. By adding any user SID or username to the SeEnableDelegationPrivilege line of the [Privilege Rights] section, the setting will take hold whenever the user/machine’s current DC reboots or refreshes its group policy:

If eviluser has full rights over ANY user in the domain, we can modify that user’s msDS-AllowedToDelegateTo value to be whatever target service we want to compromise. We can also modify the TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION UAC flag if needed. In this case, let’s use ldap/DOMAIN_CONTROLLER to facilitate DCSyncing at will:

If eviluser has GenericAll over any target victim, then we don’t even have to know the victim user’s password. We can execute a force password reset using Set-DomainUserPassword to a known value and then execute the asktgt.exe/s4u.exe attack flow.

Obviously, from the defensive side, take note of what users have the SeEnableDelegationPrivilege privilege on your domain controllers, through PowerView or other means. This right effectively gives those users complete control of the domain, making a great ‘subtle’, but easy to detect (if you know what you’re looking for) AD backdoor. There are obviously ways you could subvert this given SYSTEM access on a domain controller, and I will detail methods to detect specific DACL modification in the coming weeks, but auditing these applied GPOs is a great start.

One thought on “The Most Dangerous User Right You (Probably) Have Never Heard Of

  1. If you have Windows Event Logs in Elasticsearch with GPO enabled for “Requires GPO Computer Configuration\Windows Settings\Security Settings\Advanced Audit Policy Configuration\Audit Policies\Policy Change\Audit Authorization Policy Change —- Success” use this query to find this:
    EventID:4704 AND SeEnableDelegationPrivilege

    Great blog! Keep it coming for us defenders who don’t have the time/cycles to devote to in-depth evasion/persistence.

Leave a Reply

Your email address will not be published. Required fields are marked *