模拟后CreateMutex失败

时间:2016-12-28 20:26:47

标签: c++ windows mutex impersonation

这是我尝试冒充用户然后创建互斥锁的代码。互斥锁没有被创建。我收到ERROR_ACCESS_DENIED错误。

{{1}}

我发现了几个类似的主题,但他们都在讨论从两个不同的用户上下文创建同名互斥,即互斥" MUTEX_1"已经在模拟之前创建,并且尝试使用相同的名称调用CreateMutex,但是由于缺少权限,模拟用户失败了。

这不是这种情况,因为我很确定在此代码之前没有创建具有相同名称(或任何互斥锁)的互斥锁。

我想我应该将非null的内容传递给CreateMutex,但具体到底是什么?

我在Windows安全方面不是很好。我知道传递NULL作为CreateMutex的第一个参数意味着'默认'将使用安全属性。在这种情况下,它将是与线程相关联的安全参数,即与模拟用户。

我的假设是否正确?

1 个答案:

答案 0 :(得分:4)

首先,您需要了解NT Namespaces并使用WinObj工具。

这就像内存中的小文件系统,包含文件夹和不同的"文件"在其中(在"文件"表示不同的对象类型 - EventMutant(互斥),SectionDevice,...)。每次创建命名对象时 - 它都放在NT Namespaces中的某个文件夹中。这里的文件夹(如NTFS中的文件夹)具有安全描述符。结果不是每个人都可以在任何文件夹下创建对象。

用你的文件系统语言来解释(也许会更清楚):

我(John)尝试创建文件" mutex_good"在%USERPROFILE%\Documents下,这没关系。因为这是我的个人文件夹,我有写入权限。

然后我登录(模仿)zoom并尝试创建文件" mutex_797"再次在%USERPROFILE%\Documents%USERPROFILE%在两种情况下都扩展到相同的路径,假设c:\Users\John模拟不会影响此内容)

并且zoom无法创建文件。为什么?他根本无权这样做。只有JohnAdministartorsSYSTEM具有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

有关此阅读Kernel object namespaces

的详细信息

当然我们必须了解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-1SYSTEMAdministrators,当前登录会话用户(LogonSessionId_0_294807),当前用户(John) - 以及所有。 zoom没有此权限。

例如Everyone有(3) - DIRECTORY_QUERY|DIRECTORY_TRAVERSE - Name lookupQuery但不是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 - 所有需要的访问权限。希望zoomEveryone的成员?下一个代码我肯定会工作

CreateMutexA(0, 0, "Global\\mutex_797");

for \BaseNamedObjects全局命名空间)存在一个例外:

  

在全局命名空间中创建文件映射对象   使用CreateFileMapping,来自会话0以外的会话是一个   特权行动。正因为如此,一个应用程序在运行   任意远程桌面会话主机(RD会话主机)服务器会话   必须启用SeCreateGlobalPrivilege才能创建   成功地在全局命名空间中创建文件映射对象。该   特权检查仅限于创建文件映射对象,   并不适用于开放现有的。例如,如果是服务   或者系统创建文件映射对象,运行的任何进程   任何会话都可以访问该用户提供的文件映射对象   有必要的访问权。

但是对于Mutex或说事件 - 不需要启用 SeCreateGlobalPrivilege

您也可以说,zoom是管理员帐户,Administrator可以访问\Sessions\<N>\BaseNamedObjects - 为什么这不起作用?因为LOGON32_LOGON_INTERACTIVEUAC系统已分配给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的一些可视化 enter image description here