예제 #1
0
파일: MainForm.cs 프로젝트: thexur/1code
        /// <summary>
        /// The function launches an application at low integrity level.
        /// </summary>
        /// <param name="commandLine">
        /// The command line to be executed. The maximum length of this string is 32K
        /// characters.
        /// </param>
        /// <remarks>
        /// To start a low-integrity process,
        /// 1) Duplicate the handle of the current process, which is at medium
        ///    integrity level.
        /// 2) Use SetTokenInformation to set the integrity level in the access token
        ///    to Low.
        /// 3) Use CreateProcessAsUser to create a new process using the handle to
        ///    the low integrity access token.
        /// </remarks>
        internal void CreateLowIntegrityProcess(string commandLine)
        {
            SafeTokenHandle     hToken        = null;
            SafeTokenHandle     hNewToken     = null;
            IntPtr              pIntegritySid = IntPtr.Zero;
            int                 cbTokenInfo   = 0;
            IntPtr              pTokenInfo    = IntPtr.Zero;
            STARTUPINFO         si            = new STARTUPINFO();
            PROCESS_INFORMATION pi            = new PROCESS_INFORMATION();

            try
            {
                // Open the primary access token of the process.
                if (!NativeMethod.OpenProcessToken(Process.GetCurrentProcess().Handle,
                                                   NativeMethod.TOKEN_DUPLICATE | NativeMethod.TOKEN_ADJUST_DEFAULT |
                                                   NativeMethod.TOKEN_QUERY | NativeMethod.TOKEN_ASSIGN_PRIMARY,
                                                   out hToken))
                {
                    throw new Win32Exception();
                }

                // Duplicate the primary token of the current process.
                if (!NativeMethod.DuplicateTokenEx(hToken, 0, IntPtr.Zero,
                                                   SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation,
                                                   TOKEN_TYPE.TokenPrimary, out hNewToken))
                {
                    throw new Win32Exception();
                }

                // Create the low integrity SID.
                if (!NativeMethod.AllocateAndInitializeSid(
                        ref NativeMethod.SECURITY_MANDATORY_LABEL_AUTHORITY, 1,
                        NativeMethod.SECURITY_MANDATORY_LOW_RID,
                        0, 0, 0, 0, 0, 0, 0, out pIntegritySid))
                {
                    throw new Win32Exception();
                }

                TOKEN_MANDATORY_LABEL tml;
                tml.Label.Attributes = NativeMethod.SE_GROUP_INTEGRITY;
                tml.Label.Sid        = pIntegritySid;

                // Marshal the TOKEN_MANDATORY_LABEL struct to the native memory.
                cbTokenInfo = Marshal.SizeOf(tml);
                pTokenInfo  = Marshal.AllocHGlobal(cbTokenInfo);
                Marshal.StructureToPtr(tml, pTokenInfo, false);

                // Set the integrity level in the access token to low.
                if (!NativeMethod.SetTokenInformation(hNewToken,
                                                      TOKEN_INFORMATION_CLASS.TokenIntegrityLevel, pTokenInfo,
                                                      cbTokenInfo + NativeMethod.GetLengthSid(pIntegritySid)))
                {
                    throw new Win32Exception();
                }

                // Create the new process at the Low integrity level.
                si.cb = Marshal.SizeOf(si);
                if (!NativeMethod.CreateProcessAsUser(hNewToken, null, commandLine,
                                                      IntPtr.Zero, IntPtr.Zero, false, 0, IntPtr.Zero, null, ref si,
                                                      out pi))
                {
                    throw new Win32Exception();
                }
            }
            finally
            {
                // Centralized cleanup for all allocated resources.
                if (hToken != null)
                {
                    hToken.Close();
                    hToken = null;
                }
                if (hNewToken != null)
                {
                    hNewToken.Close();
                    hNewToken = null;
                }
                if (pIntegritySid != IntPtr.Zero)
                {
                    NativeMethod.FreeSid(pIntegritySid);
                    pIntegritySid = IntPtr.Zero;
                }
                if (pTokenInfo != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(pTokenInfo);
                    pTokenInfo  = IntPtr.Zero;
                    cbTokenInfo = 0;
                }
                if (pi.hProcess != IntPtr.Zero)
                {
                    NativeMethod.CloseHandle(pi.hProcess);
                    pi.hProcess = IntPtr.Zero;
                }
                if (pi.hThread != IntPtr.Zero)
                {
                    NativeMethod.CloseHandle(pi.hThread);
                    pi.hThread = IntPtr.Zero;
                }
            }
        }
