When UAC is enabled, and you log in with an administrative account, you get two tokens:
the elevated token; this has the Administrators group enabled, is high integrity (i.e., the mandatory integrity label SID is S-1-16-12288) and has elevation type TokenElevationTypeFull.
the limited token; this has the Administrators group disabled, is medium integrity (S-1-16-8192) and has elevation type TokenElevationTypeLimited.
Do these three factors always match up in this way? That is, does the kernel require that only tokens with the Administrators group enabled can have high integrity and/or TokenElevationTypeFull?
Are there any circumstances under which a process will not have Administrators privilege but will be running with high integrity and/or TokenElevationTypeFull?
(Rationale for the question: the answer affects the ways in which a programmer can safely test for elevated privileges. For example, it came up here.)
No, the kernel does not require that the integrity level and elevation type of a token match up with the status of the Administrators group. This means that a process having a high integrity level, or
TokenElevationTypeFull
, does not necessarily have administrator access.In particular, note that using
runas /trustlevel:0x20000
from an administrative command prompt will result in a process that does not have administrator privilege but nonetheless runs with high integrity and (if UAC is enabled) will haveTokenElevationTypeFull
. (As discovered here.) I believe this represents a bug inrunas
.Addendum October 2022: I suspect that the bug in
runas
is that it only allows you to specify certain integrity levels, and gets them wrong! Medium integrity is 0x2000, not 0x20000.This sample code demonstrates the behaviour; if run with admin privilege, it launches a subprocess with the administrators group (and all privileges except
SeChangeNotifyPrivilege
) disabled but which is still running with high integrity andTokenElevationTypeFull
.Output when run from an elevated command prompt:
If you run the sample code again from the child process, you can confirm that the child process did retain these properties:
If UAC is disabled, the elevation type is TokenElevationTypeDefault but otherwise the outcome is the same:
As expected, the limited token looks like this:
Or if you're logged in as a non-admin user, whether UAC is enabled or not:
(All tests run on Windows 7 SP1 x64.)