【问题标题】:Windows process with Untrusted Integrity level具有不受信任完整性级别的 Windows 进程
【发布时间】:2017-10-17 02:21:16
【问题描述】:

我在 Windows 中找不到关于 Untrusted 完整性级别的太多信息,并且对此有一些疑问:

  1. 是否存在不受信任的完整性级别进程可以创建命名对象的地方? (互斥体、事件等)
  2. 不受信任的完整性级别进程是否应该能够打开现有的命名对象,该对象在创建时被赋予了安全描述符,ACESYSTEM_MANDATORY_LABEL_NO_WRITE_UPMandatoryLevelUntrusted?当我尝试它时,它会因0xc0000022(拒绝访问)而失败,而使用MandatoryLevelLow 时效果很好。
  3. 通常不受信任的完整性进程如何与其代理进程通信? (比如 google chrome 选项卡如何与 google chrome 代理通信?)

【问题讨论】:

  • 但是您是否可以使用 WinUntrustedLabelSid 创建进程,该进程在启动时不会失败?在我的测试中,当尝试加载 kernel32.dll 时,此进程发现失败 - 因为在加载进程过程中,他尝试使用 SECTION_MAP_WRITE 打开 \KnownDlls\kernel32.dll 部分在访问掩码中。在这里失败,因为它需要写权限,但是这个部分有Low Mandatory Level,但没有untrusted
  • 据我了解,为了拥有一个不受信任的进程,您首先需要将其创建为低完整性,让它完成需要更高强制级别的工作(如加载 dll),然后使其变得不受信任。不过我自己没试过。
  • 是的,这可行,但是您的目标是什么? Is there a place where an untrusted integrity level process can create named objects - 这必须是带有Untrusted Mandatory Level 的文件夹 - 如果我没记错的话(需要检查) - Windows NT 命名空间中没有默认文件夹带有这个。你需要自己创建它。对于 2.) - 对于只读访问,我们可以打开带有任何标签的对象。但对于写访问需要不受信任的标签。如果您在使用此标签分配 sid 时得到0xc0000022 - 您的代码中有一些错误
  • Untrusted 就是这样一个级别,它本身有权不做任何事情。通常,具有更高完整性的父进程会创建子进程需要的任何对象,然后在设置权限作为启动的一部分后将它们显式传递给子进程。 Chromium source 应该有一个很好的例子。

标签: windows security winapi uac windows-security


【解决方案1】:

是否有一个不受信任的完整性级别进程可以创建的地方 命名对象? (互斥体、事件等)

默认情况下 - 没有。具有不受信任的令牌(线程或进程)的代码只能在具有Untrusted Mandatory Level 的目录中创建对象 - 没有一个标准文件夹具有这种标签。有些人有 Low Mandatory Level 但不受信任 - 没有。

但您可以自己轻松创建此文件夹。使用Untrusted Mandatory LevelNULL DACL - 不受信任的代码可以在此文件夹中创建对象。

NTSTATUS CreateUntrustedFolder(PHANDLE phObject, PCUNICODE_STRING ObjectName)
{
    ULONG cb = MAX_SID_SIZE;
    PSID UntrustedSid = (PSID)alloca(MAX_SID_SIZE);
    if (CreateWellKnownSid(WinUntrustedLabelSid, 0, UntrustedSid, &cb))
    {
        PACL Sacl = (PACL)alloca(cb += sizeof(ACL) + sizeof(ACE_HEADER) + sizeof(ACCESS_MASK));
        InitializeAcl(Sacl, cb, ACL_REVISION);
        if (AddMandatoryAce(Sacl, ACL_REVISION, 0, 0, UntrustedSid))
        {
            SECURITY_DESCRIPTOR sd;
            InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
            SetSecurityDescriptorDacl(&sd, TRUE, NULL, FALSE);
            SetSecurityDescriptorSacl(&sd, TRUE, Sacl, FALSE);

            OBJECT_ATTRIBUTES oa = { sizeof(oa), 0, (PUNICODE_STRING)ObjectName, OBJ_CASE_INSENSITIVE|OBJ_OPENIF, &sd };

            return ZwCreateDirectoryObject(phObject, DIRECTORY_ALL_ACCESS, &oa);
        }
    }

    return STATUS_UNSUCCESSFUL;
}