예제 #2
0
        /// <summary>
        /// 此函数以低完整性级别启动一个应用程序
        /// </summary>
        /// <param name="commandLine">
        /// 需要被执行的命令行。此字符串最长为32K个字符。
        /// </param>
        /// <remarks>
        /// 启动一个低完整性进程
        /// 1) 复制当前进程的句柄,它拥有中完整性级别
        /// 2)使用SetTokenInformation设置访问进程的完整性级别为低。
        /// 3)使用CreateProcessAsUser及低完整性级别的访问令牌创建一个新的进程。
        /// </remarks>
        internal void CreateLowIntegrityProcess(string commandLine)
        {
            SafeTokenHandle     hToken          = null;
            SafeTokenHandle     hNewToken       = null;
            string              strIntegritySid = "S-1-16-4096"; // Low integrity SID string 低完整性SID字符串
            IntPtr              pIntegritySid   = IntPtr.Zero;
            int                 cbTokenInfo     = 0;
            IntPtr              pTokenInfo      = IntPtr.Zero;
            STARTUPINFO         si = new STARTUPINFO();
            PROCESS_INFORMATION pi = new PROCESS_INFORMATION();

            try
            {
                // 打开进程的主访问令牌。
                if (!NativeMethod.OpenProcessToken(Process.GetCurrentProcess().Handle,
                                                   NativeMethod.TOKEN_DUPLICATE | NativeMethod.TOKEN_ADJUST_DEFAULT |
                                                   NativeMethod.TOKEN_QUERY | NativeMethod.TOKEN_ASSIGN_PRIMARY,
                                                   out hToken))
                {
                    throw new Win32Exception();
                }

                // 复制当前进程的主令牌。
                if (!NativeMethod.DuplicateTokenEx(hToken, 0, IntPtr.Zero,
                                                   SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation,
                                                   TOKEN_TYPE.TokenPrimary, out hNewToken))
                {
                    throw new Win32Exception();
                }

                // 创建低完整性SID。
                if (!NativeMethod.ConvertStringSidToSid(strIntegritySid,
                                                        out pIntegritySid))
                {
                    throw new Win32Exception();
                }

                TOKEN_MANDATORY_LABEL tml;
                tml.Label.Attributes = NativeMethod.SE_GROUP_INTEGRITY;
                tml.Label.Sid        = pIntegritySid;

                // 转换TOKEN_MANDATORY_LABEL结构至native内存。
                cbTokenInfo = Marshal.SizeOf(tml);
                pTokenInfo  = Marshal.AllocHGlobal(cbTokenInfo);
                Marshal.StructureToPtr(tml, pTokenInfo, false);

                // 设置访问令牌的完整性级别为低。
                if (!NativeMethod.SetTokenInformation(hNewToken,
                                                      TOKEN_INFORMATION_CLASS.TokenIntegrityLevel, pTokenInfo,
                                                      cbTokenInfo + NativeMethod.GetLengthSid(pIntegritySid)))
                {
                    throw new Win32Exception();
                }

                // 以低完整性级别创建一个新进程。
                si.cb = Marshal.SizeOf(si);
                if (!NativeMethod.CreateProcessAsUser(hNewToken, null, commandLine,
                                                      IntPtr.Zero, IntPtr.Zero, false, 0, IntPtr.Zero, null, ref si,
                                                      out pi))
                {
                    throw new Win32Exception();
                }
            }
            finally
            {
                // 集中清理已分配的资源
                if (hToken != null)
                {
                    hToken.Close();
                    hToken = null;
                }
                if (hNewToken != null)
                {
                    hNewToken.Close();
                    hNewToken = null;
                }
                if (pIntegritySid != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(pIntegritySid);
                    pIntegritySid = IntPtr.Zero;
                }
                if (pTokenInfo != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(pTokenInfo);
                    pTokenInfo  = IntPtr.Zero;
                    cbTokenInfo = 0;
                }
                if (pi.hProcess != IntPtr.Zero)
                {
                    NativeMethod.CloseHandle(pi.hProcess);
                    pi.hProcess = IntPtr.Zero;
                }
                if (pi.hThread != IntPtr.Zero)
                {
                    NativeMethod.CloseHandle(pi.hThread);
                    pi.hThread = IntPtr.Zero;
                }
            }
        }