Программа превращается из администратора в систему - PullRequest
0 голосов
/ 14 ноября 2018

Я написал программу, которая должна работать как SYSTEM. Я добавляю опцию компоновщика «Уровень выполнения UAC» в «requireAdministrator», и он выдает UAC так, как должен, но теперь мне нужно перейти от администратора к SYSTEM, как я могу это сделать? Я думал об открытии токена программы и вводе его токена СИСТЕМЫ, но это нелегально. Как я могу сделать это аккуратно, потому что я знаю, как только вы, администратор, вы можете быть SYSTEM.

Ответы [ 2 ]

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

После того, как вы запустите администратор, вот несколько вариантов:

  1. Если вы знаете, что не собираетесь использовать функции графического интерфейса, вы можете создать запланированное задание, которое будет запускать тот же exe-файл, что и NT AUTHORITY \ SYSTEM, в течение нескольких секунд и проверить в своем коде, какая учетная запись процесса работает как.

    Скопировано из моего проекта и немного изменено:

    #include <Windows.h>
    #include <WinNls.h>
    #include <shobjidl.h>
    #include <objbase.h>
    #include <ObjIdl.h>
    #include <ShlGuid.h>
    #include <taskschd.h>
    #include <comdef.h>
    #include <strsafe.h>
    
    #pragma comment(lib, "taskschd.lib")
    #pragma comment(lib, "comsupp.lib")
    
    HRESULT WINAPI CreateSchedTask(WCHAR *wszExePath)
    {
        ITaskService *pService = NULL;
        ITaskFolder *pRoot = NULL;
        ITaskDefinition *pTask = NULL;
        ITaskSettings *pSettings = NULL;
        IRegistrationInfo *pInfo = NULL;
        ITriggerCollection *pCollection = NULL;
        ITrigger *pTrigger = NULL;
        ITimeTrigger *pTime = NULL;
        IPrincipal *pPrincipal = NULL;
        IActionCollection *pActionCollection = NULL;
        IAction *pAction = NULL;
        IExecAction *pExecAction = NULL;
        IRegisteredTask *pRegTask = NULL;
        SYSTEMTIME stNow;
        WCHAR wFmt[100];
        VARIANT vBlank = _variant_t();
    
        CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
        //CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_PKT_PRIVACY, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, 0, NULL);
        CoCreateInstance(CLSID_TaskScheduler, NULL, CLSCTX_INPROC_SERVER, IID_ITaskService, (LPVOID *)&pService);
    
        pService->Connect(vBlank, vBlank, vBlank, vBlank);
        pService->GetFolder(SysAllocString(L"\\"), &pRoot);
        pService->NewTask(0, &pTask);
        pService->Release();
    
        pTask->get_RegistrationInfo(&pInfo);
    
        pInfo->put_Author(SysAllocString(L"TASKNAMEHERE"));
    
        pInfo->Release();
    
        pTask->get_Settings(&pSettings);
        pSettings->put_StartWhenAvailable(VARIANT_TRUE);
        pSettings->put_Enabled(VARIANT_TRUE);
        pSettings->Release();
    
        pTask->get_Triggers(&pCollection);
        pCollection->Create(TASK_TRIGGER_TIME, &pTrigger);
        pCollection->Release();
        pTrigger->QueryInterface(IID_ITimeTrigger, (void **)&pTime);
    
        GetLocalTime(&stNow);
        // Note: replace -07:00 with the appropriate UTC offset for your time zone
        StringCchPrintfW(wFmt, 100, L"%.4hu-%.2hu-%.2huT%.2hu:%.2hu:%.2hu-07:00", stNow.wYear, stNow.wMonth, stNow.wDay, stNow.wHour, stNow.wMinute, stNow.wSecond + 30);
        pTime->put_StartBoundary(SysAllocString(wFmt));
        StringCchPrintfW(wFmt, 100, L"%.4hu-%.2hu-%.2huT%.2hu:%.2hu:%.2hu-07:00", stNow.wYear, stNow.wMonth, stNow.wDay, stNow.wHour, stNow.wMinute + 1, stNow.wSecond);
        pTime->put_EndBoundary(SysAllocString(wFmt));
        pTime->put_Id(SysAllocString(L"TimeTrigger"));
        pTime->Release();
    
        pTask->get_Actions(&pActionCollection);
        pActionCollection->Create(TASK_ACTION_EXEC, &pAction);
        pActionCollection->Release();
    
        pAction->QueryInterface(IID_IExecAction, (void **)&pExecAction);
        pAction->Release();
    
        pExecAction->put_Path(SysAllocString(wszExePath));
        pExecAction->Release();
    
        pTask->get_Principal(&pPrincipal);
        pPrincipal->put_RunLevel(TASK_RUNLEVEL_HIGHEST);
        pPrincipal->put_LogonType(TASK_LOGON_SERVICE_ACCOUNT);
        pTask->put_Principal(pPrincipal);
        pPrincipal->Release();
    
        pRoot->RegisterTaskDefinition(
            SysAllocString(L"System Elevation"),
            pTask, TASK_CREATE_OR_UPDATE,
            _variant_t(L"NT AUTHORITY\\SYSTEM"),
            _variant_t(), TASK_LOGON_SERVICE_ACCOUNT,
            _variant_t(L""), &pRegTask);
    
        pRoot->Release();
        pTask->Release();
        pRegTask->Release();
        CoUninitialize();
    
        return S_OK;
    }
    
    INT APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, INT nShowCmd)
    {
        WCHAR wUsername[100], wExePath[MAX_PATH];
        GetEnvironmentVariableW(L"USERNAME", wUsername, 100);
    
        if (!wcschr(wUsername, L'$'))
        {
            GetModuleFileNameW(hInstance, wExePath, MAX_PATH);
            CreateSchedTask(wExePath);
        }
        else
        {
            // NOTE: MessageBox and other GUI functions won't work since the process isn't running in winsta0\default
            // File I/O instead
            HANDLE hLog = CreateFileW(L"C:\\Temp\\Log.txt", GENERIC_WRITE | GENERIC_READ, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
            DWORD dwWritten;
            UINT uLen;
            CHAR szBuf[100];
            SetFilePointer(hLog, 0, NULL, FILE_END);
            StringCchPrintfA(szBuf, 100, "Hello from NT AUTHORITY\\SYSTEM\r\n", wUsername);
            StringCbLengthA(szBuf, 100, &uLen);
            WriteFile(hLog, szBuf, uLen, &dwWritten, NULL);
            CloseHandle(hLog);
                }
        return 0;
    }
    
  2. Используйте Windows Process API для повышения до System. У меня не так много примеров кода для этого, но вы можете взглянуть на PAExec , альтернативу инструменту SysInternals PSExec с открытым исходным кодом, которая позволяет создавать новые интерактивные процессы как System.

  3. Идиоматический способ сделать это в Windows, то есть создать службу Windows.

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

Написать службу Windows. По умолчанию он будет работать как пользователь SYSTEM.

Простое руководство - здесь , но помните, что для установки службы требуются права администратора.

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