/// <summary> /// Get a safer token. /// </summary> /// <param name="token">The base token.</param> /// <param name="level">The safer level to use.</param> /// <param name="make_inert">True to make the token inert.</param> /// <returns>The safer token.</returns> public static NtToken GetTokenFromSaferLevel(NtToken token, SaferLevel level, bool make_inert) { IntPtr level_handle; if (!Win32NativeMethods.SaferCreateLevel(SaferScope.User, level, Win32NativeMethods.SAFER_LEVEL_OPEN, out level_handle, IntPtr.Zero)) { throw new SafeWin32Exception(); } try { using (NtToken duptoken = token.Duplicate(TokenAccessRights.GenericRead | TokenAccessRights.GenericExecute)) { SafeKernelObjectHandle handle; if (Win32NativeMethods.SaferComputeTokenFromLevel(level_handle, duptoken.Handle, out handle, make_inert ? SaferFlags.MakeInert : 0, IntPtr.Zero)) { return(NtToken.FromHandle(handle)); } else { throw new SafeWin32Exception(); } } } finally { Win32NativeMethods.SaferCloseLevel(level_handle); } }
internal static extern bool SaferCreateLevel(SaferScope dwScopeId, SaferLevel dwLevelId, int OpenFlags, out IntPtr pLevelHandle, IntPtr lpReserved);
public static NtToken GetTokenFromSaferLevel(NtToken token, SaferLevel level, bool make_inert) { IntPtr level_handle; if (!SaferCreateLevel(SaferScope.User, level, SAFER_LEVEL_OPEN, out level_handle, IntPtr.Zero)) { throw new SafeWin32Exception(); } try { using (NtToken duptoken = token.Duplicate(TokenAccessRights.GenericRead | TokenAccessRights.GenericExecute)) { SafeKernelObjectHandle handle; if (SaferComputeTokenFromLevel(level_handle, duptoken.Handle, out handle, make_inert ? SaferFlags.MakeInert : 0, IntPtr.Zero)) { return NtToken.FromHandle(handle); } else { throw new SafeWin32Exception(); } } } finally { SaferCloseLevel(level_handle); } }
static extern bool SaferCreateLevel(SaferScope dwScopeId, SaferLevel dwLevelId, int OpenFlags, out IntPtr pLevelHandle, IntPtr lpReserved);
public static Process CreateSaferProcess(String fileName, string arguments, SaferLevel saferLevel, IntegrityLevel integrityLevel, CreateProcessFlags flags = CreateProcessFlags.CREATE_NEW_CONSOLE) { IntPtr saferLevelHandle = IntPtr.Zero; //Create a SaferLevel handle to match what was requested if (!SaferCreateLevel(SaferLevelScope.User, saferLevel, SaferOpen.Open, out saferLevelHandle, IntPtr.Zero)) { throw new Win32Exception(Marshal.GetLastWin32Error()); } try { //Generate the access token to use, based on the safer level handle. IntPtr hToken = IntPtr.Zero; if (!SaferComputeTokenFromLevel( saferLevelHandle, // SAFER Level handle IntPtr.Zero, // NULL is current thread token. out hToken, // Target token SaferTokenBehaviour.Default, // No flags IntPtr.Zero)) // Reserved { throw new Win32Exception(Marshal.GetLastWin32Error()); } // Get the Integrity SID IntPtr pIntegritySid = GetIntegritySid(integrityLevel); // Construct a structure describing the token integrity level var TIL = new TOKEN_MANDATORY_LABEL(); TIL.Label.Attributes = SE_GROUP_INTEGRITY; TIL.Label.Sid = pIntegritySid; IntPtr pTIL = Marshal.AllocHGlobal(Marshal.SizeOf <TOKEN_MANDATORY_LABEL>()); Marshal.StructureToPtr(TIL, pTIL, false); // Modify the token if (!SetTokenInformation(hToken, TOKEN_INFORMATION_CLASS.TokenIntegrityLevel, pTIL, (uint)Marshal.SizeOf <TOKEN_MANDATORY_LABEL>() + GetLengthSid(pIntegritySid))) { throw new Win32Exception(); } try { //Now that we have a security token, we can lauch the process //using the standard CreateProcessAsUser API STARTUPINFO si = new STARTUPINFO(); si.cb = Marshal.SizeOf(si); si.lpDesktop = String.Empty; var processAttributes = new SECURITY_ATTRIBUTES(); var threadAttributes = new SECURITY_ATTRIBUTES(); // Spin up the new process //bool result = CreateProcessAsUser(hToken, fileName, arguments, bool result = CreateProcessAsUser(hToken, fileName, $"\"{fileName}\"{(arguments?.Length > 0 ? " " + arguments : "")}", ref processAttributes, ref threadAttributes, false, //inherit handles flags, IntPtr.Zero, //environment null, //current directory ref si, //startup info out PROCESS_INFORMATION pi); //process info if (!result) { throw new Win32Exception(Marshal.GetLastWin32Error()); } if (pi.hProcess != IntPtr.Zero) { CloseHandle(pi.hProcess); } if (pi.hThread != IntPtr.Zero) { CloseHandle(pi.hThread); } return(Process.GetProcessById(pi.dwProcessId)); } finally { if (hToken != IntPtr.Zero) { CloseHandle(hToken); } } } finally { SaferCloseLevel(saferLevelHandle); } }
public static extern bool SaferCreateLevel(SaferLevelScope scopeId, SaferLevel levelId, SaferOpen openFlags, out IntPtr levelHandle, IntPtr reserved);