Example #1
0
/// \brief Starts a new process with low integrity level
///
/// The newly started process is sandboxed and cannot increase its integrity level
///
int StartRestricted()
{
    BOOL ret;
    HANDLE token = nullptr;
    HANDLE newToken = nullptr;
    PSID integritySid = nullptr;
    TOKEN_MANDATORY_LABEL til = { 0 };
    PROCESS_INFORMATION procInfo = { 0 };
    STARTUPINFO startupInfo = { 0 };
    WCHAR procCommand[MAX_PATH] = _T("QnSend.exe /restricted");
    WCHAR lowIntegrityLevelSid[20] = _T("S-1-16-4096");

    try
    {
        ret = OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE | TOKEN_ADJUST_DEFAULT | TOKEN_QUERY | TOKEN_ASSIGN_PRIMARY, &token);
        if (!ret)
            throw ret;
        ret = DuplicateTokenEx(token, 0, nullptr, SecurityImpersonation, TokenPrimary, &newToken);
        if (!ret)
            throw ret;
        ret = ConvertStringSidToSid(lowIntegrityLevelSid, &integritySid);
        if (!ret)
            throw ret;
        til.Label.Attributes = SE_GROUP_INTEGRITY;
        til.Label.Sid = integritySid;
        ret = SetTokenInformation(newToken, TokenIntegrityLevel, &til, sizeof(TOKEN_MANDATORY_LABEL) + GetLengthSid(integritySid));
        if (!ret)
            throw ret;
        ret = CreateProcessAsUser(newToken, NULL, procCommand, NULL, NULL, FALSE, 0, NULL, NULL, &startupInfo, &procInfo);
        if (!ret)
            throw ret;
    }
    catch (...)
    {
#pragma region Cleanup
        if (procInfo.hProcess != nullptr)
            CloseHandle(procInfo.hProcess);
        if (procInfo.hThread != nullptr)
            CloseHandle(procInfo.hThread);
        LocalFree(integritySid);
        if (newToken != nullptr)
            CloseHandle(newToken);
        if (token != nullptr)
            CloseHandle(token);
#pragma endregion
        return ERROR_C;
    }
#pragma region Cleanup
    if (procInfo.hProcess != nullptr)
        CloseHandle(procInfo.hProcess);
    if (procInfo.hThread != nullptr)
        CloseHandle(procInfo.hThread);
    LocalFree(integritySid);
    if (newToken != nullptr)
        CloseHandle(newToken);
    if (token != nullptr)
        CloseHandle(token);
#pragma endregion
    return SUCCESS_C;
}
HRESULT GetProcessToken(DWORD dwProcessID, LPHANDLE token, DWORD nUserNameMax, LPWSTR szwUserName, DWORD nUserDomainMax, LPWSTR szwUserDomain) {
	HANDLE hProcess=OpenProcess(PROCESS_DUP_HANDLE|PROCESS_QUERY_INFORMATION,TRUE,dwProcessID); 
	if (!hProcess) throw std::runtime_error("OpenProcess failed");
	HRESULT retval = S_OK;
	HANDLE hToken = INVALID_HANDLE_VALUE;
	if (!OpenProcessToken(hProcess, TOKEN_DUPLICATE | TOKEN_QUERY, &hToken)) retval = HRESULT_FROM_WIN32(GetLastError());
	else {
		BYTE buf[MAX_PATH]; DWORD dwRead = 0;
		if (!GetTokenInformation(hToken, TokenUser, buf, MAX_PATH, &dwRead)) retval = HRESULT_FROM_WIN32(GetLastError());
		else {
			TOKEN_USER *puser = reinterpret_cast<TOKEN_USER*>(buf);
			SID_NAME_USE eUse;
			if (!LookupAccountSid(NULL, puser->User.Sid, szwUserName, &nUserNameMax, szwUserDomain, &nUserDomainMax, &eUse))
				retval = HRESULT_FROM_WIN32(GetLastError());
			}
		if (FAILED(retval)) return retval;
		if (!DuplicateTokenEx(hToken, 
			TOKEN_IMPERSONATE | TOKEN_QUERY | TOKEN_ASSIGN_PRIMARY | TOKEN_DUPLICATE, 
			NULL, SecurityImpersonation, TokenPrimary,token))
			retval = HRESULT_FROM_WIN32(GetLastError());
		else  retval = S_OK;
		CloseHandle(hToken);
		}
	return retval;
}
Example #3
0
HANDLE
MSWindowsWatchdog::duplicateProcessToken(HANDLE process, LPSECURITY_ATTRIBUTES security)
{
	HANDLE sourceToken;

	BOOL tokenRet = OpenProcessToken(
		process,
		TOKEN_ASSIGN_PRIMARY | TOKEN_ALL_ACCESS,
		&sourceToken);

	if (!tokenRet) {
		LOG((CLOG_ERR "could not open token, process handle: %d", process));
		throw XArch(new XArchEvalWindows());
	}
	
	LOG((CLOG_DEBUG "got token %i, duplicating", sourceToken));

	HANDLE newToken;
	BOOL duplicateRet = DuplicateTokenEx(
		sourceToken, TOKEN_ASSIGN_PRIMARY | TOKEN_ALL_ACCESS, security,
		SecurityImpersonation, TokenPrimary, &newToken);

	if (!duplicateRet) {
		LOG((CLOG_ERR "could not duplicate token %i", sourceToken));
		throw XArch(new XArchEvalWindows());
	}
	
	LOG((CLOG_DEBUG "duplicated, new token: %i", newToken));
	return newToken;
}
Example #4
0
BOOL CALLBACK kuhl_m_token_list_or_elevate_callback(HANDLE hToken, DWORD ptid, PVOID pvArg)
{
	HANDLE hNewToken;
	TOKEN_STATISTICS tokenStats;
	DWORD szNeeded;
	BOOL isUserOK = TRUE;
	PKUHL_M_TOKEN_ELEVATE_DATA pData = (PKUHL_M_TOKEN_ELEVATE_DATA) pvArg;
	PWSTR name, domainName;

	if(ptid != GetCurrentProcessId())
	{
		if(GetTokenInformation(hToken, TokenStatistics, &tokenStats, sizeof(TOKEN_STATISTICS), &szNeeded))
		{
			if(pData->pUsername)
			{
				if(kull_m_token_getNameDomainFromToken(hToken, &name, &domainName, NULL, NULL))
				{
					isUserOK = (_wcsicmp(name, pData->pUsername) == 0);
					LocalFree(name);
					LocalFree(domainName);
				}
			} else if(pData->tokenId)
				isUserOK = (pData->tokenId == tokenStats.TokenId.LowPart);

			if(isUserOK && DuplicateTokenEx(hToken, TOKEN_QUERY | TOKEN_IMPERSONATE, NULL, (tokenStats.TokenType == TokenPrimary) ? SecurityDelegation : tokenStats.ImpersonationLevel, TokenImpersonation, &hNewToken))
			{
				if(pData->pSid)
				{
					isUserOK = FALSE;
					if(!CheckTokenMembership(hNewToken, pData->pSid, &isUserOK))
						PRINT_ERROR_AUTO(L"CheckTokenMembership");
				}
				if(isUserOK)
				{
					kprintf(L"%u\t", ptid);
					kuhl_m_token_displayAccount(hToken);

					if(pData->elevateIt)
					{
						if(SetThreadToken(NULL, hNewToken))
						{
							kprintf(L" -> Impersonated !\n");
							kuhl_m_token_whoami(0, NULL);
							isUserOK = FALSE;
						}
						else PRINT_ERROR_AUTO(L"SetThreadToken");
					}
				}
				else isUserOK = TRUE;
				CloseHandle(hNewToken);
			}
			else isUserOK = TRUE;
		}
	}
	return isUserOK;
}
Example #5
0
Token Token::duplicate_impersonation()
{
    HANDLE h;
    if (FALSE != DuplicateTokenEx(handle_, MAXIMUM_ALLOWED, nullptr, SecurityImpersonation, TokenImpersonation, &h)) {
        return std::move(Token(h));
    }

    // TODO THROW CORRECTLY
    throw 1;
}
Example #6
0
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;
}
Example #7
0
	BOOL GetSessionUserToken(ULONG SessionId, LPHANDLE lphUserToken) {
		BOOL   bResult = FALSE;
		HANDLE hImpersonationToken = INVALID_HANDLE_VALUE;
		if (lphUserToken != NULL) {
			if (_WTSQueryUserToken (SessionId, &hImpersonationToken)) {
				bResult = DuplicateTokenEx(hImpersonationToken, 0, NULL, SecurityImpersonation, TokenPrimary, lphUserToken);
				CloseHandle(hImpersonationToken);
			}            
		}
		return bResult;
	}
