Определите, может ли пользователь повысить уровень процесса с помощью c ++ - PullRequest
0 голосов
/ 28 мая 2018

Моему приложению нужна функция для проверки, разрешено ли текущему пользователю повысить уровень процесса (запуск от имени администратора).Функция IsUserAnAdmin() только сообщает мне, если процесс уже повышен, но в моем случае это не так.

Есть ли другие варианты, чтобы определить, может ли пользователь повысить уровень процесса (является администратором)

Ответы [ 2 ]

0 голосов
/ 28 мая 2018

для проверки текущего статуса высот мы можем запросить TOKEN_ELEVATION_TYPE текущего процесса с TokenElevationType:

  • TokenElevationTypeFull - мы уже запустилиповышенный.
  • TokenElevationTypeLimited - мы работаем по ограниченному токену, но имеем
    повышенный связанный токен.обычно это учетная запись администратора с интерактивным входом в систему.мы можем поднять под того же пользователя.
  • TokenElevationTypeDefault - у нас нет связанного токена.здесь существует 2
    кейс:

    1. мы уже повысили (для проверки этого использования TokenElevation и ищите TokenIsElevated из TOKEN_ELEVATION) это может быть, если мы запускаем под встроенной учетной записью администратора
      (DOMAIN_ALIAS_RID_ADMINS 500), которая не фильтруется, или UAC отключен в системе.

    2. мызапускать не под учетной записью администратора.в этом случае мы можем повысить уровень, но только под другим аккаунтом.для этого нужно знать пароль этой учетной записи

демонстрационный код:

inline ULONG BTE(BOOL f)
{
    return f ? 0 : GetLastError();
}

void TryElevate()
{
    WCHAR path[MAX_PATH];
    if (GetModuleFileNameW(0, path, RTL_NUMBER_OF(path)))
    {
        SHELLEXECUTEINFOW sei = { sizeof(sei), 0, 0, L"runas", path };
        ShellExecuteExW(&sei);
    }
}

ULONG CheckElevation()
{
    HANDLE hToken;
    ULONG err = BTE(OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken));
    if (!err)
    {
        ULONG cb = 0, rcb = 0x20;
        union {
            PTOKEN_USER ptu;
            PVOID buf;
        };
        static volatile UCHAR guz;
        PVOID stack = alloca(guz);
        PWSTR SzSid = 0;

        //++ for display user sid only
        do 
        {
            if (cb < rcb)
            {
                cb = RtlPointerToOffset(buf = alloca(rcb - cb), stack);
            }

            if (!(err = BTE(GetTokenInformation(hToken, ::TokenUser, buf, cb, &rcb))))
            {
                ConvertSidToStringSidW(ptu->User.Sid, &SzSid);
                break;
            }

        } while (err == ERROR_INSUFFICIENT_BUFFER);
        // -- for display user sid only

        union {
            TOKEN_ELEVATION te;
            TOKEN_ELEVATION_TYPE tet;
        };

        if (!(err = BTE(GetTokenInformation(hToken, ::TokenElevationType, &tet, sizeof(tet), &rcb))))
        {
            switch (tet)
            {
            case TokenElevationTypeDefault:
                if (!(err = BTE(GetTokenInformation(hToken, ::TokenElevation, &te, sizeof(te), &rcb))))
                {
                    if (te.TokenIsElevated)
                    {
                        // we are built-in admin or UAC is disabled in system
            case TokenElevationTypeFull:
                MessageBoxW(HWND_DESKTOP, L"we run elevated", SzSid, MB_ICONINFORMATION);
                break;
                    }

                    // we can not elevate under same user, but still can elevate under another admin account
                    // non admin account
                    TryElevate();
                    MessageBoxW(HWND_DESKTOP, L"Default", SzSid, MB_ICONINFORMATION);
                }

                break;


            case TokenElevationTypeLimited:
                // this mean that we have linked token, which is elevated. we can elevate under same user
                TryElevate();
                MessageBoxW(HWND_DESKTOP, L"Limited", SzSid, MB_ICONINFORMATION);
                break;

            default:
                MessageBoxW(HWND_DESKTOP, L"unknown elevation type", SzSid, MB_ICONWARNING);
                err = ERROR_GEN_FAILURE;
            }
        }

        if (SzSid) LocalFree(SzSid);

        CloseHandle(hToken);
    }

    return err;
}

и результат:

enter image description here

0 голосов
/ 28 мая 2018

Используя комментарий @RbMm, Ive создал следующую функцию, чтобы определить, может ли процесс быть повышен. (без пароля)

bool IsElevationPossible()
{
    TOKEN_ELEVATION_TYPE tokenElevationType;
    DWORD size;
    if (!GetTokenInformation(
        GetCurrentProcessToken(),
        TokenElevationType,
        &tokenElevationType,
        sizeof(tokenElevationType),
        &size))
        {
        // Log Error

        return false;
    }

    return tokenElevationType == TokenElevationTypeLimited;
}
...