What is an Access Token?
An access token is a security object that uniquely identifies a user or process in Windows. It contains information about the user's identity, privileges, and group memberships. When a user logs in or a process starts, the system generates an access token that is associated with that security context.
Access tokens are fundamental to the Windows security model. They are used by the system to determine whether a user or process has the necessary permissions to perform a requested operation on a securable object (like a file, registry key, or process).
Key Components of an Access Token:
- Security Identifier (SID) of the user or process: Uniquely identifies the subject.
- List of SIDs for groups: Indicates the groups the user or process belongs to.
- Privileges: Specific system privileges assigned to the user or process (e.g., the privilege to shut down the system).
- Owner SID: The SID of the owner of the token.
- Primary Group SID: The SID of the primary group associated with the token.
- Access Control List (ACL) information: Though not directly stored in the token, it relates to how the token's SIDs are checked against the ACLs of objects.
- Mandatory Integrity Control (MIC) Level: Indicates the system's assessment of the token's trustworthiness.
How Access Tokens Work
When a user or process attempts to access a securable object, the Windows security reference monitor compares the access token of the subject with the Discretionary Access Control List (DACL) of the object. The DACL contains Access Control Entries (ACEs) that specify which SIDs are granted or denied specific access rights. If the access token contains an SID that matches an ACE and the requested access rights are permitted, the access is granted. Otherwise, it is denied.
Token Types:
There are two primary types of access tokens:
- Primary Tokens: Associated with a process. A process can have only one primary token, which represents the security context of the process itself.
- Impersonation Tokens: Associated with a thread. A thread can impersonate another user by using an impersonation token. This is commonly used in client-server scenarios where a server thread needs to perform actions on behalf of a client.
Working with Access Tokens in Win32
Developers can interact with access tokens using various Win32 API functions:
OpenProcessToken: Retrieves a handle to the access token associated with a process.GetTokenInformation: Retrieves various types of information from an access token, such as user SID, group SIDs, privileges, and logon session ID.AdjustTokenPrivileges: Enables or disables privileges in an access token.ImpersonateLoggedOnUser: Enables a thread to impersonate a user represented by a token.RevertToSelf: Stops impersonating and restores the thread's original security context.
OpenProcessToken
This function opens the access token associated with a specified process.
BOOL OpenProcessToken(
HANDLE ProcessHandle,
DWORD DesiredAccess,
PHANDLE TokenHandle
);
Arguments:
ProcessHandle: A handle to the process whose token is to be opened. UseGetCurrentProcess()for the current process.DesiredAccess: Specifies the desired access rights to the access token. Common values includeTOKEN_QUERY,TOKEN_IMPERSONATE, andTOKEN_ADJUST_PRIVILEGES.TokenHandle: A pointer to a variable that receives the handle to the newly opened access token.
GetTokenInformation
This function retrieves various types of information from the specified access token.
BOOL GetTokenInformation(
HANDLE TokenHandle,
TOKEN_INFORMATION_CLASS TokenInformationClass,
LPVOID TokenInformation,
DWORD TokenInformationLength,
PDWORD ReturnLength
);
Arguments:
TokenHandle: A handle to the access token.TokenInformationClass: Specifies the type of information to retrieve. Common values includeTokenUser,TokenGroups, andTokenPrivileges.TokenInformation: A pointer to a buffer that receives the requested information.TokenInformationLength: Specifies the size, in bytes, of theTokenInformationbuffer.ReturnLength: A pointer to a variable that receives the number of bytes copied into theTokenInformationbuffer. If this parameter isNULL, the parameter is ignored.
AdjustTokenPrivileges
This function enables or disables privileges in the specified access token of the calling process or thread.
BOOL AdjustTokenPrivileges(
HANDLE TokenHandle,
BOOL DisableAllPrivileges,
PTOKEN_PRIVILEGES NewState,
DWORD BufferLength,
PTOKEN_PRIVILEGES PreviousState,
PDWORD ReturnLength
);
Arguments:
TokenHandle: A handle to the access token.DisableAllPrivileges: If this parameter isTRUE, all privileges in the token are disabled.NewState: A pointer to aTOKEN_PRIVILEGESstructure that specifies the privileges to be modified.BufferLength: The size, in bytes, of thePreviousStatebuffer.PreviousState: A pointer to a buffer that receives the previous state of the privileges.ReturnLength: A pointer to a variable that receives the number of bytes written to thePreviousStatebuffer.
ImpersonateLoggedOnUser
This function enables a server thread to impersonate a client using a security token.
BOOL ImpersonateLoggedOnUser(
HANDLE hToken
);
Arguments:
hToken: A handle to the access token representing the client.
RevertToSelf
This function causes a thread that is impersonating a client to revert to the original security context of the thread.
BOOL RevertToSelf();
This function takes no arguments.
Security Implications
Proper management of access tokens is crucial for maintaining the security of Windows applications. Misconfigurations or improper handling of tokens can lead to privilege escalation vulnerabilities, unauthorized access, and other security breaches. Developers must always adhere to the principle of least privilege, granting only the necessary permissions to users and processes.