見出し画像

#144 Token Privileges

 WindowsのTokenで遊んでみました。Tokenは、ユーザーのアクセス権限を管理するチケットのようなものですが、自分で書き換えることもできます。

例えば、下記のような特権情報もTokenに含まれています。

>whoami /priv

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

Privilege Name                            Description                                                        State
========================================= ================================================================== ========
SeIncreaseQuotaPrivilege                  Adjust memory quotas for a process                                 Disabled
SeSecurityPrivilege                       Manage auditing and security log                                   Disabled
SeTakeOwnershipPrivilege                  Take ownership of files or other objects                           Disabled
SeLoadDriverPrivilege                     Load and unload device drivers                                     Disabled
SeSystemProfilePrivilege                  Profile system performance                                         Disabled
SeSystemtimePrivilege                     Change the system time                                             Disabled
SeProfileSingleProcessPrivilege           Profile single process                                             Disabled
SeIncreaseBasePriorityPrivilege           Increase scheduling priority                                       Disabled
SeCreatePagefilePrivilege                 Create a pagefile                                                  Disabled
SeBackupPrivilege                         Back up files and directories                                      Disabled
SeRestorePrivilege                        Restore files and directories                                      Disabled
SeShutdownPrivilege                       Shut down the system                                               Disabled
SeDebugPrivilege                          Debug programs                                                     Disabled
SeSystemEnvironmentPrivilege              Modify firmware environment values                                 Disabled
SeChangeNotifyPrivilege                   Bypass traverse checking                                           Enabled
SeRemoteShutdownPrivilege                 Force shutdown from a remote system                                Disabled
SeUndockPrivilege                         Remove computer from docking station                               Disabled
SeManageVolumePrivilege                   Perform volume maintenance tasks                                   Disabled
SeImpersonatePrivilege                    Impersonate a client after authentication                          Enabled
SeCreateGlobalPrivilege                   Create global objects                                              Enabled
SeIncreaseWorkingSetPrivilege             Increase a process working set                                     Disabled
SeTimeZonePrivilege                       Change the time zone                                               Disabled
SeCreateSymbolicLinkPrivilege             Create symbolic links                                              Disabled
SeDelegateSessionUserImpersonatePrivilege Obtain an impersonation token for another user in the same session Disabled

それでは、書き換えてみましょう!

Enable Token Privileges

C++でプログラムを作りました。

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



BOOL CheckPrivilege(IN HANDLE hProcess, IN LPCSTR lpPrivilegeName, OUT HANDLE hToken) {
    PTOKEN_PRIVILEGES pTokenPrivs = {};
    DWORD dwLength = NULL;
    if (!OpenProcessToken(hProcess, TOKEN_QUERY, &hToken)) {
        return FALSE;
    }
    GetTokenInformation(hToken, TokenPrivileges, NULL, 0, &dwLength);
    pTokenPrivs = (PTOKEN_PRIVILEGES)LocalAlloc(LPTR, dwLength);
    GetTokenInformation(hToken, TokenPrivileges, pTokenPrivs, dwLength, &dwLength);

    for (DWORD i = 0; i < pTokenPrivs->PrivilegeCount; i++) {
        char szPrivilegeName[256];
        LookupPrivilegeNameA(NULL, &pTokenPrivs->Privileges[i].Luid, szPrivilegeName, &dwLength);

        if (strcmp(szPrivilegeName, lpPrivilegeName) == 0) {
            printf("[+] %s %d \n", szPrivilegeName, pTokenPrivs->Privileges[i].Attributes & SE_PRIVILEGE_ENABLED);
        }
        
    }

}

BOOL ChangePrivilege(IN HANDLE hProcess, IN LPCSTR lpPrivilegeName, IN BOOL bEnablePrivilege, OUT HANDLE hToken) {
    TOKEN_PRIVILEGES tp;
    LUID luid;

    OpenProcessToken(hProcess, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken);

    if (!LookupPrivilegeValueA(NULL, lpPrivilegeName, &luid)) {
        printf("[!] LookupPrivilegeValueA failed with error : %d \n", GetLastError());
        return FALSE;
    }

    tp.PrivilegeCount = 1;
    tp.Privileges[0].Luid = luid;

    if (bEnablePrivilege) {
        tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
    }
    else {
        tp.Privileges[0].Attributes = SE_PRIVILEGE_REMOVED;
    }

    if (!AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), (PTOKEN_PRIVILEGES)NULL, (PDWORD)NULL)) {
        printf("[!] AdjustTokenPrivileges failed with error : %d \n", GetLastError());
        return FALSE;
    }

    return TRUE;
}



int main()
{
    HANDLE hProcess = NULL;
    HANDLE hToken = NULL;
    LPCSTR lpPrivilegeName = "SeIncreaseQuotaPrivilege";
    hProcess = GetCurrentProcess();
    CheckPrivilege(hProcess, lpPrivilegeName, hToken);

    ChangePrivilege(hProcess, lpPrivilegeName, true, hToken);

    CheckPrivilege(hProcess, lpPrivilegeName, hToken);
}

実行すると、1回目と2回目でちゃんとPrivilegeが更新されていることがわかります。

>.\TokenTest.exe
[+] SeIncreaseQuotaPrivilege 0
[+] SeIncreaseQuotaPrivilege 2

こうして、必要な特権を有効化することで、別の攻撃につなげることができます…


EOF

この記事が気に入ったらサポートをしてみませんか?