Security is controlled, in NTFS based file systems, on just a few key concepts. Two of the main concepts are: ACE's (access control entry) and ACL's (access control list). An ACE is a structure applied to an object indicated a specific right required by the object to be accessed. An ACL is a composite list of ACE's used to indicate the full permissions required/applied to an object. In short, an ACE belongs to an ACL; conversely, an ACL is composed of ACE's.
ACL's come in two flavors: 1) DACL (discretionary access control list) and SACL (system access control list). Keith Brown gives a great description of the two structures, in The .NET Developer's Guide to Windows Security,
The discretionary access control list (DACL) contains a list of permissions granted or denied to various users and groups. The reason it's called "discretionary" is that the owner of the object is always allowed to control its contents. Contrast this to the system access control list (SACL), over which the owner has no special control. In fact, the owner of an object isn't even allowed to read it. The SCAL is designed for use by security officers, and it specifies what actions will be audited by the system. I like to think of the SACL as the "Big Brother" bits.In usage, SACL's are great for tracking who accesses a file. They provide a way to keep track of who works with a given object. One thing to note is that ACL's are not stored in the object, but, rather in the $MFT (master file table). For example, using Access Data's FTK Imager, you can see, below, two permission sets: 1) Take ownership and 2) Full permission.
Full permissions - explorer properties
Full permissions - FTK Imager ($MFT) view
Take ownership - explorer properties
Take ownership - FTK Imager ($MFT) view
When you start working with PowerShell, the Access Masks are displayed in terms of .NET enumerations. Below is a quick example to create a new file and return the SACL (Audit) permissions of the file listed above.
When I run this I get the following output in PowerShell:# Start afreshClear-Host
# Create new directory if it doesn't already existif(!(Test-Path ($path = 'C:\test'))){md $path}
# Pipe dir contents to test.logdir C:\ > ($file = "$path\test.log")
# Get ACL information for new fileGet-Acl $file -Audit | select *
What is important to note here is the Sddl values. For more information on SDDL, check out this link:PSPath : Microsoft.PowerShell.Core\FileSystem::C:\test\test.logPSParentPath : Microsoft.PowerShell.Core\FileSystem::C:\testPSChildName : test.logPSDrive : CPSProvider : Microsoft.PowerShell.Core\FileSystemAudit : {}AccessToString : BUILTIN\Administrators Allow FullControlNT AUTHORITY\SYSTEM Allow FullControlBUILTIN\Users Allow ReadAndExecute, SynchronizeNT AUTHORITY\Authenticated Users Allow Modify, SynchronizeAuditToString :Path : Microsoft.PowerShell.Core\FileSystem::C:\test\test.logOwner : BUILTIN\AdministratorsGroup : DOMAIN\Domain UsersAccess : {System.Security.AccessControl.FileSystemAccessRule, System.Security.Ac cessControl.FileSystemAccessRule, System.Security.AccessControl.FileSys temAccessRule, System.Security.AccessControl.FileSystemAccessRule}Sddl * O:BAG:DUD:AI(A;ID;FA;;;BA)(A;ID;FA;;;SY)(A;ID;0x1200a9;;;BU)(A;ID;0x1301bf;;;AU)S:AI(AU;SA;WO;;;S-1-5-21-1234567890-1234567890 -1234567890 -1000)AccessRightType : System.Security.AccessControl.FileSystemRightsAccessRuleType : System.Security.AccessControl.FileSystemAccessRuleAuditRuleType : System.Security.AccessControl.FileSystemAuditRuleAreAccessRulesProtected : FalseAreAuditRulesProtected : FalseAreAccessRulesCanonical : TrueAreAuditRulesCanonical : True
Understanding SDDL SyntaxAs I start playing around with Get-Acl and the various options I wanted to know what all was available to work with, so, I did a Get-Member:
There's quite a bit to work with, so, I decide to try and map out some options in order to figure out how to manually create a SACL. This link helps me get a few starting steps:Get-Acl C:\test\test.log |Get-Member |ft name,membertype -AutoSize
Name MemberType---- ----------Access CodePropertyGroup CodePropertyOwner CodePropertyPath CodePropertySddl CodePropertyAccessRuleFactory MethodAddAccessRule MethodAddAuditRule MethodAuditRuleFactory MethodEquals MethodGetAccessRules MethodGetAuditRules MethodGetGroup MethodGetHashCode MethodGetOwner MethodGetSecurityDescriptorBinaryForm MethodGetSecurityDescriptorSddlForm MethodGetType MethodModifyAccessRule MethodModifyAuditRule MethodPurgeAccessRules : MethodPurgeAuditRules MethodRemoveAccessRule MethodRemoveAccessRuleAll MethodRemoveAccessRuleSpecific MethodRemoveAuditRule MethodRemoveAuditRuleAll MethodRemoveAuditRuleSpecific MethodResetAccessRule MethodSetAccessRule MethodSetAccessRuleProtection MethodSetAuditRule MethodSetAuditRuleProtection MethodSetGroup MethodSetOwner MethodSetSecurityDescriptorBinaryForm MethodSetSecurityDescriptorSddlForm MethodToString MethodPSChildName NotePropertyPSDrive NotePropertyPSParentPath NotePropertyPSPath NotePropertyPSProvider NotePropertyAccessRightType PropertyAccessRuleType PropertyAreAccessRulesCanonical PropertyAreAccessRulesProtected PropertyAreAuditRulesCanonical PropertyAreAuditRulesProtected PropertyAuditRuleType PropertyAccessToString ScriptPropertyAuditToString ScriptProperty
How to Handle NTFS Folder Permissions, Security Descriptors and ACLs in PowerShellTo get a more explicit breakdown of what I am working with currently, I run this command:
This helps me connect the dots I see with this post:get-acl C:\test\test.log -audit | select -ExpandProperty access
FileSystemRights : FullControlAccessControlType : AllowIdentityReference : BUILTIN\AdministratorsIsInherited : TrueInheritanceFlags : NonePropagationFlags : None
FileSystemRights : FullControlAccessControlType : AllowIdentityReference : NT AUTHORITY\SYSTEMIsInherited : True
InheritanceFlags : NonePropagationFlags : None
FileSystemRights : ReadAndExecute, SynchronizeAccessControlType : AllowIdentityReference : BUILTIN\UsersIsInherited : TrueInheritanceFlags : NonePropagationFlags : None
FileSystemRights : Modify, SynchronizeAccessControlType : AllowIdentityReference : NT AUTHORITY\Authenticated UsersIsInherited : TrueInheritanceFlags : NonePropagationFlags : None
Is there a way to create ACL's from scratch in powershell, as opposed to copying existing ones and modifying them?Specifically, I want to focus on the AddAuditRule method of the member set. Using the information listed above, I can see the various objects I need to focus on. MSDN provides details, in particular, about the objects, one by one, as designated by the System.Security.AccessControl.FileSystemAuditRule class:
FileSystemAuditRule ConstructorThere are, in .NET 4.0, four overrides. Working from the first example above, we will explore the objects we need to focus on:
Based on this list, we have the following objects:FileSystemRights : FullControlAccessControlType : AllowIdentityReference : BUILTIN\AdministratorsIsInherited : TrueInheritanceFlags : NonePropagationFlags : None
- System.Security.AccessControl.FileSystemRights - FileSystemRights Enumeration
- System.Security.AccessControl.AccessControlType - AccessControlType Enumeration
- System.Security.Principal.NTAccount - IdentityReference Class
- System.Security.AccessControl.Authorization.IsInherited - AuthorizationRule.IsInherited Property
- System.Security.AccessControl.InheritanceFlags - InheritanceFlags Enumeration
- System.Security.AccessControl.PropagationFlags - PropagationFlags Enumeration
Working from this list, and, the example above, I was able to identify, based on the FileSystemAuditRuleConstructor, only three of these objects are needed to create a new ACE:
- FileSystemRights
- IdentityReference
- AuditFlags
From here, I was able to create the following example which added a SACL to my test file:
which returns this:# Get ACL prior to script for referenceGet-Acl C:\test\test.log -Audit |Format-Table SDDL -AutoSize -Wrap
Now, as I walk through my steps,Sddl----O:BAG:DUD:AI(A;ID;FA;;;BA)(A;ID;FA;;;SY)(A;ID;0x1200a9;;;BU)(A;ID;0x1301bf;;;AU)
I am able to set the exact SACL properities I need, and, apply them. To verify I have added exactly what I need, I rerun my initial Get-Acl cmdlet:# Declare SACL structure$FileSystemRights = [System.Security.AccessControl.FileSystemRights]::FullControl$IdentityReference = New-Object System.Security.Principal.NTAccount("$($env:computername)\test"),o:p>$AuditFlags = [System.Security.AccessControl.AuditFlags]::Success
# Create new ACE$Ace = New-Object System.Security.AccessControl.FileSystemAuditRule($IdentityReference, $FileSystemRights, $AuditFlags)
# Get ACL$Acl = Get-Acl -Path C:\test\test.log
# Add ACE to ACL$Acl.AddAuditRule($ACE)
# Set ACLSet-Acl -Path C:\test\test.log -AclObject $Acl
and see my new SACL:# Get ACL prior to script for referenceGet-Acl C:\test\test.log -Audit |Format-Table SDDL -AutoSize -Wrap
Breaking down the last portion of the SDDL (S:AI(AU;SA;FA;;; S-1-5-21-1234567890Sddl----O:BAG:DUD:AI(A;ID;FA;;;BA)(A;ID;FA;;;SY)(A;ID;0x1200a9;;;BU)(A;ID;0x1301bf;;;AU)S:AI(AU;SA;FA;;; S-1-5-21-1234567890-1234567890-1234567890-1000)
- ace_type:
- AceType: AU
- Value: SYSTEM_AUDIT_ACE_TYPE
- ace_flags:
- ACE flags string: SA
- SUCCESSFUL_ACCESS_ACE_FLAG
- rights:
- Access rights string: FA
- Access right value: FILE_ALL_ACCESS
- object_guid: none
- inherit_object_guid: none
- account_sid: S-1-5-21-1234567890-1234567890-1234567890-1000
- resource_attributes: n/a
Without getting into an in-depth exploration of specific combinations of the Security namespace, one of the key things to be aware of is the variety of options you have for adding SACL's; files are not the only objects which can be audited. Below is a list of additional object types which can be set up with SACL monitoring:
- Directory service objects
- File objects
- Registry keys