使用 CreateRestrictedToken(LUA_TOKEN) 从提升的进程创建低/中进程 [英] Create a Low/Medium process from a elevated process with CreateRestrictedToken(LUA_TOKEN)

查看:234
本文介绍了使用 CreateRestrictedToken(LUA_TOKEN) 从提升的进程创建低/中进程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试从提升的进程创建一个中等或低完整性进程.我知道还有其他类似的问题,但它们主要集中在使用资源管理器或任务计划程序等解决方法上,我想坚持使用 CreateRestrictedToken()+CreateProcessAsUser().

I'm trying to create a Medium or Low integrity process from a elevated process. I know there are other questions like this but they mostly focus on the workarounds like using Explorer or the Task Scheduler and I want to stick with CreateRestrictedToken()+CreateProcessAsUser().

我认为一定有可能以某种方式执行此操作,因为我相信 UAC 在您登录时会执行此操作,但我无法使令牌中的所有内容看起来都像普通的 UAC Medium IL 令牌.

I assume it must be possible to do this somehow since I believe UAC does it when you log in but I have not been able to get everything in the token to look like the normal UAC Medium IL token.

通过使用 CreateRestrictedToken(hThisProcessToken, LUA_TOKEN, ...) 创建令牌,然后设置 TokenOwner, TokenDefaultDacl,您可以获得 80%> 和 TokenIntegrityLevel 在调用 CreateProcessAsUser() 之前.

You can get 80% there by creating the token with CreateRestrictedToken(hThisProcessToken, LUA_TOKEN, ...) and then setting TokenOwner, TokenDefaultDacl and TokenIntegrityLevel before calling CreateProcessAsUser().

剩下的问题是TokenVirtualizationAllowedTokenVirtualizationEnabledTokenElevationTokenElevationTypeTokenMandatoryPolicy 其中 SetTokenInformation() 因 ERROR_PRIVILEGE_NOT_HELD 或 ERROR_INVALID_PARAMETER 而失败.

The remaining issues are TokenVirtualizationAllowed, TokenVirtualizationEnabled, TokenElevation, TokenElevationType and TokenMandatoryPolicy where SetTokenInformation() fails with ERROR_PRIVILEGE_NOT_HELD or ERROR_INVALID_PARAMETER.

如果我以 SYSTEM @ SECURITY_MANDATORY_SYSTEM_RID 的身份运行并启用所有权限而不是管理员 @ SECURITY_MANDATORY_HIGH_RID 那么我可以设置 TokenMandatoryPolicyTokenVirtualization* 但设置 TokenElevation* 仍然失败!(目前仅在 Windows 8 上测试过)

If I run as SYSTEM @ SECURITY_MANDATORY_SYSTEM_RID with all privileges enabled as opposed to an Administrator @ SECURITY_MANDATORY_HIGH_RID then I'm able to set TokenMandatoryPolicy and TokenVirtualization* but setting TokenElevation* still fails! (Only tested on Windows 8 so far)

令牌中没有正确的 TokenElevation* 值是一个大问题,因为 Internet Explorer 无法在保护模式下启动,因为它认为令牌已提升.

Not having the correct TokenElevation* values in the token is a big issue because Internet Explorer fails to start in Protected Mode because it thinks the token is elevated.

文档 对于 SetTokenInformation() 没有说明可以设置哪些 TOKEN_INFORMATION_CLASS 项以及需要哪些权限(如果有),我不明白为什么你不会允许将这些设置为与令牌的实际完整性级别 (TokenIntegrityLevel) 匹配的较低安全值.

The documentation for SetTokenInformation() does not say which TOKEN_INFORMATION_CLASS items it is possible to set and which privileges, if any, are required and I don't understand why you would not be allowed to set these to lower security values that match the actual integrity level (TokenIntegrityLevel) of the token.

使用更安全的 API 创建 SAFER_LEVELID_NORMALUSER 令牌并不能解决任何这些问题,并且还会创建一个比普通 Medium IL 令牌更受限制的令牌.

Using the Safer API to create a SAFER_LEVELID_NORMALUSER token does not fix any of these issues and also creates a token that is more restricted than the normal Medium IL token.

我找到了一个一个类似的问题来自早期的 Vista/Longhorn 时代,从那时起没有任何变化吗?

I found somebody with a similar issue from the early Vista/Longhorn days, has nothing changed since then?

推荐答案

function CreateLowProcess(szProcessName: WideString; const IntegritySid: UnicodeString=''): Boolean;
var
    hToken: THandle;
    hNewToken: THandle;
    szIntegritySid: WideString;
    pIntegritySid: PSID;
    TIL: TOKEN_MANDATORY_LABEL;
    ProcInfo: PROCESS_INFORMATION;
    startupInfo: TStartupInfo;
const
    SE_GROUP_INTEGRITY = $00000020;
    TokenIntegrityLevel = 25;
    SLowIntegritySid:    UnicodeString = 'S-1-16-4096';
    SMediumIntegritySid: UnicodeString = 'S-1-16-8192';
    SHighIntegritySid:   UnicodeString = 'S-1-16-12288';
    SSystemIntegritySid: UnicodeString = 'S-1-16-16384';
begin
    {
        Designing Applications to Run at a Low Integrity Level
        http://msdn.microsoft.com/en-us/library/bb625960.aspx

        To start a low-integrity process:

        - Duplicate the handle of the current process, which is at medium integrity level.
        - Use SetTokenInformation to set the integrity level in the access token to Low.
        - Use CreateProcessAsUser to create a new process using the handle to the low integrity access token.

        CreateProcessAsUser updates the security descriptor in the new child process and the security descriptor
        for the access token to match the integrity level of the low-integrity access token.
    }

    // Low integrity SID
    if IntegritySid <> '' then
        szIntegritySid := IntegritySid
    else
        szIntegritySid := SLowIntegritySid;
//  szIntegritySid  := 'S-1-5-32-545'; //BUILTIN\USERS

    ZeroMemory(@startupInfo, sizeof(startupInfo));

    if (not OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE or TOKEN_ADJUST_DEFAULT or TOKEN_QUERY or TOKEN_ASSIGN_PRIMARY,
                {var}hToken)) then
        RaiseLastOSError;
    try
        if (not DuplicateTokenEx(hToken, 0, nil, SecurityImpersonation, TokenPrimary, {var}hNewToken)) then
            RaiseLastOSError;
        try
            pIntegritySid := StringToSid(szIntegritySid); //free with LocalFree
            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
                    RaiseLastOSError;

                //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(HLOCAL(pIntegritySid));
            end;
        finally
            CloseHandle(hNewToken);
        end;
    finally
        CloseHandle(hToken);
    end;
end;

这篇关于使用 CreateRestrictedToken(LUA_TOKEN) 从提升的进程创建低/中进程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