介紹
在早期版本的Windows中,同一個用戶帳號下運行的進程共享相同的安全權限。例如,一 個線程可以發送窗口信息到另一個線程中的窗口。從Windows Vista開媽這個並不總能正常工 作。新特性權限級別被附加到進程上(也可以是其它特性)。進程不可以將消息窗口發送到 具有更高權限級別的進程,盡管他們以運行於同一個用戶帳號(例如當前登錄用戶)。
UIPI防止來自其它可能更高權限的線程中創建的windows消息進行惡意代碼攻擊。
顯示UIPI
此問題在UAC(用戶帳戶控制)啟用時最為清晰(默認情況下是啟用的)。UAC中,一個管 理員登錄獲取兩個令牌對象:第一個是管理員令牌,具有最高權限(類似於Windows Vista以 前版本的系統帳號),第二個令牌是過濾後的版本,帶有標准用戶權限。
默認情況下,進程用完整性級別為normal(UIPI 級別分為low,normal,high,和system)的 標准用戶啟動。作為對比,進程使用管理員權限(例如,當用戶右擊“Run as Administrator”或用”runas”命令調用SheellExecute)使得進程具有high的權限級別。
如此,系統可以用使單一權限級別運行兩種類型的進程(技術上講用的是同一用戶帳號) 。UIPI支持低完整性級別(integrity level)的進程和更高級別的進程進行通信。
使用用Windows Sysinternals 的Process Explorer查看權限級別 (http://www.microsoft.com/technet/sysinternals ) ,選擇“Integrity Level”列
這裡有 個基於同一圖片的兩個進程的例子,其中一個用標准用戶權限啟動另一個使用管理員權限啟 動。注意他們是不同的完整性級別(integrity level)。
UIPI 施加限制
較低權限的應用程序不能做如下操作:
• 驗證更高權 限進程創建的窗口。調用 SendMessage 或 PostMessage到更高權限進程創建的窗口
• 使用線程鉤子來附加一個更高權限的進程。
• 使用日志鉤子 (SetWindowsHookEx) 來監視更高權限的進程
• DLL注入到更高權限的進程。
下列windows消息永遠是允許狀態:
• 0x000 - WM_NULL
• 0x003 - WM_MOVE
• 0x005 - WM_SIZE
• 0x00D - WM_GETTEXT
• 0x00E - WM_GETTEXTLENGTH
• 0x033 - WM_GETHOTKEY
• 0x07F - WM_GETICON
• 0x305 - WM_RENDERFORMAT
• 0x308 - WM_DRAWCLIPBOARD
• 0x30D - WM_CHANGECBCHAIN
• 0x31A - WM_THEMECHANGED
• 0x313, 0x31B (WM_???)
UIPI 問題的修復
基於比Windows Vista更早的操作系統的應用程序 會需要互相之前能傳遞消息。Windows Vista 引入了ChangeWindowMessageFilter API,這是 已編檔方法,用來添加或刪除能通過隔離級別的消息。需要允許消息傳遞到更高權限的進程 的窗口時,使用如下方法:
ChangeWindowMessageFilter(message, MSGFLT_ADD);
類似的標記 MSGFLT_REMOVE從進程允許列表中刪除消息。
Windows 7引入了一個新的函數 ChangeWindowMessageFilterEx,相對於控制整個進程它可以在特定窗口控制允許消息:
BOOL ChangeWindowMessageFilterEx(
HWND hWnd, UINT message, DWORD action,
PCHANGEFILTERSTRUCT pChangeFilterStruct
);
事件的參數可以是MSGFLT_ALLOW (類似於ChangeWindowMessageFilter 中的MSGFLT_ADD ), MSGFLT_DISALLOW (類似於MSGFLT_REMOVE),和 MSGFLT_RESET,將窗 口重設成默認篩選器,可選的架構允許操作結果以接收更多的信息。