原創文章,轉載請注明: 轉載自C/C++程式員之家
本文連結位址: MFC管理者權限(UAC下的程式權限提升)
UAC是微軟為了提高Windows的安全性,自Windows Vista開始引入的新安全機制。
傳統的NT核心系統依靠access token來做權限處理,access token由目前使用者所在的使用者組的權限決定。而由于長期以來的不當使用習慣問題,幾乎所有Windows上使用者所在的組都是管理者。
在啟用UAC之後,系統會額外引入一個filtered token,并且這個token預設隻能按照Standard User的權限去執行。是以這個token也通常被叫做limited filtered token。
PS:關于上面的簡單介紹,請參考這裡
因為執行權限有限,某些操作必然會要求更高的管理者權限。此時,通常就需要一個privilegs elevation的操作。程式可以向系統請求提權,系統會将此請求通過提一個提示框,請使用者确認。
這裡多說一點,如果目前使用者的使用者組權限不是管理者,提權操作是要求輸入管理者密碼的,這點和在Linux中的相應操作類似。不過我想大部分人的使用者組都是管理者,是以這句話當我沒說好了…
另外需要注意的一點是,這個elevation是受到一個process-boundary的限制的,具體展現在兩方面:
- 程式隻能在運作前要求提權。如果已經在運作了,那麼将失去申請提權的能力
- 權限提升僅對此次程序有效
不過,一個具有full administrator token的程序利用CreateProcess建立的程序預設都繼承了full administrator token。
提升權限的操作大緻有兩個:
- 自動提權請求
- 手動提權請求
自動提權請求
如果你的程式始終要求以full administrator token的模式運作,那麼應該考慮在程式啟動時自動向系統請求提權。
需要做的事情很簡單,隻需要更改程式的manifest檔案。這個檔案本質上是一個XML檔案,預設情況下,它的内容因該是:
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
隻要将requestExecutionLevel的level的值改成requiredAdministrator,再重新将這個檔案連結入EXE即可。
另外,如果使用Visual Studio作為開發環境,直接在項目的屬性裡可以更改UAC的權限要求設定
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIyZuBnLwEDMyMndvwVNw8CX0EDMy8CXzRWYvxGc19CX05WZ052bj1Cc39CXt92Yu4GZ1lmbpFnLuR2YwB3Yvw1LcpDc0RHaiojIsJye.png)
UAC下的程式權限提升
手動提權請求
如果程序在運作途中需要full administrator token怎麼辦?
答案是,沒辦法。具體原因前面說了。
不過,一個具有limited filtered token的程序是可以運作一個程式,并且讓這個程式去請求系統提權。而且,我們可以讓這個程序去再一次運作自己的EXE檔案,并且請求提權。
這裡需要的API是ShellExecuteEx而不是根正苗紅的CreateProcess。因為後者沒有和UAC相關的屬性設定
ShellExecuteEx需要一個SHELLEXECUTEINFO結構,這個結構如下:
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
這裡我們需要關心大概隻有三個成員:lpVerb,lpFile和nShow
lpVerb必須被設定為runas;而lpFile是要運作可執行檔案的完整路徑;nShow控制視窗的顯示。
需要關注nShow是因為大部分初始化操作都将這個屬性預設初始化為0,很不巧的是,0對應的屬性是SW_HIDE。除非你不需要窗體,否則還是需要手動調教下這個成員。
通常來說,如果某個程式運作途中可以通過觸發,轉而使用full administrator token運作,那麼八成是利用這個API重新運作EXE檔案,再将原有的程式退出或者隐藏。
至于剩下的那兩成,表示不明白,不過我想可以請教傳說中的花大嬸。
Demo
自己手寫了一個Demo,程式預設以limited filtered token運作。單擊提權按鈕,向系統請求提權。
預設時是這樣:
MFC管理者運作
提升權限後是這樣:
MFC管理者運作
核心代碼是兩塊:
- 判斷目前程序是否已經提權. 這個通過判斷目前進