Change permissions of Windows registry key using PowerShell (and C#)
Tagged: permissions, registry
- This topic has 9 replies, 2 voices, and was last updated 3 months ago by Andrew Brehm.
Wed, Feb 23 2022 at 3:37 am #1564565
I am trying to change permissions on a registry key owned by my user.
Using RegEdit it works, regardless of whether my user has “Set Value” and/or “Write DAC”.
But using PowerShell (or C#), changing permissions only works if my user has “Set Value”, regardless of the value of “Write DAC”.
The same applies to a member of the Administrators group when the key is owned by Administrators. “Set Value” appears to allow changing permissions, “Write DAC” is ignored, with RegEdit it works.
How is it possible to set “Set Value” without using RegEdit when it isn’t already set?
This is on Windows 10.0.19042.1466.
Fri, Feb 25 2022 at 12:23 am #1564593
This could be an issue related to UAC. Did you elevate your PowerShell console?
Mon, Feb 28 2022 at 1:54 pm #1564618
Yes, both the PowerShell window and the C# test program ran elevated. In fact, it wouldn’t matter, because as mentioned, this happens with both permissions for the user himself and permissions for the Administrators group.
Also as mentioned, when the user has “Set Value”, he can change permissions, so the user is affected by the key’s permissions. But “Write DACL” appears not to have an effect and “Set Value” can only be set by a user who has “Set Value” which is somehow pointless.
Mon, Feb 28 2022 at 5:21 pm #1564620
I wouldn’t say that it is pointless. It is just like only an admin can give admin rights. So you should have the right if you want to give it.
Tue, Mar 1 2022 at 10:10 am #1564624
What are you talking about? It’s not admins but owners who can set permissions on objects*. Plus as I said this affects Administrators just as much as other users.
(*Administrators have SeTakeOwnershipPrivilege and with this can take ownership of an object and then set permissions. But this won’t work here because even if Administrators is owner of the registry key, setting permissions with PowerShell or C# still won’t work, as stated in the question.)
Tue, Mar 1 2022 at 7:40 pm #1564625
Even admins can’t do everything on a Windows machine. Think of UAC. This is Microsoft’s faulty logic. Don’t blame me. If you work in a Microsoft environment you have to learn with weird behavior that makes no sense whatsoever. I can’t tell from here what went wrong in your case. I guess the best way is to ensure that the user account that makes the changes has the Set Value privilege.
Wed, Mar 2 2022 at 4:27 am #1564635
I am not talking about admins, but about an ACL. There is no “Set Value” privilege, it’s a permission in the ACL. In order for my user to have that permission, it has to be set by someone who has that permission. The owner of the key should be able to set that permission and, with regedit, can.
But that doesn’t help with a script, for example.
My question is not about UAC or about admins, it’s only about a problem with .NET where an ACL is obviously interpreted differently as by Win32 (which is why regedit works).
A user who owns a key should be able to modify the key’s ACL. With C# and PowerShell he cannot, and I was wondering about that.
I will try another way now and see if it’s purely a .NET issue.
Sun, Mar 6 2022 at 7:30 am #1564661
For what it’s worth, I tried it without C# or PowerShell.
Using SetNamedSecurityInfo() it appears to be possible to set a new DAC on an object owned by me without either Set Value or Write DACL set (and obviously without being an administrator).
Originally Benoit has full control on his key:
I then got SDDLs for Full Control and two versions for without Set Value and without Write DAC
And finally I wrote that SDDL over the existing DACL
It appears that .NET ignores the fact that the owner can modify the DACL without any specific permissions set.
Now, I tried the same thing with opening registry keys and writing security descriptors to them (without using SetNamedSecurityInfo()) and then I found the same behaviour as with .NET: I could only change a DACL if I had Set Value. Perhaps .NET (and thus both C# and PowerShell) set registry permissions using RegSetKeySecurity() rather than SetNamedSecurityInfo().
I didn’t try if Write DAC becomes relevant if I am not the owner of the key, I assume it does.
Hope this helps someone else who has this problem in a script.
The (not very good and entirely non-error-checking) code can be found here: https://github.com/ajbrehm/ABTokenTools
- You must be logged in to reply to this topic.