Glossary

Attribute - $SECURITY_DESCRIPTOR (0x50)

Previous Next

Overview

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:

Layout of the Attribute

Notes

Size

As defined in $AttrDef, this attribute has a no minimum or maximum size.

Other Information

Layout of the stream

Questions

To Do

Header

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

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.

ACE

Offset Size Description
0x00 1 Type
0x01 1 Flags
0x02 2 Size
0x04 4 Access mask
0x08 V SID

Flags

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

Access Mask / Access Rights

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

SID (Security Identifier)

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.

Security Descriptor Control Flags

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

OWNER DEFAULTED

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.

GROUP DEFAULTED

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.

DACL PRESENT

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.

DACL DEFAULTED

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.

SACL PRESENT

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.

SACL DEFAULTED

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.

SELF RELATIVE

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.
   

Copyright ©