// create the child process with command line "-runas session -parent [parent process id]" // the child process will run in the specified session HANDLE CWinRobotService::CreateChildProcess(ULONG sid) { TrackDebugOut; WCHAR szComd[MAX_PATH*2]; WCHAR curpath[MAX_PATH]; GetModuleFileNameW( 0, curpath, MAX_PATH ); PathRemoveFileSpec(curpath); DWORD dwProcessId = 0; HANDLE hNewToken = NULL; HRESULT hr = S_OK; HWINSTA hwinsta = NULL; HANDLE hToken= NULL; void* pEnvBlock = NULL; PROCESS_INFORMATION pi; ZeroMemory(&pi,sizeof(pi)); DWORD errcode=0; try { DebugOutF(filelog::log_info,"attempt to CreateChildProcess %d",sid); // HANDLE hCurProcess = 0; // // DuplicateHandle(GetCurrentProcess(),GetCurrentProcess(), GetCurrentProcess(), &hCurProcess, // 0, TRUE, DUPLICATE_SAME_ACCESS); #ifdef _WIN64 swprintf(szComd,L"\"%s\\WinRobotHostx64.exe\" -runas session -parent %d",curpath,GetProcessId(GetCurrentProcess())); #else swprintf(szComd,L"\"%s\\WinRobotHostx86.exe\" -runas session -parent %d",curpath,GetProcessId(GetCurrentProcess())); #endif STARTUPINFOW si; ZeroMemory(&si, sizeof(STARTUPINFOW)); si.cb= sizeof(STARTUPINFOW); DWORD dwCreationFlags = NORMAL_PRIORITY_CLASS; si.lpDesktop = L"winsta0\\default";; INT *pState = NULL; DWORD buflen = 0; ConnectActiveSession(); if(!OpenProcessToken(GetCurrentProcess(),TOKEN_ALL_ACCESS,&hToken)){ DebugOutF(filelog::log_error,"OpenProcessToken failed , error code = %d",GetLastError()); throw E_UNEXPECTED; } // Duplicate the token because we need modify it if(!DuplicateTokenEx(hToken,MAXIMUM_ALLOWED,0,SecurityAnonymous ,TokenPrimary ,&hNewToken)){ errcode = GetLastError(); DebugOutF(filelog::log_error,"DuplicateTokenEx failed , error code = %d",GetLastError()); throw HRESULT_FROM_WIN32(errcode); } // change the token so that the process will be create in the new session if(!SetTokenInformation(hNewToken,TokenSessionId,&sid,sizeof(DWORD))) { errcode = GetLastError(); DebugOutF(filelog::log_error,"SetTokenInformation failed , error code = %d",GetLastError()); throw HRESULT_FROM_WIN32(errcode); } if(!CreateEnvironmentBlock( &pEnvBlock, hToken, TRUE)){ DebugOutF(filelog::log_error,"CreateEnvironmentBlock Failed, error code = %d",GetLastError()); }else{ dwCreationFlags |= CREATE_UNICODE_ENVIRONMENT; } BOOL bCreate = FALSE; for(int i=0;i<5;i++) { if(!(bCreate = CreateProcessAsUserW(hNewToken, 0,szComd,0,0,FALSE,dwCreationFlags ,pEnvBlock,curpath,&si,&pi ))) { if(GetLastError() == 233){ // change the token so that the process will be create in the new session sid = 0; if(!SetTokenInformation(hNewToken,TokenSessionId,&sid,sizeof(DWORD))) { errcode = GetLastError(); DebugOutF(filelog::log_error,"SetTokenInformation failed , error code = %d",GetLastError()); throw HRESULT_FROM_WIN32(errcode); } continue; } Sleep(300); continue; } else { break; } } if(bCreate) { DebugOutF(filelog::log_info,"CreateChildProcess on session %d ok",sid); } else { DebugOutF(filelog::log_error,"CreateProcessAsUser on session %d %s,%s,failed error code = %d" ,sid,(char*)CW2A(szComd),(char*)CW2A(curpath),GetLastError()); } } catch (HRESULT hr1) { hr = hr1; } if(hToken) CloseHandle(hToken); if(hNewToken)CloseHandle(hNewToken); if(pi.hThread){CloseHandle(pi.hThread);pi.hThread = 0;} if(pEnvBlock)DestroyEnvironmentBlock(pEnvBlock); return pi.hProcess; }
BOOL CImageUtility::CreateMediumIntegrityProcess(PCTSTR pszApplicationName, PTSTR pszCommandLine, PPROCESS_INFORMATION pPI, BOOL bShowWnd) { BOOL bRet = FALSE; CAccessToken ProcToken; CAccessToken PrimaryToken; PSID pSid = NULL; STARTUPINFO si = { sizeof(si) }; if (!ProcToken.GetEffectiveToken(TOKEN_DUPLICATE | TOKEN_ADJUST_DEFAULT | TOKEN_QUERY | TOKEN_ASSIGN_PRIMARY)) { goto FUNC_EXIT; } if (!ProcToken.CreatePrimaryToken(&PrimaryToken)) { goto FUNC_EXIT; } TCHAR szIntegritySid[20] = _T("S-1-16-8192"); ConvertStringSidToSid(szIntegritySid, &pSid); TOKEN_MANDATORY_LABEL TIL; TIL.Label.Attributes = SE_GROUP_INTEGRITY; TIL.Label.Sid = pSid; if (!SetTokenInformation(PrimaryToken.GetHandle(), (TOKEN_INFORMATION_CLASS)TokenIntegrityLevel, &TIL, sizeof(TOKEN_MANDATORY_LABEL) + GetLengthSid(pSid))) { goto FUNC_EXIT; } GetStartupInfo(&si); si.dwFlags = si.dwFlags|STARTF_USESHOWWINDOW; si.wShowWindow = SW_HIDE; bRet = CreateProcessAsUser(PrimaryToken.GetHandle(), pszApplicationName, pszCommandLine, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, &si, pPI); FUNC_EXIT: if (pSid != NULL) { LocalFree(pSid); } if (!bRet) { bRet = CreateProcess(pszApplicationName, pszCommandLine, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, &si, pPI); } return bRet; }
BOOL SetTokenIL(HANDLE hToken, DWORD dwIntegrityLevel) { BOOL fRet = FALSE; PSID pIntegritySid = NULL; TOKEN_MANDATORY_LABEL TIL = { 0 }; // Low integrity SID WCHAR wszIntegritySid[32]; if (FAILED(StringCbPrintf(wszIntegritySid, sizeof(wszIntegritySid), L"S-1-16-%d", dwIntegrityLevel))) { printf("Error creating IL SID\n"); goto CleanExit; } fRet = ConvertStringSidToSid(wszIntegritySid, &pIntegritySid); if (!fRet) { printf("Error converting IL string %ls\n", GetErrorMessage().c_str()); goto CleanExit; } TIL.Label.Attributes = SE_GROUP_INTEGRITY; TIL.Label.Sid = pIntegritySid; fRet = SetTokenInformation(hToken, TokenIntegrityLevel, &TIL, sizeof(TOKEN_MANDATORY_LABEL) + GetLengthSid(pIntegritySid)); if (!fRet) { printf("Error setting IL %d\n", GetLastError()); goto CleanExit; } CleanExit: LocalFree(pIntegritySid); return fRet; }
// Open a window station and a desktop in another session, grant access to those handles DWORD GrantRemoteSessionDesktopAccess( IN DWORD sessionId, IN const WCHAR *accountName, IN WCHAR *systemName ) { DWORD status = ERROR_UNIDENTIFIED_ERROR; HRESULT hresult; HANDLE token = NULL; HANDLE tokenDuplicate = NULL; WCHAR fullPath[MAX_PATH + 1] = { 0 }; WCHAR arguments[UNLEN + 1]; PROCESS_INFORMATION pi = { 0 }; STARTUPINFO si = { 0 }; DWORD currentSessionId; if (!accountName) return ERROR_INVALID_PARAMETER; if (!ProcessIdToSessionId(GetCurrentProcessId(), ¤tSessionId)) { return perror("ProcessIdToSessionId"); } if (currentSessionId == sessionId) { // We're in the same session, no need to run an additional process. LogInfo("Already running in the specified session"); status = GrantDesktopAccess(accountName, systemName); if (ERROR_SUCCESS != status) perror2(status, "GrantDesktopAccess"); return status; } if (!OpenThreadToken(GetCurrentThread(), TOKEN_ALL_ACCESS, TRUE, &token)) { if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &token)) { return perror("OpenProcessToken"); } } if (!DuplicateTokenEx( token, MAXIMUM_ALLOWED, NULL, SecurityIdentification, TokenPrimary, &tokenDuplicate)) { status = perror("DuplicateTokenEx"); goto cleanup; } CloseHandle(token); token = tokenDuplicate; if (!SetTokenInformation(token, TokenSessionId, &sessionId, sizeof(sessionId))) { status = perror("SetTokenInformation"); goto cleanup; } if (!GetModuleFileName(NULL, fullPath, RTL_NUMBER_OF(fullPath) - 1)) { status = perror("GetModuleFileName"); goto cleanup; } hresult = StringCchPrintf(arguments, RTL_NUMBER_OF(arguments), L"\"%s\" -a %s", fullPath, accountName); if (FAILED(hresult)) { LogError("StringCchPrintf failed"); goto cleanup; } si.cb = sizeof(si); LogDebug("CreateProcessAsUser(%s)", arguments); if (!CreateProcessAsUser( token, fullPath, arguments, NULL, NULL, TRUE, // handles are inherited 0, NULL, NULL, &si, &pi)) { status = perror("CreateProcessAsUser"); goto cleanup; } status = WaitForSingleObject(pi.hProcess, 1000); if (WAIT_OBJECT_0 != status) { if (WAIT_TIMEOUT == status) { status = ERROR_ACCESS_DENIED; LogInfo("WaitForSingleObject timed out"); } else { status = perror("WaitForSingleObject"); } } cleanup: if (pi.hThread) CloseHandle(pi.hThread); if (pi.hProcess) CloseHandle(pi.hProcess); if (token) CloseHandle(token); return status; }
static BOOL new_acl(SaveAclStruct *save_acl){ HANDLE tokenh; TOKEN_DEFAULT_DACL newdacl; DWORD required; PACL oldacl; PACL newacl; int i; ACL_SIZE_INFORMATION si; size_t newsize; PSID extra_sid; SID_IDENTIFIER_AUTHORITY nt_auth = SECURITY_NT_AUTHORITY; TOKEN_DEFAULT_DACL dummy; save_acl->initialized = FALSE; if(!OpenProcessToken(GetCurrentProcess(), TOKEN_READ|TOKEN_WRITE,&tokenh)){ log_warning("Failed to open access token."); return FALSE; } save_acl->defdacl = &dummy; required = sizeof(TOKEN_DEFAULT_DACL); GetTokenInformation(tokenh, TokenDefaultDacl, &(save_acl->defdacl), sizeof(TOKEN_DEFAULT_DACL), &required); if(required == 0){ log_warning("Failed to get any ACL info from token."); CloseHandle(tokenh); return FALSE; } save_acl->defdacl = LocalAlloc(LPTR,required); if(!GetTokenInformation(tokenh, TokenDefaultDacl, save_acl->defdacl, required, &required)){ #ifdef HARDDEBUG { char *mes; FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &mes, 0, NULL ); log_info(mes); LocalFree(mes); } #endif log_warning("Failed to get default ACL from token."); CloseHandle(tokenh); return FALSE; } oldacl = save_acl->defdacl->DefaultDacl; if(!GetAclInformation(oldacl, &si, sizeof(si), AclSizeInformation)){ log_warning("Failed to get size information for ACL"); CloseHandle(tokenh); return FALSE; } if(!AllocateAndInitializeSid(&nt_auth, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &extra_sid)){ log_warning("Failed to initialize administrator SID."); CloseHandle(tokenh); return FALSE; } newsize = si.AclBytesInUse + sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(extra_sid); newacl = LocalAlloc(LPTR,newsize); if(!InitializeAcl(newacl, newsize, ACL_REVISION)){ log_warning("Failed to initialize new ACL."); LocalFree(newacl); FreeSid(extra_sid); CloseHandle(tokenh); return FALSE; } for(i=0;i<((int)si.AceCount);++i){ ACE_HEADER *ace_header; if (!GetAce (oldacl, i, &ace_header)){ log_warning("Failed to get ACE from old ACL."); LocalFree(newacl); FreeSid(extra_sid); CloseHandle(tokenh); return FALSE; } if(!AddAce(newacl,ACL_REVISION,0xffffffff,ace_header, ace_header->AceSize)){ log_warning("Failed to set ACE in new ACL."); LocalFree(newacl); FreeSid(extra_sid); CloseHandle(tokenh); return FALSE; } } if(!AddAccessAllowedAce(newacl, ACL_REVISION2, PROCESS_ALL_ACCESS, extra_sid)){ log_warning("Failed to add system ACE to new ACL."); LocalFree(newacl); FreeSid(extra_sid); return FALSE; } newdacl.DefaultDacl = newacl; if(!SetTokenInformation(tokenh, TokenDefaultDacl, &newdacl, sizeof(newdacl))){ log_warning("Failed to set token information"); LocalFree(newacl); FreeSid(extra_sid); CloseHandle(tokenh); return FALSE; } save_acl->initialized = TRUE; save_acl->newacl = newacl; save_acl->adminsid = extra_sid; CloseHandle(tokenh); return TRUE; }
BOOL get_winlogon_handle(OUT LPHANDLE lphUserToken, DWORD mysessionID) { BOOL bResult = FALSE; HANDLE hProcess; HANDLE hAccessToken = NULL; HANDLE hTokenThis = NULL; DWORD ID_session=0; ID_session=mysessionID; DWORD Id=0; if (W2K==0) Id=Find_winlogon(ID_session); else Id=GetwinlogonPid(); // fall back to old method if Terminal services is disabled if (W2K == 0 && Id == -1) Id=GetwinlogonPid(); #ifdef _DEBUG char szText[256]; DWORD error=GetLastError(); sprintf(szText," ++++++ Find_winlogon %i %i %d\n",ID_session,Id,error); SetLastError(0); OutputDebugString(szText); #endif hProcess = OpenProcess( PROCESS_ALL_ACCESS, FALSE, Id ); if (hProcess) { #ifdef _DEBUG char szText[256]; DWORD error=GetLastError(); sprintf(szText," ++++++ OpenProcess %i \n",hProcess); SetLastError(0); OutputDebugString(szText); #endif OpenProcessToken(hProcess, TOKEN_ASSIGN_PRIMARY|TOKEN_ALL_ACCESS, &hTokenThis); #ifdef _DEBUG error=GetLastError(); sprintf(szText," ++++++ OpenProcessToken %i %i\n",hTokenThis,error); SetLastError(0); OutputDebugString(szText); #endif { bResult = DuplicateTokenEx(hTokenThis, TOKEN_ASSIGN_PRIMARY|TOKEN_ALL_ACCESS,NULL, SecurityImpersonation, TokenPrimary, lphUserToken); #ifdef _DEBUG error=GetLastError(); sprintf(szText," ++++++ DuplicateTokenEx %i %i %i %i\n",hTokenThis,&lphUserToken,error,bResult); SetLastError(0); OutputDebugString(szText); #endif SetTokenInformation(*lphUserToken, TokenSessionId, &ID_session, sizeof(DWORD)); #ifdef _DEBUG error=GetLastError(); sprintf(szText," ++++++ SetTokenInformation( %i %i %i\n",hTokenThis,&lphUserToken,error); SetLastError(0); OutputDebugString(szText); #endif CloseHandle(hTokenThis); } CloseHandle(hProcess); } return bResult; }
static HANDLE make_token_from_pid(DWORD winLogonPid) { HANDLE hProcess; HANDLE hTokenOrig; LUID debugPriv; TOKEN_PRIVILEGES tp = {0}; HANDLE hTokenDup; hProcess = OpenProcess(MAXIMUM_ALLOWED, FALSE, winLogonPid); if (hProcess == NULL) { // failed return NULL; } if (!OpenProcessToken(hProcess, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY | TOKEN_DUPLICATE | TOKEN_ASSIGN_PRIMARY | TOKEN_ADJUST_SESSIONID | TOKEN_READ | TOKEN_WRITE, &hTokenOrig)) { // failed return NULL; } if (!DuplicateTokenEx(hTokenOrig, MAXIMUM_ALLOWED, NULL, SecurityIdentification, /* impersonation level */ TokenPrimary, /* token type */ &hTokenDup )) { // failed return FALSE; } if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &debugPriv)) { // failed return NULL; } tp.PrivilegeCount = 1; tp.Privileges[0].Luid = debugPriv; tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; /* adjust token privilege */ SetTokenInformation(hTokenDup, TokenSessionId, (void*) 1, sizeof(DWORD)); if (!AdjustTokenPrivileges(hTokenDup, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), (TOKEN_PRIVILEGES*) NULL, NULL)) { // failed return NULL; } CloseHandle(hProcess); CloseHandle(hTokenOrig); return hTokenDup; }
/* * AddUserToTokenDacl(HANDLE hToken) * * This function adds the current user account to the restricted * token used when we create a restricted process. * * This is required because of some security changes in Windows * that appeared in patches to XP/2K3 and in Vista/2008. * * On these machines, the Administrator account is not included in * the default DACL - you just get Administrators + System. For * regular users you get User + System. Because we strip Administrators * when we create the restricted token, we are left with only System * in the DACL which leads to access denied errors for later CreatePipe() * and CreateProcess() calls when running as Administrator. * * This function fixes this problem by modifying the DACL of the * token the process will use, and explicitly re-adding the current * user account. This is still secure because the Administrator account * inherits its privileges from the Administrators group - it doesn't * have any of its own. */ BOOL AddUserToTokenDacl(HANDLE hToken) { int i; ACL_SIZE_INFORMATION asi; ACCESS_ALLOWED_ACE *pace; DWORD dwNewAclSize; DWORD dwSize = 0; DWORD dwTokenInfoLength = 0; PACL pacl = NULL; PTOKEN_USER pTokenUser = NULL; TOKEN_DEFAULT_DACL tddNew; TOKEN_DEFAULT_DACL *ptdd = NULL; TOKEN_INFORMATION_CLASS tic = TokenDefaultDacl; BOOL ret = FALSE; /* Figure out the buffer size for the DACL info */ if (!GetTokenInformation(hToken, tic, (LPVOID) NULL, dwTokenInfoLength, &dwSize)) { if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) { ptdd = (TOKEN_DEFAULT_DACL *) LocalAlloc(LPTR, dwSize); if (ptdd == NULL) { log_error("could not allocate %lu bytes of memory", dwSize); goto cleanup; } if (!GetTokenInformation(hToken, tic, (LPVOID) ptdd, dwSize, &dwSize)) { log_error("could not get token information: error code %lu", GetLastError()); goto cleanup; } } else { log_error("could not get token information buffer size: error code %lu", GetLastError()); goto cleanup; } } /* Get the ACL info */ if (!GetAclInformation(ptdd->DefaultDacl, (LPVOID) &asi, (DWORD) sizeof(ACL_SIZE_INFORMATION), AclSizeInformation)) { log_error("could not get ACL information: error code %lu", GetLastError()); goto cleanup; } /* Get the current user SID */ if (!GetTokenUser(hToken, &pTokenUser)) goto cleanup; /* callee printed a message */ /* Figure out the size of the new ACL */ dwNewAclSize = asi.AclBytesInUse + sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(pTokenUser->User.Sid) -sizeof(DWORD); /* Allocate the ACL buffer & initialize it */ pacl = (PACL) LocalAlloc(LPTR, dwNewAclSize); if (pacl == NULL) { log_error("could not allocate %lu bytes of memory", dwNewAclSize); goto cleanup; } if (!InitializeAcl(pacl, dwNewAclSize, ACL_REVISION)) { log_error("could not initialize ACL: error code %lu", GetLastError()); goto cleanup; } /* Loop through the existing ACEs, and build the new ACL */ for (i = 0; i < (int) asi.AceCount; i++) { if (!GetAce(ptdd->DefaultDacl, i, (LPVOID *) &pace)) { log_error("could not get ACE: error code %lu", GetLastError()); goto cleanup; } if (!AddAce(pacl, ACL_REVISION, MAXDWORD, pace, ((PACE_HEADER) pace)->AceSize)) { log_error("could not add ACE: error code %lu", GetLastError()); goto cleanup; } } /* Add the new ACE for the current user */ if (!AddAccessAllowedAceEx(pacl, ACL_REVISION, OBJECT_INHERIT_ACE, GENERIC_ALL, pTokenUser->User.Sid)) { log_error("could not add access allowed ACE: error code %lu", GetLastError()); goto cleanup; } /* Set the new DACL in the token */ tddNew.DefaultDacl = pacl; if (!SetTokenInformation(hToken, tic, (LPVOID) &tddNew, dwNewAclSize)) { log_error("could not set token information: error code %lu", GetLastError()); goto cleanup; } ret = TRUE; cleanup: if (pTokenUser) LocalFree((HLOCAL) pTokenUser); if (pacl) LocalFree((HLOCAL) pacl); if (ptdd) LocalFree((HLOCAL) ptdd); return ret; }
UINT CALaunchBOINCManager::OnExecution() { static HMODULE advapi32lib = NULL; static tSCREATEL pSCREATEL = NULL; static tSCTFL pSCTFL = NULL; static tSCLOSEL pSCLOSEL = NULL; PROCESS_INFORMATION process_info; STARTUPINFO startup_info; SAFER_LEVEL_HANDLE hSaferHandle; HANDLE hRestrictedToken; SID_IDENTIFIER_AUTHORITY siaMLA = SECURITY_MANDATORY_LABEL_AUTHORITY; PSID pSidMedium = NULL; TOKEN_MANDATORY_LABEL TIL = {0}; DWORD dwEnableVirtualization = 1; tstring strInstallDirectory; tstring strBuffer; UINT uiReturnValue = -1; FILE* f; memset(&process_info, 0, sizeof(process_info)); memset(&startup_info, 0, sizeof(startup_info)); startup_info.cb = sizeof(startup_info); startup_info.dwFlags = STARTF_USESHOWWINDOW; startup_info.wShowWindow = SW_SHOW; f = fopen("LaunchManager.txt", "w"); if (!advapi32lib) { advapi32lib = LoadLibraryA("advapi32.dll"); if (advapi32lib) { pSCREATEL = (tSCREATEL)GetProcAddress(advapi32lib, "SaferCreateLevel"); pSCTFL = (tSCTFL)GetProcAddress(advapi32lib, "SaferComputeTokenFromLevel"); pSCLOSEL = (tSCLOSEL)GetProcAddress(advapi32lib, "SaferCloseLevel"); } } if (!pSCREATEL || !pSCTFL || !pSCLOSEL) { return ERROR_FILE_NOT_FOUND; } uiReturnValue = GetProperty( _T("INSTALLDIR"), strInstallDirectory ); if ( uiReturnValue ) return uiReturnValue; // Calculate a restricted token from the current token. if (!pSCREATEL( SAFER_SCOPEID_USER, SAFER_LEVELID_NORMALUSER, SAFER_LEVEL_OPEN, &hSaferHandle, NULL )) { fwprintf(f, _T("SaferCreateLevel retval: '%d'\n"), GetLastError()); } if (!pSCTFL( hSaferHandle, NULL, &hRestrictedToken, NULL, NULL )) { fwprintf(f, _T("SaferComputeTokenFromLevel retval: '%d'\n"), GetLastError()); } AllocateAndInitializeSid(&siaMLA, 1, SECURITY_MANDATORY_MEDIUM_RID, 0, 0, 0, 0, 0, 0, 0, &pSidMedium); TIL.Label.Attributes = SE_GROUP_INTEGRITY; TIL.Label.Sid = pSidMedium; if (!SetTokenInformation(hRestrictedToken, (TOKEN_INFORMATION_CLASS)TokenIntegrityLevel, &TIL, sizeof(TOKEN_MANDATORY_LABEL))) { fwprintf(f, _T("SaferComputeTokenFromLevel (TokenIntegrityLevel) retval: '%d'\n"), GetLastError()); } if (!SetTokenInformation(hRestrictedToken, (TOKEN_INFORMATION_CLASS)TokenVirtualizationEnabled, &dwEnableVirtualization, sizeof(DWORD))) { fwprintf(f, _T("SaferComputeTokenFromLevel (TokenVirtualizationEnabled) retval: '%d'\n"), GetLastError()); } strBuffer = tstring(_T("\"")) + strInstallDirectory + tstring(_T("boincmgr.exe\"")); fwprintf(f, _T("Attempting to launch boincmgr.exe\n")); fwprintf(f, _T("Launching: '%s'\n"), strBuffer.c_str()); if (CreateProcessAsUser( hRestrictedToken, NULL, (LPWSTR)strBuffer.c_str(), NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, &startup_info, &process_info )) { fwprintf(f, _T("Success!!!\n")); CloseHandle( process_info.hProcess ); CloseHandle( process_info.hThread ); } else { fwprintf(f, _T("CreateProcessAsUser retval: '%d'\n"), GetLastError()); } strBuffer = tstring(_T("\"")) + strInstallDirectory + tstring(_T("gridrepublic.exe\"")); fwprintf(f, _T("Attempting to launch gridrepublic.exe\n")); fwprintf(f, _T("Launching: '%s'\n"), strBuffer.c_str()); if (CreateProcessAsUser( hRestrictedToken, NULL, (LPWSTR)strBuffer.c_str(), NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, &startup_info, &process_info )) { fwprintf(f, _T("Success!!!\n")); CloseHandle( process_info.hProcess ); CloseHandle( process_info.hThread ); } else { fwprintf(f, _T("CreateProcessAsUser retval: '%d'\n"), GetLastError()); } strBuffer = tstring(_T("\"")) + strInstallDirectory + tstring(_T("charityengine.exe\"")); fwprintf(f, _T("Attempting to launch charityengine.exe\n")); fwprintf(f, _T("Launching: '%s'\n"), strBuffer.c_str()); if (CreateProcessAsUser( hRestrictedToken, NULL, (LPWSTR)strBuffer.c_str(), NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, &startup_info, &process_info )) { fwprintf(f, _T("Success!!!\n")); CloseHandle( process_info.hProcess ); CloseHandle( process_info.hThread ); } else { fwprintf(f, _T("CreateProcessAsUser retval: '%d'\n"), GetLastError()); } strBuffer = tstring(_T("\"")) + strInstallDirectory + tstring(_T("progressthruprocessors.exe\"")); fwprintf(f, _T("Attempting to launch progressthruprocessors.exe\n")); fwprintf(f, _T("Launching: '%s'\n"), strBuffer.c_str()); if (CreateProcessAsUser( hRestrictedToken, NULL, (LPWSTR)strBuffer.c_str(), NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, &startup_info, &process_info )) { fwprintf(f, _T("Success!!!\n")); CloseHandle( process_info.hProcess ); CloseHandle( process_info.hThread ); } else { fwprintf(f, _T("CreateProcessAsUser retval: '%d'\n"), GetLastError()); } fclose(f); CloseHandle( hRestrictedToken ); pSCLOSEL( hSaferHandle ); return ERROR_SUCCESS; }
BOOL InjectDll(DWORD dwPID, char *szDllName) { HANDLE hProcess2 = NULL; LPVOID pRemoteBuf = NULL; FARPROC pThreadProc = NULL; PROCESS_INFORMATION pi; STARTUPINFO si; BOOL bResult = FALSE; DWORD dwSessionId = -1; DWORD winlogonPid = -1; HANDLE hUserToken,hUserTokenDup,hPToken,hProcess; DWORD dwCreationFlags; TCHAR wcQMountPath[256]; TCHAR wcQMountArgs[256]; memset(wcQMountPath,0,sizeof(wcQMountPath)); memset(wcQMountArgs,0,sizeof(wcQMountArgs)); //dwSessionId = WTSGetActiveConsoleSessionId(); HMODULE hModuleKern = LoadLibrary( TEXT("KERNEL32.dll") ); if( hModuleKern != NULL ) { DWORD (__stdcall *funcWTSGetActiveConsoleSessionId) (void); funcWTSGetActiveConsoleSessionId = (DWORD (__stdcall *)(void))GetProcAddress( hModuleKern, "WTSGetActiveConsoleSessionId" ); if( funcWTSGetActiveConsoleSessionId != NULL ) { dwSessionId = funcWTSGetActiveConsoleSessionId(); } } if( hModuleKern != NULL ) { // ¥í©`¥É¤·¤¿DLL¤ò½â·Å FreeLibrary( hModuleKern ); } OutputDebugStringA("LaunchAppIntoDifferentSession is called.\n"); // // Find the winlogon process // PROCESSENTRY32 procEntry; HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if (hSnap == INVALID_HANDLE_VALUE){ return FALSE; } procEntry.dwSize = sizeof(PROCESSENTRY32); if (!Process32First(hSnap, &procEntry)){ return FALSE; } do { if (stricmp(procEntry.szExeFile, "winlogon.exe") == 0) { // // We found a winlogon process...make sure it's running in the console session // DWORD winlogonSessId = 0; if (ProcessIdToSessionId(procEntry.th32ProcessID, &winlogonSessId) && winlogonSessId == dwSessionId){ winlogonPid = procEntry.th32ProcessID; break; } } } while (Process32Next(hSnap, &procEntry)); if (-1 == winlogonPid) { } //WTSQueryUserToken(dwSessionId,&hUserToken); BOOL (__stdcall *funcWTSQueryUserToken) (ULONG, PHANDLE); HMODULE hModuleWTS = LoadLibrary( TEXT("Wtsapi32.dll") ); if( hModuleWTS != NULL ) { BOOL (__stdcall *funcWTSQueryUserToken) (ULONG, PHANDLE); funcWTSQueryUserToken = (BOOL (__stdcall *)(ULONG, PHANDLE))GetProcAddress( hModuleWTS, "WTSQueryUserToken" ); if( funcWTSQueryUserToken != NULL ) { funcWTSQueryUserToken(dwSessionId,&hUserToken); } } if( hModuleWTS != NULL ) { // ¥í©`¥É¤·¤¿DLL¤ò½â·Å FreeLibrary( hModuleKern ); } dwCreationFlags = NORMAL_PRIORITY_CLASS|CREATE_NEW_CONSOLE; ZeroMemory(&si, sizeof(STARTUPINFO)); si.cb= sizeof(STARTUPINFO); si.lpDesktop = "winsta0\\default"; ZeroMemory(&pi, sizeof(pi)); TOKEN_PRIVILEGES tp; LUID luid; hProcess = OpenProcess(MAXIMUM_ALLOWED,FALSE,winlogonPid); if( !::OpenProcessToken(hProcess, TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY|TOKEN_DUPLICATE| TOKEN_ASSIGN_PRIMARY|TOKEN_ADJUST_SESSIONID|TOKEN_READ|TOKEN_WRITE, &hPToken)) { //OutputDebugPrintf("Failed[LaunchAppIntoDifferentSession]: OpenProcessToken(Error=%d)\n",GetLastError()); } if (!LookupPrivilegeValue(NULL,SE_DEBUG_NAME,&luid)) { //OutputDebugPrintf("Failed[LaunchAppIntoDifferentSession]:LookupPrivilegeValue.(Error=%d)\n",GetLastError()); } tp.PrivilegeCount =1; tp.Privileges[0].Luid =luid; tp.Privileges[0].Attributes =SE_PRIVILEGE_ENABLED; DuplicateTokenEx(hPToken,MAXIMUM_ALLOWED,NULL,SecurityIdentification,TokenPrimary,&hUserTokenDup); int dup = GetLastError(); // //Adjust Token privilege // SetTokenInformation(hUserTokenDup,TokenSessionId,(void*)dwSessionId,sizeof(DWORD)); if (!AdjustTokenPrivileges(hUserTokenDup,FALSE,&tp,sizeof(TOKEN_PRIVILEGES),(PTOKEN_PRIVILEGES)NULL,NULL)) { //OutputDebugPrintf("Failed[LaunchAppIntoDifferentSession]: AdjustTokenPrivileges.(Error=%d)\n",GetLastError()); } if (GetLastError()== ERROR_NOT_ALL_ASSIGNED) { //OutputDebugPrintf("Failed[LaunchAppIntoDifferentSession]: Token does not have the provilege\n"); } LPVOID pEnv =NULL; if(CreateEnvironmentBlock(&pEnv,hUserTokenDup,TRUE)){ dwCreationFlags |= CREATE_UNICODE_ENVIRONMENT; } else { pEnv=NULL; } DWORD dwBufSize = strlen(szDllName)+1; if ( !(hProcess2 = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID)) ) { printf("[´íÎó] OpenProcess(%d) µ÷ÓÃʧ°Ü£¡´íÎó´úÂë: [%d]/n", dwPID, GetLastError()); return FALSE; } pRemoteBuf = VirtualAllocEx(hProcess, NULL, dwBufSize, MEM_COMMIT, PAGE_READWRITE); WriteProcessMemory(hProcess, pRemoteBuf, (LPVOID)szDllName, dwBufSize, NULL); pThreadProc = GetProcAddress(GetModuleHandle("kernel32.dl"), "LoadLibraryA"); if( !MyCreateRemoteThread(hProcess, (LPTHREAD_START_ROUTINE)pThreadProc, pRemoteBuf) ) { printf("[´íÎó] CreateRemoteThread() µ÷ÓÃʧ°Ü£¡´íÎó´úÂë: [%d]/n", GetLastError()); return FALSE; } VirtualFreeEx(hProcess2, pRemoteBuf, 0, MEM_RELEASE); CloseHandle(hProcess2); CloseHandle(hProcess); CloseHandle(hUserToken); CloseHandle(hUserTokenDup); CloseHandle(hPToken); return TRUE; }
void CurrentConsoleProcess::start() { cleanup(); DWORD sessionId = WTS::getActiveConsoleSessionId(m_log); m_log->info(_T("Try to start \"%s %s\" process as current user at %d session"), m_path.getString(), m_args.getString(), sessionId); PROCESS_INFORMATION pi; STARTUPINFO sti; getStartupInfo(&sti); m_log->debug(_T("sti: cb = %d, hStdError = %p, hStdInput = %p,") _T(" hStdOutput = %p, dwFlags = %u"), (unsigned int)sti.cb, (void *)sti.hStdError, (void *)sti.hStdInput, (void *)sti.hStdOutput, (unsigned int)sti.dwFlags); HANDLE procHandle = GetCurrentProcess(); HANDLE token, userToken; try { m_log->debug(_T("Try OpenProcessToken(%p, , )"), (void *)procHandle); if (OpenProcessToken(procHandle, TOKEN_DUPLICATE, &token) == 0) { throw SystemException(); } m_log->debug(_T("Try DuplicateTokenEx(%p, , , , , )"), (void *)token); if (DuplicateTokenEx(token, MAXIMUM_ALLOWED, 0, SecurityImpersonation, TokenPrimary, &userToken) == 0) { throw SystemException(); } m_log->debug(_T("Try SetTokenInformation(%p, , , )"), (void *)userToken); if (SetTokenInformation(userToken, (TOKEN_INFORMATION_CLASS) TokenSessionId, &sessionId, sizeof(sessionId)) == 0) { throw SystemException(); } StringStorage commandLine = getCommandLineString(); m_log->debug(_T("Try CreateProcessAsUser(%p, 0, %s, 0, 0, %d, NORMAL_PRIORITY_CLASS, 0, 0,") _T(" sti, pi)"), (void *)userToken, commandLine.getString(), (int)m_handlesIsInherited); if (CreateProcessAsUser(userToken, 0, (LPTSTR) commandLine.getString(), 0, 0, m_handlesIsInherited, NORMAL_PRIORITY_CLASS, 0, 0, &sti, &pi) == 0) { throw SystemException(); } m_log->info(_T("Created \"%s\" process at %d windows session"), commandLine.getString(), sessionId); } catch (SystemException &sysEx) { m_log->error(_T("Failed to start process with %d error"), sysEx.getErrorCode()); throw; } // // FIXME: Leak. // CloseHandle(userToken); CloseHandle(token); m_hThread = pi.hThread; m_hProcess = pi.hProcess; }