0

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

0 Answers0