如何在启用 UAC 的 Windows 服务中调用 LogonUser() 以获取不受限制的完整令牌?

Posted

技术标签:

【中文标题】如何在启用 UAC 的 Windows 服务中调用 LogonUser() 以获取不受限制的完整令牌?【英文标题】:How to call LogonUser() to get a non-restricted full token inside a Windows Service with UAC enabled? 【发布时间】:2016-09-09 02:44:49 【问题描述】:

我在 Windows Server 2012 上运行 WindowsService,它需要模拟域管理员用户(该用户也已添加到计算机上的本地管理员组中)。

在系统上启用了 UAC,并且使用 LogonType 为 LOGON32_LOGON_INTERACTIVE 的凭据调用 LogonUser,似乎返回了受限令牌而不是完整令牌。

这导致我尝试执行的管理任务失败。

在这种情况下调用 LogonUser 以便返回完整令牌而不是受限令牌的正确方法是什么?

PS:我在这里遇到了一个相关的问题How can I get elevated permissions (UAC) via impersonation under a non-interactive login? 但它没有显示获得完整令牌所需的确切调用。

【问题讨论】:

【参考方案1】:

您可以使用 LOGON32_LOGON_BATCH 选项而不是 LOGON32_LOGON_INTERACTIVE 选项从 LogonUser() 获取未过滤的令牌。

this answer 中有一些示例代码显示了使用LOGON32_LOGON_BATCH 和 LogonUser() 函数来获取管理令牌。


附录:

如果你有 SeTcbPrivilege,你有另一个选择:你可以在调用 LogonUser() 时使用 LOGON32_LOGON_INTERACTIVE,然后在 GetTokenInformation() 中使用 TokenLinkedToken 选项来获取链接到过滤的提升令牌的句柄令牌。

SeTcbPrivilege 也称为“作为操作系统的一部分”,通常仅在您在本地系统上下文中运行时可用。

如果您没有 SeTcbPrivilege,您仍然可以调用 GetTokenInformation() 来获取链接令牌的副本,但在这种情况下,您会在 SecurityIdentification 级别获得一个模拟令牌,因此如果您想要它是没有用的创建一个新的进程。 (感谢 RbMm 指出这一点。)

【讨论】:

只有LOGON32_LOGON_NETWORK 产生模拟令牌。所有其他选项,包括LOGON32_LOGON_BATCH,都会生成一个主令牌。 (当然,您始终可以将模拟令牌转换为主要令牌,反之亦然。) 只需要清楚明白一件事-我们可以获得链接令牌,但它具有SecurityIdentification模拟级别-这意味着如果我们模拟此令牌-每个安全检查都失败.我们对此无能为力(我知道的一个例外 - 可以查询 DosDevices )。如果是的话,我们可以使用这个提升的令牌 - 我们可以轻松跳过 UAC - 所以这个令牌几乎只用于查询 @RbMm,我说的是当 code 作为本地系统运行时,而不是当令牌用于本地系统时。我的测试代码调用 LogonUser 来获取特定用户帐户的过滤令牌,然后调用 GetTokenInformation 来获取链接的令牌。如果代码以管理员身份运行,则链接令牌是模拟令牌,但如果代码作为本地系统运行,则它是主令牌。 @RbMm,具体来说,您需要在调用 GetTokenInformation 时启用 SeTcbPrivilege(“作为操作系统的一部分”)。 是的,所以你的编辑是绝对正确的——我们可以使用LOGON32_LOGON_INTERACTIVE然后得到LinkedToken——它将是主要的而不是过滤的——可以在CreateProcessAsUser中使用它

以上是关于如何在启用 UAC 的 Windows 服务中调用 LogonUser() 以获取不受限制的完整令牌?的主要内容,如果未能解决你的问题,请参考以下文章

如何获取 Windows SYSTEM 用户令牌

东塔 | Windows UAC 本地提权复现

[提权]Windows UAC 提权(CVE-2019-1388)

如何启动 Windows 服务网络进程以侦听 UAC 下普通用户可见的 localhost 套接字上的端口?

如何启用普通和 UAC 提升权限应用程序之间的拖放

golang windows程序获取管理员权限(UAC )