如何创建具有较低完整性等级(IL)的新流程?

Jer*_*emy 17 c++ windows security winapi

从Windows Vista开始,具有较低完整性级别(IL)的进程似乎无法向具有更高完整性级别的进程发送消息.从安全角度来看,这是有道理的,但它打破了我们的一些进程间通信.

我们有遗留应用程序(进程A),不幸的是必须以提升的"管理员"权限运行(通过将其快捷方式设置为始终以管理员身份运行来完成).有时它需要实例化一个单独的应用程序(进程B).因此,进程B继承了与进程A相同的提升权限(和IL).这就是问题所在.可能还有其他独立的进程B实例没有提升权限,并且所有这些进程B实例都需要能够相互发送消息.如果进程B的一个实例被提升而另一个实例没有提升,这显然会失败.

我知道我们可以使用ChangeWindowMessageFilterAPI方法在UIPI消息过滤器中打开漏洞,但这似乎不是理想的解决方案.相反,我宁愿让进程A生成具有降低权限的进程B,特别是它可以与其他进程B实例进行通信.我认为默认情况下其他进程B实例运行在"中"IL,因此我希望进程A使用相同的IL生成进程B实例.

我的搜索引导我使用CreateProcessAsUserCreateRestrictedTokenAPI方法,但是尽管有这些文档,令牌和安全描述符的所有各个方面对我来说仍然非常混乱.

我也接触过一些线程这里(运行使用尽可能低的权限的进程中WINAPIWindows上用C删除权限++),但我无法找到任何代码很好的例子.

任何人都可以为我提供一些简单但"正确"的代码,这将帮助我使用适当的Windows IL生成子进程吗?具体来说,我想要一个如何获取现有Process A令牌并将其转换为具有降低权限的示例(我很确定我可以弄清楚其余的).在修改进程'令牌之前,我真的不清楚是否需要复制进程'令牌.

Har*_*ton 9

警告! 虽然这种方法对于原始海报来说可能或多或少都可以,但总的来说这并不是一个好主意.特别是,注意(根据评论主题)据报道,人工操作令牌会在更复杂的应用程序中引起问题,因此如果您使用它们,请务必坚持使用基本的Win32 API.当然还有潜在的安全隐患.

在大多数类似于OP的场景中,最好用启动器应用程序替换启动提升的应用程序的快捷方式.只要提升的应用程序正在运行,启动程序就可以保持运行,并为提升的应用程序提供自然的有限令牌,以用于启动非提升的进程.


在MSDN中的"在低完整性级别运行设计应用程序"一文中,有一个用于启动低完整性过程的代码,类似于您的情况.

首先,您复制了进程令牌,因为您不能(或者至少不应该)使用已经使用的令牌.然后使用SetTokenInformation和TokenIntegrityLevel类来设置完整性级别.示例代码中似乎存在错误,因为低完整性级别的正确SID是S-1-16-4096而不是S-1-16-1024,但是无论如何您都需要中等完整性级别,这是S -1-16-8192.这些可以在这里找到.

一旦你有了这个工作(也就是说,一旦你能够从高完整性过程启动中等完整性过程),你应该尝试使用CreateRestrictedToken创建新令牌而不是DuplicateToken,并删除管理员令牌和所有权限(SeChangeNotifyPrivilege除外) .否则,新进程将具有中等完整性,但仍具有管理员权限,这可以使任何可能在同一会话中运行的恶意代码更容易提升其权限.

  • @Elmue 我明白了,很有趣。好吧,令牌不同是绝对正确的 - Process Hacker 显示了很多差异,至少在我创建它的方式上是这样。Raymond Chen 说 [我们真的应该要求 Explorer 为我们运行该应用程序](https://blogs.msdn.microsoft.com/oldnewthing/20131118-00/?p=2643) 以获得未升级的版本。 (3认同)
  • 我还测试CreateRestrictedToken()和SaferComputeTokenFromLevel(),但结果却总是相同的:开始我跟CreateProcessAsUser过程时,人工令牌不具有相同的行为作为一个真正的媒体令牌().令人难以置信的是,对于这样一个重要的功能(例如,安装程序想要使用中等IL启动已安装的应用程序),没有SIMPLE和SAFE API来获取高进程中的中等令牌!像ShellExecute(...,"asMedium",...)之类的东西.不是在Vista中,也不在Win 7,8,10中.我不明白为什么微软让程序员单独完成这项任务? (2认同)