Program escalates itself from admin to system










0















I wrote a program that needs to be running as SYSTEM. I add the linker option 'UAC Execution Level' to 'requireAdministrator' and it pops the UAC like it should but now I need to escalate from admin to SYSTEM how can I do that?
I thought about opening the program's token and inject it the SYSTEM token but it is not legit way. How can I do it neatly because I know once you admin you can be SYSTEM.










share|improve this question

















  • 1





    Run it as a service under the local system account. Of course, one wonders why you feel the need to do this at all.

    – David Heffernan
    Nov 14 '18 at 18:18











  • you can get token from system process or impersonate system thread, if you have debug privileges. and impersonate some your thread(s) with this system token, when you need do some task as LocalSystem. and anyway - what concrete you need ? some concrete privileges ? be membership of S-1-5-18 or what ?

    – RbMm
    Nov 14 '18 at 21:14












  • @RbMm I need in my program to load a driver. I am creating and starting a new service for the driver. My program also has GUI so I think I will load the driver with a thread running as system like you said

    – user3725519
    Nov 17 '18 at 21:45











  • but in this case i not understand for what you need run as SYSTEM. for load driver direct, via ZwLoadDriver you need SE_LOAD_DRIVER_PRIVILEGE privilege enabled (it usually have by admins). or if you do this via service manager - for create service you need be member of Administrators. for start already existing service - depend from it security descriptor but usually you also need be member of Administrators. in all case you not need SYSTEM token

    – RbMm
    Nov 17 '18 at 21:53












  • @RbMm I have just realized I confused this with some other thing and when I tested the program with admin it worked. Thank you

    – user3725519
    Nov 17 '18 at 22:07















0















I wrote a program that needs to be running as SYSTEM. I add the linker option 'UAC Execution Level' to 'requireAdministrator' and it pops the UAC like it should but now I need to escalate from admin to SYSTEM how can I do that?
I thought about opening the program's token and inject it the SYSTEM token but it is not legit way. How can I do it neatly because I know once you admin you can be SYSTEM.










share|improve this question

















  • 1





    Run it as a service under the local system account. Of course, one wonders why you feel the need to do this at all.

    – David Heffernan
    Nov 14 '18 at 18:18











  • you can get token from system process or impersonate system thread, if you have debug privileges. and impersonate some your thread(s) with this system token, when you need do some task as LocalSystem. and anyway - what concrete you need ? some concrete privileges ? be membership of S-1-5-18 or what ?

    – RbMm
    Nov 14 '18 at 21:14












  • @RbMm I need in my program to load a driver. I am creating and starting a new service for the driver. My program also has GUI so I think I will load the driver with a thread running as system like you said

    – user3725519
    Nov 17 '18 at 21:45











  • but in this case i not understand for what you need run as SYSTEM. for load driver direct, via ZwLoadDriver you need SE_LOAD_DRIVER_PRIVILEGE privilege enabled (it usually have by admins). or if you do this via service manager - for create service you need be member of Administrators. for start already existing service - depend from it security descriptor but usually you also need be member of Administrators. in all case you not need SYSTEM token

    – RbMm
    Nov 17 '18 at 21:53












  • @RbMm I have just realized I confused this with some other thing and when I tested the program with admin it worked. Thank you

    – user3725519
    Nov 17 '18 at 22:07













0












0








0








I wrote a program that needs to be running as SYSTEM. I add the linker option 'UAC Execution Level' to 'requireAdministrator' and it pops the UAC like it should but now I need to escalate from admin to SYSTEM how can I do that?
I thought about opening the program's token and inject it the SYSTEM token but it is not legit way. How can I do it neatly because I know once you admin you can be SYSTEM.










share|improve this question














I wrote a program that needs to be running as SYSTEM. I add the linker option 'UAC Execution Level' to 'requireAdministrator' and it pops the UAC like it should but now I need to escalate from admin to SYSTEM how can I do that?
I thought about opening the program's token and inject it the SYSTEM token but it is not legit way. How can I do it neatly because I know once you admin you can be SYSTEM.







c windows winapi elevated-privileges






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 14 '18 at 18:09









user3725519user3725519

205