关于不受信任的代码创建 - 如果以标记为不受信任的完整性级别的令牌开头启动进程 - 进程无法启动。这当 ntdll.dll 尝试加载 kernel32.dll - 它也尝试用SECTION_MAP_WRITE 打开部分\KnownDlls\kernel32.dll,但是这个对象有Low Mandatory LevelSYSTEM_MANDATORY_LABEL_NO_WRITE_UP - 结果不受信任的代码无法以写访问权限打开此部分。

因此,您首先需要使用Low Mandatory Level 创建进程,然后设置不受信任的级别

ULONG SetProcessUntrusted(HANDLE hProcess)
{
    TOKEN_MANDATORY_LABEL tml = { { (PSID)alloca(MAX_SID_SIZE), SE_GROUP_INTEGRITY } };

    ULONG cb = MAX_SID_SIZE;

    HANDLE hToken;

    if (!CreateWellKnownSid(WinUntrustedLabelSid, 0, tml.Label.Sid, &cb) ||
        !OpenProcessToken(hProcess, TOKEN_ADJUST_DEFAULT, &hToken))
    {
        return GetLastError();
    }

    ULONG dwError = NOERROR;
    if (!SetTokenInformation(hToken, TokenIntegrityLevel, &tml, sizeof(tml)))
    {
        dwError = GetLastError();
    }

    CloseHandle(hToken);

    return dwError;
}

不受信任的完整性级别进程是否应该能够打开现有的 命名对象

这取决于对象标签(级别和掩码)、代码完整性级别和所需的访问权限。如果代码完整性级别 >= 对象标签级别 - 我们可以打开对象(如果 dacl 让我们这样做)。否则需要寻找对象标签掩码和所需的访问权限。例如对象有Low Mandatory LevelSYSTEM_MANDATORY_LABEL_NO_WRITE_UP 和代码Untrusted Mandatory Level - 此代码可以打开具有读取和执行访问权限的对象,但无法打开它进行写入访问

【讨论】:

  • 来自ZwCreateDirectoryObject: "如果在用户态调用这个函数,你应该使用名称"NtCreateDirectoryObject"而不是"ZwCreateDirectoryObject “。”
  • @IInspectable - 在用户模式下,NtZw 之间绝对没有区别 - 这是别名 - 两个名称始终指向同一个地址。在内核模式下差异很大 - Zw 是重新进入内核的 thunk,而 Nt 是实际功能。为什么在用户模式下编写的文档中需要使用 Nt 变体(当这与此处的 Zw 相同时) - 我不知道。你认为微软可以从 ntdll.dll 中删除 Zw 导出并只留下 Nt 导出的名称?这是唯一可以解释这个注释的原因。但是,我在自己的代码中包含 wdm.h。这里只声明了 ZwCreateDirectoryObject。所以我用它
  • 我不会争论遵守书面合同的好处。如果你这样做了,你需要提供一个非常更强有力的理由,为什么这是一件好事。它碰巧起作用的事实非常薄弱,并且在此过程中错误地记录代码是完全错误的。
  • @IInspectable - 这很有趣。起初,这个信息是最近在 MSDN 中的。每年都不是这样。看起来像added to all api。但是 all ntdll api 在用户模式下 unsupported 怎么样?现在 Nt 名称 become supported 已经可以合法调用了吗?如果我在某些代码 sn-p 调用例如 NtOpenFile 而不是 CreateFileW - 你不会评论这是不合法的并且在用户模式下不受支持?
  • @conio - 你混淆了 ntoskrnl.exeNt/Zw api 的 内核模式 版本nrdll.dll 中此 api 的用户模式 版本 - 在内核模式 NtZw 是存根时,这是真正的功能,它重新进入内核并调用 Nt 函数。但在 用户模式 - NtZwalias - 两个名称都指向 相同 功能。所以从 user mode 调用 Nt ot Zw 变体没有什么不同。仅当将来 MS 不打算从 ntdll.dll 中删除 Zw 导出并且在许多示例中 MS 自己在用户模式下使用 Zw 版本。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-19
  • 1970-01-01
  • 2011-11-07
  • 1970-01-01
  • 2019-04-23
  • 1970-01-01
相关资源
最近更新 更多