Glossary |
Standard Attribute Header?
The security descriptor can be summarised as:
Component | Description | ||
---|---|---|---|
Header | Offsets to various structures | ||
Audit ACL | ACE | SID | ACEs for the Audit ACL |
Permissions ACL | ACE | SID | ACEs for the Permissions ACL |
ACE | SID | ||
ACE | SID | ||
SID (User) | The owner of this object | ||
SID (Group) |
The security descriptor is necessary to prevent unauthorised access to files. It stores information about:
As defined in $AttrDef, this attribute has a no minimum or maximum size.
Offset | Size | Description |
---|---|---|
0x00 | 1 | Revision (a) |
0x01 | 1 | Padding |
0x02 | 2 | Control Flags (b) |
0x04 | 4 | Offset to User SID |
0x08 | 4 | Offset to Group SID |
0x0C | 4 | Offset to SACL |
0x10 | 4 | Offset to DACL |
(a) 0x1 for now
(b) Usually 0x4 (DACL Present), or 0x14 (DACL Present + SACL Present). See Flags below.
(c) This refers to the Auditing ACL
(d) This refers to the Permissions ACL
Offset | Size | Description |
---|---|---|
0x00 | 1 | ACL Revision |
0x01 | 1 | Padding (0x00) |
0x02 | 2 | ACL size |
0x04 | 2 | ACE count |
0x06 | 2 | Padding (0x0000) |
The Access Control List (ACL) contains one or many ACEs.
The ACL revision is currently 0x02, on my machine.
The Win32 APIs suggest that 0x01 and 0x06 contain padding 0x00's for alignment
purposes.
Offset | Size | Description |
---|---|---|
0x00 | 1 | Type |
0x01 | 1 | Flags |
0x02 | 2 | Size |
0x04 | 4 | Access mask |
0x08 | V | SID |
The currently implemented (in NT) Types are:
Value | Description |
---|---|
0x00 | Access Allowed |
0x01 | Access Denied |
0x02 | System Audit |
Flags is a bit field. The possible values of Flags depend on the value of Type. When applied to a directory, Access Allowed or Access Denied can have flags of
Value | Description |
---|---|
0x01 | Object inherits ACE |
0x02 | Container inherits ACE |
0x04 | Don't propagate 'Inherit ACE' |
0x08 | Inherit only ACE |
If the Type is System Audit, then the flags can be
Value | Description |
---|---|
0x40 | Audit on Success |
0x80 | Audit on Failure |
The Access Mask / Rights is a bit field enumerating all the (dis)allowed actions.
Bit (Range) | Meaning | Description / Examples |
---|---|---|
0 - 15 | Object Specific Access Rights | Read data, Execute, Append data |
16 - 22 | Standard Access Rights | Delete, Write ACL, Write Owner |
23 | Can access security ACL | |
24 - 27 | Reserved | |
28 | Generic ALL (Read, Write, Execute) | Everything below |
29 | Generic Execute | All things necessary to execute a program |
30 | Generic Write | All things necessary to write to a file |
31 | Generic Read | All things necessary to read a file |
A typical SID looks like: S-1-5-21-646518322-1873620750-619646970-1110
It's composed of 'S-p-q-r-s-t-u-v'
S | Security |
p | Revision number (currently 1) |
q | NT Authority. This number is divided into 6 bytes (48 bit big-endian number). |
r - v | NT Sub-authorities (there can be many of these) |
On disk the SID is stored as follows:
S-1-5-21-646518322-1873620750-619646970-1110
in hex:
S-1-5-15-26891632-6fad2f0e-24ef0ffa-456 (5 Sub-authorities)
0x00 | 01 | 05 | 00 | 00 | 00 | 00 | 00 | 05 |
0x08 | 15 | 00 | 00 | 00 | 32 | 16 | 89 | 26 |
0x10 | 0e | 2f | ad | 6f | fa | 0f | ef | 24 |
0x18 | 56 | 04 | 00 | 00 |
NB This is a variable length structure. The could have been more, or fewer, sub-authorities making the structure larger, or smaller.
Flag | Description |
---|---|
0x0001 | Owner Defaulted |
0x0002 | Group Defaulted |
0x0004 | DACL Present |
0x0008 | DACL Defaulted |
0x0010 | SACL Present |
0x0020 | SACL Defaulted |
0x0100 | DACL Auto Inherit Req |
0x0200 | SACL Auto Inherit Req |
0x0400 | DACL Auto Inherited |
0x0800 | SACL Auto Inherited |
0x1000 | DACL Protected |
0x2000 | SACL Protected |
0x4000 | RM Control Valid |
0x8000 | Self Relative |
This boolean flag, when set, indicates that the SID pointed to by the Owner field was provided by a defaulting mechanism rather than explicitly provided by the original provider of the security descriptor. This may affect the treatment of the SID with respect to inheritence of an owner.
This boolean flag, when set, indicates that the SID in the Group field was provided by a defaulting mechanism rather than explicitly provided by the original provider of the security descriptor. This may affect the treatment of the SID with respect to inheritence of a primary group.
This boolean flag, when set, indicates that the security descriptor contains a discretionary ACL. If this flag is set and the Dacl field of the SECURITY DESCRIPTOR is null, then a null ACL is explicitly being specified.
This boolean flag, when set, indicates that the ACL pointed to by the Dacl field was provided by a defaulting mechanism rather than explicitly provided by the original provider of the security descriptor. This may affect the treatment of the ACL with respect to inheritence of an ACL. This flag is ignored if the DaclPresent flag is not set.
This boolean flag, when set, indicates that the security descriptor contains a system ACL pointed to by the Sacl field. If this flag is set and the Sacl field of the SECURITY DESCRIPTOR is null, then an empty (but present) ACL is being specified.
This boolean flag, when set, indicates that the ACL pointed to by the Sacl field was provided by a defaulting mechanism rather than explicitly provided by the original provider of the security descriptor. This may affect the treatment of the ACL with respect to inheritence of an ACL. This flag is ignored if the SaclPresent flag is not set.
This boolean flag, when set, indicates that the security descriptor is in self-relative form. In this form, all fields of the security descriptor are contiguous in memory and all pointer fields are expressed as offsets from the beginning of the security descriptor.
The SID structure is a variable-length structure used to uniquely identify users or groups. SID stands for security identifier. The standard textual representation of the SID is of the form: S-R-I-S-S... Where: - The first "S" is the literal character 'S' identifying the following digits as a SID. - R is the revision level of the SID expressed as a sequence of digits either in decimal or hexadecimal (if the later, prefixed by "0x"). - I is the 48-bit identifier_authority, expressed as digits as R above. - S... is one or more sub_authority values, expressed as digits as above. Example SID; the domain-relative SID of the local Administrators group on Windows NT/2k: S-1-5-32-544 This translates to a SID with: revision = 1, sub_authority_count = 2, identifier_authority = {0,0,0,0,0,5}, SECURITY_NT_AUTHORITY sub_authority[0] = 32, SECURITY_BUILTIN_DOMAIN_RID sub_authority[1] = 544 DOMAIN_ALIAS_RID_ADMINS ACE Types ACCESS_MIN_MS_ACE_TYPE = 0 ACCESS_ALLOWED_ACE_TYPE = 0 ACCESS_DENIED_ACE_TYPE = 1 SYSTEM_AUDIT_ACE_TYPE = 2 SYSTEM_ALARM_ACE_TYPE = 3 Not implemented as of Win2k. ACCESS_MAX_MS_V2_ACE_TYPE = 3 ACCESS_ALLOWED_COMPOUND_ACE_TYPE = 4 ACCESS_MAX_MS_V3_ACE_TYPE = 4 The following are Win2k only. ACCESS_MIN_MS_OBJECT_ACE_TYPE = 5 ACCESS_ALLOWED_OBJECT_ACE_TYPE = 5 ACCESS_DENIED_OBJECT_ACE_TYPE = 6 SYSTEM_AUDIT_OBJECT_ACE_TYPE = 7 SYSTEM_ALARM_OBJECT_ACE_TYPE = 8 ACCESS_MAX_MS_OBJECT_ACE_TYPE = 8 ACCESS_MAX_MS_V4_ACE_TYPE = 8 This one is for WinNT&2k. ACCESS_MAX_MS_ACE_TYPE = 8 The ACE flags (8-bit) for audit and inheritance SUCCESSFUL_ACCESS_ACE_FLAG is only used with system audit and alarm ACE types to indicate that a message is generated (in Windows!) for successful accesses. FAILED_ACCESS_ACE_FLAG is only used with system audit and alarm ACE types to indicate that a message is generated (in Windows!) for failed accesses. The inheritance flags. OBJECT_INHERIT_ACE = 0x01 CONTAINER_INHERIT_ACE = 0x02 NO_PROPAGATE_INHERIT_ACE = 0x04 INHERIT_ONLY_ACE = 0x08 INHERITED_ACE = 0x10 Win2k only VALID_INHERIT_FLAGS = 0x1f The audit flags. SUCCESSFUL_ACCESS_ACE_FLAG = 0x40 FAILED_ACCESS_ACE_FLAG = 0x80 The access mask defines the access rights. The standard rights. DELETE = 0x00010000 READ_CONTROL = 0x00020000 WRITE_DAC = 0x00040000 WRITE_OWNER = 0x00080000 SYNCHRONIZE = 0x00100000 STANDARD_RIGHTS_REQUIRED = 0x000f0000 STANDARD_RIGHTS_READ = 0x00020000 STANDARD_RIGHTS_WRITE = 0x00020000 STANDARD_RIGHTS_EXECUTE = 0x00020000 STANDARD_RIGHTS_ALL = 0x001f0000 The access system ACL and maximum allowed access types. ACCESS_SYSTEM_SECURITY = 0x01000000 MAXIMUM_ALLOWED = 0x02000000 The generic rights. GENERIC_ALL = 0x10000000 GENERIC_EXECUTE = 0x20000000 GENERIC_WRITE = 0x40000000 GENERIC_READ = 0x80000000 The object ACE flags (32-bit). ACE_OBJECT_TYPE_PRESENT = 1 ACE_INHERITED_OBJECT_TYPE_PRESENT = 2 ACL_CONSTANTS Current revision. ACL_REVISION = 2 ACL_REVISION_DS = 4 History of revisions. ACL_REVISION1 = 1 MIN_ACL_REVISION = 2 ACL_REVISION2 = 2 ACL_REVISION3 = 3 ACL_REVISION4 = 4 MAX_ACL_REVISION = 4 Absolute security descriptor. Does not contain the owner and group SIDs, nor the sacl and dacl ACLs inside the security descriptor. Instead, it contains pointers to these structures in memory. Obviously, absolute security descriptors are only useful for in memory representations of security descriptors. On disk, a self-relative security descriptor is used. Attribute: Security descriptor (0x50). A standard self-relative security descriptor. NOTE: Always resident. NOTE: Not used in NTFS 3.0+, as security descriptors are stored centrally in FILE_$Secure and the correct descriptor is found using the security_id from the standard information attribute. On NTFS 3.0+, all security descriptors are stored in FILE_$Secure. Only one referenced instance of each unique security descriptor is stored. FILE_$Secure contains no unnamed data attribute, i.e. it has zero length. It does, however, contain two indexes ($SDH and $SII) as well as a named data stream ($SDS). Every unique security descriptor is assigned a unique security identifier (security_id, not to be confused with a SID). The security_id is unique for the NTFS volume and is used as an index into the $SII index, which maps security_ids to the security descriptor's storage location within the $SDS data attribute. The $SII index is sorted by ascending security_id. A simple hash is computed from each security descriptor. This hash is used as an index into the $SDH index, which maps security descriptor hashes to the security descriptor's storage location within the $SDS data attribute. The $SDH index is sorted by security descriptor hash and is stored in a B+ tree. When searching $SDH (with the intent of determining whether or not a new security descriptor is already present in the $SDS data stream), if a matching hash is found, but the security descriptors do not match, the search in the $SDH index is continued, searching for a next matching hash. When a precise match is found, the security_id coresponding to the security descriptor in the $SDS attribute is read from the found $SDH index entry and is stored in the $STANDARD_INFORMATION attribute of the file/directory to which the security descriptor is being applied. The $STANDARD_INFORMATION attribute is present in all base mft records (i.e. in all files and directories). If a match is not found, the security descriptor is assigned a new unique security_id and is added to the $SDS data attribute. Then, entries referencing the this security descriptor in the $SDS data attribute are added to the $SDH and $SII indexes. Note: Entries are never deleted from FILE_$Secure, even if nothing references an entry any more. The $SDS data stream contains the security descriptors, aligned on 16-byte boundaries, sorted by security_id in a B+ tree. Security descriptors cannot cross 256kib boundaries (this restriction is imposed by the Windows cache manager). Each security descriptor is contained in a SDS_ENTRY structure. Also, each security descriptor is stored twice in the $SDS stream with a fixed offset of 0x40000 bytes (256kib, the Windows cache manager's max size) between them; i.e. if a SDS_ENTRY specifies an offset of 0x51d0, then the the first copy of the security descriptor will be at offset 0x51d0 in the $SDS data stream and the second copy will be at offset 0x451d0. $SII index. The collation type is COLLATION_NTOFS_ULONG. $SDH index. The collation rule is COLLATION_NTOFS_SECURITY_HASH.