Ejemplo n.º 1
0
BOOL My_CreateProcessAsUserA()
{
	HANDLE hToken=NULL;
	LPCSTR lpApplicationName=NULL;
	LPSTR lpCommandLine=NULL;
	LPSECURITY_ATTRIBUTES lpProcessAttributes=NULL;
	LPSECURITY_ATTRIBUTES lpThreadAttributes=NULL;
	BOOL bInheritHandles=NULL;
	DWORD dwCreationFlags=NULL;
	LPVOID lpEnvironment=NULL;
	LPCSTR lpCurrentDirectory=NULL;
	LPSTARTUPINFOA lpStartupInfo=NULL;
	LPPROCESS_INFORMATION lpProcessInformation=NULL;
	BOOL returnVal_Real = NULL;
	BOOL returnVal_Intercepted = NULL;

	DWORD error_Real = 0;
	DWORD error_Intercepted = 0;
	__try{
	disableInterception();
	returnVal_Real = CreateProcessAsUserA (hToken,lpApplicationName,lpCommandLine,lpProcessAttributes,lpThreadAttributes,bInheritHandles,dwCreationFlags,lpEnvironment,lpCurrentDirectory,lpStartupInfo,lpProcessInformation);
	error_Real = GetLastError();
	enableInterception();
	returnVal_Intercepted = CreateProcessAsUserA (hToken,lpApplicationName,lpCommandLine,lpProcessAttributes,lpThreadAttributes,bInheritHandles,dwCreationFlags,lpEnvironment,lpCurrentDirectory,lpStartupInfo,lpProcessInformation);
	error_Intercepted = GetLastError();
	}__except(puts("in filter"), 1){puts("exception caught");}
	return ((returnVal_Real == returnVal_Intercepted) && (error_Real == error_Intercepted));
}
Ejemplo n.º 2
0
int pacifica_switch_process_user(char *user, char *pw, char *program)
{
	DWORD len;
	HANDLE token;
	PROCESS_INFORMATION pi;
	STARTUPINFOA si;
	memset(&si, 0, sizeof(STARTUPINFO));
	si.cb = sizeof(STARTUPINFO);
	si.lpDesktop = "";
//FIXME Still need to pull this out of storage somehow...
	int res = LogonUserA(user, ".", pw, LOGON32_LOGON_SERVICE, LOGON32_PROVIDER_DEFAULT, &token);
	if(res == 0)
	{
		return GetLastError();
	}
	res = CreateProcessAsUserA(token, NULL, program, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi);
	if(res == 0)
	{
		return GetLastError();
	}
	res = WaitForSingleObject(pi.hProcess, INFINITE);
	if(res == 0)
	{
		return GetLastError();
	}
	res = GetExitCodeProcess(pi.hProcess, &len);
	if(res == 0)
	{
		return GetLastError();
	}
	return 0;
}
/* good1() uses if(5!=5) instead of if(5==5) */
static void good1()
{
    if(5!=5)
    {
        /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */
        printLine("Benign, fixed string");
    }
    else
    {
        {
            STARTUPINFOA si;
            PROCESS_INFORMATION pi;
            HANDLE pHandle = NULL;
            /* FIX: The commandLine parameter to CreateProcessAsUser() contains quotes surrounding
               the executable path. */
            if(!CreateProcessAsUserA(pHandle,
                                     NULL,
                                     "\"C:\\Program Files\\GoodApp\" arg1 arg2",
                                     NULL,
                                     NULL,
                                     FALSE,
                                     DETACHED_PROCESS,
                                     NULL,
                                     NULL,
                                     &si,
                                     &pi))
            {
                printLine("CreateProcessAsUser failed");
                RevertToSelf();
                CloseHandle(pHandle);
                return;
            }
            else
            {
                printLine("CreateProcessAUser successful");
            }
            /* Wait until child process exits. */
            WaitForSingleObject(pi.hProcess, INFINITE);
            /* Close process and thread handles.*/
            CloseHandle(pi.hProcess);
            CloseHandle(pi.hThread);
            CloseHandle(pHandle);
        }
    }
}
void CWE272_Least_Privilege_Violation__w32_char_CreateProcessAsUser_03_bad()
{
    if(5==5)
    {
        {
            STARTUPINFOA si;
            PROCESS_INFORMATION pi;
            HANDLE pHandle = NULL;
            /* FLAW: The commandLine parameter to CreateProcessAsUser() contains a space in it and does not
               surround the executable path with quotes.  A malicious executable could be run because of the
               way the function parses spaces. The process will attempt to run "Program.exe," if it exists,
               instead of the intended "GoodApp.exe"  */
            if(!CreateProcessAsUserA(pHandle,
                                     NULL,
                                     "C:\\Program Files\\GoodApp arg1 arg2",
                                     NULL,
                                     NULL,
                                     FALSE,
                                     DETACHED_PROCESS,
                                     NULL,
                                     NULL,
                                     &si,
                                     &pi))
            {
                printLine("CreateProcessAsUser failed");
                RevertToSelf();
                CloseHandle(pHandle);
                return;
            }
            else
            {
                printLine("CreateProcessAUser successful");
            }
            /* Wait until child process exits. */
            WaitForSingleObject(pi.hProcess, INFINITE);
            /* Close process and thread handles.*/
            CloseHandle(pi.hProcess);
            CloseHandle(pi.hThread);
            CloseHandle(pHandle);
        }
    }
}
Ejemplo n.º 5
0
static BOOL WINAPI
MyCreateProcessAsUserA(HANDLE hToken,
                       LPCSTR lpApplicationName,
                       LPSTR lpCommandLine,
                       LPSECURITY_ATTRIBUTES lpProcessAttributes,
                       LPSECURITY_ATTRIBUTES lpThreadAttributes,
                       BOOL bInheritHandles,
                       DWORD dwCreationFlags,
                       LPVOID lpEnvironment,
                       LPCSTR lpCurrentDirectory,
                       LPSTARTUPINFOA lpStartupInfo,
                       LPPROCESS_INFORMATION lpProcessInformation)
{
    if (VERBOSITY >= 2) {
        debugPrintf("inject: intercepting %s(\"%s\", \"%s\", ...)\n",
                    __FUNCTION__,
                    lpApplicationName,
                    lpCommandLine);
    }

    BOOL bRet;
    bRet = CreateProcessAsUserA(hToken,
                               lpApplicationName,
                               lpCommandLine,
                               lpProcessAttributes,
                               lpThreadAttributes,
                               bInheritHandles,
                               dwCreationFlags,
                               lpEnvironment,
                               lpCurrentDirectory,
                               lpStartupInfo,
                               lpProcessInformation);

    MyCreateProcessCommon(bRet, dwCreationFlags, lpProcessInformation);

    return bRet;
}
Ejemplo n.º 6
0
static int
CreateRestrictedProcess(char *command, PROCESS_INFORMATION *processInfo, bool as_service)
{
	int				r;
	BOOL			b;
	STARTUPINFOA	si;
	HANDLE			origToken;
	HANDLE			restrictedToken;
	SID_IDENTIFIER_AUTHORITY NtAuthority = {SECURITY_NT_AUTHORITY};
	SID_AND_ATTRIBUTES dropSids[2];

	/* Functions loaded dynamically */
	__CreateRestrictedToken _CreateRestrictedToken = NULL;
	__IsProcessInJob _IsProcessInJob = NULL;
	__CreateJobObjectA _CreateJobObject = NULL;
	__SetInformationJobObject _SetInformationJobObject = NULL;
	__AssignProcessToJobObject _AssignProcessToJobObject = NULL;
	__QueryInformationJobObject _QueryInformationJobObject = NULL;
	HANDLE		Kernel32Handle;
	HANDLE		Advapi32Handle;

    SECURITY_ATTRIBUTES	sa = {0};
    HANDLE				hRead, hWrite;

	/* create unnamed pipes */
    sa.lpSecurityDescriptor = NULL;
    sa.nLength = sizeof(SECURITY_ATTRIBUTES);
    sa.bInheritHandle = TRUE;
    if (!CreatePipe(&hRead, &hWrite, &sa, 0))
		elog(ERROR, "cannot create pipes");

	DuplicateHandle(GetCurrentProcess(), hWrite,
					GetCurrentProcess(), NULL,
					0, FALSE, DUPLICATE_SAME_ACCESS);

	ZeroMemory(&si, sizeof(si));
	si.cb = sizeof(si);
	si.dwFlags = STARTF_USESTDHANDLES;
	si.hStdInput = hRead;
	si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
	si.hStdError = GetStdHandle(STD_ERROR_HANDLE);

	Advapi32Handle = LoadLibraryA("ADVAPI32.DLL");
	if (Advapi32Handle != NULL)
	{
		_CreateRestrictedToken = (__CreateRestrictedToken) GetProcAddress(Advapi32Handle, "CreateRestrictedToken");
	}

	if (_CreateRestrictedToken == NULL)
	{
		/*
		 * NT4 doesn't have CreateRestrictedToken, so just call ordinary
		 * CreateProcess
		 */
		if (Advapi32Handle != NULL)
			FreeLibrary(Advapi32Handle);
		b = CreateProcessA(NULL, command, NULL, NULL, FALSE, 0, NULL, NULL, &si, processInfo);
		goto done;
	}

	/* Open the current token to use as a base for the restricted one */
	if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &origToken))
	{
		elog(WARNING, "could not open process token: %lu", GetLastError());
		return -1;
	}

	/* Allocate list of SIDs to remove */
	ZeroMemory(&dropSids, sizeof(dropSids));
	if (!AllocateAndInitializeSid(&NtAuthority, 2,
		 SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0,
								  0, &dropSids[0].Sid) ||
		!AllocateAndInitializeSid(&NtAuthority, 2,
	SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_POWER_USERS, 0, 0, 0, 0, 0,
								  0, &dropSids[1].Sid))
	{
		elog(WARNING, "could not allocate SIDs: %lu", GetLastError());
		return -1;
	}

	b = _CreateRestrictedToken(origToken,
							   DISABLE_MAX_PRIVILEGE,
							   sizeof(dropSids) / sizeof(dropSids[0]),
							   dropSids,
							   0, NULL,
							   0, NULL,
							   &restrictedToken);

	FreeSid(dropSids[1].Sid);
	FreeSid(dropSids[0].Sid);
	CloseHandle(origToken);
	FreeLibrary(Advapi32Handle);

	if (!b)
	{
		elog(WARNING, "could not create restricted token: %lu", GetLastError());
		return -1;
	}

