Exemple #1
0
Result<ExitCode> ProcessAsUser::Run(const Settings& settings, ProcessTracker& processTracker) const
{
	Trace trace(settings.GetLogLevel());
	trace < L"ProcessAsUser::Attempt to log a user on to the local computer";
	StringBuffer userName(settings.GetUserName());
	StringBuffer domain(settings.GetDomain());
	StringBuffer password(settings.GetPassword());
	StringBuffer workingDirectory(settings.GetWorkingDirectory());
	StringBuffer commandLine(settings.GetCommandLine());

	SecurityManager securityManager;
	auto setPrivilegesResult = securityManager.SetPrivileges(trace, { SE_TCB_NAME, SE_ASSIGNPRIMARYTOKEN_NAME }, true);
	if(setPrivilegesResult.HasError())
	{
		return setPrivilegesResult.GetError();
	}

	auto newUserSecurityTokenHandle = Handle(L"New user security token");
	unsigned long logonTypeCount = sizeof(allLogonTypes) / sizeof(allLogonTypes[0]);
	for (unsigned long logonTypeIndex = 0; logonTypeIndex < logonTypeCount; logonTypeIndex++)
	{
		auto logonType = allLogonTypes[logonTypeIndex];
		trace < L"::LogonUser using logon type ";
		switch (logonType)
		{
			case LOGON32_LOGON_INTERACTIVE:
				trace << L"LOGON32_LOGON_INTERACTIVE";
				break;

			case LOGON32_LOGON_NETWORK:
				trace << L"LOGON32_LOGON_NETWORK";
				break;

			case LOGON32_LOGON_BATCH:
				trace << L"LOGON32_LOGON_BATCH";
				break;

			case LOGON32_LOGON_SERVICE:
				trace << L"LOGON32_LOGON_SERVICE";
				break;
		}

		if (LogonUser(
			userName.GetPointer(),
			domain.GetPointer(),
			password.GetPointer(),
			logonType,
			LOGON32_PROVIDER_DEFAULT,
			&newUserSecurityTokenHandle))
		{
			break;
		}
		
		auto error = Error(L"LogonUser");
		trace << L" - ";
		trace << error.GetDescription();

		if(logonTypeIndex == logonTypeCount -1)
		{
			return error;
		}
	}

	trace < L"ProcessAsUser::InitializeConsoleRedirection a new security descriptor";
	trace < L"::InitializeSecurityDescriptor";
	SECURITY_DESCRIPTOR securityDescriptor = {};
	if (!InitializeSecurityDescriptor(
		&securityDescriptor,
		SECURITY_DESCRIPTOR_REVISION))
	{
		return Error(L"InitializeSecurityDescriptor");
	}

	trace < L"::SetSecurityDescriptorDacl";
	if (!SetSecurityDescriptorDacl(
		&securityDescriptor,
		true,
		nullptr,
		false))
	{
		return Error(L"SetSecurityDescriptorDacl");
	}

	trace < L"ProcessAsUser::Creates a new access primary token that duplicates new process's token";
	auto primaryNewUserSecurityTokenHandle = Handle(L"Primary new user security token");
	SECURITY_ATTRIBUTES processSecAttributes = {};
	processSecAttributes.lpSecurityDescriptor = &securityDescriptor;
	processSecAttributes.nLength = sizeof(SECURITY_DESCRIPTOR);
	processSecAttributes.bInheritHandle = true;
	trace < L"::DuplicateTokenEx";
	if (!DuplicateTokenEx(
		newUserSecurityTokenHandle,
		0, // MAXIMUM_ALLOWED
		&processSecAttributes,
		SecurityImpersonation,
		TokenPrimary,
		&primaryNewUserSecurityTokenHandle))
	{
		return Error(L"DuplicateTokenEx");
	}	

	SECURITY_ATTRIBUTES threadSecAttributes = {};
	threadSecAttributes.lpSecurityDescriptor = nullptr;
	threadSecAttributes.nLength = 0;
	threadSecAttributes.bInheritHandle = false;	
	STARTUPINFO startupInfo = {};	

	trace < L"ProcessTracker::InitializeConsoleRedirection";
	auto error = processTracker.InitializeConsoleRedirection(processSecAttributes, startupInfo);
	if(error.HasError())
	{
		return Result<ExitCode>(error.GetError());
	}

	trace < L"::LoadUserProfile";
	PROFILEINFO profileInfo = {};
	profileInfo.dwSize = sizeof(PROFILEINFO);
	profileInfo.lpUserName = userName.GetPointer();
	if (!LoadUserProfile(primaryNewUserSecurityTokenHandle, &profileInfo))
	{
		return Error(L"LoadUserProfile");
	}

	auto newProcessEnvironmentResult = GetEnvironment(settings, primaryNewUserSecurityTokenHandle, settings.GetInheritanceMode(), trace);
	if (newProcessEnvironmentResult.HasError())
	{
		UnloadUserProfile(primaryNewUserSecurityTokenHandle, profileInfo.hProfile);
		return Result<ExitCode>(newProcessEnvironmentResult.GetError());
	}

	auto setIntegrityLevelResult = securityManager.SetIntegrityLevel(settings.GetIntegrityLevel(), primaryNewUserSecurityTokenHandle, trace);
	if (setIntegrityLevelResult.HasError())
	{
		return Result<ExitCode>(setIntegrityLevelResult.GetError());
	}

	trace < L"ProcessAsUser::Create a new process and its primary thread. The new process runs in the security context of the user represented by the specified token.";
	PROCESS_INFORMATION processInformation = {};
	startupInfo.dwFlags = STARTF_USESHOWWINDOW;
	startupInfo.wShowWindow = ShowModeConverter::ToShowWindowFlag(settings.GetShowMode());
	auto cmdLine = settings.GetCommandLine();
	trace < L"::CreateProcessAsUser";	
	if (!CreateProcessAsUser(
		primaryNewUserSecurityTokenHandle,
		nullptr,
		commandLine.GetPointer(),
		&processSecAttributes,
		&threadSecAttributes,
		true,
		CREATE_UNICODE_ENVIRONMENT,
		newProcessEnvironmentResult.GetResultValue().CreateEnvironment(),
		workingDirectory.GetPointer(),
		&startupInfo,
		&processInformation))
	{		
		auto result = Error(L"CreateProcessAsUser");
		UnloadUserProfile(primaryNewUserSecurityTokenHandle, profileInfo.hProfile);
		return result;
	}

	// ReSharper disable CppInitializedValueIsAlwaysRewritten
	// ReSharper disable CppEntityAssignedButNoRead
	
	auto processHandle = Handle(L"Service Process");
	processHandle = processInformation.hProcess;
	
	auto threadHandle = Handle(L"Thread");
	threadHandle = processInformation.hThread;

	auto exitCode = processTracker.WaiteForExit(processInformation.hProcess, trace);
	UnloadUserProfile(primaryNewUserSecurityTokenHandle, profileInfo.hProfile);	

	return exitCode;
}
Exemple #2
0
Result<SelfTestStatistic> SelfTest::GetStatistic(const Settings& settings) const
{
	Trace trace(settings.GetLogLevel());
	trace < L"SelfTest::GetStatistic";

	Handle processToken(L"Process token");
	if (!::OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &processToken))
	{
		return Error(L"OpenProcessToken");
	}

	trace < L"Token groups:";
	auto tokenGroupsResult = _securityManager.GetTokenGroups(trace, processToken);
	if (!tokenGroupsResult.HasError())
	{
		auto tokenGroups = tokenGroupsResult.GetResultValue();
		for (auto groupsIterator = tokenGroups.begin(); groupsIterator != tokenGroups.end(); ++groupsIterator)
		{
			trace < groupsIterator->ToString();
		}
	}	
	
	auto isServiceResult = IsService(trace, processToken);
	if (isServiceResult.HasError())
	{
		return isServiceResult.GetError();
	}

	trace < L"SelfTest::IsService: ";
	trace << isServiceResult.GetResultValue();

	auto hasAdministrativePrivilegesResult = HasAdministrativePrivileges(trace);
	if (hasAdministrativePrivilegesResult.HasError())
	{
		return hasAdministrativePrivilegesResult.GetError();
	}

	trace < L"SelfTest::HasAdministrativePrivileges: ";
	trace << hasAdministrativePrivilegesResult.GetResultValue();

	auto hasSeAssignPrimaryTokenPrivilegeResult = HasPrivilege(trace, processToken, SE_ASSIGNPRIMARYTOKEN_NAME);
	if (hasSeAssignPrimaryTokenPrivilegeResult.HasError())
	{
		return hasSeAssignPrimaryTokenPrivilegeResult.GetError();
	}

	trace < L"SelfTest::HasPrivilege(SE_ASSIGNPRIMARYTOKEN_NAME): ";
	trace << hasSeAssignPrimaryTokenPrivilegeResult.GetResultValue();

	auto hasSeTcbPrivilegeResult = HasPrivilege(trace, processToken, SE_TCB_NAME);
	if (hasSeTcbPrivilegeResult.HasError())
	{
		return hasSeTcbPrivilegeResult.GetError();
	}

	trace < L"SelfTest::HasPrivilege(SE_TCB_NAME): ";
	trace << hasSeTcbPrivilegeResult.GetResultValue();

	auto integrityLevelResult = GetIntegrityLevel(trace, processToken);
	if (integrityLevelResult.HasError())
	{
		return integrityLevelResult.GetError();
	}
	
	
	trace < L"SelfTest::GetIntegrityLevel: ";
	trace << integrityLevelResult.GetResultValue();

	return SelfTestStatistic(
		isServiceResult.GetResultValue(),
		hasAdministrativePrivilegesResult.GetResultValue(),
		hasSeAssignPrimaryTokenPrivilegeResult.GetResultValue(),
		hasSeTcbPrivilegeResult.GetResultValue(),
		integrityLevelResult.GetResultValue());
}
Exemple #3
0
Result<ExitCode> ProcessWithLogon::Run(const Settings& settings, ProcessTracker& processTracker) const
{
	Trace trace(settings.GetLogLevel());
	trace < L"ProcessWithLogon::Run";
	if (_changeIntegrityLevel)
	{
		trace << L" elevated";
	}
	
	Environment callingProcessEnvironment;
	Environment targetUserEnvironment;
	Environment environment;
	if (settings.GetInheritanceMode() != INHERITANCE_MODE_OFF)
	{
		trace < L"ProcessWithLogon::Get calling process Environment";
		auto callingProcessEnvironmentResult = Environment::CreateForCurrentProcess(trace);
		if (callingProcessEnvironmentResult.HasError())
		{
			return Result<ExitCode>(callingProcessEnvironmentResult.GetError());
		}

		callingProcessEnvironment = callingProcessEnvironmentResult.GetResultValue();
		environment = callingProcessEnvironment;
	}

	if (settings.GetInheritanceMode() != INHERITANCE_MODE_ON)
	{		
		trace < L"ProcessWithLogon::Get target user environment";
		Settings getEnvVarsProcessSettings(
			settings.GetUserName(),
			settings.GetDomain(),
			settings.GetPassword(),
			L"cmd.exe",
			settings.GetWorkingDirectory(),
			EXIT_CODE_BASE,
			{ L"/U", L"/C", L"SET" },
			{ },
			INHERITANCE_MODE_OFF,
			INTEGRITY_LEVEL_AUTO,			
			SHOW_MODE_HIDE,
			false);

		if(settings.GetLogLevel() == LOG_LEVEL_DEBUG)
		{
			getEnvVarsProcessSettings.SetLogLevel(LOG_LEVEL_DEBUG);
		}
		else
		{
			getEnvVarsProcessSettings.SetLogLevel(LOG_LEVEL_OFF);
		}

		wstringstream getEnvVarsStream;
		StringWriter getEnvVarsWriter(getEnvVarsStream);
		StubWriter nullWriter;
		ProcessTracker getEnvVarsProcessTracker(getEnvVarsWriter, nullWriter);
		auto getEnvVarsResult = RunInternal(trace, getEnvVarsProcessSettings, getEnvVarsProcessTracker, targetUserEnvironment, false);
		if (getEnvVarsResult.HasError() || getEnvVarsResult.GetResultValue() != 0)
		{
			return getEnvVarsResult;
		}

		targetUserEnvironment = Environment::CreateFormString(getEnvVarsStream.str(), trace);
		environment = targetUserEnvironment;
	}

	if (settings.GetInheritanceMode() == INHERITANCE_MODE_AUTO)
	{
		environment = Environment::Override(callingProcessEnvironment, targetUserEnvironment, trace);
	}

	environment = Environment::Apply(environment, Environment::CreateFormList(settings.GetEnvironmentVariables(), L"from command line", trace), trace);
	return RunInternal(trace, settings, processTracker, environment, _changeIntegrityLevel);
}