How to launch a process as a Full Administrator when UAC is enabled?

With the introduction of User Access Control (UAC) with Windows VISTA, the ability to launch a process as a full administrator when UAC was enabled doesn’t automatically happen anymore.  Typically, you make the following API calls to launch a process as an Administrator (if the current user is not an administrator):

  1. You call LogonUser() where you specify a user who belongs to the administrator group.
  2. CreateProcessAsUser() with the token returned from LogonUser().

If you run this code on Windows XP versus Windows 8, you are going to see different results.  The resultant process on Windows XP will be running as administrator while on Windows 8, the user will NOT be running as an Administrator.

A couple of things to note, UAC only impacts Interactive logons.  (This is specified by the logon type in LogonUser, LOGON32_LOGON_INTERACTIVE).  You can see this with services, a service configured for an Administrator runs as an Administrator.  One way to make sure your launched process is running as an
Administrator is to use a Service or Batch logon type.  The other way is to launch a process as an Administrator is to realize that the Administrator Token for a user who belongs to the Administrator group is embedded in their token.  Windows just doesn’t use it by default when UAC is enabled.  You can programmatically
retrieve the Administrator Token via the GetTokenInformation() call and specifying TokenLinkedToken as the token information class.  This operation requires the caller to have the SeTcbPrivilege so not any user can make this call.  The new steps to launch a process as an administrator with an interactive token are:

  1. You must have the SeTcbPrivilege and it must be enabled. 
  2. LogonUser() with LOGON32_LOGON_INTERACTIVE
  3. GetTokenInformation() with the token returned from LogonUser() specifying the TokenLinkedToken class.
  4. CreateProcessAsUser() with the token returned from GetTokenInformation().

If you don’t have the SeTcbPrivilege(), you will still be able to obtain the TokenLinkedToken but it will result in an IDENTIFY level token which will fail in the call to CreateProcessAsUser().