Отключить все привилегии с помощью AdjustTokenPrivileges, используя DisableAllPrivileges? - PullRequest
0 голосов
/ 15 ноября 2018

Я пытаюсь удалить процесс из всех привилегий, используя AdjustTokenPrivileges, установив для параметра DisableAllPrivileges значение TRUE:

#include <Windows.h>
#include <cwchar>

int main()
{
  auto process = GetCurrentProcess();
  HANDLE primary_token;

  if (OpenProcessToken(process, TOKEN_ADJUST_PRIVILEGES, &primary_token) == FALSE)
  {
    fwprintf(stderr, L"OpenProcessToken: failed");
  }

  if (AdjustTokenPrivileges(primary_token, TRUE, nullptr, 0, nullptr, nullptr) == FALSE)
  {
    fwprintf(stderr, L"AdjustTokenPrivileges: failed");
  }

  CloseHandle(primary_token);

  auto event = CreateEventW(nullptr, FALSE, FALSE, nullptr);
  WaitForSingleObject(event, INFINITE);
}

Кажется, он не работает при просмотре привилегий процесса в Sysinternals Process Explorer .

Я решил эту проблему, запросив все привилегии и изменив атрибут на SE_PRIVILEGE_REMOVED, но я не уверен, почему установка DisableAllPrivileges на TRUE не работает.

1 Ответ

0 голосов
/ 15 ноября 2018

Кажется, он не работает при просмотре привилегий процесса в Sysinternals Process Explorer.

Sysinternals Process Explorer показывает неправильное изображение.DisableAllPrivileges работать как исключено - удалить атрибут SE_PRIVILEGE_ENABLED из всех привилегий в токене.но некоторые привилегии также могут иметь атрибут SE_PRIVILEGE_ENABLED_BY_DEFAULT.SeChangeNotifyPrivilege например, имеют этот атрибут.оно останется неизменным, что и покажет ваш образ.но в любом случае только атрибут SE_PRIVILEGE_ENABLED используется в PrivilegeCheck или SePrivilegeCheck api.таким образом, вы действительно отключаете все привилегии в своем токене, включая SeChangeNotifyPrivilege.все вызовы, требующие конкретной привилегии, которые не имеют атрибута SE_PRIVILEGE_ENABLED в вашем токене - сбой, даже если существует атрибут SE_PRIVILEGE_ENABLED_BY_DEFAULT.

тестовый код

#ifndef RtlPointerToOffset
#define RtlPointerToOffset(B,P) ((ULONG)( ((PCHAR)(P)) - ((PCHAR)(B)) ))
#endif

inline ULONG BOOL_TO_ERROR(BOOL fOk)
{
    return fOk ? NOERROR : GetLastError();
}

volatile UCHAR guz = 0;

void DumpTokenPrivs(HANDLE hToken)
{
    union {
        PVOID buf;
        PTOKEN_PRIVILEGES ptp;
    };

    PVOID stack = alloca(guz);

    ULONG cb = 0, rcb = 0x40;

    ULONG dwError;
    do 
    {
        if (cb < rcb)
        {
            cb = RtlPointerToOffset(buf = alloca(rcb - cb), stack);
        }

        if (NOERROR == (dwError = BOOL_TO_ERROR(
            GetTokenInformation(hToken, TokenPrivileges, buf, cb, &rcb))))
        {
            ULONG PrivilegeCount = ptp->PrivilegeCount;

            DbgPrint("PrivilegeCount = %u\n", PrivilegeCount);
            if (PrivilegeCount)
            {
                PLUID_AND_ATTRIBUTES Privileges = ptp->Privileges;
                do 
                {
                    WCHAR Name[64];
                    ULONG cch = RTL_NUMBER_OF(Name);
                    if (!LookupPrivilegeNameW(0, &Privileges->Luid, Name, &cch))
                    {
                        _swprintf(Name, L"{%u-%u}", 
                            Privileges->Luid.HighPart, Privileges->Luid.LowPart);
                    }

                    BOOL fResult;
                    PRIVILEGE_SET ps = { 
                        1, PRIVILEGE_SET_ALL_NECESSARY, { 
                            { Privileges->Luid.LowPart, Privileges->Luid.HighPart } 
                        } 
                    };

                    if (!PrivilegeCheck(hToken, &ps, &fResult))
                    {
                        DbgPrint("PrivilegeCheck=%u\n", GetLastError());
                    }

                    DbgPrint("%08x %x %S\n", Privileges->Attributes, fResult, Name);

                } while (Privileges++, --PrivilegeCount);
            }
        }

    } while (dwError == ERROR_INSUFFICIENT_BUFFER);
}

void PrivTest()
{
    HANDLE hToken;

    if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY, &hToken))
    {
        ULONG rcb;
        TOKEN_LINKED_TOKEN tlk;
        GetTokenInformation(hToken, TokenLinkedToken, &tlk, sizeof(tlk), &rcb);
        CloseHandle(hToken);
        hToken = tlk.LinkedToken;

        DumpTokenPrivs(hToken);

        if (AdjustTokenPrivileges(hToken, TRUE, 0, 0, 0, 0) && GetLastError() == NOERROR)
        {
            DumpTokenPrivs(hToken);
        }
    }

    CloseHandle(hToken);
}

и вывод:

PrivilegeCount = 5
00000000 0 SeShutdownPrivilege
00000003 1 SeChangeNotifyPrivilege
00000000 0 SeUndockPrivilege
00000000 0 SeIncreaseWorkingSetPrivilege
00000000 0 SeTimeZonePrivilege
PrivilegeCount = 5
00000000 0 SeShutdownPrivilege
00000001 0 SeChangeNotifyPrivilege
00000000 0 SeUndockPrivilege
00000000 0 SeIncreaseWorkingSetPrivilege
00000000 0 SeTimeZonePrivilege

обратите внимание, что перед вызовом было

00000003 1 SeChangeNotifyPrivilege

означало SE_PRIVILEGE_ENABLED_BY_DEFAULT | SE_PRIVILEGE_ENABLED атрибутов и PrivilegeCheck говорят, что привилегия включена.

после вызова

00000001 0 SeChangeNotifyPrivilege

означало SE_PRIVILEGE_ENABLED_BY_DEFAULT атрибутов, а PrivilegeCheck говорят, что привилегия отключена.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...