Microsoft Security Descriptor(SID)Attributes
On this web page we want to have a look at the directory attributes which are used by Microsoft to store the so called Security Identifiers (SID).
These SIDs plays an important role in delegating and granting
permissions and in authentication of trustee holders against the
system. Examples for such attributes:
objectSid | User objects Computer objects Group objects |
The Security ID which unambiguously identifies the regarding security principal (=potential permission trustee). |
sIDHistory | User objects Computer objects Group objects |
Only exists for migrated objects, which was copied (for example with ADMT) from a foreign domain. The list of the security IDs in the sIDHistory attribute allows the regarding account or group to access resources with their old identities - all former permissions are retained this way. |
tokenGroups | User objects Computer objects |
The
SIDs of all groups of the same AD forest where the user is member of.
This attribute takes account even of nested groups, that means that
both direct and transitive group memberships are included here. A very interesting attribute which can not be searched for, because unfortunately it's a Constructed Attribute. |
tokenGroupsGlobalAndUniversal | User objects Computer objects |
A subset of the tokenGroups attribute. Only the global and universal group SIDs are included. |
tokenGroupsNoGCAcceptable | User objects Computer objects |
A subset of the tokenGroups attribute. Only the group SIDs whose evaluation don't require a global catalog are included. |
The basic LDAP attribute data type of these attributes is a Microsoft proprietary LDAP attribute syntax named String(Sid) -
basically this is binary data which have to be handled specifically
even if you just want to read it from the directory in scripts. You can
get more information about this in the SelfADSI tutorial article Object
Attributes of type 'Octet String'.
The internal structure of a SID value is described in this Microsoft document: Microsoft Data Type Reference [MSDTY].
1-Byte Revision: An 8-bit unsigned integer that specifies the revision level of the SID structure. This value is always set to 1.
1-Byte SubAuthority Count: An 8-bit unsigned integer that specifies the number of elements in the SubAuthority array (these are a kind of Sub IDs in the SID). The maximum number of these sub authorities allowed is 15.
6-Byte IdentifierAuthority: This 6 bytes indicates the so called Authority Identifier, which indicates the authority under which the SID was created. The following values has been defined so far:
0x00, 0x00, 0x00, 0x00, 0x00, 0x00 : NULL_SID_AUTHORITY
0x00, 0x00, 0x00, 0x00, 0x00, 0x01 : WORLD_SID_AUTHORITY
0x00, 0x00, 0x00, 0x00, 0x00, 0x02 : LOCAL_SID_AUTHORITY
0x00, 0x00, 0x00, 0x00, 0x00, 0x03 : CREATOR_SID_AUTHORITY
0x00, 0x00, 0x00, 0x00, 0x00, 0x04 : NON_UNIQUE_AUTHORITY
0x00, 0x00, 0x00, 0x00, 0x00, 0x05 : NT_AUTHORITY
0x00, 0x00, 0x00, 0x00, 0x00, 0x06 : SECURITY_MANDATORY_LABEL_AUTHORITY
Variable-Length SubAuthority: A variable length array of one or several (the exact count is stored at the beginning of the SID) sub authorities. A sub authority is represented by a unsigned 32-bit integers that is stored in reverse byte order (Little Endian). The SID of a normal Active Directory account consists of 5 sub authorities, the first one has always the value 21, the next three blocks are the SID-'base' of the domain, and the last sub authority block is finally the relative ID of the account (the RID) which is unique in its domain. An example of such an account SID:
Although SIDs are binary values with a variable length (normal Active Directory SIDs have a length of 28 byte), they are normally displayed as a string with a specific notation syntax, for example like these:
S-1-5-7 (Wellknown SID for 'Anonymous Logon')
S-1-5-21-1621763826-2590103247-2238570322-1113
This display form is called SDDL (Security Descriptor Definition Language). The rule for the SDDL notation of a SID is
S-1-IdentifierAuthority-SubAuthority1-SubAuthority2-...-SubAuthorityn
Every Active Directory Configuration Partition stores information about the wellknown standard SIDs
which can be used by the regarding system. The according objects are in
the CN=WellKnown Security Principals,CN=Configuration,DC=....
organizational unit. This is structure of the wellknown SID 'Everyone'
(S-1-1-0):
And this is the structure of the wellknown sid 'System' (S-1-5-18):
Converting binary SID data to readable SDDL strings
If
you want to read SID attributes from directory with an LDAP script,
there is one question: How to convert the binary data into a readable
SDDL string?
As we've seen in the discussion about
the data structure of a SID attribute, we face two obstacles to
overcome. First the pure binary data has to be converted into a hex
string: This is performed by the function OctetToHexStr.
Then we can convert this into a SDDL notation by transferring the
authority blocks according to the correct byte order to long integer
values. This is done with the function HexStrToSID. We need a few additional helper functions here which can be found at the end of the script:
Converting readable SID Strings to the according hex string
Now
the other way round: How to convert a given SID string (in readable
SDDL form) into the according binary data (as a hex string). We need
this binary data for example when we want to build an LDAP filter which
can search for a certain SID attribute, or if we want to write directly
into any ACL structure.
Now we need functions which
can built the correct hexadecimal strings from given long integer
values. This helper functions are called in the central conversion
function SIDToHexStr then:
SIDs in LDAP Filters
If you want to perform an LDAP search to find an object with a certain SID value in one attribute, you have to built a special LDAP filter.
This filter has to contain the pure binary data in hexadecimal
notation, therefore such filter contains the single bytes of the data,
divided with backslash (\) characters. So we need the old function SIDToHexStr again to use it to built this filter strings.
The example is based on a normal ADO LDAP search which is described in detail in the SelfADSI tutorial article 'Searching Objects with specific Criteria'. We read the tokenGroups
attribute from a user object and search for the regarding group objects
(in the global catalog). So we can determine all the groups where the
user is direct or nested member of:
LDAP Bind with SIDs instead of object DNs
A very interesting variation for the search for objects with a certain SID: In an Active Directory environment, you can bind to an LDAP object in scripts with the SDDL SID string. You just have to use a specific notation with <...> like this one:
<SID=S-1-5-21-34672221-56910222-80333210-57321189-511> (example)
Even the pure hexstrings of SIDs can be used in LDAP Binds:
<SID=0105000000000005150000001b0e683dbf16479eb5a59ec158040000> (example)
So
we could use this to identify the object with a certain SID without
having to perform an LDAP search with the special filter from the last
example - this is much more elegant than the last example script.
Tools for displaying and converting SIDs
There are several other tools for displaying a Microsoft String(SID) attribute and for converting such attributes into a readable SDDL-SID-String.
LEX - The LDAP Explorer
LEX - The LDAP Explorer (a commercial powerful LDAP browser I developed) has special attribute editors for SID values and can show them as SDDL strings as well as raw data:
LEX Editor for Microsoft SID Attributes:
PSGETSID
This tool is included in the wellknown SysInternals PSTools suite and can be downloaded for free at Microsoft website. You can use it to resolve SIDs into account names and vice versa: