mfc HackerTools进程令牌设置为debug权限

博客园:https://www.cnblogs.com/ndyxb/p/12734717.html

要对一个任意进程(包括系统安全进程和服务进程)进行指定了写相关的访问权的OpenProcess操作,需要当前进程具有SeDeDebug权限。

实现原理:

  获取进程的访问令牌,然后将访问令牌的权限修改为指定权限。但是系统内部并不直接识别权限名称,而是识别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, SE_DEBUG_NAME, &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-06-28 11:21  zebra_彬  阅读(284)  评论(0编辑  收藏  举报