Esempio n. 1
0
        public TokenSwitchRenderer(Connection connection, ElevationRequest elevationRequest)
        {
            if (Settings.SecurityEnforceUacIsolation && !elevationRequest.NewWindow)
            {
                throw new Exception("TokenSwitch mode not supported when SecurityEnforceUacIsolation is set.");
            }

            _connection       = connection;
            _elevationRequest = elevationRequest;
            Environment.SetEnvironmentVariable("prompt", Environment.ExpandEnvironmentVariables(elevationRequest.Prompt));

            ProcessApi.CreateProcessFlags dwCreationFlags = ProcessApi.CreateProcessFlags.CREATE_SUSPENDED;

            if (elevationRequest.NewWindow)
            {
                dwCreationFlags |= ProcessApi.CreateProcessFlags.CREATE_NEW_CONSOLE;
            }

            string exeName, args;

            if (elevationRequest.IntegrityLevel == IntegrityLevel.MediumPlus &&
                ArgumentsHelper.UnQuote(elevationRequest.FileName.ToUpperInvariant()) != Environment.GetEnvironmentVariable("COMSPEC").ToUpperInvariant())
            {
                // Now, we have an issue with this method: The process launched with the new token throws Access Denied if it tries to read its own token.
                // Kind of dirty workaround is to wrap the call with a "CMD.exe /c ".. this intermediate process will then
                // launching the command with a fresh new (desired) token and we know cmd wont try to read it's substitute token (throwing Access Denied).

                exeName = Environment.GetEnvironmentVariable("COMSPEC");
                args    = $"/s /c \"{elevationRequest.FileName} {elevationRequest.Arguments}\"";
            }
            else
            {
                // Hack not needed if we are already calling CMD
                exeName = elevationRequest.FileName;
                args    = elevationRequest.Arguments;
            }

            _process = ProcessFactory.CreateProcessAsUserWithFlags(exeName, args, dwCreationFlags, out _processInformation);

            elevationRequest.TargetProcessId = _processInformation.dwProcessId;
            if (!elevationRequest.NewWindow)
            {
                ConsoleApi.SetConsoleCtrlHandler(ConsoleHelper.IgnoreConsoleCancelKeyPress, true);
            }
        }
Esempio n. 2
0
 public static extern bool CreateProcessWithTokenW(IntPtr hToken, LogonFlags dwLogonFlags, string lpApplicationName, string lpCommandLine, ProcessApi.CreateProcessFlags dwCreationFlags, IntPtr lpEnvironment, string lpCurrentDirectory, [In] ref STARTUPINFO lpStartupInfo, out PROCESS_INFORMATION lpProcessInformation);
Esempio n. 3
0
        internal static SafeProcessHandle CreateProcessAsUserWithFlags(string lpApplicationName, string args, ProcessApi.CreateProcessFlags dwCreationFlags, out PROCESS_INFORMATION pInfo)
        {
            var sInfoEx = new ProcessApi.STARTUPINFOEX();

            sInfoEx.StartupInfo.cb = Marshal.SizeOf(sInfoEx);
            IntPtr lpValue = IntPtr.Zero;

            var pSec = new ProcessApi.SECURITY_ATTRIBUTES();
            var tSec = new ProcessApi.SECURITY_ATTRIBUTES();

            pSec.nLength = Marshal.SizeOf(pSec);
            tSec.nLength = Marshal.SizeOf(tSec);

            var command = $"{lpApplicationName} {args}";

            Logger.Instance.Log($"{nameof(CreateProcessAsUser)}: {lpApplicationName} {args}", LogLevel.Debug);
            if (!ProcessApi.CreateProcess(null, command, ref pSec, ref tSec, false, dwCreationFlags, IntPtr.Zero, null, ref sInfoEx, out pInfo))
            {
                throw new Win32Exception((int)ConsoleApi.GetLastError());
            }

            return(new SafeProcessHandle(pInfo.hProcess, true));
        }