Windows Privileges - Trusted Computing Base
Note that absolutely none of this is authoritative or directly based on relevant documentation. It is mostly what I found and figured out and guessed and (in some cases) made up. Some of it may be wrong or dangerous or lead to disaster or confusion. I am not taking responsibility here for anything, not even spelling. Read and digest at your own peril!
“Act as part of the operating system”
That is the legal name of a privilege with the technical name SeTcbPrivilege or SE_TCB_NAME. The official description is
This privilege identifies its holder as part of the trusted computer base. Some trusted protected subsystems are granted this privilege.
I cannot see how one can be clearer than that!
I am myself not very familiar with SeTcbPrivilege. It is not something one runs into daily and or something that many applications would need for normal operation. In fact is it not even held by the Administrators group (and therefor also not by members of that group, usually) and Microsoft themselves apparently recommend not assinging it to any account and run services that need this privilege under the LocalSystem account which has this privilege.
As far as I know it allows a process to assume any identity and is meant to be used by the Local Security Authority to log on accounts (users and services likewise).
Thus it is required by many Lsa* APIs but also by some uses of the SetTokenInformation API which manipulates access tokens.
For example, to create a process in an arbitrary session (not the session of the process-creating process), SeTcbPrivilege is needed, among other things.
What else is needed:
- the process-creating process has to run in the services session (session 0) and
- the process-creating process has to run in a service or batch logon context (i.e. not interactive or network) and
- the process-creating process has to hold SeAssignPrimaryTokenPrivilege as well (to create the process with the manipulated token)
Alternatively, the procress-creating service has to run under LocalSystem, in which case it will have all the necessary privileges and does not matter how it logged on or in which session it runs.
The easiest way to accomplish this feat is to equip an account with SeTcbPrivilege and SeAssignPrimaryTokenPrivilege and create a scheduled task to create a process.
Remember that privileges have to be enabled before they can be used.
// we need a handle to a token, let's use the current process' primary token
HANDLE hToken;
ok = OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &hToken);
// we need a copy of the token to modify it and use it elsewhere
HANDLE hModifiedToken;
ok = DuplicateTokenEx(hToken, MAXIMUM_ALLOWED, NULL, SecurityImpersonation, TokenPrimary, &hModifiedToken);
// this next step requires SeTcbPrivilege, it changes the session id of the token to iSessionId (maybe 2)
ok = SetTokenInformation(hModifiedToken, TokenSessionId, &iSessionId, sizeof(DWORD));The call to SetTokenInformation() will fail with an error 1314 (“privilege not held”) if the process does not hold SeTcbPrivilege:
PS B:\> .\TcbDemo.exe C:\windows\system32\winver.exe 2
Image [C:\windows\system32\winver.exe] in session with id [2].
OpenProcessToken OK: [1] STATUS: [0], Error: [0]
DuplicateTokenEx OK: [1] STATUS: [0], Error: [0]
SetTokenInformation OK: [0] STATUS: [0], Error: [1314]
PS B:\> certutil /error 1314
0x522 (WIN32: 1314 ERROR_PRIVILEGE_NOT_HELD) -- 1314 (1314)
Error message text: A required privilege is not held by the client.
CertUtil: -error command completed successfully.
PS B:\>Now that we have a modified second token, we can start a process with it. And if everything else is perfect (session 0, service or batch logon, SeAssignPrimaryTokenPrivilege held, moon in conjunction with venus etc.) this will start an unusable program in the requested session. (It is unusable because it does not belong into the session it runs in and is missing permissions. A window will appear though. See Scheduled Task to Start Privileged Application which describes a program that implements exactly this mechanism.)
// creating the process, this step requires SeAssignPrimaryTokenPrivilege to, well, assign the primary token
ok = CreateProcessAsUserW(hModifiedToken, pathImage, NULL, NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi);Running this without holding SeAssignPrimaryTokenPrivilege leads to disaster again:
PS B:\> .\TcbDemo.exe c:\windows\system32\cmd.exe 2
Image [c:\windows\system32\cmd.exe] in session with id [2].
OpenProcessToken OK: [1] STATUS: [0], Error: [0]
DuplicateTokenEx OK: [1] STATUS: [0], Error: [0]
SetTokenInformation OK: [1] STATUS: [0], Error: [0]
CreateProcessAsUserW OK: [0] STATUS: [0], Error: [1314]
PS B:\>And with SeAssignPrimaryTokenPrivilege:
PS B:\> .\TcbDemo.exe c:\windows\system32\cmd.exe 2
Image [c:\windows\system32\cmd.exe] in session with id [2].
OpenProcessToken OK: [1] STATUS: [0], Error: [0]
DuplicateTokenEx OK: [1] STATUS: [0], Error: [0]
SetTokenInformation OK: [1] STATUS: [0], Error: [0]
CreateProcessAsUserW OK: [0] STATUS: [0], Error: [5]
PS B:\>The privilege works but creating a process in another session fails due to missing permissions. That’s where running in session 0 comes in.
A scheduled task defined as cmd.exe with arguments /c C:\TcbDemo\TcbDemo.exe C:\Windows\System32\cmd.exe 2 2> C:\Temp\TcbDemo.log produces an error log file
PS C:\> Get-Content .\Temp\TcbDemo.log
OpenProcessToken OK: [1] STATUS: [0], Error: [0]
DuplicateTokenEx OK: [1] STATUS: [0], Error: [0]
SetTokenInformation OK: [1] STATUS: [0], Error: [0]
CreateProcessAsUserW OK: [1] STATUS: [0], Error: [0]
PS C:\>and a window running cmd.exe in session 2. In fact, the process still remembers where it comes from and runs inside a batch logon:
PS C:\> whoami /groups|Select-String "NT Authority"
NT AUTHORITY\Local account and member of Administrators group Well-known group S-1-5-114 Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\BATCH Well-known group S-1-5-3 Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\Authenticated Users Well-known group S-1-5-11 Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\This Organization Well-known group S-1-5-15 Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\Local account Well-known group S-1-5-113 Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\NTLM Authentication Well-known group S-1-5-64-10 Mandatory group, Enabled by default, Enabled group
PS C:\>Note the NT AUTHORITY\BATCH pseudo group. The PowerShell process is a daughter of the cmd.exe process is a daughter of the scheduled task which logged in as a batch job.
Examples of how this mechanism can be used (but shouldn’t be):
In real life it is generally completely unnecessary to start processes in arbitrary sessions unless you are writing malware.
And if you are writing malware you should really find a vulnerability and exploit it and not rely on idiots granting your process system privileges.
Although you likely can.
Next: OpenSSH on Windows