SeDebugPrivilege and Integrity Level
Windows Integrity mechanism was introduced in Vista/Win 2008. With this feature, operating system assigns so-called integrity level to process or thread. There are 5 integrity levels - Untrusted level (0x0000), Low integrity level (0x1000), Medium integrity level (0x2000), High integrity level (0x3000), System integrity level (0x4000). An interesting point is any process or thread with lower integrity level cannot access higher integrity level process or thread.

When an administrator runs an appliication with normal mode, its integrity level is Medium. If an administrator runs the application in elevated mode, its integrity level becomes High integrity level. Then can the elevated application access any process having System integrity level? The anwser is no. The attempt to access system integrity level process or thread will return Access Denied exception.

So if we cannot access any System integrity level process even if the current user is administrator, how can we solve this problem? We know there are various user scenarios that need to access system process.

There is a way. If SeDebugPrivilege is set in elevated process, the process/thread can access System integrity level process or thread. The below code shows one way of enabling (or disabling) SeDebugPrivilege in the access token.

BOOL EnableDebugPrivilege(BOOL bEnable)
{
HANDLE hToken = NULL;

if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken))
return FALSE;

LUID luid;
if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid ))
return FALSE;

TOKEN_PRIVILEGES tokenPriv;
tokenPriv.PrivilegeCount = 1;
tokenPriv.Privileges[0].Luid = luid;
tokenPriv.Privileges[0].Attributes = bEnable ? SE_PRIVILEGE_ENABLED : 0;

if (!AdjustTokenPrivileges(hToken, FALSE, &tokenPriv, sizeof(TOKEN_PRIVILEGES), NULL, NULL))
return FALSE;

return TRUE;
}

Once the code is executed, we can check the SeDebugPrivilege
by running !token in the debugger.

0:011> !token –n
Privs:
00 0x000000005 SeIncreaseQuotaPrivilege Attributes -
01 0x000000007 SeTcbPrivilege Attributes -
02 0x000000008 SeSecurityPrivilege Attributes -
03 0x000000009 SeTakeOwnershipPrivilege Attributes -
04 0x00000000a SeLoadDriverPrivilege Attributes -
05 0x00000000b SeSystemProfilePrivilege Attributes -
06 0x00000000c SeSystemtimePrivilege Attributes -
07 0x00000000d SeProfileSingleProcessPrivilege Attributes -
08 0x00000000e SeIncreaseBasePriorityPrivilege Attributes -
09 0x00000000f SeCreatePagefilePrivilege Attributes -
10 0x000000011 SeBackupPrivilege Attributes -
11 0x000000012 SeRestorePrivilege Attributes -
12 0x000000013 SeShutdownPrivilege Attributes -
13 0x000000014 SeDebugPrivilege Attributes - Enabled
14 0x000000016 SeSystemEnvironmentPrivilege Attributes -
15 0x000000017 SeChangeNotifyPrivilege Attributes - Enabled Default
16 0x000000018 SeRemoteShutdownPrivilege Attributes -
17 0x000000019 SeUndockPrivilege Attributes -
18 0x00000001c SeManageVolumePrivilege Attributes -
19 0x00000001d SeImpersonatePrivilege Attributes - Enabled Default
20 0x00000001e SeCreateGlobalPrivilege Attributes - Enabled Default
21 0x000000021 SeIncreaseWorkingSetPrivilege Attributes -
22 0x000000022 SeTimeZonePrivilege Attributes -
23 0x000000023 SeCreateSymbolicLinkPrivilege Attributes -

Auth ID: 0:19c236
Impersonation Level: Impersonation
TokenType: Impersonation
Is restricted token: no.

One more thing. If a process sets debug privilege and calls some function in another process - through impersonation - the debug privilege can be propagated to called process. For instance, if a process with debug privilege calls a method in WMI process, the WMI thread will have the same privilege in its thread.