Security descriptor recipes

See also: all the recipes and the intro

For a nicer introduction, please read my series of posts on security descriptors. Here are just the short recipes (partially overlapping with that series).

 # Privileges and SDDL
https://msdn.microsoft.com/en-us/library/windows/desktop/aa379306%28v=vs.85%29.aspx
# Changing ACLs from PowerShell
https://technet.microsoft.com/en-us/magazine/2008.02.powershell.aspx
# ACL/SDDL in .NET
https://msdn.microsoft.com/en-us/library/ms229925%28v=vs.110%29.aspx

# Control of permissions in PowerShell
https://stackoverflow.com/questions/7690994/powershell-running-a-command-as-administrator
[Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()
# how to change Registry permissions with PowerShell
https://powertoe.wordpress.com/2010/08/28/controlling-registry-acl-permissions-with-powershell/

# Convert ACL SDDL 
Invoke-WmiMethod -Class Win32_SecurityDescriptorHelper -Name SDDLToWin32SD -ArgumentList "O:BAG:DUD:AI(A;ID;FA;;;BA)(A;ID;FA;;;SY)(A;ID;0x1200a9;;;BU)(A;ID;0x1301bf;;;AU)"
# A better way
$sd = New-Object System.Security.AccessControl.RawSecurityDescriptor "O:BAG:DUD:AI(A;ID;FA;;;BA)(A;ID;FA;;;SY)(A;ID;0x1200a9;;;BU)(A;ID;0x1301bf;;;AU)"

# Create Principal identity object from name - DOES NOT check if the name is
# valid, try translating it or otherwise using to check
$id = new-object System.Security.Principal.NTAccount("BUILTIN\Users")
# Create Principal identity object from SID (does check the SID for validity)
$id = new-object System.Security.Principal.SecurityIdentifier("BA")
# Convert the identity to name
$id.Translate([System.Security.Principal.NTAccount])
# Convert the identity to SID
$id.Translate([System.Security.Principal.SecurityIdentifier])

# Create one access rule (an element of ACL) - from principal name
$rule=new-object System.Security.AccessControl.FileSystemAccessRule("BUILTIN\Users", "ReadAndExecute, Synchronize","Allow")
# Create one access rule (an element of ACL) - from identity object
$rule=new-object System.Security.AccessControl.FileSystemAccessRule($id, "ReadAndExecute, Synchronize","Allow")
# Access control type as an enum value
[System.Security.AccessControl.AccessControlType]::Allow
# Filesystem rights as enum
[Enum]::Parse([System.Security.AccessControl.FileSystemRights], "ReadAndExecute, Synchronize")
[System.Security.AccessControl.FileSystemRights]::Synchronize
([int]([System.Security.AccessControl.FileSystemRights]::Synchronize) + [int]([System.Security.AccessControl.FileSystemRights]::ReadAndExecute))


# Get the property of permissions for a logger (as a byte[])
$rsd = (get-item hklm:SYSTEM\CurrentControlSet\Control\WMI\Security\).GetValue("fa5ae656-8e4a-ac95-0980-4eb8342436d8")
# Convert it to a descriptor
$sd = New-Object System.Security.AccessControl.RawSecurityDescriptor @($rsd, 0)
# Convert back to bytes
$o = new-Object "byte[]" $sd.BinaryLength
$sd.GetBinaryForm($o, 0)
# Translate the principals
$sd.DiscretionaryAcl | % { (new-object System.Security.Principal.SecurityIdentifier($_.SecurityIdentifier)).Translate([System.Security.Principal.NTAccount]) }

# manipulate ACLs
cacls.exe
icacls.exe
icacls c:\Users\me\tmp /grant "DOMAIN\me:(OI)(CI)F"
icacls c:\Users\me\tmp /remove "DOMAIN\me"
# downloadable tool, works for Registry too
subinacl.exe
# change owner - chown analog
takeown /f <file>
# change ACL - full acces?
icacls <file> /grant <your alias or admin>:(F)

# get the current user name
[System.Security.Principal.WindowsIdentity]::GetCurrent().Name

# Granting permissions access in registry
$ctl = (Get-Item "HKLM:$path").GetAccessControl()
$fc = New-Object System.Security.AccessControl.RegistryAccessRule @("BUILTIN\Administrators", "FullControl", "Allow") # NOT "BA"
$ctl.AddAccessRule($fc)
(Get-Item "HKLM:$path").SetAccessControl($ctl)
# Granting permissions access in registry if have no access to the node yet
$key = [Microsoft.Win32.Registry]::LocalMachine.OpenSubKey("tmp\Objects",[Microsoft.Win32.RegistryKeyPermissionCheck]::ReadWriteSubTree,[System.Security.AccessControl.RegistryRights]::ChangePermissions)
$ck = $key.GetAccessControl()
$rule = New-Object System.Security.AccessControl.RegistryAccessRule @("BUILTIN\Administrators","FullControl","Allow")
$ck.SetAccessRule($rule)
$key.SetAccessControl($ck)
$key.Flush()

# changing a password through PowerShell
([adsi]"WinNT://./Administrator").SetPassword("password")
 # Certificates management
# Also see winhttpcertcfg from https://go.microsoft.com/fwlink/p/?linkid=100966
certutil