I try to start a process using the CreateProcessAsUser() function. Everything goes well, I even get the id of the created process but the program does not start. I have created process in suspended state, attach debugger to new created process and after this resume it, but it disappears. I also ran the function within a service in NT USER, same result. CreateProcess() and createprocesswithlogonw() don't solve it.
Here is the code, inspired in large part by the GitHub project : https://github.com/lucent-sea/Adit.
public static bool OpenInteractiveProcess(cDebug oDebugMipSvc)
{
string applicationName = K_ExePath;
IntPtr m_hProcess = IntPtr.Zero;
IntPtr m_hThread = IntPtr.Zero;
IntPtr hUserTokenDup = IntPtr.Zero, hPToken = IntPtr.Zero, hProcess = IntPtr.Zero;
bool result = true;
try
{
uint winlogonPid = 0;
PROCESS_INFORMATION procInfo = new PROCESS_INFORMATION();
// Obtain session ID for active session.
uint dwSessionId = Kernel32.WTSGetActiveConsoleSessionId();
// Obtain the process ID of the winlogon process that is running within the currently active session.
Process[] processes = Process.GetProcessesByName("winlogon");
foreach (Process p in processes)
{
if ((uint)p.SessionId == dwSessionId)
{
winlogonPid = (uint)p.Id;
}
}
// Obtain a handle to the winlogon process.
hProcess = Kernel32.OpenProcess(MAXIMUM_ALLOWED, false, winlogonPid);
// Obtain a handle to the access token of the winlogon process.
if (OpenProcessToken(hProcess, TOKEN_DUPLICATE, ref hPToken) == 0)
{
Kernel32.CloseHandle(hProcess);
result = false;
throw new Exception($"OpenProcessToken :{Marshal.GetExceptionForHR(Marshal.GetHRForLastWin32Error()).Message}");
}
// Security attibute structure used in DuplicateTokenEx and CreateProcessAsUser.
SECURITY_ATTRIBUTES sa = new SECURITY_ATTRIBUTES();
sa.nLength = Marshal.SizeOf(sa);
// Copy the access token of the winlogon process; the newly created token will be a primary token.
if (!DuplicateTokenEx(hPToken, MAXIMUM_ALLOWED, ref sa, SECURITY_IMPERSONATION_LEVEL.SecurityIdentification, TOKEN_TYPE.TokenPrimary, out hUserTokenDup))
{
Kernel32.CloseHandle(hProcess);
Kernel32.CloseHandle(hPToken);
result = false;
throw new Exception($"DuplicateTokenEx :{Marshal.GetExceptionForHR(Marshal.GetHRForLastWin32Error()).Message}");
}
// By default, CreateProcessAsUser creates a process on a non-interactive window station, meaning
// the window station has a desktop that is invisible and the process is incapable of receiving
// user input. To remedy this we set the lpDesktop parameter to indicate we want to enable user
// interaction with the new process.
STARTUPINFO si = new STARTUPINFO();
si.cb = (int)Marshal.SizeOf(si);
si.lpDesktop = @"WinSta0\Default";
// Flags that specify the priority and creation method of the process.
uint dwCreationFlags = NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE;
// Create a new process in the current user's logon session.
if (!CreateProcessAsUser(hUserTokenDup, null, applicationName, ref sa, ref sa, false, dwCreationFlags, IntPtr.Zero, null, ref si, out procInfo))
{
result = false;
throw new Exception($"CreateProcessAsUser :{Marshal.GetExceptionForHR(Marshal.GetHRForLastWin32Error()).Message}");
}
m_hProcess = procInfo.hProcess;
m_hThread = procInfo.hThread;
oDebug.Log("After CreateProcessAsUser - _processInfo : dwpProcessId --> " + procInfo.dwProcessId + " and dwThreadId --> " + procInfo.dwThreadId);
return result;
}
catch
{
return false;
}
finally
{
// Invalidate the handles.
Kernel32.CloseHandle(m_hProcess);
Kernel32.CloseHandle(m_hThread);
Kernel32.CloseHandle(hUserTokenDup);
}
}
And the logs are :
2022/07/05 16:45:01 - SVC____ - //////////////////////////////////////STARTING\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
2022/07/05 16:45:01 - SVC____ - Value of Current desktop: default
2022/07/05 16:45:01 - SVC____ - Current Session Id --> 0
2022/07/05 16:45:01 - SVC____ - Current Process user name : NT AUTHORITY\SYSTEM
2022/07/05 16:45:01 - SVC____ - Current Session Id --> 0
2022/07/05 16:45:01 - SVC____ - LogonId (LUID): 999
2022/07/05 16:45:01 - SVC____ - TokenSessionId --> 0
2022/07/05 16:45:01 - SVC____ - Originating Session Id: 0x0
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\STOPING//////////////////////////////////////
2022/07/05 16:45:01 - SVC____ - After CreateProcessAsUser - _processInfo : dwpProcessId --> 25592 and dwThreadId --> 41236
2022/07/05 16:45:01 - SVC____ - Log Stop