Somewhat unconventional question, but I want to know if it is possible/am trying to create a process in session 0 using a user's token duplicated from their logon session. There are ample examples of having a service/localSystem create a process in the user's session, however I am trying to use localSystem to create a process in session 0 running in the context of a normal user.
Assumptions are as follows:
Code execution as system, full availability of requisite permissions (SeTcbPrivilige, SeAssignPrimaryTokenPrivilige, SeIncreaseQuotaPrivilege, etc)
A user is logged into a console session
I have a working code snippet using
WTSGetActiveConsoleSessionId
WTSQueryUsertoken
DuplicateTokenEx
//SetTokenInformation
CreateProcessAsUser
Which allows me to, from a system shell, spawn a notepad.exe in the terminal user's session. However when I uncomment the SetTokenInformation() call, while it succeeds and calling GetTokenInformation reflects that the tokenSession has been set to 0, CreateProcessAsUser() now fails with error 5: Access Denied. Notepad is of course not the end desired process for this project, and a gui is not necessary.
I have played with various different parts of CreateProcessAsUser, including specifying an environment by using CreateEnvironmentBlock and several process creation flags in the CPAU() call, but to no avail.
I recently saw a process running in session 0 in a user's context, having been spawn via a wmic process call create command. This leads me to believe it is possible; is it?
A code snippet (incomplete but showing major pieces) is below:
DWORD sessId = WTSGetActiveConsoleSessionId();
printf("SessionID is: %d\n", sessId);
HANDLE explorerToken;
WTSQueryUserToken(sessId, &explorerToken);
DuplicateTokenEx(explorerToken, 0, NULL, SecurityImpersonation, TokenPrimary, &NewToken);
STARTUPINFOW si = { sizeof(STARTUPINFO) };
PROCESS_INFORMATION pi;
//memset(&si, 0, sizeof(si));
//memset(&pi, 0, sizeof(pi));
si.cb = sizeof(si);
//si.lpDesktop = L"winsta0\\default";
//si.wShowWindow = SW_HIDE;
/*
LPVOID lpEnvironment = NULL;
CreateEnvironmentBlock(&lpEnvironment, explorerToken, TRUE);
*/
DWORD SessionId, l;
printf("GetTokenInformation %d\n", GetTokenInformation(NewToken, TokenSessionId, &SessionId, sizeof(SessionId), &l));
printf("SessionId %d\n", SessionId);
SessionId = 0;
printf("SetTokenInformation %d\n", SetTokenInformation(NewToken, TokenSessionId, &SessionId, sizeof(SessionId)));
printf("SessionId %d\n", SessionId);
printf("CreateProcessAsUser %d\n", CreateProcessAsUserW(NewToken, L"C:\\windows\\system32\\notepad.exe", NULL, NULL, NULL, FALSE, NULL, NULL, NULL, &si, &pi));
printf("Error is: %u\n", GetLastError());
printf("Process Id: %d\n", pi.dwProcessId);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
CloseHandle(NewToken);
Any insight or suggestions? Thanks for your time.