为何通过SSH运行.NET Windows C#程序时UAC不触发?如何强制验证?
解决UAC绕过问题的方案
你的问题核心是SSH会话默认继承了高权限上下文,跳过了UAC验证。以下是几种可行的解决方法:
1. 修改SSH服务的运行权限
- 打开服务管理器:按下Win+R,输入
services.msc回车 - 找到你的SSH服务(通常是OpenSSH SSH Server),右键选择「属性」
- 切换到「登录」选项卡,将登录身份从默认的
Local System(高权限)改为一个普通权限的本地用户 - 重启SSH服务后,后续SSH会话会以普通用户权限运行,启动程序时会因权限不足触发UAC(非交互式环境下UAC无法弹出,程序直接启动失败,达到阻止效果)
2. 在程序内验证权限来源
通过代码检查当前进程是否是交互式UAC提升的权限,非交互式的高权限会话直接终止程序:
using System; using System.Runtime.InteropServices; class Program { [DllImport("advapi32.dll", SetLastError = true)] private static extern bool GetTokenInformation(IntPtr TokenHandle, uint TokenInformationClass, IntPtr TokenInformation, uint TokenInformationLength, out uint ReturnLength); [DllImport("kernel32.dll", SetLastError = true)] private static extern bool CloseHandle(IntPtr hObject); [DllImport("advapi32.dll", SetLastError = true)] private static extern bool OpenProcessToken(IntPtr ProcessHandle, uint DesiredAccess, out IntPtr TokenHandle); private enum TOKEN_ELEVATION_TYPE { TokenElevationTypeDefault = 1, TokenElevationTypeFull = 2, TokenElevationTypeLimited = 3 } private const uint TokenElevationType = 18; private const uint TOKEN_QUERY = 0x0008; static void Main(string[] args) { var currentProcess = System.Diagnostics.Process.GetCurrentProcess(); if (!OpenProcessToken(currentProcess.Handle, TOKEN_QUERY, out IntPtr hToken)) { Console.WriteLine("权限验证失败"); Environment.Exit(1); } uint returnLength = 0; GetTokenInformation(hToken, TokenElevationType, IntPtr.Zero, 0, out returnLength); IntPtr elevationPtr = Marshal.AllocHGlobal((int)returnLength); try { if (!GetTokenInformation(hToken, TokenElevationType, elevationPtr, returnLength, out returnLength)) { Console.WriteLine("权限验证失败"); Environment.Exit(1); } var elevationType = (TOKEN_ELEVATION_TYPE)Marshal.ReadInt32(elevationPtr); // 检查是否为交互式会话且通过UAC提升权限 bool isInteractive = System.Environment.UserInteractive; if (elevationType != TOKEN_ELEVATION_TYPE.Full || !isInteractive) { Console.WriteLine("程序必须通过UAC确认后运行"); Environment.Exit(1); } } finally { Marshal.FreeHGlobal(elevationPtr); CloseHandle(hToken); } Console.WriteLine("hello world"); } }
3. 通过组策略限制非交互式提升
- 打开本地组策略编辑器:Win+R输入
gpedit.msc回车 - 依次展开:计算机配置 → Windows设置 → 安全设置 → 本地策略 → 安全选项
- 启用「用户账户控制:拒绝非交互式管理员的提升请求」,该设置会阻止非交互式会话(如SSH)中的管理员账户自动获取高权限,程序启动时会因权限不足失败
内容的提问来源于stack exchange,提问作者Bob5421
相关产品推荐
相关产品推荐