Example #8
0
bool DebugToken::CreateToken()
{
	HANDLE hProcessToken = NULL;
	BOOL rc = OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE, &hProcessToken);

	if (!rc)
		return false;

	HANDLE hToken = NULL;
	rc = DuplicateTokenEx(
	         hProcessToken,
	         TOKEN_IMPERSONATE | TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES,
	         NULL,
	         SecurityImpersonation,
	         TokenImpersonation,
	         &hToken);

	if (!rc)
	{
		CloseHandle(hProcessToken);
		return false;
	}

	TOKEN_PRIVILEGES tp;
	tp.PrivilegeCount = 1;
	tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
	rc = LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tp.Privileges[0].Luid);

	if (!rc)
	{
		CloseHandle(hToken);
		CloseHandle(hProcessToken);
		return false;
	}

	rc = AdjustTokenPrivileges(
	         hToken,
	         FALSE,
	         &tp,
	         sizeof(tp),
	         NULL,
	         NULL);

	if (!rc)
	{
		CloseHandle(hToken);
		CloseHandle(hProcessToken);
		return false;
	}

	hDebugToken = hToken;
	return true;
}
Example #9
0
/*
 * @implemented
 */
BOOL WINAPI
DuplicateToken(IN HANDLE ExistingTokenHandle,
               IN SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
               OUT PHANDLE DuplicateTokenHandle)
{
    return DuplicateTokenEx(ExistingTokenHandle,
                            TOKEN_IMPERSONATE | TOKEN_QUERY,
                            NULL,
                            ImpersonationLevel,
                            TokenImpersonation,
                            DuplicateTokenHandle);
}
static int get_token(connection_context *c)
{
	int res = 0;
	int wres;
	HANDLE token;

	if (c->runas) {
		credentials crd;
		if (!prepare_credentials(c->runas, &crd)) {
			hprintf(c->pipe, "error Incorrect runas credentials\n");
			goto finish;
		}
		wres = LogonUser(crd.user, crd.domain, crd.password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, &c->token);
		if (!wres) {
			hprintf(c->pipe, "error Cannot LogonUser(%s,%s,%s) %d\n", crd.user, crd.domain, crd.password, GetLastError());
			goto finish;
		}
		res = 1;
		goto finish;
	} else if (c->system) {
		if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &token)) {
			hprintf(c->pipe, "error Cannot OpenProcessToken %d\n", GetLastError());
			goto finish;
		}
	} else {
		if (!ImpersonateNamedPipeClient(c->pipe->h)) {
			hprintf(c->pipe, "error Cannot ImpersonateNamedPipeClient %d\n", GetLastError());
			goto finish;
		}
		if (!OpenThreadToken(GetCurrentThread(), TOKEN_ALL_ACCESS, FALSE, &token)) {
			hprintf(c->pipe, "error Cannot OpenThreadToken %d\n", GetLastError());
			goto finishRevertToSelf;
		}
	}
	if (!DuplicateTokenEx(token, MAXIMUM_ALLOWED, 0, c->implevel, TokenPrimary, &c->token)) {
		hprintf(c->pipe, "error Cannot Duplicate Token %d\n", GetLastError());
		goto finishCloseToken;
	}
	res = 1;