205







  • 1





    Run it as a service under the local system account. Of course, one wonders why you feel the need to do this at all.

    – David Heffernan
    Nov 14 '18 at 18:18











  • you can get token from system process or impersonate system thread, if you have debug privileges. and impersonate some your thread(s) with this system token, when you need do some task as LocalSystem. and anyway - what concrete you need ? some concrete privileges ? be membership of S-1-5-18 or what ?

    – RbMm
    Nov 14 '18 at 21:14












  • @RbMm I need in my program to load a driver. I am creating and starting a new service for the driver. My program also has GUI so I think I will load the driver with a thread running as system like you said

    – user3725519
    Nov 17 '18 at 21:45











  • but in this case i not understand for what you need run as SYSTEM. for load driver direct, via ZwLoadDriver you need SE_LOAD_DRIVER_PRIVILEGE privilege enabled (it usually have by admins). or if you do this via service manager - for create service you need be member of Administrators. for start already existing service - depend from it security descriptor but usually you also need be member of Administrators. in all case you not need SYSTEM token

    – RbMm
    Nov 17 '18 at 21:53












  • @RbMm I have just realized I confused this with some other thing and when I tested the program with admin it worked. Thank you

    – user3725519
    Nov 17 '18 at 22:07












  • 1





    Run it as a service under the local system account. Of course, one wonders why you feel the need to do this at all.

    – David Heffernan
    Nov 14 '18 at 18:18











  • you can get token from system process or impersonate system thread, if you have debug privileges. and impersonate some your thread(s) with this system token, when you need do some task as LocalSystem. and anyway - what concrete you need ? some concrete privileges ? be membership of S-1-5-18 or what ?

    – RbMm
    Nov 14 '18 at 21:14












  • @RbMm I need in my program to load a driver. I am creating and starting a new service for the driver. My program also has GUI so I think I will load the driver with a thread running as system like you said

    – user3725519
    Nov 17 '18 at 21:45











  • but in this case i not understand for what you need run as SYSTEM. for load driver direct, via ZwLoadDriver you need SE_LOAD_DRIVER_PRIVILEGE privilege enabled (it usually have by admins). or if you do this via service manager - for create service you need be member of Administrators. for start already existing service - depend from it security descriptor but usually you also need be member of Administrators. in all case you not need SYSTEM token

    – RbMm
    Nov 17 '18 at 21:53












  • @RbMm I have just realized I confused this with some other thing and when I tested the program with admin it worked. Thank you

    – user3725519
    Nov 17 '18 at 22:07







1




1





Run it as a service under the local system account. Of course, one wonders why you feel the need to do this at all.

– David Heffernan
Nov 14 '18 at 18:18





Run it as a service under the local system account. Of course, one wonders why you feel the need to do this at all.

– David Heffernan
Nov 14 '18 at 18:18













you can get token from system process or impersonate system thread, if you have debug privileges. and impersonate some your thread(s) with this system token, when you need do some task as LocalSystem. and anyway - what concrete you need ? some concrete privileges ? be membership of S-1-5-18 or what ?

– RbMm
Nov 14 '18 at 21:14






you can get token from system process or impersonate system thread, if you have debug privileges. and impersonate some your thread(s) with this system token, when you need do some task as LocalSystem. and anyway - what concrete you need ? some concrete privileges ? be membership of S-1-5-18 or what ?

– RbMm
Nov 14 '18 at 21:14














@RbMm I need in my program to load a driver. I am creating and starting a new service for the driver. My program also has GUI so I think I will load the driver with a thread running as system like you said

– user3725519
Nov 17 '18 at 21:45





@RbMm I need in my program to load a driver. I am creating and starting a new service for the driver. My program also has GUI so I think I will load the driver with a thread running as system like you said

– user3725519
Nov 17 '18 at 21:45













but in this case i not understand for what you need run as SYSTEM. for load driver direct, via ZwLoadDriver you need SE_LOAD_DRIVER_PRIVILEGE privilege enabled (it usually have by admins). or if you do this via service manager - for create service you need be member of Administrators. for start already existing service - depend from it security descriptor but usually you also need be member of Administrators. in all case you not need SYSTEM token

– RbMm
Nov 17 '18 at 21:53






but in this case i not understand for what you need run as SYSTEM. for load driver direct, via ZwLoadDriver you need SE_LOAD_DRIVER_PRIVILEGE privilege enabled (it usually have by admins). or if you do this via service manager - for create service you need be member of Administrators. for start already existing service - depend from it security descriptor but usually you also need be member of Administrators. in all case you not need SYSTEM token

– RbMm
Nov 17 '18 at 21:53














@RbMm I have just realized I confused this with some other thing and when I tested the program with admin it worked. Thank you

– user3725519
Nov 17 '18 at 22:07





@RbMm I have just realized I confused this with some other thing and when I tested the program with admin it worked. Thank you

– user3725519
Nov 17 '18 at 22:07












2 Answers
2






active

oldest

votes


















1














Write a windows service. It will run as SYSTEM user by default.



A simple tutorial is here, but remember that installing a service requires administrator privileges.






