权限提升和访问令牌权限修改

Privilege Escalation and Access Token Rights Modification

我已经开始越来越多地了解 Windows 访问令牌和权限调整,但随着我的进步,我越来越困惑。我在这里问一些问题,以便更好地理解 Windows.

的这种安全机制

在 windows 中,当我对非管理员用户执行 运行 whoami /priv 命令时,得到以下结果:

C:\Users\light>whoami /priv

PRIVILEGES INFORMATION
----------------------

Privilege Name                Description                          State
============================= ==================================== ========
SeShutdownPrivilege           Shut down the system                 Disabled
SeChangeNotifyPrivilege       Bypass traverse checking             Enabled
SeUndockPrivilege             Remove computer from docking station Disabled
SeIncreaseWorkingSetPrivilege Increase a process working set       Disabled
SeTimeZonePrivilege           Change the time zone                 Disabled

但是当我使用管理员帐户 运行 这个命令时,它会给我一长串权限名称,其中大部分都被禁用了。现在我的第一个问题是:为什么其中一些权限被禁用?当一个权限被禁用时,这意味着用户无法获得使用该权限的权利?

我的第二个问题:我应该如何准确修改访问令牌以获得 Se_Debug 特权?我执行以下步骤,但我的应用程序没有修改令牌:

  1. 调用 OpenProcessToken 打开进程进行访问令牌查询。
  2. 已初始化 TOKEN_PRIVILEGES 以查询访问令牌。
  3. 调用 LookupPrivilegeValue 检查权限
  4. 调用 AdjustTokenPrivileges 来调整该权限

我的源代码:

#include <Windows.h>
#include <iostream>

#pragma comment(lib, "advapi32.lib")

class privilege
{
private:
    BOOL m_ok;
    LUID m_luid;
    LUID m_privilege_id;
    HANDLE m_handle_token;
    BOOL m_has_priviliege;
    PRIVILEGE_SET m_privilege_set;
    TOKEN_PRIVILEGES m_token_privilege;

public:
    BOOL check(LPCWSTR arg_privilege)
    {
        if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &m_handle_token))
            m_ok = LookupPrivilegeValue(NULL, arg_privilege, &m_privilege_id);

        if (m_ok) 
        {
            m_privilege_set.PrivilegeCount = 1;
            m_privilege_set.Control = PRIVILEGE_SET_ALL_NECESSARY;
            m_privilege_set.Privilege[0].Luid = m_privilege_id;
            m_privilege_set.Privilege[0].Attributes = SE_PRIVILEGE_ENABLED;
            m_ok = PrivilegeCheck(m_handle_token, &m_privilege_set, &m_has_priviliege);
        }

        if (m_ok && !m_has_priviliege) 
            return FALSE;
        else 
            return TRUE;
    }

    BOOL set(HANDLE arg_token, LPCTSTR arg_privilege, BOOL arg_enable_privilege)
    {
        if (!LookupPrivilegeValue(NULL, arg_privilege, &m_luid))
        {
            printf("LookupPrivilegeValue error: %u\n", GetLastError());
            return FALSE;
        }

        m_token_privilege.PrivilegeCount = 1;
        m_token_privilege.Privileges[0].Luid = m_luid;
        
        if (arg_enable_privilege)
            m_token_privilege.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
        else
            m_token_privilege.Privileges[0].Attributes = 0;

        // Enable the privilege or disable all privileges.
        if (!AdjustTokenPrivileges(arg_token, FALSE, &m_token_privilege, sizeof(TOKEN_PRIVILEGES), (PTOKEN_PRIVILEGES)NULL, (PDWORD)NULL))
        {
            printf("AdjustTokenPrivileges error: %u\n", GetLastError());
            return FALSE;
        }

        if (GetLastError() == ERROR_NOT_ALL_ASSIGNED)
        {
            printf("The token does not have the specified privilege. \n");
            return FALSE;
        }

        return TRUE;
    }
};

int main(int argc, wchar_t* argv)
{
    HANDLE      process_handle;
    PHANDLE     token_handle = NULL;
    privilege   o_privilege;

    BOOL open_token_status = OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, token_handle);
    if (open_token_status != NULL)
    {
        std::wcout << L"OpenProcessToken has been failed." << std::endl;
        return EXIT_FAILURE;
    }
    else
    {
        std::wcout << L"Process has Backup privilege: " << std::boolalpha << o_privilege.check(L"SE_BACKUP_NAME") << std::endl;
        BOOL privilege_adjust_status = o_privilege.set(token_handle, L"SeBackupPrivilege", TRUE);
        std::wcout << L"Process has Backup privilege: " << std::boolalpha << o_privilege.check(L"SE_BACKUP_NAME") << std::endl;
        return privilege_adjust_status;
    }

    return 0;
}

但是这个程序无法为进程设置备份权限。有人可以逐步解释 Windows OS 中的令牌枚举和调整吗?

我对模拟概念也有一个真正的问题。 Windows OS 为什么我们需要这样的东西?

How should I exactly modify an access token to get Se_Debug privilege?

根据Changing Privileges in a Token

You can change the privileges in either a primary or an impersonation token in two ways:

  • Enable or disable privileges by using the AdjustTokenPrivileges function.
  • Restrict or remove privileges by using the CreateRestrictedToken function.

根据Assigning Privileges to an Account

为用户帐户分配权限

You can assign privileges to accounts either by using the Local Security Policy Microsoft Management Console (MMC) snap-in (Secpol.msc) or by calling the LsaAddAccountRights function.