【问题标题】:Elevating from low to medium integrity从低完整性提升到中等完整性
【发布时间】:2011-11-30 19:46:08
【问题描述】:

这类似于“how create medium integrity level process from low integrity level process?”,但我的角度略有不同。 (无论如何都没有回答。):)

如果文件保存为低完整性(通常来自浏览器等低完整性应用),则它会被标记为低完整性强制标签。 (这个标签也可以和icacls /setintegritylevel low一起应用。)如果这样的文件被执行,它就会变成一个低完整性的进程,可以理解。

是否有某种方法可以(通过同意 UI)将此过程提升到中等完整性?如果应用程序标有requiresAdministrator 清单,或者如果它使用runas 动词调用ShellExecute,则可以达到高度完整性,但显然这也需要管理员权限。进入中等完整性不需要管理员权限,它仍然会解锁许多低完整性进程无法使用的权限。

显然,任何这样做的机制都应该需要用户同意 UI(应该不可能静默进行,否则有什么意义?),但是如何调用呢?

我发现关于这个主题的唯一讨论涉及拥有自己的原始中等完整性流程并从中分离出低完整性流程;这允许通过通信提升到中等完整性进程并让它启动任何东西。但是,当操作系统本身最初以低完整性启动进程时,这无济于事。

【问题讨论】:

  • 如果一个进程具有 Low Mandatory Integrity Level 标签 (S-1-16-4096),则该进程将成为 Low 完整性。我现在正在查看 MSDN 代码,您在其中复制当前令牌,并添加 LowIL sid。大概创建一个中等完整性级别的流程同样容易——添加一个中等完整性级别标签 (S-1-16-8192)。
  • 没关系,这行不通。调用SetTokenInformation,尝试添加更高的完整性标签失败,1314 - A required privilege is not held by the client.
  • @Miral:你能重现这个问题吗?
  • @HarryJohnston:我无法重现从 IE9 保存为低完整性的文件,不(这个想法是基于用户报告,但可能是由其他原因引起的)。我已经复制了我上面提到的情况,其中通过未指定意味着与问题无关的文件标记为低完整性的文件将作为低完整性进程运行并且无法将自身提升到中等,只有高。这似乎很奇怪。我接受此提升必须需要同意 UI,我只是很惊讶似乎没有一个标准的经纪人来处理它,因为它具有高度的完整性。
  • @Miral:我认为底线是文件不应该在没有充分理由的情况下被标记为低完整性。正确的解决方案不是让可执行文件能够请求非特权用户允许将自己提升到中等,而是识别并纠正导致它首先被标记为低完整性的问题。

标签: windows windows-vista uac integrity


【解决方案1】:

我从未见过或听说过获得用户同意以将流程从低完整性提升到中等完整性的方法。我会说你运气不好。

另请参阅此博客文章以供参考:Internet Explorer in Protected Mode – How the Low Integrity Environment Gets Created

【讨论】:

  • 我希望不会。据说IE9有将下载的文件标记为低完整性的习惯......
  • @Miral:你有可靠的来源吗?它通常不会这样做,如果它有时确实发生,我怀疑它是故意的。如果您对此感到担心,最好的办法可能是测试您是否在低完整性下运行,如果是,则弹出一个对话框,向用户解释情况。
  • @Miral:另一种可能的解决方法是下载一个 zip 文件,提取时应删除低完整性标签。
  • @Miral:我更新了我的答案,提供了一个讨论相关问题的文章的链接。
  • @HarryJohnston Miral 对所谓“网络标志”的思考;通过单击文件属性对话框中的Unblock 按钮可以摆脱的东西。完整性级别未触及。
【解决方案2】:

您必须像 Internet Explorer(和 Chrome)那样做。浏览器选项卡本身是在低强制完整性级别运行的独立进程。但是还有一个Medium级别的父进程。

客户端进程通过命名管道与“父”进程通信,要求父进程执行一些操作。由于 parent 是 medium,它可以在 medium 上启动一些东西。


更新:下面是一个示例,说明如何无法从低完整性进程创建中等完整性进程:

