为什么 AccessCheck 不将 GenericMapping 应用于 DACL?
Why is AccessCheck NOT applying GenericMapping to the DACL?
AccessCheck 函数获取一个 GenericMapping 参数。这个参数有什么用?它不用于 DesiredAccess 参数,因为之前必须将 MapGenericMask 应用于 DesiredAccess。
它也不适用于 SecurityDescriptor 中包含的 DACL,因为我发现使用 C 程序执行此操作:
- 打开当前线程令牌
- 创建一个安全描述符,其中包含令牌的所有者和默认组,以及将 GENERIC_ALL 授予所有者 "D:(A;;GA;;;ownerSID)"
的 DACL
- 设置 GENERIC_MAPPING,它将(除其他外)GenericAll 映射到我的 OWN_READ | OWN_WRITE(定义为 0x0001 和 0x0002)
- 使用上面创建的安全描述符调用 AccessCheck,线程令牌,OWN_READ 作为 DesiredAccess,所描述的 GENERIC_MAPPING
但是,此操作失败并出现拒绝访问错误。当我将安全描述符更改为 "D:(A;;0x0001;;;ownerSID)" 时,访问被授予。这表明 AccessCheck 未使用 GenericMapping 参数将 DACL 中的通用访问标志 (GA/GW/GR/GX) 转换为特定访问权限。为什么?我做错了什么吗?
https://msdn.microsoft.com/de-de/library/windows/desktop/aa374815(v=vs.85).aspx 没有给出任何关于应该如何设置安全描述符的提示。
你做的几乎都是正确的,但你没有考虑到当你尝试将安全描述符(SD
)分配给内核对象时 - 系统不完全 "as is" 分配了你的 SD
但首先将 GenericMapping
应用到 ACEs
。
每个对象 - 都关联了 _OBJECT_TYPE
which containing _OBJECT_TYPE_INITIALIZER
并且这里存在 GENERIC_MAPPING GenericMapping;
并且这个 GenericMapping
(对于每种类型的对象都是唯一的)用于转换 ACCESS_MASK
中的通用标志非通用。
为了测试,我使用下一个 SD
- "D:P(A;;GA;;;WD)" (10000000 - GenericAll for S-1-1-0 EveryOne)
创建文件。然后我从创建的文件中查询 DACL
- 并且真的 001F01FF
看到 S-1-1-0
而不是 10000000
.
当我使用 "D:P(A;;GX;;;WD)" (GenericExecute - 20000000 for S-1-1-0)
时 - 在最终文件中我查看 001200A0
用于 S-1-1-0
所以真正的内核对象在 ACCESS_MASK
中没有通用位,而你的 DACL
不能分配给任何对象。
Why is AccessCheck NOT applying GenericMapping to the DACL?
AccessCheck
假设 DACL
中的 ACCESS_MASK
已经 转换(无通用位)
我认为这是性能优化 - 更好地转换通用位一次(在对象创建或分配 SD
给它 - 而不是每次有人尝试打开对象时都进行这种转换)
请问GenericMapping
参数如何使用?
真的很弱 - 只有当对象没有 DACL
(或者如果 PreviousMode == KernelMode
)并且你请求 MAXIMUM_ALLOWED
作为 DesiredAccess
- 系统授予你 GenericMapping->GenericAll
。这是基于从 WRK
(accessck.c
)
查看源代码
没有 DACL
和 MAXIMUM_ALLOWED
这种情况很少见,但在这种情况下,系统如何计算需要授予调用者哪些具体访问权限?他不问具体的访问权限(比如 read/write/delete)——但是 "ALL"。所以系统给他GenericMapping->GenericAll
AccessCheck 函数获取一个 GenericMapping 参数。这个参数有什么用?它不用于 DesiredAccess 参数,因为之前必须将 MapGenericMask 应用于 DesiredAccess。
它也不适用于 SecurityDescriptor 中包含的 DACL,因为我发现使用 C 程序执行此操作:
- 打开当前线程令牌
- 创建一个安全描述符,其中包含令牌的所有者和默认组,以及将 GENERIC_ALL 授予所有者 "D:(A;;GA;;;ownerSID)" 的 DACL
- 设置 GENERIC_MAPPING,它将(除其他外)GenericAll 映射到我的 OWN_READ | OWN_WRITE(定义为 0x0001 和 0x0002)
- 使用上面创建的安全描述符调用 AccessCheck,线程令牌,OWN_READ 作为 DesiredAccess,所描述的 GENERIC_MAPPING
但是,此操作失败并出现拒绝访问错误。当我将安全描述符更改为 "D:(A;;0x0001;;;ownerSID)" 时,访问被授予。这表明 AccessCheck 未使用 GenericMapping 参数将 DACL 中的通用访问标志 (GA/GW/GR/GX) 转换为特定访问权限。为什么?我做错了什么吗?
https://msdn.microsoft.com/de-de/library/windows/desktop/aa374815(v=vs.85).aspx 没有给出任何关于应该如何设置安全描述符的提示。
你做的几乎都是正确的,但你没有考虑到当你尝试将安全描述符(SD
)分配给内核对象时 - 系统不完全 "as is" 分配了你的 SD
但首先将 GenericMapping
应用到 ACEs
。
每个对象 - 都关联了 _OBJECT_TYPE
which containing _OBJECT_TYPE_INITIALIZER
并且这里存在 GENERIC_MAPPING GenericMapping;
并且这个 GenericMapping
(对于每种类型的对象都是唯一的)用于转换 ACCESS_MASK
中的通用标志非通用。
为了测试,我使用下一个 SD
- "D:P(A;;GA;;;WD)" (10000000 - GenericAll for S-1-1-0 EveryOne)
创建文件。然后我从创建的文件中查询 DACL
- 并且真的 001F01FF
看到 S-1-1-0
而不是 10000000
.
当我使用 "D:P(A;;GX;;;WD)" (GenericExecute - 20000000 for S-1-1-0)
时 - 在最终文件中我查看 001200A0
用于 S-1-1-0
所以真正的内核对象在 ACCESS_MASK
中没有通用位,而你的 DACL
不能分配给任何对象。
Why is AccessCheck NOT applying GenericMapping to the DACL?
AccessCheck
假设 DACL
中的 ACCESS_MASK
已经 转换(无通用位)
我认为这是性能优化 - 更好地转换通用位一次(在对象创建或分配 SD
给它 - 而不是每次有人尝试打开对象时都进行这种转换)
请问GenericMapping
参数如何使用?
真的很弱 - 只有当对象没有 DACL
(或者如果 PreviousMode == KernelMode
)并且你请求 MAXIMUM_ALLOWED
作为 DesiredAccess
- 系统授予你 GenericMapping->GenericAll
。这是基于从 WRK
(accessck.c
)
没有 DACL
和 MAXIMUM_ALLOWED
这种情况很少见,但在这种情况下,系统如何计算需要授予调用者哪些具体访问权限?他不问具体的访问权限(比如 read/write/delete)——但是 "ALL"。所以系统给他GenericMapping->GenericAll