finishCloseToken:
	CloseHandle(token);
finishRevertToSelf:
	if (!c->system) {
		if (!RevertToSelf()) {
			hprintf(c->pipe, "error Cannot RevertToSelf %d\n", GetLastError());
			res = 0;
		}
	}
finish:
	return res;
}
Example #11
0
void Duplicate(HANDLE& h, LPCSTR file, int line)
{
	HANDLE hDupe = NULL;
	if(DuplicateTokenEx(h, MAXIMUM_ALLOWED, NULL, SecurityImpersonation, TokenPrimary, &hDupe))
	{
		CloseHandle(h);
		h = hDupe;
		hDupe = NULL;
	}
	else
	{
		DWORD gle = GetLastError();
		_ASSERT(0);
		Log(StrFormat(L"Error duplicating a user token (%S, %d)", file, line), GetLastError());
	}
}
ProcessStarterPrivate::_phandle ProcessStarterPrivate::GetCurrentUserToken()
{
	QLibrary wts("Wtsapi32");
	BOOL (__stdcall * pWTSQueryUserToken)(ULONG SessionId,PHANDLE phToken) =
		(BOOL(__stdcall *)(ULONG,PHANDLE)) wts.resolve("WTSQueryUserToken");
	BOOL (__stdcall * pWTSEnumerateSessionsW)(HANDLE hServer,DWORD Reserved,DWORD Version,
			PWTS_SESSION_INFOW * ppSessionInfo,DWORD * pCount) = 
		(BOOL(__stdcall *)(HANDLE, DWORD,DWORD,PWTS_SESSION_INFOW *, DWORD *))
			wts.resolve("WTSEnumerateSessionsW");

    PHANDLE currentToken = &curTok;
    PHANDLE primaryToken = &primTok;

    int dwSessionId = 0;

    PWTS_SESSION_INFOW pSessionInfo = 0;
    DWORD dwCount = 0;

    pWTSEnumerateSessionsW(WTS_CURRENT_SERVER_HANDLE, 0, 1, &pSessionInfo, &dwCount);

    for (DWORD i = 0; i < dwCount; ++i)
    {
        WTS_SESSION_INFO si = pSessionInfo[i];
        if (WTSActive == si.State)
        {
            dwSessionId = si.SessionId;
            break;
        }
    }

    BOOL bRet = pWTSQueryUserToken(dwSessionId, currentToken);
    int errorcode = GetLastError();
    if (bRet == false)
    {
        return 0;
    }

    bRet = DuplicateTokenEx(*currentToken, TOKEN_ASSIGN_PRIMARY | TOKEN_ALL_ACCESS, 0, SecurityImpersonation, TokenPrimary, primaryToken);
    errorcode = GetLastError();
    if (bRet == false)
    {
        return 0;
    }

    return primaryToken;
}
Example #13
0
// gets the current user (so we can launch under their session)
HANDLE 
CMSWindowsRelauncher::getCurrentUserToken(DWORD sessionId, LPSECURITY_ATTRIBUTES security)
{
	HANDLE currentToken;
	HANDLE winlogonProcess;

	if (winlogonInSession(sessionId, &winlogonProcess)) {

		LOG((CLOG_DEBUG "session %i has winlogon.exe", sessionId));

		// get the token, so we can re-launch with this token
		// -- do we really need all these access bits?
		BOOL tokenRet = OpenProcessToken(
			winlogonProcess,
			TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY | 
			TOKEN_DUPLICATE | TOKEN_ASSIGN_PRIMARY | 
			TOKEN_ADJUST_SESSIONID | TOKEN_READ | TOKEN_WRITE,
			&currentToken);

		if (!tokenRet) {
			LOG((CLOG_ERR "could not open token (error: %i)", GetLastError()));
			return 0;
		}
	}
	else {

		LOG((CLOG_ERR "session %i does not have winlogon.exe "
			"which is needed for re-launch", sessionId));
		return 0;
	}

	HANDLE primaryToken;
	BOOL duplicateRet = DuplicateTokenEx(
		currentToken, MAXIMUM_ALLOWED, security,
		SecurityImpersonation, TokenPrimary, &primaryToken);

	if (!duplicateRet) {
		LOG((CLOG_ERR "could not duplicate token %i (error: %i)",
			currentToken, GetLastError()));
		return 0;
	}

	return primaryToken;
}
Example #14
0
scoped_handle CreateLowboxToken()
{
  PSID package_sid_p;
  if (!ConvertStringSidToSid(L"S-1-15-2-1-1-1-1-1-1-1-1-1-1-1", &package_sid_p))
  {
    printf("[ERROR] creating SID: %d\n", GetLastError());
    return nullptr;
  }
  local_free_ptr package_sid(package_sid_p);

  HANDLE process_token_h;
  if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &process_token_h))
  {
    printf("[ERROR] error opening process token SID: %d\n", GetLastError());
    return nullptr;
  }

  scoped_handle process_token(process_token_h);

  NtCreateLowBoxToken fNtCreateLowBoxToken = (NtCreateLowBoxToken)GetProcAddress(GetModuleHandle(L"ntdll"), "NtCreateLowBoxToken");
  HANDLE lowbox_token_h;
  OBJECT_ATTRIBUTES obja = {};
  obja.Length = sizeof(obja);

  NTSTATUS status = fNtCreateLowBoxToken(&lowbox_token_h, process_token_h, TOKEN_ALL_ACCESS, &obja, package_sid_p, 0, nullptr, 0, nullptr);
  if (status != 0)
  {
    printf("[ERROR] creating lowbox token: %08X\n", status);
    return nullptr;
  }

  scoped_handle lowbox_token(lowbox_token_h);
  HANDLE imp_token;

  if (!DuplicateTokenEx(lowbox_token_h, TOKEN_ALL_ACCESS, nullptr, SecurityImpersonation, TokenImpersonation, &imp_token))
  {
    printf("[ERROR] duplicating lowbox: %d\n", GetLastError());
    return nullptr;
  }

  return scoped_handle(imp_token);
}
Q_PID CAuthHelperTest::createSimpleProcessAsUser( CAuthHelper& auth )
{
#	ifndef _WIN_
	Q_UNUSED( auth );
	return 0;
#else

	PROCESS_INFORMATION* pid = new PROCESS_INFORMATION;
	try
	{
		void *pToken = NULL;
		if ( ! DuplicateTokenEx( auth.GetAuth()->GetTokenHandle(),	MAXIMUM_ALLOWED, NULL, SecurityImpersonation, TokenPrimary, &pToken) )
			throw "DuplicateTokenEx failed";

		memset(pid, 0, sizeof(PROCESS_INFORMATION));

		DWORD dwCreationFlags = CREATE_NO_WINDOW | CREATE_UNICODE_ENVIRONMENT;

		QString args = "sleep 2";
		wchar_t szCmd[512] = { 0 };
		args.toWCharArray( szCmd );

		QStringList params;
		params.append( "2" );

		//QString args ;= create_commandline ( "sleep", params);
		//LPWSTR* szCmdline=wcsdup(L"sleep 2");
		//WCHAR args[]= L"sleep 2";
		if ( ! CreateProcessAsUserW( pToken,0, szCmd , 0, 0, FALSE, dwCreationFlags, 0, 0, 0, pid) )
			throw "CreateProcessAsUserW() failed";

		return pid;
	}
	catch (const char* err)
	{
		LOG_MESSAGE( DBG_FATAL, "error catched [%s], err=[%s]", err, Prl::GetLastErrorAsString() );
		Q_UNUSED(err);
		return 0;
	}

#endif
}
Example #16
0
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;
}
bool GetWinlogonHandle(LPHANDLE  lphUserToken, DWORD sessionid)
{
	BOOL   bResult = FALSE;

	HANDLE hAccessToken = NULL;
	HANDLE hTokenThis = NULL;
//	DWORD Id = GetProcessesByName(L"winlogon.exe");
	DWORD Id = Find_winlogon(sessionid);

	HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, Id);
	if (hProcess)
	{
		if (OpenProcessToken(hProcess, TOKEN_ASSIGN_PRIMARY | TOKEN_ALL_ACCESS, &hTokenThis))
		{
			bResult = DuplicateTokenEx(hTokenThis, TOKEN_ASSIGN_PRIMARY | TOKEN_ALL_ACCESS, NULL, SecurityImpersonation, TokenPrimary, lphUserToken);
			CloseHandle(hTokenThis);
		}
		CloseHandle(hProcess);
	}
	return bResult == 1;
}
// checks for presence of local admin group (must have TOKEN_DUPLICATE perms on hToken)
bool SecurityHelper::IsAdmin(HANDLE hToken)
{
    // we can pretty much assume all tokens will be primary tokens in this application
    // and CheckTokenMembership requires an impersonation token (which is really annoying)
    // so we'll just duplicate any token we get into an impersonation token before continuing...
    bool isAdmin = false;
    HANDLE hImpToken;
    if (DuplicateTokenEx(hToken, TOKEN_QUERY, 0, SecurityIdentification, TokenImpersonation, &hImpToken))
	{
        BOOL isMember;
        if (CheckTokenMembership(hImpToken, _administratorsAlias(), &isMember) && isMember)
		{
            isAdmin = true;
        }
        else LCF1(L"CheckTokenMembership failed: %d", GetLastError());

        CloseHandle(hImpToken);
    }
    else LCF1(L"DuplicateTokenEx failed: %d", GetLastError());

    return isAdmin;
}
Example #19
0
BOOL GetTokenFromPid(DWORD dwPid, _TOKEN_TYPE TokenType, HANDLE& hToken)
{
	BOOL bRetCode	= FALSE;
	BOOL bResult	= FALSE;
	HANDLE hProcess = NULL;
	HANDLE hOriToken = NULL;
	hProcess	= ::OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, dwPid);

	if (NULL == hProcess)
		goto Exit0;

	bResult		= ::OpenProcessToken(hProcess, TOKEN_ALL_ACCESS, &hOriToken);
	if (!bResult)
		goto Exit0;

	bResult = DuplicateTokenEx(hOriToken,
		TOKEN_ALL_ACCESS,
		NULL,
		SecurityImpersonation,
		TokenType,
		&hToken);

	bRetCode = TRUE;

