1、使用ntrights.exe 添加SeAssignPrimaryTokenPrivilege权限
对应 “计算机配置” -> “Windows 设置” -> “安全设置” -> “本地策略” -> “用户权限分配”->”替换一个进程级令牌”
C#
public static void AddTokenPrivilege(){ if (OperatingSystem.IsWindows()) { WindowsIdentity windowsIdentity = WindowsIdentity.GetCurrent(); Execute("cmd.exe", new string[] { $"ntrights +r SeAssignPrimaryTokenPrivilege -u {windowsIdentity.Name}" }); }}public static string Execute(string fileName, string arg, string[] commands){ Process proc = new Process(); proc.StartInfo.WorkingDirectory = Path.GetFullPath(Path.Join("./")); proc.StartInfo.CreateNoWindow = true; proc.StartInfo.FileName = fileName; proc.StartInfo.UseShellExecute = false; proc.StartInfo.RedirectStandardError = true; proc.StartInfo.RedirectStandardInput = true; proc.StartInfo.RedirectStandardOutput = true; proc.StartInfo.Arguments = arg; proc.StartInfo.Verb = "runas"; proc.Start(); if (commands.Length > 0) { for (int i = 0; i < commands.Length; i++) { proc.StandardInput.WriteLine(commands[i]); } } proc.StandardInput.AutoFlush = true; proc.StandardInput.WriteLine("exit"); proc.StandardInput.Close(); string output = proc.StandardOutput.ReadToEnd(); string error = proc.StandardError.ReadToEnd(); proc.WaitForExit(); proc.Close(); proc.Dispose(); return output;}2、提权定义
将程序提权到SYSTEM权限
C#
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]public static extern nint GetCommandLine();public static string GetCommandLineStr(){ nint commandLinePtr = GetCommandLineStr(); return Marshal.PtrToStringAuto(commandLinePtr) ?? string.Empty;}[DataContract]public enum WindowsSessionType{ Console = 1, RDP = 2}public enum WTS_INFO_CLASS{ WTSInitialProgram, WTSApplicationName, WTSWorkingDirectory, WTSOEMId, WTSSessionId, WTSUserName, WTSWinStationName, WTSDomainName, WTSConnectState, WTSClientBuildNumber, WTSClientName, WTSClientDirectory, WTSClientProductId, WTSClientHardwareId, WTSClientAddress, WTSClientDisplay, WTSClientProtocolType, WTSIdleTime, WTSLogonTime, WTSIncomingBytes, WTSOutgoingBytes, WTSIncomingFrames, WTSOutgoingFrames, WTSClientInfo, WTSSessionInfo}[StructLayout(LayoutKind.Sequential)]public struct WTS_SESSION_INFO{ public uint SessionID; [MarshalAs(UnmanagedType.LPStr)] public string pWinStationName; public WTS_CONNECTSTATE_CLASS State;}public enum WTS_CONNECTSTATE_CLASS{ WTSActive, WTSConnected, WTSConnectQuery, WTSShadow, WTSDisconnected, WTSIdle, WTSListen, WTSReset, WTSDown, WTSInit}[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]public 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 nint lpReserved2; public nint hStdInput; public nint hStdOutput; public nint hStdError;}[StructLayout(LayoutKind.Sequential)]public struct PROCESS_INFORMATION{ public nint hProcess; public nint hThread; public int dwProcessId; public int dwThreadId;}[StructLayout(LayoutKind.Sequential)]public struct SECURITY_ATTRIBUTES{ public int Length; public nint lpSecurityDescriptor; public bool bInheritHandle;}public enum SECURITY_IMPERSONATION_LEVEL : int{ SecurityAnonymous = 0, SecurityIdentification = 1, SecurityImpersonation = 2, SecurityDelegation = 3,}public enum TOKEN_TYPE : int{ TokenPrimary = 1, TokenImpersonation = 2}[DllImport("kernel32.dll")]public static extern uint WTSGetActiveConsoleSessionId();[DllImport("Wtsapi32.dll")]public static extern bool WTSQuerySessionInformation(nint hServer, uint sessionId, WTS_INFO_CLASS wtsInfoClass, out nint ppBuffer, out uint pBytesReturned);[DllImport("wtsapi32.dll", ExactSpelling = true, SetLastError = false)]public static extern void WTSFreeMemory(nint memory);[DllImport("wtsapi32.dll", SetLastError = true)]public static extern int WTSEnumerateSessions( nint hServer,int Reserved,int Version, ref nint ppSessionInfo, ref int pCount);[DllImport("kernel32.dll")]public static extern nint OpenProcess(uint dwDesiredAccess, bool bInheritHandle, uint dwProcessId);[DllImport("advapi32", SetLastError = true), SuppressUnmanagedCodeSecurity]public static extern bool OpenProcessToken(nint ProcessHandle, int DesiredAccess, ref nint TokenHandle);[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]public static extern bool DuplicateTokenEx( nint hExistingToken, uint dwDesiredAccess, ref SECURITY_ATTRIBUTES lpTokenAttributes, SECURITY_IMPERSONATION_LEVEL ImpersonationLevel, TOKEN_TYPE TokenType, out nint phNewToken);[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Auto)]public static extern bool CreateProcessAsUser( nint hToken, string? lpApplicationName, string lpCommandLine, ref SECURITY_ATTRIBUTES lpProcessAttributes, ref SECURITY_ATTRIBUTES lpThreadAttributes, bool bInheritHandles, uint dwCreationFlags, nint lpEnvironment, string? lpCurrentDirectory, ref STARTUPINFO lpStartupInfo, out PROCESS_INFORMATION lpProcessInformation);public static string GetUsernameFromSessionId(uint sessionId){ string username = string.Empty; if (WTSQuerySessionInformation(nint.Zero, sessionId,WTS_INFO_CLASS.WTSUserName, out var buffer, out var strLen) && strLen > 1) { username = Marshal.PtrToStringAnsi(buffer); WTSFreeMemory(buffer); } return username ?? string.Empty;}public static List<WindowsSession> GetActiveSessions(){ List<WindowsSession> sessions = new List<WindowsSession>(); uint consoleSessionId = WTSGetActiveConsoleSessionId(); sessions.Add(new WindowsSession() { Id = consoleSessionId, Type = WindowsSessionType.Console, Name = "Console", Username = GetUsernameFromSessionId(consoleSessionId) }); nint ppSessionInfo = nint.Zero; int count = 0; int enumSessionResult = WTSAPI32.WTSEnumerateSessions(nint.Zero, 0, 1, ref ppSessionInfo, ref count); int dataSize = Marshal.SizeOf(typeof(WTS_SESSION_INFO)); nint current = ppSessionInfo; if (enumSessionResult != 0) { for (int i = 0; i < count; i++) { object wtsInfo = Marshal.PtrToStructure(current, typeof(WTS_SESSION_INFO)); if (wtsInfo is null) { continue; } WTS_SESSION_INFO sessionInfo = (WTS_SESSION_INFO)wtsInfo; current += dataSize; if (sessionInfo.State == WTS_CONNECTSTATE_CLASS.WTSActive && sessionInfo.SessionID != consoleSessionId) { sessions.Add(new WindowsSession() { Id = sessionInfo.SessionID, Name = sessionInfo.pWinStationName, Type = WindowsSessionType.RDP, Username = GetUsernameFromSessionId(sessionInfo.SessionID) }); } } } return sessions;}private static uint GetWinLogonPid(uint dwSessionId){ uint winlogonPid = 0; Process[] processes = Process.GetProcessesByName("winlogon"); foreach (Process p in processes) { if ((uint)p.SessionId == dwSessionId) { winlogonPid = (uint)p.Id; } } return winlogonPid;}private static uint GetDwSessionId(int targetSessionId,bool forceConsoleSession){ uint dwSessionId = WTSGetActiveConsoleSessionId(); if (forceConsoleSession == false) { List<WindowsSession> activeSessions = GetActiveSessions(); if (activeSessions.Any(x => x.Id == targetSessionId)) { dwSessionId = (uint)targetSessionId; } else { dwSessionId = activeSessions.Last().Id; } } return dwSessionId;}private static STARTUPINFO GetStartUpInfo(bool hiddenWindow, string desktopName, out uint dwCreationFlags){ STARTUPINFO si = new STARTUPINFO(); si.cb = Marshal.SizeOf(si); si.lpDesktop = @"winsta0\" + desktopName; if (hiddenWindow) { dwCreationFlags = 0x20| 0x00000400 | 0x08000000; si.dwFlags = 0x00000001; si.wShowWindow = 0; } else { dwCreationFlags = 0x20| 0x00000400 | 0x00000010; } return si;}public static bool CreateInteractiveSystemProcess(string commandLine, int targetSessionId, bool forceConsoleSession, string desktopName, bool hiddenWindow, out PROCESS_INFORMATION procInfo){ nint hPToken = nint.Zero; procInfo = new PROCESS_INFORMATION(); uint dwSessionId = GetDwSessionId(targetSessionId, forceConsoleSession); uint winlogonPid = GetWinLogonPid(dwSessionId); nint hProcess = OpenProcess(MAXIMUM_ALLOWED, false, winlogonPid); if (OpenProcessToken(hProcess, TOKEN_DUPLICATE, ref hPToken) == false) { Kernel32.CloseHandle(hProcess); return false; } SECURITY_ATTRIBUTES sa = new SECURITY_ATTRIBUTES(); sa.Length = Marshal.SizeOf(sa); if (DuplicateTokenEx(hPToken, MAXIMUM_ALLOWED, ref sa, SECURITY_IMPERSONATION_LEVEL.SecurityIdentification, TOKEN_TYPE.TokenPrimary, out nint hUserTokenDup) == false) { Kernel32.CloseHandle(hProcess); Kernel32.CloseHandle(hPToken); return false; } STARTUPINFO si = GetStartUpInfo(hiddenWindow, desktopName,out uint dwCreationFlags); bool result = CreateProcessAsUser(hUserTokenDup, null, commandLine, ref sa, ref sa, false, dwCreationFlags, nint.Zero, null, ref si, out procInfo); Kernel32.CloseHandle(hProcess); Kernel32.CloseHandle(hPToken); Kernel32.CloseHandle(hUserTokenDup); return result;}3、使用提权
调用 RelaunchElevated() 将会以SYSTEM权限重启程序,并添加 –elevated 表示已提权,用以判断状态
C#
public static void RelaunchElevated(){ if (OperatingSystem.IsWindows() == false) return; try { AddTokenPrivilege(); } catch { } try { string commandLine = GetCommandLine(); bool result = CreateInteractiveSystemProcess($"{commandLine} --elevated", -1, false, "default", true, out PROCESS_INFORMATION procInfo); uint code = Kernel32.GetLastError(); //提权成功则关闭本程序 if (result) { Environment.Exit(0); } } catch { }}
支付宝微信扫一扫,打赏作者吧~