void CreateLowProcess(String szProcessName; String IntegritySid)
{
    hToken: THandle;
    hNewToken: THandle;
    szIntegritySid: WideString;
    pIntegritySid: PSID;
    TIL: TOKEN_MANDATORY_LABEL;
    ProcInfo: PROCESS_INFORMATION;
    startupInfo: TStartupInfo;

    const int SE_GROUP_INTEGRITY = 0x00000020;
    const int TokenIntegrityLevel = 25;

    const String SLowIntegritySid = "S-1-16-4096";
    const String SMediumIntegritySid = "S-1-16-8192";
    const String SHighIntegritySid = "S-1-16-12288";
    const String SSystemIntegritySid = "S-1-16-16384";

    /*
        Designing Applications to Run at a Low Integrity Level
        http://msdn.microsoft.com/en-us/library/bb625960.aspx
    */

    // Low integrity SID
    if IntegritySid == ""
       IntegritySid = SMediumIntegritySid;

    pIntegritySid = null;

    ZeroMemory(@startupInfo, sizeof(startupInfo));


    if (!OpenProcessToken(GetCurrentProcess(), 
          TOKEN_DUPLICATE or TOKEN_ADJUST_DEFAULT or TOKEN_QUERY or TOKEN_ASSIGN_PRIMARY, 
          ref hToken))
    RaiseLastWin32Error;
    try
        if (not DuplicateTokenEx(hToken, 0, nil, SecurityImpersonation, TokenPrimary, {var}hNewToken)) then
            RaiseLastWin32Error;
        try
            if (not ConvertStringSidToSidW(PWideChar(szIntegritySid), {var}pIntegritySid)) then
                RaiseLastWin32Error;
            try
                TIL._Label.Attributes := SE_GROUP_INTEGRITY;
                TIL._Label.Sid := pIntegritySid;

                // Set the process integrity level
                if (not SetTokenInformation(hNewToken, TTokenInformationClass(TokenIntegrityLevel), @TIL,
                        sizeof(TOKEN_MANDATORY_LABEL) + GetLengthSid(pIntegritySid))) then
                    RaiseLastWin32Error;

                //Create the new process at Low integrity
                Result := CreateProcessAsUserW(
                        hNewToken,
                        nil,
                        PWideChar(szProcessName),
                        nil, //ProcessAttributes
                        nil, //ThreadAttributes
                        False, //bInheritHandles
                        0, //dwCreationFlags
                        nil, //lpEnvironment
                        nil, //lpCurrentDirectory
                        startupInfo,
                        ProcInfo);
            finally
                LocalFree(Cardinal(pIntegritySid));
            end;
        finally
            CloseHandle(hNewToken);
        end;
    finally
        CloseHandle(hToken);
    end;
end;

我放弃将其余部分从 pascal 转码为 C#。反正做不到,这就是答案。

【讨论】:

  • 我特别声明这是一个不可接受的答案。唯一正在运行的进程最初是由 Explorer 以低完整性启动的。没有可与之交谈的中等完整性流程。
  • 抱歉,我混淆了两个问题 - 一个人想知道如何从低完整性流程开始中等完整性流程,然后是您的。无论哪种方式,我都试过了:你不能。欢迎与否,这就是答案。
  • 我很高兴低完整性进程无法将自己的令牌提升到中等完整性。否则,拥有低完整性概念就没有任何意义。我要问的是如何调用一个标准的操作系统提供的代理过程来通过同意 UI 进行提升,因为你可以达到高完整性。或许没有这样的事。但如果不是,那似乎是 Windows 中的一个错误。
  • 在 Windows 中没有用于询问用户是否想从低到中“提升”的同意 UI。 Windows 提供的唯一标准 UI 是提升为管理员。一个例子是 Internet Explorer,它甚至没有同意对话框——它有自己的“打开”、“另存为”、“取消”。在我看来,Windows 不应该有一个低->中高程对话框;它很容易与 UAC 同意对话框混淆。
猜你喜欢
  • 2011-11-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-12
  • 1970-01-01
  • 2011-09-17
  • 1970-01-01
相关资源
最近更新 更多