Exit0:

	if (hOriToken)
	{
		::CloseHandle(hOriToken);
	}

	if (hProcess)
	{
		::CloseHandle(hProcess);
	}

	return bRetCode;
}
Example #20
0
TStatus GetUnElevatedToken(CAutoHandle& hToken)
{
	HWND hShellWnd = GetShellWindow();
	if(hShellWnd == NULL)
	{
		SW_TSTATUS_RET(SW_ERR_WND_NOT_FOUND, L"GetShellWindow() return NULL");
	}
	DWORD dwShellPID = 0;
	GetWindowThreadProcessId(hShellWnd, &dwShellPID);
	SW_WINBOOL_RET(dwShellPID != 0);

	CAutoHandle hShellProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, dwShellPID);
	SW_WINBOOL_RET(hShellProcess.IsValid());

	CAutoHandle hShellProcessToken;

	SW_WINBOOL_RET(OpenProcessToken(hShellProcess, TOKEN_DUPLICATE, &hShellProcessToken));

	const DWORD dwTokenRights = TOKEN_QUERY | TOKEN_ASSIGN_PRIMARY | TOKEN_DUPLICATE | TOKEN_ADJUST_DEFAULT | TOKEN_ADJUST_SESSIONID;
	SW_WINBOOL_RET(DuplicateTokenEx(hShellProcessToken, dwTokenRights, NULL, SecurityImpersonation, TokenPrimary, &hToken));

	SW_RETURN_SUCCESS;
}
Example #21
0
TSRM_API FILE *popen_ex(const char *command, const char *type, const char *cwd, char *env)
{
	FILE *stream = NULL;
	int fno, type_len, read, mode;
	STARTUPINFO startup;
	PROCESS_INFORMATION process;
	SECURITY_ATTRIBUTES security;
	HANDLE in, out;
	DWORD dwCreateFlags = 0;
	BOOL res;
	process_pair *proc;
	char *cmd;
	int i;
	char *ptype = (char *)type;
	HANDLE thread_token = NULL;
	HANDLE token_user = NULL;
	BOOL asuser = TRUE;

	if (!type) {
		return NULL;
	}

	/*The following two checks can be removed once we drop XP support */
	type_len = (int)strlen(type);
	if (type_len <1 || type_len > 2) {
		return NULL;
	}

	for (i=0; i < type_len; i++) {
		if (!(*ptype == 'r' || *ptype == 'w' || *ptype == 'b' || *ptype == 't')) {
			return NULL;
		}
		ptype++;
	}

	security.nLength				= sizeof(SECURITY_ATTRIBUTES);
	security.bInheritHandle			= TRUE;
	security.lpSecurityDescriptor	= NULL;

	if (!type_len || !CreatePipe(&in, &out, &security, 2048L)) {
		return NULL;
	}

	memset(&startup, 0, sizeof(STARTUPINFO));
	memset(&process, 0, sizeof(PROCESS_INFORMATION));

	startup.cb			= sizeof(STARTUPINFO);
	startup.dwFlags		= STARTF_USESTDHANDLES;
	startup.hStdError	= GetStdHandle(STD_ERROR_HANDLE);

	read = (type[0] == 'r') ? TRUE : FALSE;
	mode = ((type_len == 2) && (type[1] == 'b')) ? O_BINARY : O_TEXT;

	if (read) {
		in = dupHandle(in, FALSE);
		startup.hStdInput  = GetStdHandle(STD_INPUT_HANDLE);
		startup.hStdOutput = out;
	} else {
		out = dupHandle(out, FALSE);
		startup.hStdInput  = in;
		startup.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
	}

	dwCreateFlags = NORMAL_PRIORITY_CLASS;
	if (strcmp(sapi_module.name, "cli") != 0) {
		dwCreateFlags |= CREATE_NO_WINDOW;
	}

	/* Get a token with the impersonated user. */
	if(OpenThreadToken(GetCurrentThread(), TOKEN_ALL_ACCESS, TRUE, &thread_token)) {
		DuplicateTokenEx(thread_token, MAXIMUM_ALLOWED, &security, SecurityImpersonation, TokenPrimary, &token_user);
	} else {
		DWORD err = GetLastError();
		if (err == ERROR_NO_TOKEN) {
			asuser = FALSE;
		}
	}

	cmd = (char*)malloc(strlen(command)+strlen(TWG(comspec))+sizeof(" /c ")+2);
	if (!cmd) {
		return NULL;
	}

	sprintf(cmd, "%s /c \"%s\"", TWG(comspec), command);
	if (asuser) {
		res = CreateProcessAsUser(token_user, NULL, cmd, &security, &security, security.bInheritHandle, dwCreateFlags, env, cwd, &startup, &process);
		CloseHandle(token_user);
	} else {
		res = CreateProcess(NULL, cmd, &security, &security, security.bInheritHandle, dwCreateFlags, env, cwd, &startup, &process);
	}
	free(cmd);

	if (!res) {
		return NULL;
	}

	CloseHandle(process.hThread);
	proc = process_get(NULL);

	if (read) {
		fno = _open_osfhandle((tsrm_intptr_t)in, _O_RDONLY | mode);
		CloseHandle(out);
	} else {
		fno = _open_osfhandle((tsrm_intptr_t)out, _O_WRONLY | mode);
		CloseHandle(in);
	}

	stream = _fdopen(fno, type);
	proc->prochnd = process.hProcess;
	proc->stream = stream;
	return stream;
}
Example #22
0
/*
 * @implemented
 */
