Access Token Theory
An access token is created by the kernel upon user authentication and contains
important values that are linked to a specific user through the SID.
Access tokens are stored inside the kernel which prevents us from directly
interacting with the token or modifying it.
As penetration testers, we’ll focus on two concepts relating to the access token,
specifically integrity levels and privileges.
Windows defines four integrity levels, which determine the level of access:
low, medium, high and system.
Low integrity is used with sandbox processes like web browsers.
Applications executing in the context of a regular user run at medium integrity,
and administrators can execute applications at high integrity.
System is typically only used for SYSTEM services.
It’s not possible for a process of a certain integrity level to modify
a process of higher integrity level but the opposite is possible.
This is done to prevent trivial privilege escalation.
Local administrators receive two access tokens when authenticating.
The first, which is used by default,
is configured to create processes as medium integrity.
When the user selects the “Run as administrator” option for an application
the second elevated token is used instead, and allows the process
to run at high integrity.
The User Account Control or UAC mechanism
links these two tokens to a single user and creates the consent prompt.
A local administrator regulated by UAC is sometimes also called
a split-token administrator.
Privileges are also included in the access token.
They are a set of predefined operating system access rights
that govern which actions a process can perform.
Within the access token, privileges are controlled by two bitmasks.
The first sets the privileges which are present for that specific token
and cannot be modified through any API’s inside the same logon session.
The second registers if the present privileges are enabled or disabled
and may be dynamically updated through the Win32 API AdjustTokenPrivileges.
For example, we can easily view the available privileges for the current user
with whoami from cmd.exe by specifying the /priv flag:
The output shows five privileges.
Although we won’t discuss every privilege,
let’s discuss token privilege modification.
The SeShutdownPrivilege privilege
allows the user to reboot or shutdown the computer.
Since it is listed in the output, it is present in the access token,
but it is also disabled.
If we choose to shut down the computer through the shutdown command
the back-end code will enable the privilege with AdjustTokenPrivileges,
and then perform the required actions to power off the operating system.
While it is impossible to modify the set of privileges that are associated with
an active logon session, it is however possible to add additional privileges
that will take effect after the targeted user account logs out and logs back in.
Programatically this can be done with the Win32 API LsaAddAccountRights,
but more often it would be performed through a group policy
or locally through an application like secpol.msc.
The selected privilege SeLoadDriverPrivilege
yields the permission to load a kernel driver.
If we were to apply that privilege to our user, the current token would not be
modified, rather a new token would be created
once the user logs out and back in again.
As we wrap up this theoretical section, we must discuss two types of access tokens.
Each process has a primary access token which originates from the user’s token
created during authentication.
In addition, an impersonation token can be created
which allows a user to act on behalf of another user
without that user’s credentials.
Impersonation tokens have four levels:
Anonymous, Identification, Impersonation and Delegation.
Anonymous and Identification only allow enumeration of information.
Impersonation, as the name implies, allows impersonation of the client’s identity,
while Delegation makes it possible to perform sequential access control checks
across multiple machines.
The latter is critical to the functionality of distributed applications.
For example, let’s assume a user authenticates to a web server
and performs an action on that server that requires a database lookup.
The web service could use delegation to pass authentication to the database server
“through” the web server.
Now that we’ve discussed the main theory behind Windows post-authentication permissions
and access rights we’ll practically apply this theory in the next section.