#ifndef __CYGWIN__
	AddUserToTokenDacl(restrictedToken);
#endif

	r = CreateProcessAsUserA(restrictedToken, NULL, command, NULL, NULL, TRUE, CREATE_SUSPENDED, NULL, NULL, &si, processInfo);

	Kernel32Handle = LoadLibraryA("KERNEL32.DLL");
	if (Kernel32Handle != NULL)
	{
		_IsProcessInJob = (__IsProcessInJob) GetProcAddress(Kernel32Handle, "IsProcessInJob");
		_CreateJobObject = (__CreateJobObjectA) GetProcAddress(Kernel32Handle, "CreateJobObjectA");
		_SetInformationJobObject = (__SetInformationJobObject) GetProcAddress(Kernel32Handle, "SetInformationJobObject");
		_AssignProcessToJobObject = (__AssignProcessToJobObject) GetProcAddress(Kernel32Handle, "AssignProcessToJobObject");
		_QueryInformationJobObject = (__QueryInformationJobObject) GetProcAddress(Kernel32Handle, "QueryInformationJobObject");
	}

	/* Verify that we found all functions */
	if (_IsProcessInJob == NULL || _CreateJobObject == NULL || _SetInformationJobObject == NULL || _AssignProcessToJobObject == NULL || _QueryInformationJobObject == NULL)
	{
		/*
		 * IsProcessInJob() is not available on < WinXP, so there is no need
		 * to log the error every time in that case
		 */
		OSVERSIONINFO osv;

		osv.dwOSVersionInfoSize = sizeof(osv);
		if (!GetVersionEx(&osv) ||		/* could not get version */
			(osv.dwMajorVersion == 5 && osv.dwMinorVersion > 0) ||		/* 5.1=xp, 5.2=2003, etc */
			osv.dwMajorVersion > 5)		/* anything newer should have the API */

			/*
			 * Log error if we can't get version, or if we're on WinXP/2003 or
			 * newer
			 */
			elog(WARNING, "could not locate all job object functions in system API");
	}
	else
	{
		BOOL		inJob;

		if (_IsProcessInJob(processInfo->hProcess, NULL, &inJob))
		{
			if (!inJob)
			{
				/*
				 * Job objects are working, and the new process isn't in one,
				 * so we can create one safely. If any problems show up when
				 * setting it, we're going to ignore them.
				 */
				HANDLE		job;
				char		jobname[128];

				sprintf(jobname, "PostgreSQL_%lu", processInfo->dwProcessId);

				job = _CreateJobObject(NULL, jobname);
				if (job)
				{
					JOBOBJECT_BASIC_LIMIT_INFORMATION basicLimit;
					JOBOBJECT_BASIC_UI_RESTRICTIONS uiRestrictions;
					JOBOBJECT_SECURITY_LIMIT_INFORMATION securityLimit;
					OSVERSIONINFO osv;

					ZeroMemory(&basicLimit, sizeof(basicLimit));
					ZeroMemory(&uiRestrictions, sizeof(uiRestrictions));
					ZeroMemory(&securityLimit, sizeof(securityLimit));

					basicLimit.LimitFlags = JOB_OBJECT_LIMIT_DIE_ON_UNHANDLED_EXCEPTION | JOB_OBJECT_LIMIT_PRIORITY_CLASS;
					basicLimit.PriorityClass = NORMAL_PRIORITY_CLASS;
					_SetInformationJobObject(job, JobObjectBasicLimitInformation, &basicLimit, sizeof(basicLimit));

					uiRestrictions.UIRestrictionsClass = JOB_OBJECT_UILIMIT_DESKTOP | JOB_OBJECT_UILIMIT_DISPLAYSETTINGS |
						JOB_OBJECT_UILIMIT_EXITWINDOWS | JOB_OBJECT_UILIMIT_READCLIPBOARD |
						JOB_OBJECT_UILIMIT_SYSTEMPARAMETERS | JOB_OBJECT_UILIMIT_WRITECLIPBOARD;

					if (as_service)
					{
						osv.dwOSVersionInfoSize = sizeof(osv);
						if (!GetVersionEx(&osv) ||
							osv.dwMajorVersion < 6 ||
						(osv.dwMajorVersion == 6 && osv.dwMinorVersion == 0))
						{
							/*
							 * On Windows 7 (and presumably later),
							 * JOB_OBJECT_UILIMIT_HANDLES prevents us from
							 * starting as a service. So we only enable it on
							 * Vista and earlier (version <= 6.0)
							 */
							uiRestrictions.UIRestrictionsClass |= JOB_OBJECT_UILIMIT_HANDLES;
						}
					}
					_SetInformationJobObject(job, JobObjectBasicUIRestrictions, &uiRestrictions, sizeof(uiRestrictions));

					securityLimit.SecurityLimitFlags = JOB_OBJECT_SECURITY_NO_ADMIN | JOB_OBJECT_SECURITY_ONLY_TOKEN;
					securityLimit.JobToken = restrictedToken;
					_SetInformationJobObject(job, JobObjectSecurityLimitInformation, &securityLimit, sizeof(securityLimit));

					_AssignProcessToJobObject(job, processInfo->hProcess);
				}
			}
		}
	}


	CloseHandle(restrictedToken);

	ResumeThread(processInfo->hThread);

	FreeLibrary(Kernel32Handle);

