Windows UIPI

本文详细解析了Windows Vista中引入的UIPI安全概念,解释了低权限进程如何受到高权限进程的限制,包括窗口句柄验证、消息传递、线程钩子、日志钩子和动态链接库注入等。同时,通过实战演示了两个不同权限级别进程之间的交互,展示了如何在特定条件下绕过UIPI保护。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

从Vista开始,微软引入了一个新的安全概念称作UIPI。UIPI是指低权限的进程不能对高权限的进程做以下的一些事情:


  • Perform a window handle validation of higher process privilege.

  • SendMessage or PostMessage to higher privilege application windows. These application programming interfaces (APIs) return success but silently drop the window message.

  • Use thread hooks to attach to a higher privilege process.

  • Use Journal hooks to monitor a higher privilege process.

  • Perform dynamic link-library (DLL) injection to a higher privilege process

就第二项来说,并非所有的调用都会失败,通过更改MessageFilter,还是可以让一些消息进入到高权限进程的队列中的( ChangeWindowMessageFilter )。

无论怎样,UIPI保护了高权限进程的界面和用户对象(User Object)不受到低权限恶意进程的更改。

通常,一个进程权限的高低取决于它的Integrity Level (IL)。

-------------------------------------------

实战:

现在有两个进程,进程代码基本完全一致,有一个进程将作为管理员模式运行,另一个则使用采取直接运行的方式。

在这种条件下,管理员模式运行的进程比后者的IL要高


进程代码:

高权限进程

/********获取进程的IL等级********/
	HANDLE hToken = NULL;
	OpenProcessToken(GetCurrentProcess(),TOKEN_QUERY,&hToken);
	TOKEN_MANDATORY_LABEL* pIL;
	DWORD dwRetLen = 0;
	GetTokenInformation(hToken,TOKEN_INFORMATION_CLASS::TokenIntegrityLevel,NULL,0,&dwRetLen);
	BYTE* pBuffer = new BYTE[dwRetLen];
	GetTokenInformation(hToken,TOKEN_INFORMATION_CLASS::TokenIntegrityLevel,pBuffer,dwRetLen,&dwRetLen);
	pIL = (TOKEN_MANDATORY_LABEL*)pBuffer;
	DWORD* pRID= GetSidSubAuthority(pIL->Label.Sid,0);
	printf_s("Process IL:<%08x>\n",*pRID);


/********创建窗口(即UI)********/
	WNDCLASS wc = {0};
	wc.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH);
	wc.hCursor = ::LoadCursor((HINSTANCE)::GetModuleHandle(NULL),IDC_ARROW);
	wc.hInstance = (HINSTANCE)::GetModuleHandle(NULL);
	wc.lpszClassName = _T("CHighPrivilegeWindow");
	wc.style = CS_HREDRAW | CS_VREDRAW;
	wc.lpfnWndProc = HighPrevilegeWindowProc;
	if(!RegisterClass(&wc)) return GetLastError();
	HWND hMainWnd = CreateWindow(_T("CHighPrivilegeWindow"),_T("ProcessHighPrevilege"),WS_OVERLAPPEDWINDOW | WS_VISIBLE,0,0,1000,500,NULL,NULL,(HINSTANCE)GetModuleHandle(NULL),NULL);
	if (!hMainWnd) return GetLastError();
	::SetTimer(hMainWnd,1,1000,NULL); //启动一个定时器,每1秒更改一次低权限进程的窗口标题
	BOOL bRet;
	MSG msg;
	while((bRet = GetMessage(&msg,NULL,0,0)))
	{
		if(bRet != -1)
		{
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
		else break;
	}
	return 0;

/********定时器响应********/
{UINT nTimerID = (UINT)wParam;if(nTimerID == 1){HWND hLowWnd = ::FindWindow(_T("CLowPrivilegeWindow"),_T("ProcessLowPrevilege"));if(hLowWnd){if(SendMessage(hLowWnd,WM_SETTEXT,(WPARAM)_tcslen(_T("Low_Set")),(LPARAM)_T("Low_Set")) == TRUE) //设定低权限窗口标题printf_s("Text set to Low Window\n");KillTimer(hWnd,1);}}}return 0;

低权限进程

低权限进程则定时搜索高权限进程窗口,并更改高权限进程的窗口标题

{
	UINT nTimerID = (UINT)wParam;
	if(nTimerID == 1)
	{
		HWND hHighWnd = ::FindWindow(_T("CHighPrivilegeWindow"),_T("ProcessHighPrevilege"));
		if(hHighWnd)
		{
			if(SendMessage(hHighWnd,WM_SETTEXT,(WPARAM)_tcslen(_T("High_Set")),(LPARAM)_T("High_Set")) == TRUE) //设定高权限的窗口标题
				printf_s("Text set to High Window\n");
			KillTimer(hWnd,1);
		}
	}
}
return 0;




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值