主令牌和模拟令牌有什么区别 [英] What's the difference between a Primary Token and an Impersonation Token

查看:236
本文介绍了主令牌和模拟令牌有什么区别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

某些Windows API返回主令牌,而某些返回模拟令牌.有些API需要使用主令牌,而另一些API需要模拟令牌.

Some Windows APIs return a primary token and some return an impersonation token. Some APIs require a primary token while others require an impersonation token.

例如, 通常返回主令牌,除非使用LOGON32_LOGON_NETWORK作为登录类型(dwLogonType):

For example, LogonUser usually returns a primary token, except when using LOGON32_LOGON_NETWORK as the logon type (dwLogonType):

在大多数情况下,返回的句柄是一个主要令牌,您可以在对CreateProcessAsUser函数的调用中使用它.但是,如果指定LOGON32_LOGON_NETWORK标志,则除非调用DuplicateTokenEx将其转换为主要令牌,否则LogonUser返回的模拟令牌不能在CreateProcessAsUser中使用.

In most cases, the returned handle is a primary token that you can use in calls to the CreateProcessAsUser function. However, if you specify the LOGON32_LOGON_NETWORK flag, LogonUser returns an impersonation token that you cannot use in CreateProcessAsUser unless you call DuplicateTokenEx to convert it to a primary token.

SetThreadToken 需要模拟令牌,而 ImpersonateLoggedOnUser 似乎几乎可以做同样的事情,但是其中之一也需要.

SetThreadToken requires an impersonation token while ImpersonateLoggedOnUser which seems to do pretty much the same thing takes either one.

CreateProcessAsUser CreateProcessWithTokenW 都需要一个主令牌,并且都请注意,可以通过调用词汇表中的内容如下:

访问令牌

访问令牌包含登录会话的安全信息.当用户登录时,系统会创建一个访问令牌,并且代表该用户执行的每个进程都具有该令牌的副本.令牌标识用户,用户的组和用户的特权.系统使用令牌来控制对安全对象的访问,并控制用户在本地计算机上执行各种与系统相关的操作的能力.访问令牌有两种,主要令牌和模拟令牌.

An access token contains the security information for a logon session. The system creates an access token when a user logs on, and every process executed on behalf of the user has a copy of the token. The token identifies the user, the user's groups, and the user's privileges. The system uses the token to control access to securable objects and to control the ability of the user to perform various system-related operations on the local computer. There are two kinds of access token, primary and impersonation.

主令牌

通常仅由Windows内核创建的访问令牌.可以将其分配给一个流程,以表示该流程的默认安全信息.

An access token that is typically created only by the Windows kernel. It may be assigned to a process to represent the default security information for that process.

模拟令牌

已经创建了用于捕获客户端进程的安全信息的访问令牌,从而允许服务器模拟"访问令牌.安全操作中的客户端进程.

An access token that has been created to capture the security information of a client process, allowing a server to "impersonate" the client process in security operations.

但这并不完全有用.似乎有人想使用像"kernel"这样的大男孩字样.但这只会引发更多的问题,例如主要令牌还可以用于什么(除了分配给进程之外),以及除内核以外还可以创建访问令牌的其他人?

But that's not entirely useful. It seems like somebody wanted to use big boy words like "kernel" but this only serves to raise more questions such as what else (besides being assigned to a process) can a primary token be used for and who else besides the kernel can create access tokens?

(这是微软的一种感觉,即内核只是内核模式下运行的一部分,还有执行程序等.还是意味着用户模式代码也可以创建令牌?无论如何,即使用户模式代码可以创建令牌,就像任何对象管理器对象一样,它必须通过系统调用来完成,因此无论如何实际上都将以内核模式创建令牌.)

