【问题标题】:Does SetThreadToken() keep the impersonation token alive?SetThreadToken() 是否使模拟令牌保持活动状态?
【发布时间】:2019-03-21 20:34:03
【问题描述】:

当主线程模拟客户端时,我的代码创建一个线程并使用SetThreadToken 为其分配模拟令牌。然后主线程关闭令牌。

具体来说,主线程是这样做的:

  1. 使用LogonUser 获取主令牌。
  2. 使用DuplicateToken 从主令牌获取模拟令牌。
  3. 致电ImpersonateLoggedOnUser
  4. 产生一个辅助线程并在具有模拟令牌的线程上调用SetThreadToken
  5. RevertToSelf
  6. CloseHandle 模拟和主令牌。

此时,辅助线程仍在运行。即使令牌句柄已在主线程中关闭,模拟令牌是否仍可用于辅助线程?

【问题讨论】:

  • 是的,当您将线程分配给令牌时(通过SetThreadToken) - 将向此令牌添加额外的引用。因此当你关闭它句柄时它不会被破坏。
  • 谢谢。但是对于SetThreadToken,我需要一个模拟令牌,所以无论如何我都必须DuplicateToken。主线程模拟用户,因为它也必须代表他们做其他事情。
  • 明白。任何对象(以及令牌)在存在对其的引用之前都保持有效。对象的句柄这是参考。当您将令牌分配给线程时 - 将向此令牌对象添加额外的引用。结果你可以关闭句柄。令牌将一直有效,直到您没有为您的工作线程分配另一个令牌或该线程不退出

标签: winapi windows-security


【解决方案1】:

Windows 内核对对象使用引用计数。 TOKEN 也是对象。当您将令牌分配给线程(通过SetThreadToken)时,指向TOKEN 对象的指针存储在ETHREAD 对象中,并且附加引用添加到TOKEN 对象中。当然内核不能依赖关闭你或不是原始句柄(引用)TOKEN 对象。这是一般的指针计数规则 - 如果 A 在 self 中存储了指向 B 的指针 - 它添加对 B 的引用,因为它将在 A 使用 B 之前有效。令牌将一直有效,直到您的线程不模拟另一个令牌,或者结束模拟或退出。无论如何,在您将令牌分配给线程后,您可以关闭它的句柄 - 令牌仍然有效


如果存在兴趣,内部SetThreadToken 的工作方式:

SetThreadToken 调用 NtSetInformationThreadThreadImpersonationToken 信息类。从内核端 implementation 调用 PsAssignImpersonationToken - 这个 api 在 ntifs.h 中声明。它 implementation call PsImpersonateClientreference 传递的令牌。结果它成为分配给线程的有效util

服务器线程可能已经在模拟客户端 调用 PsImpersonateClient。如果是这种情况,参考 计数代表该客户端的令牌递减。

但无论如何 - 我们不需要这种内部知识 - 需要一般的思考理解 - 对象引用计数。如果指向令牌的指针保存在线程中 - 这个令牌当然必须在线程使用之前有效。结果它引用了。当线程停止使用此标记时(更改指针或退出) - 取消引用标记

【讨论】:

  • 您有任何可以证实您观点的参考资料吗?也许是代码示例?
  • @j6t - 没有参考。这是 Windows 内部知识,但是如果指向 TOKEN 的指针保存在 Thread->ImpersonationInfo->Token 中,当然会将引用添加到令牌中,因为它将是有效的。你想要的代码示例?
  • Windows内部知识?您是从事 Windows 内核工作的 Microsoft 员工吗?也许您知道一个著名的开源软件,它使用了正在讨论的模式。
  • @j6t - 我当然不是 Microsoft 员工,但请尝试自己思考一下 - 我们如何存储指向对象(令牌)的指针以供将来使用,而不添加对它的引用,确保它会是有效,直到我们使用它?这是常识
猜你喜欢
  • 2013-06-17
  • 1970-01-01
  • 2012-03-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多