这是我尝试冒充用户然后创建互斥锁的代码。互斥锁没有被创建。我收到ERROR_ACCESS_DENIED错误。
{{1}}
我发现了几个类似的主题,但他们都在讨论从两个不同的用户上下文创建同名互斥,即互斥" MUTEX_1"已经在模拟之前创建,并且尝试使用相同的名称调用CreateMutex,但是由于缺少权限,模拟用户失败了。
这不是这种情况,因为我很确定在此代码之前没有创建具有相同名称(或任何互斥锁)的互斥锁。
我想我应该将非null的内容传递给CreateMutex,但具体到底是什么?
我在Windows安全方面不是很好。我知道传递NULL作为CreateMutex的第一个参数意味着'默认'将使用安全属性。在这种情况下,它将是与线程相关联的安全参数,即与模拟用户。
我的假设是否正确?
答案 0 :(得分:4)
首先,您需要了解NT Namespaces并使用WinObj工具。
这就像内存中的小文件系统,包含文件夹和不同的"文件"在其中(在"文件"表示不同的对象类型 - Event
,Mutant
(互斥),Section
,Device
,...)。每次创建命名对象时 - 它都放在NT Namespaces中的某个文件夹中。这里的文件夹(如NTFS中的文件夹)具有安全描述符。结果不是每个人都可以在任何文件夹下创建对象。
用你的文件系统语言来解释(也许会更清楚):
我(John
)尝试创建文件" mutex_good"在%USERPROFILE%\Documents
下,这没关系。因为这是我的个人文件夹,我有写入权限。
然后我登录(模仿)zoom
并尝试创建文件" mutex_797"再次在%USERPROFILE%\Documents
下%USERPROFILE%
在两种情况下都扩展到相同的路径,假设c:\Users\John
模拟不会影响此内容)
并且zoom
无法创建文件。为什么?他根本无权这样做。只有John
,Administartors
,SYSTEM
具有c:\Users\John
的写入权限,但不能zoom
。
现在让我们回到NT Namespaces。当我们致电CreateMutexA( NULL, FALSE, "mutex_797" );
时,"mutex_797"
会在哪里?
如果你不是appcontainer
而没有在系统session 0
中运行 - 你在某个用户session <N>
中运行,你的命名对象将放在\Sessions\<N>\BaseNamedObjects
目录中,其中N = 1,2- ..
所以请致电CreateMutexA( NULL, FALSE, "mutex_797" );
尝试在\Sessions\<N>\BaseNamedObjects\mutex_797
但是\Sessions\<N>\BaseNamedObjects
存在下一个SymbolicLinks(这就像在NTFS文件系统中一样):
Global -> \BaseNamedObjects
Local -> \Sessions\<N>\BaseNamedObjects
Session -> \Sessions\BNOLINKS
如果你拨打CreateMutexA( NULL, FALSE, "Global\\mutex_797" );
对象管理器尝试将您的互斥锁放在\BaseNamedObjects\mutex_797
当然我们必须了解How AccessCheck Works
为目录对象定义了下一个访问权限:
//
// Object Manager Directory Specific Access Rights.
//
#define DIRECTORY_QUERY (0x0001)
#define DIRECTORY_TRAVERSE (0x0002)
#define DIRECTORY_CREATE_OBJECT (0x0004)
#define DIRECTORY_CREATE_SUBDIRECTORY (0x0008)
还可以在DirectoryObject DesiredAccess Flags
更多地了解这一点我们需要DIRECTORY_CREATE_OBJECT
访问(对目录对象的名称创建访问权限),以便在目录中创建互斥(或事件或任何对象)
现在要了解为什么你可以在\Sessions\<N>\BaseNamedObjects
中创建互斥,但zoom
不能 - 需要为此文件夹查找Security Descriptor
。我抛弃它:
T FL AcessMsK Sid
0 00 000F000F S-1-5-90-0-1 DWM-1
0 00 000F000F S-1-5-18 SYSTEM
0 0B 10000000 S-1-5-18 SYSTEM
0 0B 10000000 S-1-3-0 CREATOR OWNER
0 00 000F000F S-1-5-21-4026734978-3280735129-2412320105-1001 John
0 0B 10000000 S-1-5-5-0-294807 LogonSessionId_0_294807
0 00 0002000F S-1-5-5-0-294807 LogonSessionId_0_294807
0 00 0002000F S-1-5-32-544 Administrators
0 02 00000003 S-1-1-0 Everyone
0 00 00000002 S-1-5-12 RESTRICTED
17 00 00000001 S-1-16-4096 Low Mandatory Level
那么谁DIRECTORY_CREATE_OBJECT
(4)在这里? DWM-1
,SYSTEM
,Administrators
,当前登录会话用户(LogonSessionId_0_294807
),当前用户(John
) - 以及所有。 zoom
没有此权限。
例如Everyone
有(3) - DIRECTORY_QUERY|DIRECTORY_TRAVERSE
- Name lookup
和Query
但不是Name creation
你可以问一下在这种情况下我可以在模仿后创建互斥锁吗?需要使用\BaseNamedObjects
(全局命名空间)或\BaseNamedObjects\Restricted
目录 - 我测试它的安全描述符和结果:
代表\BaseNamedObjects
T FL AcessMsK Sid
0 00 0002000F S-1-1-0 Everyone
0 00 00000002 S-1-5-12 RESTRICTED
0 00 000F000F S-1-5-90-0-0
0 00 000F000F S-1-5-18 SYSTEM
17 00 00000001 S-1-16-4096 Low Mandatory Level
代表\BaseNamedObjects\Restricted
T FL AcessMsK Sid
0 00 0002000F S-1-1-0 Everyone
0 00 0002000F S-1-5-12 RESTRICTED
0 00 000F000F S-1-5-90-0-0
0 00 000F000F S-1-5-18 SYSTEM
17 00 00000001 S-1-16-4096 Low Mandatory Level
所以你如何在这里查看Everyone
有2000F - 所有需要的访问权限。希望zoom
是Everyone
的成员?下一个代码我肯定会工作
CreateMutexA(0, 0, "Global\\mutex_797");
for \BaseNamedObjects
(全局命名空间)存在一个例外:
在全局命名空间中创建文件映射对象 使用CreateFileMapping,来自会话0以外的会话是一个 特权行动。正因为如此,一个应用程序在运行 任意远程桌面会话主机(RD会话主机)服务器会话 必须启用SeCreateGlobalPrivilege才能创建 成功地在全局命名空间中创建文件映射对象。该 特权检查仅限于创建文件映射对象, 并不适用于开放现有的。例如,如果是服务 或者系统创建文件映射对象,运行的任何进程 任何会话都可以访问该用户提供的文件映射对象 有必要的访问权。
但是对于Mutex或说事件 - 不需要启用 SeCreateGlobalPrivilege
您也可以说,zoom
是管理员帐户,Administrator
可以访问\Sessions\<N>\BaseNamedObjects
- 为什么这不起作用?因为LOGON32_LOGON_INTERACTIVE
和UAC
系统已分配给zoom
已过滤的令牌。 Administrator
组(S-1-5-32-544
)仅存在于标记但且仅包含SE_GROUP_USE_FOR_DENY_ONLY
属性 - 因此它忽略了SID允许访问的ACE。
并且zoom
还有另一个LogonSessionId_0_XXX
SID - 结果和ERROR_ACCESS_DENIED
正如@Harry Johnston所说 - 如果我们使用LOGON32_LOGON_BATCH
代替LOGON32_LOGON_INTERACTIVE
- 我们获得了提升令牌 - 此处Administrator
群组将具有SE_GROUP_ENABLED
属性 - 已启用访问检查允许访问的ACE
或我如何提供 - 在名称前使用Global\
前缀 - 将地点对象设置为\BaseNamedObjects
,其中Everyone
具有完全访问权限
我理解传递NULL作为
CreateMutex
的第一个参数意味着 那个&#39;默认&#39;将使用安全属性。在这种情况下它会 是与线程相关的安全参数,即 模仿用户。
第一个参数 - 指向SECURITY_ATTRIBUTES
的指针允许您覆盖新对象的默认安全描述符。这是谁可以访问它的控件。但这并没有让您或多或少地访问您尝试放置对象的目录 - 您必须授予DIRECTORY_CREATE_OBJECT
访问权限,我们不能通过SECURITY_ATTRIBUTES
影响这一点 - 这对新对象的影响但不在现有目录上
最后是NT Namespace的一些可视化