使用管理员进程创建具有普通权限的进程

时间:2010-02-05 10:57:54

标签: winapi

有哪种方法可以从以管理员身份运行的进程中运行具有普通权限的另一个进程?从具有提升权限的进程开始,我想要启动一个具有普通权限的进程,就像它从资源管理器启动一样。我试过冒充,但我没有工作。

6 个答案:

答案 0 :(得分:2)

使用CreateProcessAsUser()。详细信息位于链接的SDK文档中。

答案 1 :(得分:1)

不可能这样做(有几种hacky方法可以做到这一点(注入资源管理器,任务调度程序,SaferAPI + MediumIL等),但它们都不适用于所有情况)

答案 2 :(得分:1)

这似乎是一种很好的方法,只要你不关心Shell没有运行的情况(例如,可能是一些终端服务应用程序设置,可能,虽然我不确定):

http://brandonlive.com/2008/04/27/getting-the-shell-to-run-an-application-for-you-part-2-how/

它获取Explorer.exe的接口,该接口应该在用户的正常上下文中运行,并要求Explorer代表它执行命令。这只需使用简单的文档化COM接口即可完成,无需处理进程令牌或代码/ DLL注入。

答案 3 :(得分:1)

我成功使用的技术是使用IShellDispatch2 :: ShellExecute来请求Explorer启动该进程。由于Explorer通常以正常的完整性运行,因此这是有效的。诀窍是获取IShellDispatch2对象有点工作。我按照this blog中列出的流程进行了操作。

答案 4 :(得分:0)

在Linux上

你可以使用setuid来改变程序用户ID

用于Windows 你可以看看他的: https://serverfault.com/questions/16886/is-there-an-equivalent-of-su-for-windows

答案 5 :(得分:0)

如果可能的话,请使用Larry Osterman的解决方案(在Anders回答的评论中),即,让父流程在没有提升的情况下运行,并从那里启动提升流程和非提升流程。 / p>

如果无法做到这一点,那么几乎在所有情况下都应该有一种方法,尽管它通常比它的价值更麻烦:

  • 安装并启动系统服务,配置为以本地系统运行。为您提供远程桌面会话ID,例如,通过命令行参数或注册表设置,以及您要运行的进程ID和命令行。

  • 从系统服务中,使用带有TokenLinkedToken的GetTokenInformation从目标进程获取链接的令牌。您必须从系统服务执行此操作,因为您需要SE_TCB_NAME来获取可用的令牌。 (此限制似乎没有记录,但与Windows中令牌的行为一致。)

  • 或者,如果没有链接令牌,请使用WTSQueryUserToken获取用户令牌的副本。我相信这总是会给你有限的令牌(如果有的话),但是如果你想要安全,你可以使用GetTokenInformation和TokenElevationType来检查它是否是一个提升或有限的令牌;如果它是一个提升的令牌,你可以使用TokenLinkedToken来获得有限的令牌。

  • 如果没有链接令牌(TokenElevationTypeDefault),您应该按原样使用令牌。这可能是因为用户不是管理员,或者因为全局或因为用户使用内置管理员帐户登录而禁用了UAC。如果用户不是管理员,则令牌已经适合。如果禁用UAC,则应尊重用户的意图并使用管理令牌。

  • 然后,您可以使用系统服务中的CreateProcessAsUser或CreateProcessWithTokenW来启动新进程。

  • 最后,服务应自行删除并停止。

至少有一个边缘情况:如果从使用runas和非管理凭据启动的命令窗口(或其他进程)启动提升的进程。在这种情况下没有拆分令牌,并且原始令牌可能已被删除,因此除非您在升级之前捕获了副本(Larry的解决方案或其变体),否则没有通用的方法来运行子进程升级过程最初启动的用户上下文。您可以做的最好的是登录用户的上下文(通过如上所述的WTSQueryUserToken),这可能不是最终用户期望的行为。 (但这可能是一个可接受的限制,具体取决于方案。)

相关问题