2016-01-27 92 views
11

某些Windows API返回主令牌,有些会返回模拟令牌。一些API需要主令牌,而其他API需要模仿令牌。主令牌和假冒令牌之间的区别是什么

例如,LogonUser通常返回主令牌,使用LOGON32_LOGON_NETWORK的登录类型(dwLogonType)时除外:

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

SetThreadToken需要一个模拟令牌,而ImpersonateLoggedOnUser这似乎做几乎同样的事情发生的任何一个。

CreateProcessAsUserCreateProcessWithTokenW都需要一个主令牌和两个注意主令牌可以从模拟令牌通过调用DuplicateTokenEx被收购,但什么令牌类型意思

的词汇说以下内容:

access token

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

primary token

是通常只由Windows内核创建的访问令牌。它可能被分配给一个进程来表示该进程的默认安全信息。

impersonation token

已创建捕获客户端进程的安全信息,允许安全操作的服务器,以“模拟”客户端进程的访问令牌。

但这并不完全有用。看起来有人想要使用像“内核”这样的大男孩的话,但这只能提出更多的问题,比如除了被分配给进程之外,还有哪些其他的东西可以用于主令牌?除了内核之外还有谁可以创建访问权限令牌?

(这是否意味着它是微软认为内核只是在内核模式下运行的一部分,还有执行等,或者它们是否意味着用户模式代码也可以创建令牌?无论如何,甚至如果用户模式代码可以创建令牌,则必须通过系统调用来完成,就像任何对象管理器对象一样,所以令牌实际上将以内核模式创建)

无论如何, t回答基本问题:标记类型之间有什么区别?不是他们可能被用于或如何他们通常创建。

回答

12

一位朋友转介我到基思布朗的Programming Windows Security,他准确地回答了这个问题。

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

从115页的书:

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参数是一个历史的神器。如果您查看枚举的定义,您会发现令牌已被分类为两类:模仿与主令牌。不要挂上这个术语;其意义实际上比听起来简单得多。冒充令牌只能附加到线程,而主令牌只能附加到进程。这就是全部意思。之前通过OpenProcessToken获得的进程令牌是主令牌。

在Windows NT(3.x)的非常早期版本中,根据您最初从中获取它的位置,您可以对令牌执行的操作有更严格的限制,因此将令牌类型引入跟踪令牌的预期用法。由于本文假设您使用的是Windows NT 4.0或更高版本,因此可以将模拟标记视为“线程标记”,将主标记视为“流程标记”,并在需要时使用DuplicateTokenEx进行转换。 Windows NT 4.0通过引入DuplicateTokenEx撕毁了两者之间的界限;此函数的Windows NT 3.x版本DuplicateToken已被硬编码为仅生成模拟令牌。事实上,现在您应该能够看到导致第一次调用SetThreadToken失败的愚蠢错误:代码尝试将主令牌(从进程获得的主令牌)附加到线程(这需要模拟令牌) 。这是一个禁忌。要解决这两个逻辑问题和愚蠢的历史遗留问题,这里的更正后的代码:

其他的东西,这是不严格的问题的答案,但这个问题被提及:

  • 显然ImpersonateLoggedOnUser额外的英里,并将主令牌转换为模拟令牌,而SetThreadToken不打扰。为什么?谁知道?可能出于同样的原因,某些API在呼叫期间启用特权,而其他API则需要呼叫者自行启用特权。
  • LogonUser(和LsaLogonUser)可能会返回网络登录的模拟令牌,因为通常会执行网络登录(例如,第83页)的假设。
  • 您可以使用未公开的NTDLL函数ZwCreateToken从用户模式创建令牌,这需要非常不寻常的权限(特别是唯一的SE_CREATE_TOKEN_NAME)。你可能不应该......
+0

您还可以使用记录的CreateToken和CreateTokenEx函数在用户模式下创建令牌,但由于这些功能只能从SSP/AP调用(“安全支持提供者/身份验证包”)。 –

+0

好点。注意,不仅它们要求你实现所有的SSP/AP接口(具有函数'SpLsaModeInitialize'应在函数表中返回等等),与'普通'SSP不同,SSP/AP作为LSASS的一部分运行,所以它们无论如何,在NT AUTHORITY \ SYSTEM帐户下运行并拥有“SeCreateTokenPrivilege”,“SeTcbPrivilege”等。因此,安全方面他们有相同的要求(你甚至可以说'ZwCreateToken'不太苛刻),尽管你注意到他们被证明是正确的,这是一个加号。 – conio

+0

模拟令牌处置后,线程会发生什么? – Dolev

相关问题