为什么 AccessCheck 不将 GenericMapping 应用于 DACL?

Why is AccessCheck NOT applying GenericMapping to the DACL?

AccessCheck 函数获取一个 GenericMapping 参数。这个参数有什么用?它不用于 DesiredAccess 参数,因为之前必须将 MapGenericMask 应用于 DesiredAccess。

它也不适用于 SecurityDescriptor 中包含的 DACL,因为我发现使用 C 程序执行此操作:

但是,此操作失败并出现拒绝访问错误。当我将安全描述符更改为 "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)

查看源代码

没有 DACLMAXIMUM_ALLOWED 这种情况很少见,但在这种情况下,系统如何计算需要授予调用者哪些具体访问权限?他不问具体的访问权限(比如 read/write/delete)——但是 "ALL"。所以系统给他GenericMapping->GenericAll