从流程中删除管理员特权 [英] Removing Administrator Privilages from Process

查看:272
本文介绍了从流程中删除管理员特权的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

借助这篇出色的 MSDN文章,我的第一个想法只是简单地检查该进程是否使用提升的管理员组,并使用 AdjustTokenGroups()将管理员组设置为 SE_GROUP_USE_FOR_DENY_ONLY 。但是不幸的是,我们不能在当前运行的进程上修改管理员组,因为它还具有 SE_GROUP_MANDATORY 属性,这使得更改时难以理解。

With the help of this great MSDN article, my first idea was to simply check if the process is using an elevated Administrator group, and using AdjustTokenGroups() I would set the Administrator group to SE_GROUP_USE_FOR_DENY_ONLY. Unfortunately though, we can't modify the administrator group on the currently running process as it also has the SE_GROUP_MANDATORY attribute, which makes it inelligable for changing.

MSDN文档对此有以下说法:

The MSDN document has this to say about it:

AdjustTokenGroups 函数无法禁用 TOKEN_GROUPS 结构中具有 SE_GROUP_MANDATORY 属性的组。使用 CreateRestrictedToken 代替。

The AdjustTokenGroups function cannot disable groups with the SE_GROUP_MANDATORY attribute in the TOKEN_GROUPS structure. Use CreateRestrictedToken instead.

因此,我完成了以下代码来实现这一点;

So, I am done the following code to achieve this;

bool _IsNewProcessLaunched()
{
    HANDLE hToken = NULL;   
    bool hasRestarted = false;

    if (!OpenProcessToken( GetCurrentProcess(), 
        TOKEN_ASSIGN_PRIMARY | TOKEN_QUERY | TOKEN_DUPLICATE | TOKEN_ADJUST_GROUPS, 
        &hToken )) 
    {
        return hasRestarted;
    }

    PSECURITY_DESCRIPTOR pSID = NULL;
    SID_IDENTIFIER_AUTHORITY SIDAuth = SECURITY_NT_AUTHORITY;

    if(! AllocateAndInitializeSid( &SIDAuth, 2,
        SECURITY_BUILTIN_DOMAIN_RID,
        DOMAIN_ALIAS_RID_ADMINS,
        0, 0, 0, 0, 0, 0,
        &pSID) ) 
    {
        CloseHandle(hToken);
        hToken = NULL;
        return hasRestarted;
    }

    BOOL isAdmin = FALSE;
    BOOL ok = CheckTokenMembership(NULL, pSID, &isAdmin);

    // Create the SID structure for the administrator SID
    SID_AND_ATTRIBUTES adminSID = {0};
    adminSID.Sid = pSID;

    // Create a restricted token which denies the administrator group
    HANDLE restrictedToken;

    CreateRestrictedToken(hToken,RESTR,DISABLE_MAX_PRIVILEGE,&adminSID,NULL,NULL,NULL,NULL,&restrictedToken);

    //Create startup info
    STARTUPINFO si = {0};
    PROCESS_INFORMATION pi = {0};
    si.lpDesktop = L"winsta0\\default";
    si.cb = sizeof( si );

    // Get the current executables name
    TCHAR exePath[MAX_PATH];
    GetModuleFileName(NULL,exePath,MAX_PATH);

    // Start the new (non-administrator elevated) restricted process
    if( CreateProcessAsUser(restrictedToken,exePath,NULL,NULL,NULL,TRUE,NORMAL_PRIORITY_CLASS,NULL,NULL,&si,&pi) == 0)
        hasRestarted = false;
    else
        hasRestarted  = true;

    return hasRestarted;
}

但是新流程仍以管理员的身份运行比作为普通用户

But new process is still running as administrator rather than as the normal user.

我该怎么做?

推荐答案

调用进程的令牌,则启动的进程将使用与调用进程相同的用户帐户来运行,只是具有受限的权限。请记住,在UAC下,管理员没有提升权限就没有完整的管理员权限。 CreateRestrictedToken()创建具有受限权限的令牌。因此,即使用户可能是管理员,并不意味着启动的进程将具有管理权限。

Since you are restricting the calling process's token, the launched process will be run with the same user account as the calling process, just with restricted permissions. Remember, under UAC, administrators do not have full admin rights without elevation. CreateRestrictedToken() creates a token with restricted permissions. So even though the user may be administrator does not mean the launched process will run with administrative rights.

BTW,有一个更简单的API,被称为更安全的API ,您可以使用而不是 CreateRestrictedToken()

BTW, there is a simplier API, known as the Safer API, that you can use instead of CreateRestrictedToken():

#include <WinSafer.h>

bool _IsNewProcessLaunched()
{
    // Create the restricted token.

    SAFER_LEVEL_HANDLE hLevel = NULL;
    if (!SaferCreateLevel(SAFER_SCOPEID_USER, SAFER_LEVELID_NORMALUSER, SAFER_LEVEL_OPEN, &hLevel, NULL))
    {
        return false;
    }

    HANDLE hRestrictedToken = NULL;
    if (!SaferComputeTokenFromLevel(hLevel, NULL, &hRestrictedToken, 0, NULL))
    {
        SaferCloseLevel(hLevel);
        return false;
    }

    SaferCloseLevel(hLevel);

    // Set the token to medium integrity.

    TOKEN_MANDATORY_LABEL tml = {0};
    tml.Label.Attributes = SE_GROUP_INTEGRITY; 
    // alternatively, use CreateWellKnownSid(WinMediumLabelSid) instead...
    if (!ConvertStringSidToSid(TEXT("S-1-16-8192"), &(tml.Label.Sid)))
    {
        CloseHandle(hRestrictedToken);
        return false;
    }

    if (!SetTokenInformation(hRestrictedToken, TokenIntegrityLevel, &tml, sizeof(tml) + GetLengthSid(tml.Label.Sid))))
    {
        LocalFree(tml.Label.Sid);
        CloseHandle(hRestrictedToken);
        return false;
    }

    LocalFree(tml.Label.Sid);

    // Create startup info

    STARTUPINFO si = {0};
    si.cb = sizeof( si );
    si.lpDesktop = L"winsta0\\default";

    PROCESS_INFORMATION pi = {0};

    // Get the current executable's name
    TCHAR exePath[MAX_PATH+1] = {0};
    GetModuleFileName(NULL, exePath, MAX_PATH);

    // Start the new (non-elevated) restricted process
    if (!CreateProcessAsUser(hRestrictedToken, exePath, NULL, NULL, NULL, TRUE, NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi))
    {
        CloseHandle(hRestrictedToken);
        return false;
    }

    CloseHandle(hRestrictedToken);
    CloseHandle(pi.hThread);
    CloseHandle(pi.hProcess);

    return true;
}

这篇关于从流程中删除管理员特权的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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