Beispiel #1
0
        private void SetTokenMandatoryLabel(IntPtr token, SecurityMandatoryLabel securityMandatoryLabel)
        {
            // Create the low integrity SID.
            IntPtr integritySid;

            if (!NativeMethods.AllocateAndInitializeSid(
                    ref NativeMethods.SECURITY_MANDATORY_LABEL_AUTHORITY,
                    1,
                    (int)securityMandatoryLabel,
                    0,
                    0,
                    0,
                    0,
                    0,
                    0,
                    0,
                    out integritySid))
            {
                throw new Win32Exception();
            }

            var tokenMandatoryLabel = new TokenMandatoryLabel {
                Label = default(SidAndAttributes)
            };

            tokenMandatoryLabel.Label.Attributes = NativeMethods.SE_GROUP_INTEGRITY;
            tokenMandatoryLabel.Label.Sid        = integritySid;
            //// Marshal the TOKEN_MANDATORY_LABEL structure to the native memory.
            var sizeOfTokenMandatoryLabel = Marshal.SizeOf(tokenMandatoryLabel);
            var tokenInfo = Marshal.AllocHGlobal(sizeOfTokenMandatoryLabel);

            Marshal.StructureToPtr(tokenMandatoryLabel, tokenInfo, false);

            // Set the integrity level in the access token
            if (!NativeMethods.SetTokenInformation(
                    token,
                    TokenInformationClass.TokenIntegrityLevel,
                    tokenInfo,
                    sizeOfTokenMandatoryLabel + NativeMethods.GetLengthSid(integritySid)))
            {
                throw new Win32Exception();
            }

            //// SafeNativeMethods.CloseHandle(integritySid);
            //// SafeNativeMethods.CloseHandle(tokenInfo);
        }
        private void SetTokenMandatoryLabel(IntPtr token, SecurityMandatoryLabel securityMandatoryLabel)
        {
            // Create the low integrity SID.
            IntPtr integritySid;
            if (!NativeMethods.AllocateAndInitializeSid(
                    ref NativeMethods.SECURITY_MANDATORY_LABEL_AUTHORITY,
                    1,
                    (int)securityMandatoryLabel,
                    0,
                    0,
                    0,
                    0,
                    0,
                    0,
                    0,
                    out integritySid))
            {
                throw new Win32Exception();
            }

            var tokenMandatoryLabel = new TokenMandatoryLabel { Label = default(SidAndAttributes) };
            tokenMandatoryLabel.Label.Attributes = NativeMethods.SE_GROUP_INTEGRITY;
            tokenMandatoryLabel.Label.Sid = integritySid;
            //// Marshal the TOKEN_MANDATORY_LABEL structure to the native memory.
            var sizeOfTokenMandatoryLabel = Marshal.SizeOf(tokenMandatoryLabel);
            var tokenInfo = Marshal.AllocHGlobal(sizeOfTokenMandatoryLabel);
            Marshal.StructureToPtr(tokenMandatoryLabel, tokenInfo, false);

            // Set the integrity level in the access token
            if (!NativeMethods.SetTokenInformation(
                    token,
                    TokenInformationClass.TokenIntegrityLevel,
                    tokenInfo,
                    sizeOfTokenMandatoryLabel + NativeMethods.GetLengthSid(integritySid)))
            {
                throw new Win32Exception();
            }

            //// SafeNativeMethods.CloseHandle(integritySid);
            //// SafeNativeMethods.CloseHandle(tokenInfo);
        }