BOOL WINAPI
CheckTokenMembership(IN HANDLE ExistingTokenHandle,
                     IN PSID SidToCheck,
                     OUT PBOOL IsMember)
{
    PISECURITY_DESCRIPTOR SecurityDescriptor = NULL;
    ACCESS_MASK GrantedAccess;
    struct
    {
        PRIVILEGE_SET PrivilegeSet;
        LUID_AND_ATTRIBUTES Privileges[4];
    } PrivBuffer;
    ULONG PrivBufferSize = sizeof(PrivBuffer);
    GENERIC_MAPPING GenericMapping =
    {
        STANDARD_RIGHTS_READ,
        STANDARD_RIGHTS_WRITE,
        STANDARD_RIGHTS_EXECUTE,
        STANDARD_RIGHTS_ALL
    };
    PACL Dacl;
    ULONG SidLen;
    HANDLE hToken = NULL;
    NTSTATUS Status, AccessStatus;

    /* doesn't return gracefully if IsMember is NULL! */
    *IsMember = FALSE;

    SidLen = RtlLengthSid(SidToCheck);

    if (ExistingTokenHandle == NULL)
    {
        Status = NtOpenThreadToken(NtCurrentThread(),
                                   TOKEN_QUERY,
                                   FALSE,
                                   &hToken);

        if (Status == STATUS_NO_TOKEN)
        {
            /* we're not impersonating, open the primary token */
            Status = NtOpenProcessToken(NtCurrentProcess(),
                                        TOKEN_QUERY | TOKEN_DUPLICATE,
                                        &hToken);
            if (NT_SUCCESS(Status))
            {
                HANDLE hNewToken = FALSE;
                BOOL DupRet;

                /* duplicate the primary token to create an impersonation token */
                DupRet = DuplicateTokenEx(hToken,
                                          TOKEN_QUERY | TOKEN_IMPERSONATE,
                                          NULL,
                                          SecurityImpersonation,
                                          TokenImpersonation,
                                          &hNewToken);

                NtClose(hToken);

                if (!DupRet)
                {
                    WARN("Failed to duplicate the primary token!\n");
                    return FALSE;
                }

                hToken = hNewToken;
            }
        }

        if (!NT_SUCCESS(Status))
        {
            goto Cleanup;
        }
    }
    else
    {
        hToken = ExistingTokenHandle;
    }

    /* create a security descriptor */
    SecurityDescriptor = RtlAllocateHeap(RtlGetProcessHeap(),
                                         0,
                                         sizeof(SECURITY_DESCRIPTOR) +
                                             sizeof(ACL) + SidLen +
                                             sizeof(ACCESS_ALLOWED_ACE));
    if (SecurityDescriptor == NULL)
    {
        Status = STATUS_INSUFFICIENT_RESOURCES;
        goto Cleanup;
    }

    Status = RtlCreateSecurityDescriptor(SecurityDescriptor,
                                         SECURITY_DESCRIPTOR_REVISION);
    if (!NT_SUCCESS(Status))
    {
        goto Cleanup;
    }

    /* set the owner and group */
    Status = RtlSetOwnerSecurityDescriptor(SecurityDescriptor,
                                           SidToCheck,
                                           FALSE);
    if (!NT_SUCCESS(Status))
    {
        goto Cleanup;
    }

    Status = RtlSetGroupSecurityDescriptor(SecurityDescriptor,
                                           SidToCheck,
                                           FALSE);
    if (!NT_SUCCESS(Status))
    {
        goto Cleanup;
    }

    /* create the DACL */
    Dacl = (PACL)(SecurityDescriptor + 1);
    Status = RtlCreateAcl(Dacl,
                          sizeof(ACL) + SidLen + sizeof(ACCESS_ALLOWED_ACE),
                          ACL_REVISION);
    if (!NT_SUCCESS(Status))
    {
        goto Cleanup;
    }

    Status = RtlAddAccessAllowedAce(Dacl,
                                    ACL_REVISION,
                                    0x1,
                                    SidToCheck);
    if (!NT_SUCCESS(Status))
    {
        goto Cleanup;
    }

    /* assign the DACL to the security descriptor */
    Status = RtlSetDaclSecurityDescriptor(SecurityDescriptor,
                                          TRUE,
                                          Dacl,
                                          FALSE);
    if (!NT_SUCCESS(Status))
    {
        goto Cleanup;
    }

    /* it's time to perform the access check. Just use _some_ desired access right
       (same as for the ACE) and see if we're getting it granted. This indicates
       our SID is a member of the token. We however can't use a generic access
       right as those aren't mapped and return an error (STATUS_GENERIC_NOT_MAPPED). */
    Status = NtAccessCheck(SecurityDescriptor,
                           hToken,
                           0x1,
                           &GenericMapping,
                           &PrivBuffer.PrivilegeSet,
                           &PrivBufferSize,
                           &GrantedAccess,
                           &AccessStatus);
    if (NT_SUCCESS(Status) && NT_SUCCESS(AccessStatus) && (GrantedAccess == 0x1))
    {
        *IsMember = TRUE;
    }

Cleanup:
    if (hToken != NULL && hToken != ExistingTokenHandle)
    {
        NtClose(hToken);
    }

    if (SecurityDescriptor != NULL)
    {
        RtlFreeHeap(RtlGetProcessHeap(),
                    0,
                    SecurityDescriptor);
    }

    if (!NT_SUCCESS(Status))
    {
        SetLastError(RtlNtStatusToDosError(Status));
        return FALSE;
    }

    return TRUE;
}
Example #23
0
// 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(), &currentSessionId))
    {
        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;
}
Example #24
0
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;
}
Example #25
0
/*
 * sys_steal_token
 * ----------
 *
 * Steals the primary token from an existing process
 */
