在Session 0中创建用户进程

本文介绍在Windows系统中如何在Session0中创建进程,包括两种实现方法,并解释了为何从Windows7开始,服务被隔离在Session0,以提高安全性。
在Windows XP, Windows Server 2003或者更早期的Windows操作系统中,所有的服务和应用程序都是运行在与第一个登录到控制台的用户得Session中。这个Session叫做Session 0。在Session 0 中一起运行服务和用户应用程序,由于服务是以高权限运行的,所以会造成一些安全风险。这些因素使得一些恶意代理利用这点,来寻找提升他们自身权限的结构。

在Windows7中,服务在一个叫做Session 0 的特殊Session中承载。由于应用程序运行在用户登录到系统后所创建的Session 0 之后的Session中,所以应用程序和服务也就隔离开来:第一个登录的用户在Session 1中,第二个在Session 2中,以此类推。事实上运行在不同的Session中,如果没有特别将其放入全局命名空间(并且设置了相应的访问控制配置),是不能互相传递窗体消息,共享UI元素或者共享kernel对象。

利用CreateProcessAsUser,我们可以在Session 0中创建用户进程,下面提供两种创建方式:


typedef   BOOL   (*FUNCTypeA)(   LPVOID*,   HANDLE,   BOOL)   ;   
typedef   BOOL   (*FUNCTypeB)(   LPVOID   ); 

typedef	DWORD (WINAPI* PWTSActiveSessionID)(); 

DWORD GetActiveConsoleSessionId()
{ 
	PWTSActiveSessionID pWTSActiveSessionID;
	DWORD dwResult = 0; 	
	HINSTANCE hKernal32 = NULL; 

	do { 	
		OSVERSIONINFO os = {sizeof(OSVERSIONINFO)}; 	
		GetVersionEx(&os);	
		if(os.dwMajorVersion == 5 && os.dwMinorVersion==0)
		{ 
			break; 	
		} 	
		else
		{
			hKernal32 = LoadLibrary(_T("kernel32.dll")); 		
			if(hKernal32 == NULL)
			{
				break; 
			}
			pWTSActiveSessionID = (PWTSActiveSessionID)GetProcAddress(hKernal32, "WTSGetActiveConsoleSessionId" ); 			
			if(pWTSActiveSessionID == NULL)
			{
				break; 			
			}
			dwResult = pWTSActiveSessionID();	
		} 

	} while(FALSE); 

	if(hKernal32 != NULL) 
		FreeLibrary(hKernal32);

	return dwResult;
} 
BOOL CreateUserProcess1(LPTSTR szMonName)
{
	DWORD	dwSessionId;
	BOOL	bResult;
	HANDLE	hTokenThis = NULL; 
	HANDLE	hTokenDup = NULL; 
	HANDLE	hThisProcess;

	STARTUPINFO  starinfo;
	PROCESS_INFORMATION processinfo;

	HMODULE   hModule;

	FUNCTypeA   CreateEnvironmentBlock;   
	FUNCTypeB   DestroyEnvironmentBlock;  

	hThisProcess	= GetCurrentProcess(); 
	DWORD ddd  = GetLastError();
	bResult	= OpenProcessToken(hThisProcess,TOKEN_ALL_ACCESS, &hTokenThis); 	

	ddd  = GetLastError();

	bResult = DuplicateTokenEx(hTokenThis, MAXIMUM_ALLOWED,NULL, SecurityIdentification, TokenPrimary, &hTokenDup); 

	dwSessionId = GetActiveConsoleSessionId();
	bResult = SetTokenInformation(hTokenDup, TokenSessionId, &dwSessionId, sizeof(DWORD));     	

	hModule =LoadLibrary(_T("userenv.dll")); 
	if (hModule)   
	{   
		CreateEnvironmentBlock = (FUNCTypeA) GetProcAddress(hModule,"CreateEnvironmentBlock");   
		DestroyEnvironmentBlock= (FUNCTypeB)GetProcAddress(hModule,"DestroyEnvironmentBlock");   
	}  	

	ZeroMemory( &starinfo, sizeof(STARTUPINFO) );
	ZeroMemory( &processinfo, sizeof(PROCESS_INFORMATION) );

	starinfo.cb = sizeof(starinfo);  
	starinfo.wShowWindow = SW_SHOWNORMAL;
	starinfo.dwFlags |= STARTF_USESTDHANDLES;
	starinfo.lpDesktop = L"WinSta0\\Default";

	FreeLibrary(hModule);	

	TCHAR zsAppName[MAX_PATH];
	_tcscpy(zsAppName,szMonName);
	bResult = CreateProcessAsUser(	hTokenDup,
		zsAppName,
		NULL,
		NULL,
		NULL,
		TRUE,
		NORMAL_PRIORITY_CLASS,
		NULL,
		NULL,
		&starinfo,
		&processinfo);					

	CloseHandle(hTokenDup);	
	
	if(bResult)
	{
		CloseHandle(processinfo.hThread);
		CloseHandle(processinfo.hProcess);
		return TRUE;	
	}

	return 0;	
}

typedef DWORD (*WTSGETACTIVECONSOLESESSIONID)(void);
typedef BOOL (WINAPI *WTSQUERYUSERTOKEN)(ULONG,PHANDLE);
WTSQUERYUSERTOKEN WTSProc=NULL; 
HMODULE hModWTS=NULL;
BOOL CreateUserProcess2(TCHAR *filename)
{     
	PROCESS_INFORMATION pInfo; 
	STARTUPINFO sInfo;    
	BOOL	bRet = FALSE;

	ZeroMemory(&sInfo,sizeof(sInfo));
	ZeroMemory(&pInfo,sizeof(pInfo));

	sInfo.cb=sizeof(STARTUPINFO);
	sInfo.cbReserved2=0;
	sInfo.dwFillAttribute=0;
	sInfo.dwFlags=STARTF_USESHOWWINDOW;
	sInfo.wShowWindow=SW_SHOW;
	sInfo.lpDesktop = L"winsta0\\default";
	
	HANDLE hToken=NULL; 
	HMODULE hmod = LoadLibrary( L"kernel32.dll");
	if(hmod == NULL)
	{        
		return bRet;
	}

	WTSGETACTIVECONSOLESESSIONID lpfnWTSGetActiveConsoleSessionId = (WTSGETACTIVECONSOLESESSIONID)GetProcAddress(hmod, "WTSGetActiveConsoleSessionId"); 
	DWORD dwSessionId=-1;

	
	dwSessionId = lpfnWTSGetActiveConsoleSessionId();
	FreeLibrary(hmod);

	hModWTS = LoadLibrary( L"wtsapi32.dll");

	if(hModWTS !=NULL)
	{
		WTSProc = (WTSQUERYUSERTOKEN) GetProcAddress(hModWTS, "WTSQueryUserToken");
		TCHAR zsAppName[MAX_PATH];
		_tcscpy(zsAppName,filename);
		if(WTSProc!=NULL)
		{ 
			if(WTSProc(dwSessionId,&hToken)!=0)
			{
				if(CreateProcessAsUser(hToken,NULL,zsAppName,NULL,NULL,FALSE,NORMAL_PRIORITY_CLASS ,NULL,NULL,&sInfo,&pInfo))
				{                     
					CloseHandle(pInfo.hThread);
					CloseHandle(pInfo.hProcess); 
					bRet = TRUE;
				}
				CloseHandle(hToken);
			}
		}
		FreeLibrary(hModWTS);
		hModWTS = NULL;
	}

	return bRet;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值