Wednesday, July 22, 2020

Token Privilege in Windows [CheckPrivilegeState, ShowPrivilegeInfo, ShowEnabledPrivileges]

Viewing Token Privileges

Download from ME
Download from VBForums

Privileges control access to system resources and system-related tasks, whereas access rights control access to securable objects. Most API functions typically used by VB6 applications do not relate to system resources, but there are some WinAPI functions which require specific privileges to be enabled before they will function. If the application does not have access to the required privileges, the privilege can’t be enabled, and the function will fail. If the application does have access to the required privileges, the application may have to first enable the privilege.

The privileges available to an application are primarily determined by the logged user credentials, and whether the user has elevated credentials. The privileges allocated to user and groups are defined in the Group Policy User Rights.

This application displays the privileges that are provided by Windows, the subset that are available to the process token, and the privileges which are currently enabled. This application also provides the facility to enable or disable a privilege.

The application form lists all the available OS Privileges as a collection of privilege option buttons, provides buttons to display 3 pre-configured Privilege sets, and selecting any option button will display the status of that Privilege. Selecting the Enable and Disabled buttons will attempt to set the state of the selected privilege option button.

The 3 pre pre-configured displays of Privilege sets are:

  1. CheckPrivilegeState
    Lists the state of all the OS Privileges to show which Privileges are enabled with the current process token. The state is either “Disabled” or “Enabled”. Note the “Disabled” privileges state does not indicate if this privilege is available with the process token.

  1. ShowPrivilegeInfo
    Lists the state of all the privileges available with the process token. The state is either “Disabled”, or “Enabled” and/or “Enabled(default)”.

  1. ShowEnabledPrivileges
    Lists all the privileges which are currently Enabled.




Figure 1. Example display for a process running with elevated administrators

The count boxes shows 24 of the 36 privileges are available with elevated credentials, of which 3 are enabled. With these user credentials, only 5 of the 34 privileges are available, and only one is enabled.

The Count textboxes are show the number of privileges. The LookUp counts are calculated when the form is loaded based on the LookupPrivilegeValue and LookupPrivilegeName results. These two totals should be the same, any difference would indicate a program error. The Token Counts are updated whenever the Token Privileges buttons are selected. The CheckPrivileges State updates the Check count and the Enabled Count, the Show Privileges Information updates the Info count, and the Show Enabled Privileges updates the Enabled Count and the Check count. Selecting the Enabled and Disable buttons does not update these totals.

As an example of API’s which require specific privileges and those which don’t, the functions to create a process have differing privilege requirements:

CreateProcessWithTokenW
must have the SE_IMPERSONATE_NAME privilege.
CreateProcessAsUser
must have the SE_INCREASE_QUOTA_NAME privilege and may require the SE_ASSIGNPRIMARYTOKEN_NAME privilege if the token is not assignable
CreateProcessWithLogonW
requires no special privileges as the new process runs in the security context of the Logon User
CreateProcess
requires no special privileges as the new process runs in the security context of the calling process

Windows API functions used to view and change Privileges state

There are two WinAPI functions to view the privileges available with a process token, PrivilegeCheck API, and GetTokenInformation API with the TokenPrivileges option. The AdjustTokenPrivileges API is used to enable or disable privileges

  • The PrivilegeCheck API returns the Enabled status of a specific privilege or group of privileges.

  • The GetTokenInformation API with the TokenPrivileges option returns an array of all the privileges available to a process token, together with the privileges attributes including the Enabled status.

  • The AdjustTokenPrivileges API sets the enabled state to either Enabled or Disabled for a specific privilege or group of privileges. It can also return the previous state.  The AdjustTokenPrivileges function cannot add new privileges to the access token.

Important : The PrivilegeCheck declared in the API.Txt file used with the VB6 API viewer may be incorrect. The last argument should be byref and not byval.

Each OS has a set of privilege names, and these are listed in the MSDN document “Privilege Constants”. The set of privileges rarely changes between OS version.

Each privilege is assigned a LUID value. The WinAPI function LookupPrivilegeValue returns the Privilege LUID for a Privilege Name. The corresponding function LookupPrivilegeName returns the Privilege Name for a Privilege LUID.

When a process token is created, a subset of the OS privileges is added to the token. These are determined by the User Logon credentials. Some may be set to ENABLED state by default, others are DISABLED by default. The state of each of the privileges included in the token can be changed to ENABLE the privilege or DISABLE the privilege using the AdjustTokenPrivileges API.

The AdjustTokenPrivileges requires the token must have been opened with TOKEN_ADJUST_PRIVILEGES access, and the TOKEN_QUERY to view the previous state access). In this application, the Token is opened with the MAXIMUM_ALLOWED Access.

Using the TokenPrivilege Application

Selecting any of the Privilege option buttons will display both the Info State (as in ShowPrivilegeInfo), and the Enabled State (as in CheckPrivilegeState) for the selected Privilege. In addition the Enable and Disable button will attempt to change the Enabled State of any selected privilege.

When a Privilege option button is selected, both the GetTokenInformation API and the PrivilegeCheck API are used to query the specific privilege as follows:
  • Query a privilege with the GetTokenInformation API to determine if the privilege is available and if it is enabled
    1. Open the token for the current process using the the OpenProcessToken(GetCurrentProcess()..) API functions.
    2. Lookup the Privilege LUID form the selected Privilege Name using the  LookupPrivilegeValue API.
    3. Call the GetTokenInformation API with the TokenPrivileges option to create an array of Privileges for the token.
    4. Search the array of Privileges for a matching Privilege LUID. If there is no match, the specific Privilege is not available.
    5. Test the attribute bits for the Enabled bit &H2.
  • Query a privilege enable state with PrivilegeCheck API
    1. Open the token for the current process using the the OpenProcessToken(GetCurrentProcess()..) API functions .
    2. Lookup the Privilege LUID form the selected Privilege Name using the LookupPrivilegeValue API.
    3. Create a PRIVILEGE_SET structure with this Privilege LUID, setting the control member to zero, and the count to one.
    4. Call the PrivilegeCheck API with this PRIVILEGE_SET structure, if his call fails then the privilege does not exist.
    5. Test the attribute bits in the returned PRIVILEGE_SET structure, set to a value of &H80000000 if it is enabled.

When either the Enabled or Disabled button is selected, this application uses the AdjustTokenPrivileges API to attempt to change the Enabled state as follows:
  • Change the state of the selected privilege with AdjustTokenPrivileges
a.       Open the token for the current process using the the OpenProcessToken(GetCurrentProcess(),<access mask>) API functions.
b.      Lookup the Privilege LUID form the selected Privilege Name using the  LookupPrivilegeValue API.
c.       Create a TOKEN_PRIVILEGES structure for a single privilege, setting the Attributes to either SE_PRIVILEGE_ENABLED to enable the privilege, or to 0 to disable the privilege.
d.      Call the AdjustTokenPrivileges API with the TokenPrivileges structure.
e.       Test the result for ERROR_NOT_ALL_ASSIGNED which indicates the selected privilege is not available in the token.
f.       Report the updated result using the PrivilegeCheck API.

This application illustrates the privileges available for current process token. The Token is opened using the OpenProcessToken(GetCurrentProcess(),<access mask>) API functions. The <acces mask> is set to “MAXIMUM_ALLOWED”. There are other tokens that could be used, for example if the application included the impersonating of another user, it could open the Token using OpenProcessToken(GetCurrentThread(),<access mask>) API functions. 

Source:
http://www.vbforums.com/showthread.php?863511-Viewing-Token-Privileges

No comments:

Post a Comment