share|improve this answer






























    0














    Once you're running as administrator, here are some options:




    1. If you know you're not going to be using GUI functions, you can create a scheduled task that runs your same exe as NT AUTHORITYSYSTEM within a few seconds, and check within your code which account the process is running as.



      Copied from a project of mine and slightly modified:



      #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 winsta0default
      // File I/O instead
      HANDLE hLog = CreateFileW(L"C:\Temp\Log.txt", GENERIC_WRITE
      return 0;



    2. Use the Windows Process API to elevate to System. I don't have much in the way of example code for this, but you can look at PAExec, an open source alternative to SysInternals PSExec tool, that allows creating new interactive processes as System.


    3. The idiomatic way of doing this on Windows, which is create a Windows service.






    share|improve this answer






















      Your Answer






      StackExchange.ifUsing("editor", function ()
      StackExchange.using("externalEditor", function ()
      StackExchange.using("snippets", function ()
      StackExchange.snippets.init();
      );
      );
      , "code-snippets");

      StackExchange.ready(function()
      var channelOptions =
      tags: "".split(" "),
      id: "1"
      ;
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function()
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled)
      StackExchange.using("snippets", function()
      createEditor();
      );

      else
      createEditor();

      );

      function createEditor()
      StackExchange.prepareEditor(
      heartbeatType: 'answer',
      autoActivateHeartbeat: false,
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader:
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      ,
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      );



      );













      draft saved

      draft discarded


















      StackExchange.ready(
      function ()
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53306380%2fprogram-escalates-itself-from-admin-to-system%23new-answer', 'question_page');

      );

      Post as a guest















      Required, but never shown

























      2 Answers
      2






      active

      oldest

      votes








      2 Answers
      2






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      1














      Write a windows service. It will run as SYSTEM user by default.



      A simple tutorial is here, but remember that installing a service requires administrator privileges.






      share|improve this answer



























        1














        Write a windows service. It will run as SYSTEM user by default.



        A simple tutorial is here, but remember that installing a service requires administrator privileges.






        share|improve this answer

























          1












          1








          1







          Write a windows service. It will run as SYSTEM user by default.



          A simple tutorial is here, but remember that installing a service requires administrator privileges.






          share|improve this answer













          Write a windows service. It will run as SYSTEM user by default.



          A simple tutorial is here, but remember that installing a service requires administrator privileges.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 14 '18 at 18:21









          AfshinAfshin

          3,0761625




          3,0761625























              0














              Once you're running as administrator, here are some options:




              1. If you know you're not going to be using GUI functions, you can create a scheduled task that runs your same exe as NT AUTHORITYSYSTEM within a few seconds, and check within your code which account the process is running as.



                Copied from a project of mine and slightly modified:



                #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 winsta0default
                // File I/O instead
                HANDLE hLog = CreateFileW(L"C:\Temp\Log.txt", GENERIC_WRITE
                return 0;



              2. Use the Windows Process API to elevate to System. I don't have much in the way of example code for this, but you can look at PAExec, an open source alternative to SysInternals PSExec tool, that allows creating new interactive processes as System.


              3. The idiomatic way of doing this on Windows, which is create a Windows service.






              share|improve this answer



























                0














                Once you're running as administrator, here are some options:




                1. If you know you're not going to be using GUI functions, you can create a scheduled task that runs your same exe as NT AUTHORITYSYSTEM within a few seconds, and check within your code which account the process is running as.



                  Copied from a project of mine and slightly modified:



                  #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 winsta0default
                  // File I/O instead
                  HANDLE hLog = CreateFileW(L"C:\Temp\Log.txt", GENERIC_WRITE
                  return 0;



                2. Use the Windows Process API to elevate to System. I don't have much in the way of example code for this, but you can look at PAExec, an open source alternative to SysInternals PSExec tool, that allows creating new interactive processes as System.


                3. The idiomatic way of doing this on Windows, which is create a Windows service.






                share|improve this answer

























                  0












                  0








                  0







                  Once you're running as administrator, here are some options:




                  1. If you know you're not going to be using GUI functions, you can create a scheduled task that runs your same exe as NT AUTHORITYSYSTEM within a few seconds, and check within your code which account the process is running as.



                    Copied from a project of mine and slightly modified:



                    #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 winsta0default
                    // File I/O instead
                    HANDLE hLog = CreateFileW(L"C:\Temp\Log.txt", GENERIC_WRITE
                    return 0;



                  2. Use the Windows Process API to elevate to System. I don't have much in the way of example code for this, but you can look at PAExec, an open source alternative to SysInternals PSExec tool, that allows creating new interactive processes as System.


                  3. The idiomatic way of doing this on Windows, which is create a Windows service.






                  share|improve this answer













                  Once you're running as administrator, here are some options:




                  1. If you know you're not going to be using GUI functions, you can create a scheduled task that runs your same exe as NT AUTHORITYSYSTEM within a few seconds, and check within your code which account the process is running as.



                    Copied from a project of mine and slightly modified:



                    #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 winsta0default
                    // File I/O instead
                    HANDLE hLog = CreateFileW(L"C:\Temp\Log.txt", GENERIC_WRITE
                    return 0;



                  2. Use the Windows Process API to elevate to System. I don't have much in the way of example code for this, but you can look at PAExec, an open source alternative to SysInternals PSExec tool, that allows creating new interactive processes as System.


                  3. The idiomatic way of doing this on Windows, which is create a Windows service.







                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Nov 14 '18 at 18:58









                  Govind ParmarGovind Parmar

                  11.6k53361




                  11.6k53361



























                      draft saved

                      draft discarded
















































                      Thanks for contributing an answer to Stack Overflow!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid


                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.

                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function ()
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53306380%2fprogram-escalates-itself-from-admin-to-system%23new-answer', 'question_page');

                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      這個網誌中的熱門文章

                      Barbados

                      How to read a connectionString WITH PROVIDER in .NET Core?

                      Node.js Script on GitHub Pages or Amazon S3