Windows needs to ensure that untrusted code and untrusted users aren’t accessing important areas of the operating system, and creating problems which would ultimately lead to a vast number of BSODs.
Windows manages this through Access Tokens which are used to identify the security context of a process/thread and a user. Access Tokens take two main forms: a Primary access token and a Impersonation access token. The Access Token additionally has two important features which are integral to security validation: SIDs (Security Identifiers) and a Privilege Array which contains the privileges allowed for that object.
The token type can be found within a enumeration called TOKEN_TYPE.
The data structure can be found under the TokenType field within the _TOKEN structure. The Primary type determines the security context of the process for the currently logged on user, and the Impersonation type allows a thread to temporarily use a different security context.
The Token type can also be found using the !token extension:
We can view the Privilege Array within WinDbg, by using the !token extension with the address of the access token for a given process, the Privilege Array can be seen below:
As mentioned before, the SID is used to determine if a thread or process has access to an object, and the privilege array will determine what that process or thread is able to do with that object. For example, being able to read and write to a file object.
SIDs have a unique format, and each segment will provide some useful identity information. Each SID will be stored with a _SID data structure as shown below:
These fields can be found within a SID, for which I will demonstrate in a moment. Each SID will have a S prefix. If you know the address of a SID, then you can use the !sid extension to translate the address into the appropriate SID.
The three numbers in yellow, and in preceding in chronological order, represent the use of the SID, the revision number and identifier authority. The blue represents the sub-authorities and the green represents the RID or relative identifier.
The SID use can be found within an enumeration called SID_NAME_USE. The 1 indicates that this is a User SID.
The sub-authorities belong to the identifier authority, and used for more unique identification. The identifier authority or issuing authority tends to be Windows.
The relative identifier is used to identify the SID in relation to the issuing authority. Each unique user or group will start at 1000, and for each new user or group, then this number be incremented by 1, therefore there is at least two users on this system. Administrators are typically given 500 and Guest accounts are given 501.
Primary and Impersonation Tokens have two subtypes: Restricted Tokens and Filtered Admin Token. A Restricted Token is derived from another access token with the following limitations:
- Privileges can be removed from the privilege array.
- The SIDs in the token can have their access altered.
There is also a Filtered Admin Token which alters access rights, sets the integrity level to medium and most of the privileges are removed from the privilege array.
I will conclude this article by describing some of the more interesting and helpful fields within the _TOKEN data structure.
TokenSource – The _TOKEN_SOURCE structure provides a information pretaining to the soruce of the access token. This can be the RPC server, Session Manager or LAN Manager.
TokenID, ParentTokenID and AuthenticationId – The Locally Unique Identifier (_LUID) is used to uniquely identify a access token from the many other potiental access tokens being used on the system. See the _TOKEN_CONTROL data structure for more information.
Privileges – The _SEP_TOKEN_PRIVILEGES structure contains the array of privileges related to the access token.
TokenType – The _TOKEN_TYPE shows if the access token is a primary or impersonation token.
ImpersonationLevel – The _SECURITY_IMPERSONATION_LEVEL is an enumeration of impersonation levels for the impersonation token. There is four different impersonation levels.
TokenFlags – This field contains any flags which have been set for the access token.
TokenInUse – Shows if the access token is currently being used.
SidHash, RestrictedSidHash – These two hashes for the SID have been added to prevent token stealing. These hashes are checked each time the token is used.