Privileges are a way to control who has access to certain system-wide resources. For example if a user does not have SE_SHUTDOWN_PRIVILEGE aka SeShutdownPrivilege, she cannot shutdown the machine. Privileges are stored in the token and have to be present and enabled to take effect. If a privilege is absent or disabled in the process/thread token, attempts to shutdown the system by calling ExitWindowsEx or NtShutdownSystem will fail and GetLastError will return error 1314 (ERROR_PRIVILEGE_NOT_HELD )- A required privilege is not held by the client.
Now obviously privileges are pretty powerful and play a huge role in locking down the system. As it turns out, some privileges such as SeCreateTokenPrivilege are pretty hard to obtain in Vista – even under the hallowed auspices of a LocalSystem service.
If one adds SeCreateTokenPrivilege to RequiredPrivileges REG_MULTI_SZ value under HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\<Service> registry key, which is the documented way to request that a privilege be present for a service, the service fails to start.
As an experiment I added SeCreateTokenPrivilege to Microsoft’s svchost based iphlpsvc service and attempted to start the service from Services.msc. I got error 1297 (ERROR_INCOMPATIBLE_SERVICE_PRIVILEGE) –
Granting SeCreateTokenPrivilege to LocalSystem explicitly (in Local Security Policy MMC snap-in secpol.msc) does not help either.
Services are managed (and started) by Service Control Manager (services.exe). If one looks at the process token of services.exe, the SeCreateTokenPrivilege privilege seems to be missing altogether !
What is going in here is that the Service Control Manager (services.exe) after being launched by wininit.exe, removes SeCreateTokenPrivilege (SE_CREATE_TOKEN_PRIVILEGE), SeTrustedCredManAccessPrivilege (SE_TRUSTED_CREDMAN_ACCESS_PRIVILEGE), SeRelabelPrivilege (SE_RELABEL_PRIVILEGE) from its process token1 thereby renouncing2 the privileges forever because once a privilege is removed, it cannot be added back to the token and of course a privilege cannot be enabled if it is not even there. Since these privileges are missing from Service Control Manager process token, none of the LocalSystem services can get these privileges.
So what if a LocalSystem service needs to call NtCreateToken on Vista and therefore needs SeCreateTokenPrivilege ? The short answer is – you would have to redesign and probably complicate3 your software in the process.
1This was observed in 32-bit Vista SP1 Service Control Manager when it calls NtAdjustPrivilegeToken in internal function ScRemoveProcessPrivileges.
2Service Control Manager is not the only one that does such removal. The Local Session Manager (lsm.exe) also removes SeCreateTokenPrivilegeand SeTrustedCredManAccessPrivilege but keeps SeRelabelPrivilege.
3One of the ways to be able to call NtCreateToken is to arrange code to run in lsass.exe process space which has and has to have SeCreateTokenPrivilege.