DWORD request_sys_config_steal_token(Remote *remote, Packet *packet)
{
	Packet *response = packet_create_response(packet);
	DWORD dwResult = ERROR_SUCCESS;
#ifdef _WIN32
	HANDLE hToken = NULL;
	HANDLE hProcessHandle = NULL;
	HANDLE hDupToken = NULL;
	DWORD dwPid;

	do
	{
		// Get the process identifier that we're attaching to, if any.
		dwPid = packet_get_tlv_value_uint(packet, TLV_TYPE_PID);

		if (!dwPid)
		{
			dwResult = -1;
			break;
		}

		hProcessHandle = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, dwPid);

		if (!hProcessHandle)
		{
			dwResult = GetLastError();
			dprintf("[STEAL-TOKEN] Failed to open process handle for %d (%u)", dwPid, dwResult);
			break;
		}

		if (!OpenProcessToken(hProcessHandle, TOKEN_ALL_ACCESS, &hToken))
		{
			dwResult = GetLastError();
			dprintf("[STEAL-TOKEN] Failed to open process token for %d (%u)", dwPid, dwResult);
			break;
		}

		if (!ImpersonateLoggedOnUser(hToken))
		{
			dwResult = GetLastError();
			dprintf("[STEAL-TOKEN] Failed to impersonate token for %d (%u)", dwPid, dwResult);
			break;
		}

		if (!DuplicateTokenEx(hToken, MAXIMUM_ALLOWED, NULL, SecurityIdentification, TokenPrimary, &hDupToken))
		{
			dwResult = GetLastError();
			dprintf("[STEAL-TOKEN] Failed to duplicate a primary token for %d (%u)", dwPid, dwResult);
			break;
		}

		core_update_thread_token(remote, hDupToken);

		dwResult = populate_uid(response);
	} while (0);

	if (hProcessHandle)
	{
		CloseHandle(hProcessHandle);
	}

	if (hToken)
	{
		CloseHandle(hToken);
	}
#else
	dwResult = ERROR_NOT_SUPPORTED;
#endif
	// Transmit the response
	packet_transmit_response(dwResult, remote, response);

	return dwResult;
}
/**
 * Launch a child process without elevated privilege.
 */