(Do they mean it the the Microsoft sense where the Kernel is only part of what runs in kernel-mode and there's also the Executive etc. or do they mean that user-mode code can also create tokens? Regardless, even if a user-mode code can create tokens it will have to do it through a system-call, as with any Object Manager object, so the token will actually be created in kernel mode anyway.)

无论如何,这不能回答基本问题:令牌类型之间有什么区别? 可能的用途或通常的创建方式.

Anyway, this doesn't answer the fundamental question: What the difference between the token types? Not what they may be used for or how they are usually created.

推荐答案

一个朋友向我介绍了对Windows安全进行编程由基思·布朗(Keith Brown)提出,它可以准确回答这个问题.

A friend referred me to Programming Windows Security by Keith Brown which answers this question exactly.

主令牌可以并且应该被称为进程令牌,模拟令牌可以并且应该被称为线程令牌.主令牌只能附加到进程,模拟令牌只能附加到线程.就这样.确实可以使用DuplicateTokenEx进行自由转换(显然,假设您拥有对要转换的句柄的必要访问权限).

Primary tokens can and should be called process tokens and impersonation tokens can and should be called thread tokens. Primary tokens can only be attached to process and impersonation tokens can only be attached to threads. That's all. They can indeed be freely converted using DuplicateTokenEx (assuming you have the necessary access rights to the handle you wish to convert, obviously).

从书中的第115页开始:

From page 115 in the book:

BOOL DuplicateTokenEx( HANDLE ExistingToken, // in DWORD DesiredAccess, // in LPSECURITY_ATTRIBUTES Attributes, // in, optional SECURITY_IMPERSONATION_LEVEL ImpLevel, // in TOKEN_TYPE Type, // in PHANDLE NewToken); // out

BOOL DuplicateTokenEx( HANDLE ExistingToken, // in DWORD DesiredAccess, // in LPSECURITY_ATTRIBUTES Attributes, // in, optional SECURITY_IMPERSONATION_LEVEL ImpLevel, // in TOKEN_TYPE Type, // in PHANDLE NewToken); // out

...

Type 参数是历史工件.如果查看TOKEN_TYPE枚举的定义,您会发现令牌已被分类为两类:模拟令牌与主要令牌.不要挂在这个术语上;意思实际上比听起来简单得多.模拟令牌只能附加到线程,主令牌只能附加到进程.这就是全部.因此,之前通过OpenProcessToken获得的流程令牌是主要令牌.

The Type parameter is a historical artifact. If you look at the definition of the TOKEN_TYPE enumeration, you'll find that tokens have been taxonomized into two categories: impersonation versus primary tokens. Don't get hung up on this nomenclature; the meaning is actually much simpler than it sounds. Impersonation tokens can only be attached to threads, and primary tokens can only be attached to processes. That's all it means. The process token obtained earlier via OpenProcessToken was therefore a primary token.

在Windows NT(3.x)的早期版本中,对令牌的处理方式受到了更为严格的限制,具体取决于您最初从何处获取令牌,因此引入了令牌类型来跟踪令牌.令牌的预期用途.因为本文假定您使用的是Windows NT 4.0或更高版本,所以只需将模拟令牌视为线程令牌",并将主令牌视为进程令牌",并在必要时使用DuplicateTokenEx在两者之间进行转换. Windows NT 4.0通过引入DuplicateTokenEx来缩小两者之间的界限.此功能的Windows NT 3.x版本DuplicateToken被硬编码为仅产生模拟令牌.实际上,现在您应该能够看到导致第一次调用SetThreadToken失败的愚蠢错误:代码正在尝试将主令牌(从进程中获得的令牌)附加到线程(这需要模拟)令牌).那是不可以的.为了解决逻辑问题和愚蠢的历史问题,下面是更正后的代码:

In very early versions of Windows NT (3.x), there were much more severe restrictions on what you could do with a token, depending on where you originally got it from, and hence the token type was introduced to track the intended usage of the token. Because this text assumes you're using Windows NT 4.0 or greater, just think of an impersonation token as a "thread token", and a primary token as a "process token", and use DuplicateTokenEx to convert between the two whenever necessary. Windows NT 4.0 tore down the boundaries between the two by introducing DuplicateTokenEx; the Windows NT 3.x version of this function, DuplicateToken, was hardcoded to only produce impersonation tokens. In fact, now you should be able to see the silly bug that causes the first call to SetThreadToken to fail: the code is attempting to attach a primary token (the one obtained from the process) to a thread (which requires an impersonation token). That's a no-no. To fix both the logical problem and the silly historical problem, here's the corrected code:

并非严格回答问题但在问题中提到的其他内容:

Other stuff which aren't strictly an answer to the question but were mentioned in the question:

  • 显然,ImpersonateLoggedOnUser加倍努力,并将主要令牌转换为模拟令牌,而SetThreadToken则不用理会.为什么?谁知道?可能出于相同的原因,某些API在调用期间启用特权,而另一些API则要求调用者自行启用特权.
  • LogonUser(和LsaLogonUser)可能会返回网络登录的模拟令牌,因为假定通常由谁执行网络登录(例如,第83页起).
  • 您可以使用未记录的NTDLL函数ZwCreateToken从用户模式创建令牌,该函数需要非常不同寻常的特权(特别是唯一的SE_CREATE_TOKEN_NAME).您可能不应该...
  • Apparently ImpersonateLoggedOnUser goes the extra mile and converts primary tokens to impersonation tokens while SetThreadToken doesn't bother. Why? who knows? Probably for the same reason some APIs enable privileges for the duration of the call while others require callers to enable the privileges on their own.
  • LogonUser (and LsaLogonUser) probably return impersonation tokens for network logons because of the assumption of who usually perform network logons (p. 83 onwards, for example).
  • You can create tokens from user mode using the undocumented NTDLL function ZwCreateToken which requires pretty unusual privileges (specifically the unique SE_CREATE_TOKEN_NAME). You probably shouldn't...

这篇关于主令牌和模拟令牌有什么区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