如何在启用 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 UAC 提权(CVE-2019-1388)