static BOOL
LaunchAsNormalUser(const PRUnichar *exePath, PRUnichar *cl)
{
#ifdef WINCE
  return PR_FALSE;
#else
  if (!pCreateProcessWithTokenW) {
    // IsUserAnAdmin is not present on Win9x and not exported by name on Win2k
    *(FARPROC *)&pIsUserAnAdmin =
        GetProcAddress(GetModuleHandleA("shell32.dll"), "IsUserAnAdmin");

    // CreateProcessWithTokenW is not present on WinXP or earlier
    *(FARPROC *)&pCreateProcessWithTokenW =
        GetProcAddress(GetModuleHandleA("advapi32.dll"),
                       "CreateProcessWithTokenW");

    if (!pCreateProcessWithTokenW)
      return FALSE;
  }

  // do nothing here if we are not elevated or IsUserAnAdmin is not present.
  if (!pIsUserAnAdmin || pIsUserAnAdmin && !pIsUserAnAdmin())
    return FALSE;

  // borrow the shell token to drop the privilege
  HWND hwndShell = FindWindowA("Progman", NULL);
  DWORD dwProcessId;
  GetWindowThreadProcessId(hwndShell, &dwProcessId);

  HANDLE hProcessShell = OpenProcess(MAXIMUM_ALLOWED, FALSE, dwProcessId);
  if (!hProcessShell)
    return FALSE;

  HANDLE hTokenShell;
  BOOL ok = OpenProcessToken(hProcessShell, MAXIMUM_ALLOWED, &hTokenShell);
  CloseHandle(hProcessShell);
  if (!ok)
    return FALSE;

  HANDLE hNewToken;
  ok = DuplicateTokenEx(hTokenShell,
                        MAXIMUM_ALLOWED,
                        NULL,
                        SecurityDelegation,
                        TokenPrimary,
                        &hNewToken);
  CloseHandle(hTokenShell);
  if (!ok)
    return FALSE;

  STARTUPINFOW si = {sizeof(si), 0};
  PROCESS_INFORMATION pi = {0};

  // When launching with reduced privileges, environment inheritance
  // (passing NULL as lpEnvironment) doesn't work correctly. Pass our
  // current environment block explicitly
  WCHAR* myenv = GetEnvironmentStringsW();

  ok = pCreateProcessWithTokenW(hNewToken,
                                0,    // profile is already loaded
                                exePath,
                                cl,
                                CREATE_UNICODE_ENVIRONMENT,
                                myenv, // inherit my environment
                                NULL, // use my current directory
                                &si,
                                &pi);

  if (myenv)
    FreeEnvironmentStringsW(myenv);

  CloseHandle(hNewToken);
  if (!ok)
    return FALSE;

  CloseHandle(pi.hProcess);
  CloseHandle(pi.hThread);

  return TRUE;
#endif
}
Example #27
0
File: ms11013.c Project: OJ/kekeo
void impersonateToGetData(PCSTR user, PCSTR domain, PCSTR password, PCSTR kdc, PSID *sid, DWORD *rid, PCSTR usingWhat)
{
	NTSTATUS status;
	DWORD ret, *aRid, *usage;
	ANSI_STRING aUser, aKdc, aDomain, aPass, aProg;
	UNICODE_STRING uUser, uKdc, uDomain, uPass, uProg;
	SAMPR_HANDLE hServerHandle, hDomainHandle;
	PSID domainSid;
	HANDLE hToken, hNewToken;
	PROCESS_INFORMATION processInfos;
	STARTUPINFOW startupInfo;
	RtlZeroMemory(&startupInfo, sizeof(STARTUPINFOW));
	startupInfo.cb = sizeof(STARTUPINFOW);

	RtlInitString(&aUser, user);
	RtlInitString(&aKdc, kdc);
	RtlInitString(&aDomain, domain);
	RtlInitString(&aPass, password);
	RtlInitString(&aProg, usingWhat ? usingWhat : "winver.exe");
	if(NT_SUCCESS(RtlAnsiStringToUnicodeString(&uUser, &aUser, TRUE)))
	{
		if(NT_SUCCESS(RtlAnsiStringToUnicodeString(&uKdc, &aKdc, TRUE)))
		{
			if(NT_SUCCESS(RtlAnsiStringToUnicodeString(&uDomain, &aDomain, TRUE)))
			{
				if(NT_SUCCESS(RtlAnsiStringToUnicodeString(&uPass, &aPass, TRUE)))
				{

					if(NT_SUCCESS(RtlAnsiStringToUnicodeString(&uProg, &aProg, TRUE)))
					{
						if(CreateProcessWithLogonW(uUser.Buffer, uDomain.Buffer, uPass.Buffer, LOGON_NETCREDENTIALS_ONLY, uProg.Buffer, NULL, CREATE_SUSPENDED, NULL, NULL, &startupInfo, &processInfos))
						{
							if(OpenProcessToken(processInfos.hProcess, TOKEN_DUPLICATE, &hToken))
							{
								if(DuplicateTokenEx(hToken, TOKEN_QUERY | TOKEN_IMPERSONATE, NULL, SecurityDelegation, TokenImpersonation, &hNewToken))
								{
									if(SetThreadToken(NULL, hNewToken))
									{
										kprintf("[AUTH] Impersonation\n");
										if(!(*sid && *rid))
										{
											kprintf("[SID/RID] \'%s @ %s\' must be translated to SID/RID\n", user, domain);
											status = SamConnect(&uKdc, &hServerHandle, SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN, FALSE);
											if(NT_SUCCESS(status))
											{
												status = SamLookupDomainInSamServer(hServerHandle, &uDomain, &domainSid);
												if(NT_SUCCESS(status))
												{
													status = SamOpenDomain(hServerHandle, DOMAIN_LIST_ACCOUNTS | DOMAIN_LOOKUP, domainSid, &hDomainHandle);
													if(NT_SUCCESS(status))
													{
														status = SamLookupNamesInDomain(hDomainHandle, 1, &uUser, &aRid, &usage);
														if(NT_SUCCESS(status))
															*rid = *aRid;
														else PRINT_ERROR("SamLookupNamesInDomain %08x\n", status);
													}
													else PRINT_ERROR("SamOpenDomain %08x\n", status);

													ret = GetLengthSid(domainSid);
													if(*sid = (PSID) LocalAlloc(LPTR, ret))
													{
														if(!CopySid(ret, *sid, domainSid))
														{
															*sid = (PSID) LocalFree(*sid);
															PRINT_ERROR_AUTO("CopySid");
														}
													}
													SamFreeMemory(domainSid);
												}
												else PRINT_ERROR("SamLookupDomainInSamServer %08x\n", status);
												SamCloseHandle(hServerHandle);
											}
											else PRINT_ERROR("SamConnect %08x\n", status);
										}
										RevertToSelf();
									}
									else PRINT_ERROR_AUTO("SetThreadToken");
									CloseHandle(hNewToken);
								}
								else PRINT_ERROR_AUTO("DuplicateTokenEx");
								CloseHandle(hToken);
							}
							else PRINT_ERROR_AUTO("OpenProcessToken");
							TerminateProcess(processInfos.hProcess, 0);
							CloseHandle(processInfos.hProcess);
							CloseHandle(processInfos.hThread);
						}
						else PRINT_ERROR_AUTO("CreateProcessWithLogonW");

						RtlFreeUnicodeString(&uProg);
					}
					RtlFreeUnicodeString(&uPass);
				}
				RtlFreeUnicodeString(&uDomain);
			}
			RtlFreeUnicodeString(&uKdc);
		}
		RtlFreeUnicodeString(&uUser);
	}
}
Example #28
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;
}
Example #29
0
//
// Assert an NT privilege for this thread.
//
BOOL
AssertPrivilege(
    IN  LPCSTR PrivilegeName
    )

