65.9K
CodeProject 正在变化。 阅读更多。
Home

SDK 文档不一致:支持的 Kerberos Token 声明类型

starIconstarIconstarIconstarIconstarIcon

5.00/5 (1投票)

2022年10月7日

CPOL

4分钟阅读

viewsIcon

4021

从用户令牌检索声明信息时,SDK 中关于支持的数据类型的文档是错误的。

引言

在过去几周里,我一直在编写一个开源的 whoami 版本。在显示用户令牌声明的部分,我使用 GetTokenInformation 从用户令牌中检索该信息。用户或设备的声明可以有不同的 datatype,这取决于属性的类型。然而,测试所有支持的 datatype 被证明是不可能的。

我在此记录此事,以防有人遇到同样的问题,这样他们就不必花一天时间来追踪问题。

数据类型文档

GetTokenInformation文档规定,以下 datatype 支持声明:

含义
CLAIM_SECURITY_ATTRIBUTE_TYPE_INT64
0x0001

Values 成员指向一个 LONG64 值数组。
CLAIM_SECURITY_ATTRIBUTE_TYPE_UINT64
0x0002

Values 成员指向一个 ULONG64 值数组。
CLAIM_SECURITY_ATTRIBUTE_TYPE_STRING
0x0003

Values 成员指向一个指向 Unicode 字符串值的指针数组。
CLAIM_SECURITY_ATTRIBUTE_TYPE_FQBN
0x0004

Values 成员指向一个 CLAIM_SECURITY_ATTRIBUTE_FQBN_VALUE 值数组。
CLAIM_SECURITY_ATTRIBUTE_TYPE_SID
0x0005

Values 成员指向一个 CLAIM_SECURITY_ATTRIBUTE_OCTET_STRING_VALUE 值数组,其中每个 CLAIM_SECURITY_ATTRIBUTE_OCTET_STRING_VALUEpValue 成员是一个 PSID
CLAIM_SECURITY_ATTRIBUTE_TYPE_BOOLEAN
0x0006

Values 成员指向一个 ULONG64 值数组,其中每个元素表示一个布尔值。值 1 表示 TRUE,值 0 表示 FALSE
CLAIM_SECURITY_ATTRIBUTE_TYPE_OCTET_STRING
0x0010

Values 成员指向一个 CLAIM_SECURITY_ATTRIBUTE_OCTET_STRING_VALUE 值数组。

然而,无论我怎么做,即使修改了我沙箱中的 AD 架构,我也无法设置具有 CLAIM_SECURITY_ATTRIBUTE_TYPE_SIDCLAIM_SECURITY_ATTRIBUTE_TYPE_OCTET_STRING datatype 的声明。我也没找到 CLAIM_SECURITY_ATTRIBUTE_TYPE_FQBN,但那只是一个 string,所以没关系。我之所以想设置这些声明类型,主要是因为我想看看 whoami 如何显示这些声明,以便我的输出格式与此相同。

文档不一致

经过大量搜索,我最终找到了相关的目录服务协议文档。该文档清楚地记录了目录服务方面的用户声明的 datatype

 typedef struct _CLAIM_ENTRY {
   CLAIM_ID Id;
   CLAIM_TYPE Type;
   [switch_is(Type), switch_type(CLAIM_TYPE)] 
     union {
     [case(CLAIM_TYPE_INT64)] 
       struct {
       [range(1, 10*1024*1024)] ULONG ValueCount;
       [size_is(ValueCount)] LONG64* Int64Values;
     };
     [case(CLAIM_TYPE_UINT64)] 
       struct {
       [range(1, 10*1024*1024)] ULONG ValueCount;
       [size_is(ValueCount)] ULONG64* Uint64Values;
     };
     [case(CLAIM_TYPE_STRING)] 
       struct {
       [range(1, 10*1024*1024)] ULONG ValueCount;
       [size_is(ValueCount), string] LPWSTR* StringValues;
     };
     [case(CLAIM_TYPE_BOOLEAN)] 
       struct {
       [range(1, 10*1024*1024)] ULONG ValueCount;
       [size_is(ValueCount)] ULONG64* BooleanValues;
     };
     [default]       ;
   } Values;
 } CLAIM_ENTRY,
  *PCLAIM_ENTRY;

这确凿地证明了在目录服务方面,SID 和 Octet string 不是支持的声明类型。这也意味着 GetTokenInformation 的文档是错误的。

或者更确切地说,我怀疑定义 GetTokenInformation 接口的团队只是采用了支持的属性类型列表。从技术上讲,每个 AD 属性都可以用作声明类型,因此接口不必担心当前支持哪些声明类型,而是具有用于处理未来更改的 typedef

关于那些不支持的数据类型的思考

经过一番思考,我得出结论,那些不支持的 datatype 在用户声明的上下文中没有意义。

考虑 SID 属性。例如,如果您想将对象 A 链接到对象 B,您可以使用 SID 属性。可以想象,然后您可以定义一个声明类型来对该链接提出要求。例如,只有与给定 SID 链接的用户帐户的用户才能访问资源 R。再次,您也可以使用区分名称 (Distinguished Name) 来实现这一点。它还将具有用户可读且在对象 B 迁移时可转移的优点(因为 DN 可以重用,而 SID 不可以)。

我能看到的 Octet string 的潜在用例甚至更少。它基本上是一个二进制大对象。当然,您可以将很多东西放入 Octet string 中。哈希、加密信息、证书,随便什么。问题在于 Kerberos 如何对该信息做有意义的事情来做出授予访问权限的“是/否”决定。这将需要大量的额外复杂性,并且它本质上将是一种看起来非常像证书的东西,而证书已经得到了很好的支持。

我还没有找到设置 FQBN 声明的方法,但这问题不大,因为它本质上只是一个 string,所以如果我们收到它,我们可以像处理其他 string 一样读取它。

结论

出于测试目的,目前无法对那些不支持的 datatype 做任何事情,所以您不必担心它们。我认为最好的做法是处理支持的 datatype,并在其他类型标识符上触发错误。如果 Microsoft 最终支持它们,您至少会收到一个正确的错误消息。

历史

  • 2022 年 10 月 7 日:第一版
© . All rights reserved.