done:
	/*
	 * We intentionally don't close the job object handle, because we want the
	 * object to live on until this program shuts down.
	 */
	if (r)
	{
		int		fd;
		CloseHandle(hRead);
		if ((fd = _open_osfhandle((intptr_t) hWrite, O_WRONLY | O_TEXT)) != -1)
			return fd;
		else
			CloseHandle(hWrite);
	}
	else
	{
		CloseHandle(hRead);
		CloseHandle(hWrite);
	}
	return -1;
}
Ejemplo n.º 7
0
bool ProcessStarter::Run(bool forceRun)
{
	OSVERSIONINFO version = {sizeof(OSVERSIONINFO)};

	GetVersionEx(&version);
	if (version.dwMajorVersion <= 5 && !forceRun) //dont need this on XP/Win2K
		return false;

	char winDir[260];
	GetSystemDirectoryA(winDir,sizeof(winDir));

	PHANDLE primaryToken = 0;
	try {
		if (version.dwMajorVersion <= 5) //win2K/XP
			primaryToken = GetCurrentUserTokenOld();
		else
			primaryToken = GetCurrentUserToken();
	} catch(std::exception &ex) {
		log << "exception :" << ex.what() << std::endl;
		}
    if (primaryToken == 0)
    {
		log << "primtok = 0" << std::endl;
        return false;
    }

    STARTUPINFOA StartupInfo;
    PROCESS_INFORMATION processInfo;
	memset(&StartupInfo,0,sizeof(StartupInfo));
    StartupInfo.cb = sizeof(StartupInfo);
#if 0
	std::string command = std::string("\"") + winDir + 
			"\\cmd.exe\" /C \""+ processPath_ + " " + arguments_ + "\"";
#else
    std::string command = "\"" + processPath_ + "\"";
    if (arguments_.length() != 0)
    {
        command += " " + arguments_;
    }
#endif
	log << "command:" << command << std::endl;

    void* lpEnvironment = NULL;
	if (!forceRun) {
		BOOL resultEnv = CreateEnvironmentBlock(&lpEnvironment, primaryToken, FALSE);
		if (resultEnv == 0)
		{                                
			long nError = GetLastError();                                
		}
		log << "CreateEnvironmentBlock ok" << std::endl;
		}

    BOOL result = CreateProcessAsUserA(*primaryToken, 0, (LPSTR)(command.c_str()), 
		NULL,NULL,
		FALSE, CREATE_NO_WINDOW | CREATE_UNICODE_ENVIRONMENT, 
		lpEnvironment, 0, &StartupInfo, &processInfo);

	log << "CreateProcessAsUserA " << result << " err 0x" 
		<< std::hex << std::setfill('0') << std::setw(8) << GetLastError() << std::endl;
	if (result != FALSE)
		log << "launched" << std::endl;
	else
		log << "didnt launch" << std::endl;
    if (!forceRun) 
		CloseHandle(primaryToken);
    return (result != FALSE);
}