{
    BOOL                b;
    HANDLE              hThread;
    HANDLE              hProcess;
    TOKEN_PRIVILEGES    tokenPrivileges, oldTokenPrivileges;
    DWORD               oldPrivilegesLength;


    b = OpenThreadToken(GetCurrentThread(), TOKEN_ADJUST_PRIVILEGES |
                        TOKEN_QUERY, TRUE, &hThread);
    if (!b) {
        if (GetLastError() != ERROR_NO_TOKEN) {
            return b;
        }

        b = OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE, &hProcess);
        if (!b) {
            return b;
        }

        b = DuplicateTokenEx(hProcess, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY |
                             TOKEN_IMPERSONATE, NULL, SecurityImpersonation,
                             TokenImpersonation, &hThread);
        if (!b) {
            CloseHandle(hProcess);
            return b;
        }

        b = SetThreadToken(NULL, hThread);
        if (!b) {
            CloseHandle(hProcess);
            CloseHandle(hThread);
            return b;
        }

        CloseHandle(hProcess);
    }

    ZeroMemory(&tokenPrivileges, sizeof(tokenPrivileges));

    b = LookupPrivilegeValue(NULL,PrivilegeName,&tokenPrivileges.Privileges[0].Luid);
    if (!b) {
        return b;
    }

    tokenPrivileges.PrivilegeCount = 1;
    tokenPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

    b = AdjustTokenPrivileges(hThread, FALSE, &tokenPrivileges,
                              sizeof(tokenPrivileges), &oldTokenPrivileges,
                              &oldPrivilegesLength);

    CloseHandle(hThread);

    return b;
}
Example #30
0
Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);

    // Updates only for supported platforms
    if (!supported)
        fatalError(tr("The qTox updater is not supported on this platform."));

#ifdef Q_OS_WIN
    // Get a primary unelevated token of the actual user
    hPrimaryToken = nullptr;
    HANDLE hShellProcess = nullptr, hShellProcessToken = nullptr;
    const DWORD dwTokenRights = TOKEN_QUERY | TOKEN_IMPERSONATE | TOKEN_ASSIGN_PRIMARY
                                | TOKEN_DUPLICATE | TOKEN_ADJUST_DEFAULT | TOKEN_ADJUST_SESSIONID;
    DWORD dwPID = 0;
    HWND hwnd = nullptr;
    DWORD dwLastErr = 0;

    // Enable SeIncreaseQuotaPrivilege
    HANDLE hProcessToken = NULL;
    if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hProcessToken))
        goto unelevateFail;
    TOKEN_PRIVILEGES tkp;
    tkp.PrivilegeCount = 1;
    LookupPrivilegeValueW(NULL, SE_INCREASE_QUOTA_NAME, &tkp.Privileges[0].Luid);
    tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
    AdjustTokenPrivileges(hProcessToken, FALSE, &tkp, 0, NULL, NULL);
    dwLastErr = GetLastError();
    CloseHandle(hProcessToken);
    if (ERROR_SUCCESS != dwLastErr)
        goto unelevateFail;

    // Get a primary copy of the desktop shell's token,
    // we're assuming the shell is running as the actual user
    hwnd = GetShellWindow();
    if (!hwnd)
        goto unelevateFail;
    GetWindowThreadProcessId(hwnd, &dwPID);
    if (!dwPID)
        goto unelevateFail;
    hShellProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, dwPID);
    if (!hShellProcess)
        goto unelevateFail;
    if (!OpenProcessToken(hShellProcess, TOKEN_DUPLICATE, &hShellProcessToken))
        goto unelevateFail;

    // Duplicate the shell's process token to get a primary token.
    // Based on experimentation, this is the minimal set of rights required for CreateProcessWithTokenW (contrary to current documentation).
    if (!DuplicateTokenEx(hShellProcessToken, dwTokenRights, NULL, SecurityImpersonation, TokenPrimary, &hPrimaryToken))
        goto unelevateFail;

    qDebug() << "Unelevated primary access token acquired";
    goto unelevateCleanup;
unelevateFail:
    qWarning() << "Unelevate failed, couldn't get access token";
unelevateCleanup:
    CloseHandle(hShellProcessToken);
    CloseHandle(hShellProcess);
#endif

    QMetaObject::invokeMethod(this, "update", Qt::QueuedConnection);
}