具有管理权限的进程在用户登录时运行

时间:2010-08-03 11:46:15

标签: c# security winapi uac

我正试图弄清楚如何解决特权获取问题。

应用程序需要桌面访问,因此无法作为Windows服务执行:它必须创建一个窗口,用于接收其他进程使用SendMessage发送的消息(必须用于等待消息确认)。

应用程序应在用户登录时启动,它将管理用户会话(管理应用程序,窗口......)。只能管理一个用户。

我要问的是哪个是请求权限获取的最佳解决方案,因为应用程序需要它(执行调用SetWindowsHook的进程)。

  • 如何在用户登录时使用(更高)权限运行任何进程,可能不会提示UAC消息?可以在安装阶段执行设置操作......
  • 如何在用户登录时运行实用程序服务启动进程?通过这种方式,(已安装的)服务可以使用任何特权来运行有效的过程......
  • 还有其他解决方案吗? *

拥有完全兼容的UAC应用程序需要采取哪些明确的行动? (我的意思是在构建和部署阶段?

例如,我使用mt.exe(使用VS2005)包含以下清单文件:

<?xml version="1.0" encoding="utf-8"?>
<asmv1:assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1"     xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns:asmv2="urn:schemas-microsoft-    com:asm.v2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
    security>
      <applicationRequestMinimum>
        <defaultAssemblyRequest permissionSetReference="Custom" />
        <PermissionSet class="System.Security.PermissionSet" version="1"     Unrestricted="true" ID="Custom" SameSite="site" />
      </applicationRequestMinimum>
        <requestedPrivileges>
                <requestedExecutionLevel level="requireAdministrator" uiAccess="false"/>
        </requestedPrivileges>
    </security>
  </trustInfo>
</asmv1:assembly>

对你来说似乎没问题?不,因为它对我不起作用......

*

创建一个额外的用户帐户(但这也适用于Windows域)实际上是有意义的,具有管理员权限来执行受控环境。在没有记录任何用户的情况下创建工作会话(新的桌面工作站)也是可以接受的,但实际上我不知道是否可能。

3 个答案:

答案 0 :(得分:5)

你在一个问题中提出了很多问题。关于您的解决方案的架构,有许多不清楚的主题(我不清楚)。对我来说,为什么你需要SetWindowsHook也是绝对不清楚的。所以我试着只回答你问题的技术部分。

在没有提示UAC的情况下启动程序不是一个大问题,可以在表现形式方面获得专利。

从服务启动用户桌面上的进程,以便进程不在用户凭据下运行,但是很棘手但可能。我如何理解您在SYSTEM帐户下运行的服务。然后它有SE_TCB_NAME特权。该服务在会话0中运行(参见http://www.microsoft.com/whdc/system/sysinternals/session0changes.mspx)。如果用户登录,他看到的进程在会话1或更高版本中运行。在Windows XP下,第一次登录的用户运行使用会话0,只有下一次登录(如果快速切换开启)使用会话1等。因此在任何操作系统上都需要在其他会话上启动进程 。为此,您应该使用带有SetTokenInformation参数的TokenSessionId函数。我在Launching a process in user’s session from a service中描述了详细信息。

在所有情况下,您应该监视用户登录和注销,并且应该获得用户会话ID以便能够在会话上启动进程。你可以用不同的方式做到这一点。最简单的方法之一是使用在自动启动中运行的应用程序(例如,注册为unter HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run)。此应用程序与您的服务进行通信,您将模拟用户令牌和会话ID。另一种方法是使用系统事件通知服务(SENS)的ISensLogon2通知(请参阅http://msdn.microsoft.com/en-us/library/aa376863.aspx)。

还有一个小问题。依赖于您在桌面用户桌面上启动的进程所使用的帐户,需要更改OpenWindowStationOpenDesktopSetUserObjectSecurity的桌面和Windows Station对象的安全描述符(请参阅{ {3}},http://msdn.microsoft.com/en-us/library/ms681928.aspxhttp://msdn.microsoft.com/en-us/library/ms687107.aspx

答案 1 :(得分:0)

服务免于UAC。计划任务(在用户登录时运行)不是。如果您不想要UAC提示,但又想要在登录时运行,那么最好的办法就是同时编写并让它们进行通信。设置服务以执行特权事务 - 写入Program Files或HKLM或其他任何内容。让它自动启动。现在设置一个在用户登录时运行的计划任务。当它想要完成特权时,它会要求服务执行它。他们如何沟通取决于您,取决于您的应用程序的功能。如果您涉及数据库,则可以使用表格来执行任务写入请求。或者您可以使用文件系统。或者您可以使用更直接的集成。

您在问题中包含的清单文件会使您的exe提升。这将导致您说您不想要的UAC提示。

最后,您能否重温为何需要提升?你有没有办法重写这个任务,所以它写入AppData或HKCU或其他一些保护较少的区域?然后你就可以编写任务并完成它,而不必处理与服务的交互。

答案 2 :(得分:0)

为什么不将Windows服务作为高权限帐户运行,该帐户执行所需的高权限操作,并且还有一个用户级应用程序,可以执行任何UI /交互操作并使用WCF与Windows服务器通信?