如何使用从父级继承的句柄创建提升的子进程
Posted
技术标签:
【中文标题】如何使用从父级继承的句柄创建提升的子进程【英文标题】:How can I create a elevated child process with inherited handles from his parent 【发布时间】:2017-09-20 13:00:50 【问题描述】:我正在尝试在 Windows 中创建一个具有提升权限的子进程(通过触发 UAC 提示符)并让该子进程继承其父 STDOUT 句柄,以便能够输出回父控制台。
附加信息:
Win32 API 我目前使用ShellExecuteEx()
和ShellExecuteInformation
,它指定一个“runas”动词来触发 UAC,但任何其他可以创建当前运行程序的提升副本的解决方案(子进程与父母),但能够输出回父母的控制台。
【问题讨论】:
看看Vista UAC: The Definitive Guide。从“通过 ShellExecuteEx() 路由”开始阅读。他正在通过使用命名管道和使用ShellExecuteEx
创建的中间辅助进程进行重定向,而ShellExecuteEx
又调用CreateProcess
以便能够将命名管道句柄继承到实际的子进程(如果我理解正确的话)。跨度>
是的@zett42 但是在我看来这个解决方案看起来真的很hacky......当我绝望但我还没有在这里时,我擅长spagethi编码:P
我认为您不会为此找到“简单”的方法。一旦你开始做不同寻常的事情,UAC 很快就会变得一团糟。无论如何,如果您害怕意大利面,只需将所有这些乱七八糟的东西包装到您自己漂亮的界面中即可。 ;-)
如果您无法修改子进程以将输出发送到指定的控制台,您将需要一个代理进程来代表您启动子进程。运行提升的代理进程,并在启动子进程之前将其连接回您的控制台。 (基本上与 zett42 建议的过程相同,但针对您的特定场景进行了简化。)
...顺便说一句,我向您保证,任何不涉及代理进程的解决方案都将更加骇人听闻!
【参考方案1】:
当您使用 ShellExecuteEx
和 runas
时 - 函数 CreateProcessAsUserW
不是从您的进程调用,而是从运行 appinfo.dll
的 svchost.exe -k netsvcs
调用。并且 bInheritHandles 被硬编码为 FALSE - 所以
在这种情况下,您的进程不会继承任何句柄。要使句柄可继承,唯一的方法是使用主提升令牌直接调用CreateProcessAsUserW
。但是你从哪里得到这个令牌?好的,您可以第二次以提升的身份运行 self exe(使用runas
)并将提升的令牌复制回原始未提升的进程。但无论如何(即使使用提升的令牌) - 您需要SE_ASSIGNPRIMARYTOKEN_NAME
特权才能调用CreateProcessAsUser
。但是你没有这个权限。
否则,如果你发现了一些漏洞,你可以。
ShellExecuteEx
返回的进程句柄没有PROCESS_DUP_HANDLE
访问权限 - 因此您以后不能将其用于手动句柄复制。
所以一般来说 - 这在设计上是不可能的
【讨论】:
感谢您指出ShellExecuteEx()
正在调用 svchost.exe
并且 bHinheritHandles
被硬编码为 FALSE
的事实,我会调查一个解决方法知道这一点
应用程序信息服务创建具有属性的提升进程以手动将父进程设置为客户端,因此它可以但不支持继承。此外,还有另一个创建属性可以在禁用继承时启用标准句柄复制(不是继承),但它仅在控制台应用程序创建附加到同一控制台的另一个控制台应用程序时使用。这在这里也没有使用,因为 AppInfo 服务设置了创建标志来创建一个新的控制台(用于新的安全上下文),它将孩子的标准句柄设置为新的控制台。
@eryksun - 是的,应用程序信息服务使用PROC_THREAD_ATTRIBUTE_PARENT_PROCESS
设置进程,其中ShellExecuteEx
被称为父进程。如果它也使用bInheritHandles == TRUE
- 新进程将从我们的 src 进程(我们称之为ShellExecuteEx
)继承句柄,但不是从svchost.exe
。但bInheritHandles
硬编码为假。
即使设计上可行,为另一个控制台继承标准句柄也没有意义。重要的是提升进程的ConsoleHandle
,它在分配新控制台时设置。控制台输入和屏幕缓冲区的句柄仅在附加控制台的上下文中有意义。 OP 还有另一个问题是在哪里解决的。提升的进程必须调用 FreeConsole
和 AttachConsole
来写入其父级的控制台——或者改为使用 IPC 方案,例如命名管道。以上是关于如何使用从父级继承的句柄创建提升的子进程的主要内容,如果未能解决你的问题,请参考以下文章