PowerShellAccessControl Module: New-AdaptedSecurityDescriptor

Posted: July 8, 2013 in PowerShell, Security
Tags: , , , ,

This is a function from my PowerShellAccessControl module that is used to take the SDDL or binary form of a security descriptor (SD) as input and output an object that resembles an SD from Get-Acl. Right off the bat, let me say that this thing is missing a lot of functionality. It currently only works with discretionary ACLs (the ACLs that control access to objects). Also, the script methods that it exposes aren’t very discoverable via Get-Member since they were added with Add-Member. This thing really deserves to have a true C# object be its output, and I’ll probably go in that direction at some point in the future.

Even with its flaws, I still think it’s a very useful function. Here’s the functionality of a Get-Acl SD that it currently mimics:

  • Access property lists each ACE
  • AccessToString property lists the value of the Access property in a single string
  • Sddl property gives the SDDL representation of the entire SD object
  • GetSecurityDescriptorBinaryForm method gives the binary form of the entire SD object
  • AddAccessRule method takes an ACE as input and adds it to the discretionary ACL
  • RemoveAccessRule takes either an index to an ACE or an ACE object and removes it from the discretionary ACL

So, if you can get to either the SDDL or binary form of a SD, you can pass that to this function and get an object that is much more readable, and that has the ability to change the discretionary ACL.

Besides the two SD input parameters (SDDL or BinarySD; you can only use one at a time), the function has two parameters: AccessMaskEnumeration and Path.

The AccessMaskEnumeration is an optional parameter that the output object can use to translate the access rights of the object into a readable string. In an SD, all access rights are stored as a bitmask. If you don’t have an enumeration to do the translating of rights, you’ll just see an integer in each ACE where the access rights should go. You’ll still be able to see what users/groups have rights to the object, but you won’t know what rights they have (unless you know what the numeric values mean). The function comes with several enumerations for different types of objects, and I’m going to devote a blog post to creating one for printers to show how you can easily make your own for future use. Here is a list of the enumerations that the module comes with:


PS> [System.AppDomain]::CurrentDomain.GetAssemblies().GetTypes() | 
Where-Object FullName -match "^PowerShellAccessControl\."

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     LogicalShareRights                       System.Enum
True     True     WmiNamespaceRights                       System.Enum
True     True     WsManAccessRights                        System.Enum
True     True     ServiceAccessRights                      System.Enum 

The Path parameter is another optional parameter. It gives you the ability to look at the output SD object and tell where it came from. This is very useful when you have more than one SD object and you use the Get-AccessControlEntry function from the module.

Let’s go over some examples!

Here’s a way to get the WMI namespace access rights for the root\cimv2 namespace (NOTE: I’m using the GetSD WMI method on the class directly instead of a different function that I included in the module called Get-Win32SecurityDescriptor. I’ll explain why I used this WMI method directly when I cover the Get-Win32SecurityDescriptor function).


PS> # This should be run from an elevated PS prompt:
PS> $BinarySD = Get-CimClass __SystemSecurity -Namespace root\cimv2 | 
Invoke-CimMethod -MethodName GetSD | 
Select-Object -ExpandProperty SD

PS> $SD = New-AdaptedSecurityDescriptor -BinarySD $BinarySD -Path "root\CIMV2 NameSpace"

PS> $SD.Access | ft

ObjectRights AccessControlType IdentityReference                IsInherited InheritanceFlags PropagationFlags
------------ ----------------- -----------------                ----------- ---------------- ----------------
      393279     AccessAllowed BUILTIN\Administrators                  True ContainerInherit             None
          19     AccessAllowed NT AUTHORITY\NETWORK SERVICE            True ContainerInherit             None
          19     AccessAllowed NT AUTHORITY\LOCAL SERVICE              True ContainerInherit             None
          19     AccessAllowed NT AUTHORITY\Authenticated Users        True ContainerInherit             None

PS> # Notice the ObjectRights listed are numeric. Let's try this again with an enumeration:

PS> $SD = New-AdaptedSecurityDescriptor -BinarySD $BinarySD -Path "root\CIMV2 Namespace" -AccessMaskEnumeration ([PowerShellAccessControl.WmiNamespaceRights])

PS> $SD.Access | ft # Some columns are dropped:

                                ObjectRights AccessControlType IdentityReference                IsInherited
                                ------------ ----------------- -----------------                -----------
... RemoteEnable, ReadSecurity, EditSecurity     AccessAllowed BUILTIN\Administrators                  True
EnableAccount, ExecuteMethods, ProviderWrite     AccessAllowed NT AUTHORITY\NETWORK SERVICE            True
EnableAccount, ExecuteMethods, ProviderWrite     AccessAllowed NT AUTHORITY\LOCAL SERVICE              True
EnableAccount, ExecuteMethods, ProviderWrite     AccessAllowed NT AUTHORITY\Authenticated Users        True

Show the ACEs for the microsoft.powershell session configuration:


PS> # This should be run from an elevated PS prompt
PS> dir WSMan:\localhost\Plugin\microsoft.powershell\Resources -Recurse | 
Where Name -eq Sddl | 
ForEach-Object { 
    New-AdaptedSecurityDescriptor -Sddl $_.Value -Path $_.PsPath -AccessMaskEnumeration ([PowerShellAccessControl.WsManAccessRights])
} | 
Select -exp Access

ObjectRights      : Full
AccessControlType : AccessAllowed
IdentityReference : BUILTIN\Administrators
IsInherited       : False
InheritanceFlags  : None
PropagationFlags  : None

ObjectRights      : Full
AccessControlType : AccessAllowed
IdentityReference : BUILTIN\Remote Management Users
IsInherited       : False
InheritanceFlags  : None
PropagationFlags  : None

Show the AccessToString property for all of the shares on a remote computer named ‘server’ (I’m using another function from the module that I will devote a blog post to soon):


PS> Get-CimInstance -ClassName Win32_LogicalShareSecuritySetting -ComputerName server | 
Get-Win32SecurityDescriptor -Sddl |
New-AdaptedSecurityDescriptor -AccessMaskEnumeration ([PowerShellAccessControl.LogicalShareRights]) | 
Select Path, AccessToString |
fl

Path           : \\server\root\cimv2:Win32_LogicalShareSecuritySetting.Name="share01"
AccessToString : Everyone AccessAllowed FullControl
                 BUILTIN\Users AccessAllowed Read
                 

Path           : \\server\root\cimv2:Win32_LogicalShareSecuritySetting.Name="share02"
AccessToString : BUILTIN\Administrators AccessAllowed FullControl
                 Everyone AccessAllowed FullControl

Show all ACEs from any object named Sddl in the local WSMan configuration (I’m using another function that will be described later this week; you’ll have to run this and see the results):


PS> # This should be run from an elevated PS prompt
PS> dir WSMan:\localhost -Recurse | 
Where Name -eq Sddl | 
ForEach-Object { 
    New-AdaptedSecurityDescriptor -Sddl $_.Value -Path $_.PsPath -AccessMaskEnumeration ([PowerShellAccessControl.WsManAccessRights])
} | 
Get-AccessControlEntry |
Out-GridView

So, if you can get access to a hard to read SDDL form or an impossible to read binary form of an SD, you should be able to turn it into something that’s readable with New-AdaptedSecurityDescriptor. If you have an enumeration that translates the object rights into a readable form, that’s even better (but not necessary). You can then use that object to audit and/or modify the SD (those are for another day).

I hope that you find this function useful. Please try it out and tell me what you think. Stay tuned for more posts on the module, including more on this function!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s