Beispiel #3
0
        // Based on http://blogs.microsoft.co.il/sasha/2009/07/09/launch-a-process-as-standard-user-from-an-elevated-process/
        public unsafe static Process CreateProcessAsStandardUser(string exePath, string arguments, bool launchSuspended = false)
        {
            //Enable SeIncreaseQuotaPrivilege in this process.  (This requires administrative privileges.)
            IntPtr hProcessToken  = IntPtr.Zero;
            var    currentProcess = Process.GetCurrentProcess();

            if (!OpenProcessToken(currentProcess.Handle, TokenAcess.AdjustPrivileges, out hProcessToken))
            {
                throw new Win32Exception(Marshal.GetLastWin32Error());
            }

            try
            {
                TokenPrivileges tkp = new TokenPrivileges();
                tkp.PrivilegeCount = 1;
                if (!LookupPrivilegeValue(null, IncreaseQuotaName, out Luid luid))
                {
                    throw new Win32Exception(Marshal.GetLastWin32Error());
                }

                tkp.Attributes = PrivilegeEnabled;

                if (!AdjustTokenPrivileges(hProcessToken, false, ref tkp, 0, IntPtr.Zero, IntPtr.Zero))
                {
                    throw new Win32Exception(Marshal.GetLastWin32Error());
                }
            }
            finally
            {
                CloseHandle(hProcessToken);
            }

            //Get window handle representing the desktop shell.  This might not work if there is no shell window, or when
            //using a custom shell.  Also note that we're assuming that the shell is not running elevated.
            IntPtr hShellWnd = GetShellWindow();

            if (hShellWnd == IntPtr.Zero)
            {
                throw new InvalidOperationException("Unable to locate shell window; you might be using a custom shell");
            }


            int shellPid;

            GetWindowThreadProcessId(hShellWnd, out shellPid);
            if (shellPid == 0)
            {
                throw new Win32Exception(Marshal.GetLastWin32Error());
            }

            //Open the desktop shell process in order to get the process token.
            IntPtr hShellProcess = OpenProcess(ProcessQueryInformation, false, shellPid);

            if (hShellProcess == IntPtr.Zero)
            {
                throw new Win32Exception(Marshal.GetLastWin32Error());
            }


            IntPtr hShellProcessToken = IntPtr.Zero;
            IntPtr hPrimaryToken      = IntPtr.Zero;

            try
            {
                //Get the process token of the desktop shell.
                if (!OpenProcessToken(hShellProcess, TokenAcess.Duplicate, out hShellProcessToken))
                {
                    throw new Win32Exception(Marshal.GetLastWin32Error());
                }

                //Duplicate the shell's process token to get a primary token.
                const TokenAcess tokenRights = TokenAcess.Query | TokenAcess.AssignPrimary | TokenAcess.Duplicate | TokenAcess.AdjustDefault | TokenAcess.AdjustSessionId;
                if (!DuplicateTokenEx(hShellProcessToken, tokenRights, IntPtr.Zero, SecurityImpersonationLevel.Impersonation, TokenType.Primary, out hPrimaryToken))
                {
                    throw new Win32Exception(Marshal.GetLastWin32Error());
                }

                if (!IsUacEnabled)
                {
                    if (!ConvertStringSidToSid(MediumIntegritySid, out IntPtr sid))
                    {
                        throw new Win32Exception(Marshal.GetLastWin32Error());
                    }

                    // Set integrity level to Medium
                    TokenMandatoryLabel tokenMandatoryLabel = new TokenMandatoryLabel();
                    tokenMandatoryLabel.Label.Attributes = GroupIntegrity;
                    tokenMandatoryLabel.Label.Sid        = sid;
                    var size = Marshal.SizeOf(tokenMandatoryLabel) + GetLengthSid(sid);
                    if (!SetTokenInformation(hPrimaryToken, TokenInformationClass.IntegrityLevel, &tokenMandatoryLabel, size))
                    {
                        throw new Win32Exception(Marshal.GetLastWin32Error());
                    }

                    // Remove elevation from token - Commented out because I couldn't get it to work.
                    //TokenElevation elevation = new TokenElevation();
                    //if (!SetTokenInformation(hPrimaryToken, TokenInformationClass.Elevation, &elevation, 4))
                    //    throw new Win32Exception(Marshal.GetLastWin32Error());
                }

                //Start the target process with the new token.
                StartupInfo        startupInfo = new StartupInfo();
                ProcessInformation pi          = new ProcessInformation();
                var creationFlags = launchSuspended ? CreateSuspended : 0;
                if (!CreateProcessWithTokenW(hPrimaryToken, 0, exePath, exePath + " " + arguments, creationFlags, IntPtr.Zero, IntPtr.Zero, ref startupInfo, out pi))
                {
                    throw new Win32Exception(Marshal.GetLastWin32Error());
                }

                CloseHandle(pi.ProcessHandle);
                CloseHandle(pi.ThreadHandle);
                return(Process.GetProcessById(pi.ProcessId));
            }
            finally
            {
                if (hShellProcessToken != IntPtr.Zero)
                {
                    CloseHandle(hShellProcessToken);
                }

                if (hPrimaryToken != IntPtr.Zero)
                {
                    CloseHandle(hPrimaryToken);
                }

                if (hShellProcess != IntPtr.Zero)
                {
                    CloseHandle(hShellProcess);
                }
            }
        }