进程访问令牌权限提升

使用场景:

  病毒木马想要实现一些关键的系统操作时。

  比如:通过调用ExitWindows函数实现关机或重启操作的时候就需要SE_SHUTDOWN_NAME权限

  否则,会忽视操作不执行

实现原理:

  获取进程的访问令牌,然后将访问令牌的权限修改为指定权限。但是系统内部并不直接识别权限名称,而是识别LUID值,所以需要根据权限名称获取对应的LUID值,之后传递给系统,实现进程访问令牌权限的修改。

实现过程:

  1.获取指定进程的访问令牌(需要获取TOKEN_ADJUST_PRIVILEGES权限的令牌句柄)

  2.获取本地系统指定特权名称的LUID值(LUID值相当于该特权的身份标号)

  3.创建一个新的进程令牌特权结构体,并对其进行赋值(新特权的数量,特权对应的LUID值以及特权的属性状态)

  4.调用 AdjustTokenPrivileges 函数对进程令牌的特权进行修改

注意点:

  AdjustTokenPrivileges返回TRUE,并不代表特权设置成功,还需要使用GetLastError来判断错误码返回值。

  若错误码返回值为ERROR_SUCCESS,则表示所有特权设置成功;若为ERROR_NOT_ALL_ASSIGNED,

  则表示并不是所有特权都设置成功

  换句话说,如果在程序中只提升了一个访问令牌特权,

  且错误码为ERROR_NOT_ALL_ASSIGNED,则提升失败。如果程序运行在 Windows 7或者以上版本的操作系统,

  可以尝试以管理员身份运行程序然后再测试

代码:

    //************************************
    // 函数名:  CPrivilgeEscalationDlg::EnableDebugPrivilege
    // 返回类型:   BOOL
    // 功能: 提升进程访问令牌权限
    // 参数1: 需要提升权限的进程句柄
    // 参数2: 特权名称
    //************************************
BOOL CPrivilgeEscalationDlg::EnableDebugPrivilege(HANDLE hProcess, char* pszPrivilegesName)
{
    HANDLE hToken = NULL;
    //令牌权限结构体
    TOKEN_PRIVILEGES tp;
    

    //打开进程令牌并获取进程令牌句柄
    BOOL bRet = OpenProcessToken(hProcess, TOKEN_ADJUST_PRIVILEGES, &hToken);
    if (FALSE == bRet)
    {
        MessageBox(L"打开进程令牌失败!");
        return FALSE;
    }
    //获取本地系统的 pszPrivilegesName 特权的LUID值
    bRet = LookupPrivilegeValue(NULL, (LPCWSTR)pszPrivilegesName, &tp.Privileges[0].Luid);
    if (FALSE == bRet)
    {
        MessageBox(L"获取LUID值失败!");
        CloseHandle(hToken);
        hToken = INVALID_HANDLE_VALUE;
        return FALSE;
    }
    //设置提升权限信息
    //设置新提权的数量
    tp.PrivilegeCount = 1;
    //启用该特权
    tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

    //提升进程令牌访问权限
    bRet = AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(tp), NULL, NULL);
    if (FALSE == bRet)
    {
        MessageBox(L"提升进程令牌访问权限失败!");
        CloseHandle(hToken);
        hToken = INVALID_HANDLE_VALUE;
        return FALSE;
    }
    else
    {
        //根据错误码判断是否是特权都设置成功
        DWORD dwRet = GetLastError();
        if (ERROR_SUCCESS == dwRet)
        {
            CloseHandle(hToken);
            hToken = INVALID_HANDLE_VALUE;
            return TRUE;
        }
        else if (ERROR_NOT_ALL_ASSIGNED == dwRet)
        {
            MessageBox(L"提升权限失败!,请以管理员身份运行");
            CloseHandle(hToken);
            hToken = INVALID_HANDLE_VALUE;
            return FALSE;
        }
    }
    CloseHandle(hToken);
    hToken = INVALID_HANDLE_VALUE;
    return FALSE;
}

 

  

posted @ 2020-04-19 22:35  自己的小白  阅读(1154)  评论(0编辑  收藏  举报