特权升级和访问令牌权利修改

发布于 2025-01-21 14:48:38 字数 4317 浏览 3 评论 0 原文

我已经开始学习有关Windows访问令牌和特权调整的越来越多的知识,但是随着我的进步,我感到困惑。我在这里提出一些问题,以更好地理解Windows的这种安全机制。

在Windows中,当我为非Administrator用户运行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. call openProcessToken以打开访问令牌查询的过程。
  2. 初始化的token_privileges查询访问令牌。
  3. 调用LookUpprivileGeValue查看特权,
  4. 请致电AdvationTokenPrivileges,以调整该特权

我的源代码:

#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中需要这样的东西?

I have started to learn more and more about Windows access token and privilege adjustment but as I progress, I am getting confused. I ask some questions here to better understand this security mechanism of Windows.

In windows, when I run whoami /priv command for non-administrator users, it gives me the following result:

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

But when I run this command with administrator account it gives me a long list of privilege names which most of them are disabled. Now my first question is: Why some of these privileges are disabled? When a privilege disabled, it means user couldn't take the right to use that privilege?

My second question: How should I exactly modify an access token to get Se_Debug privilege? I do the following steps, but my application has not modify the token:

  1. Call OpenProcessToken to open a process for access token query.
  2. Initialized TOKEN_PRIVILEGES for querying access token.
  3. Call LookupPrivilegeValue to check privilege
  4. Call AdjustTokenPrivileges to adjust that privilege

My source code:

#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;
}

But this program couldn't set backup privilege for the process. Somebody could explain token enumeration and adjustment in Windows OS with a step by step approach?

Also I have a real problem with impersonation concept. Why we need such thing in Windows OS?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

┊风居住的梦幻卍 2025-01-28 14:48:38

我应该如何准确修改访问令牌以获得SE_DEBUG特权?

根据

您可以更改主要或模仿中的特权
令牌有两种方式:

  • 通过使用AdvationTokenPrivileges函数启用或禁用特权。
  • 使用CreaterationalToken功能限制或删除特权。


要将特权分配给用户帐户,根据将特权分配给帐户

您可以使用本地分配特权
安全策略Microsoft Management Console(MMC)快照
(secpol.msc)或通过调用功能。


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

According to 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.

To assign privileges to a user account, according to 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文