What's in a Token
Hi, Randy here. This is my first blog post to help explain authentication and authorization. This post will be helpful in understanding "Access is Denied" messages and how to troubleshoot when these happen. I'd like to start with an explanation of the security token.
When you log on to a system, you provide credentials in order to gain access to resources to which you have permission. You typically set these permissions by going to the security tab in the properties window of an object and add a user to the list along with the access that you either allow or deny. The security token is how this list (referred to as the Access Control List (ACL), validates you to allow or deny access. The token is an object representing your credentials and an access check is a search of the ACL to see if there is an entry with your name on it. So what about group membership? Security groups are a way to simplify security administration. If we are able to group users together, we can define an entry in the access control list for the security group instead of defining an entry for every user in your environment.
Here are two screenshots. The first screenshot is of the ACL on the security properties page of an NTFS folder named Tools. Notice that it lists each of the user or group names and their permissions. The second picture is of the same ACL but with communication blocked to the domain controller. Because we cannot reach a domain controller, we cannot resolve the friendly names in the list and they are displayed as security identifiers (SIDs), for example S-1-5-21-1712426984-1618080182-1209977580-1108. Security identifiers are how computers see users and groups and will be discussed in more detail later in this post. In the second picture we see our local group resolve to a friendly name Administrators. This is because our local computer manages local groups while the domain controller manages domain groups.
When you first log on to your computer, you prove your identity by typing your username and password or validating with a smartcard. A domain controller validates these credentials and returns your user information and group membership. Your workstation uses this information to compare against its security policy and local security groups to build a security token that will accurately represent you, your domain and local group memberships, and all privileges you have to that computer. It is important to remember that your domain group membership is only part of the token; much of the security token is based on information local to the machine where the token is built. This means that your token may be different when it is built on your workstation of which you are an administrator and built on a file Server where you may have more limited access rights.
A good tool to view the contents of a token is TokenSZ. Below are two separate outputs of TokenSZ for a user named Randy in the domain Wingtiptoys.com. The first one is from an XP workstation where I am the local administrator. The second output is from a file server (where I am not a local administrator that) hosts a share that I often access. I used the command tokensz /compute_tokensize /dump_groups
Notice the output on my client workstation has more data, but much of this information is very similar between the two outputs. The first portion of both outputs reference information on the Kerberos ticket and the size of the token that is generated. This information is not relevant for this discussion, but if you would like to read more about this output and issues where this information is important, please see the whitepaper Addressing Problems Due to Access Token Limitation.
The first portion is the Security Identifier for our User:
This number is the unique SID for the user account. This string is what a computer sees when validating access and privileges. When we looked at the Security tab of a directory earlier in this discussion, we saw that the ACL is actually populated with these SIDs. The ACL editor user interface communicates with a domain controller to translate SIDs into friendly names to make our jobs a little easier. You can determine the SID of a friendly name using PSGetSid. Also, the Microsoft Script Center has an article on how to do this in a script with WMI.
Now let’s look at how this number is generated. The first three segments S-1-5 are called the revision level. You will see S-1-5 quite often, this means it is revision level 1 and generated by the Windows Security_NT_Authority. The second 4 segments is the domain identifier, 21-1712426984-1618080182-1209977580. This is a unique number for a domain. If this SID was for a local user account or group, the domain identifier would be a unique number representing that computer. The last dash is the Relative Identifier (RID), 1108, which makes this number unique to any other SID in the domain.
The next portion shows the SIDs for the enumerated groups and where the two outputs differ.
00 S-1-5-21-1712426984-1618080182-1209977580-513 Attributes - Mandatory Default Enabled
01 S-1-1-0 Attributes - Mandatory Default Enabled
02 S-1-5-32-544 Attributes - Mandatory Default Enabled Owner
03 S-1-5-32-545 Attributes - Mandatory Default Enabled
04 S-1-5-2 Attributes - Mandatory Default Enabled
05 S-1-5-11 Attributes - Mandatory Default Enabled
06 S-1-5-21-1712426984-1618080182-1209977580-1110 Attributes - Mandatory Default Enabled
This is the enumeration of all the domain and local groups. Notice that the group list contains different local groups even though we are the same user on the two machines. When my identification was returned from the domain controller, my local workstation checked its local group membership to determine that my domain account is a local administrator to that computer and added this to our token (S-1-5-32-544). We can tell that the domain identifier is 21-1712426984-1618080182-1209977580. If we were a member of a local group created on the box or in a security group in a trusted domain, that entry would have a different domain identifier in its SID. So why are some of these SIDs missing some parts? S-1-5-11 is one example. This is a well known security identifier. These are generic groups that are predefined to the workstation or domain and required for basic functionality. It is important that these security groups have the same SID regardless of domain membership. This way everything does not break if you move a computer into another domain or into a workgroup. If you look through the list in the article, you will see that several of these well known SIDs go beyond simple group membership and are used to define properties of the specific session, such as if these credentials are used as a batch job (S-1-5-3) or as a service (S-1-5-6.)
The next portion defines the Primary Group of the User
· Primary Group:
This is not relevant to our discussion but is used for compatibility for the POSIX subsystem. When a user creates an object it will set that object’s primary group to that of the user creating it. The -513 identifies this as the Domain Users group.
The next portion of the token represents privileges. The privileges represent certain actions that this token can perform local to the machine where it was built. These are basic activities such as "log on locally" or "start as a service" or "shutdown the computer." These actions define how much control a user will have to system-wide resources and will often permit the user to call these functions regardless of object-based permissions that may be set. Some of these privileges control logon access to a computer and will block or permit a user from establishing a session to the computer or connecting to the computer altogether. These privileges are defined in a computer's security policy and use the user and group security objects to define who has these privileges. Privileges are another way to perform an access check when actions are more complicated than just matching up to an access control list of an object. When comparing the token output above, you see that we have numerous privileges available to us on the workstation where we are a local administrator versus on the file server. Many of these privileges can be traced back to Windows NT 3.1 and were managed using NTRights. You can still use NTRights to script these privileges, but now they are typically defined in group policy under Computer Configuration\Security Settings\Local Policies\User Rights Assignment.
Whoami is included in Windows Server 2003 and Vista and is available for download for Windows 2000 and Windows XP. Although running Whoami with no switches only returns the name of the currently logged on user, the tool has much more functionality. Whoami /user will show the SID of the logged on user. Whoami /groups displays group membership for the current user, and Whoami /priv shows the security privileges of the current user. An important thing to note about the Whoami /priv output is that the current user has all privileges listed in the output, regardless if the State shows Enabled or Disabled. The State column indicates if the privilege is currently being used, not whether the user actually has that privilege. So if a privilege shows up in the list at all, you have it. Whoami /priv is always an easy way to demonstrate some of the differences between a full security token in Windows Vista versus a restricted token. Just run Whoami /priv under both an elevated and non-elevated command prompt in Vista to see the difference.
To summarize, a security token lists SIDs representing your user account and domain and local group membership. Some of these groups are defined by administrators and others are defined by the operating system based on characteristics of your session. Your token also contains rights and privileges granted by the machine where the token was built. It is important to know that these tokens are unique to every system and how you may access them; whether it is an interactive logon, access of a network resource or credentials passed by a service or batch file. With token in hand, we have proof of our identity and can present this token when accessing a protected object. A good analogy is viewing your token as a key ring; each security identifier and privilege is a different key that may or may not fit the lock placed on objects by the security subsystem. So now we need to look at where these tokens are and who uses them.
I will not be going into great detail on Windows internals, but it will be helpful to understand processes and object management. A process is an activity running on your computer. A process can be an application that you open, or a service that starts, or a task of the operating system, but everything a computer does can be identified as a process. When a process is created, it includes a primary token, representing the credentials used to run the process. The token may represent the local computer account, a service account, or user account based on what it does and how it was created. When a user logs on, the Winlogon process starts a process under the user’s security context. By default this is Explorer.exe, the interactive graphical user interface shell in Windows. This process contains a token that was based on the information collected about the logged on user. Explorer needs access to a resource, it can present that token. Whenever you perform an activity on your desktop, it initializes a child process from the original Explorer.exe. A child process retains the token from its parent and passes this token to any additional processes that it spawns. This is why people have the impression that when they authenticate, everything they do is performed using their security credentials. But not all processes stem from explorer.exe. There are several activities happening that are initiated by the local computer or specify their own credentials, like a service that uses a service startup account. When you troubleshoot authorization, it is important to recognize that each process running may or may not be using the credentials of the person typing at the keyboard or moving the mouse. You can see this using Process Explorer. You are able to view the Primary Token of a process by right-clicking a process and looking at the Security tab. This displays the processes’ security context. If I execute runas /user:domainname\differentuser c:\windows\system32\notepad.exe from a prompt, I will see that this process is running under different user credentials.
Notice that the process tree appears to start in two places, System and Explorer. Explorer.exe is the root of the user shell environment and runs under the context of the logged on user. When we open most applications, they open as a process underneath Explorer and inherit the user token used by Explorer (with some exceptions that will be discussed in a future post.) As discussed earlier, this is how we continue using our logged on credentials when navigating through the Windows shell. Now look at the Notepad process running under alternate credentials. This is under its own SVChost.exe because it creates a process with a new logon session. You can right click on several of the services running under Services.exe and you will see credentials of the service startup account for each of the running services. These services do not inherit the token of the parent process, Services.exe, because it is a special process running as the local system that creates new processes with a new logon session.
This ends our first post on tokens. In a future blog post we will look at how processes are able to impersonate other tokens. We will also explore several different ways the operating system can manipulate a token, such as restrictive, elevated, integrity levels and so-called “split” tokens used in Windows Vista.