在Windows Vista里面,進程是分權限級別的。Windows會根據(jù)manifest內(nèi)容、Windows Installer detection、兼容性數(shù)據(jù)庫等方法判斷一個進程是否需要一開始就運行在完整admin模式下。
但是不是所有的程序一開始就需要運行在完整admin模式下的,例如任務管理器TaskMgr.EXE。在Windows Vista里面,啟動任務管理器以后,默認只能顯示當前賬戶相關的進程信息,只有當點擊下面這個按鈕并回應UAC提示以后才能顯示所有用戶的進程信息:
Show processes from all users 按鈕前面有一個Windows 安全中心的圖標。這個表示這個操作需要觸發(fā)UAC。這個倒是沒有什么特別的。問題的關鍵在于:TaskMgr是怎么觸發(fā)UAC的?
我們知道,一個沒有完全admin權限的進程是沒法直接創(chuàng)建更高權限進程的,也就是說一般權限下的進程是沒法直接創(chuàng)建完全Admin權限進程的。因此CreateProcess API函數(shù)肯定是不能使用的。如果使用CreateProcessAsUser函數(shù),那么需要提供一個比較高的令牌才能完成,這個需要有額外的來源,而TaskMgr顯然不具備這種能力。那TaskMgr是怎么完成這個神秘的動作呢?
上述問題我思考了數(shù)個月,上網(wǎng)搜索也沒有搜索到有價值的內(nèi)容。直到昨天晚上才有空去調試一把,看看到底是怎么玩的。
我用windbg attach到 taskmgr 進程上,然后把所有的進程創(chuàng)建相關函數(shù)全部設置了斷點,然后點擊Show processes from all users 按鈕,結果ShellExecuteExW函數(shù)被斷下了,難道ShellExecuteExW有什么特殊的地方嗎?查閱最新的MSDN關于ShellExecuteExW的說明文檔,什么介紹都沒有。是斷點有問題嗎?
繼續(xù)使用windbg單步調試,當程序執(zhí)行的時候,有一個看起來很關鍵的函數(shù)調用:
call SHELL32!ShellExecuteNormal (7656e6ce),看到這個名字我的第一個直覺是這個是真正的執(zhí)行函數(shù),前面還有很多操作僅僅是一些檢查步驟。當執(zhí)行完call SHELL32!ShellExecuteNormal (7656e6ce)指令以后,UAC框彈出了??吹経AC框的彈出,我已經(jīng)可以確認任務管理器是使用ShellExecuteExW某個在MSDN上面沒有公開的操作觸發(fā)UAC的。根據(jù)前面的描述,call SHELL32!ShellExecuteNormal (7656e6ce)指令是一個關鍵指令,因此需要檢查call SHELL32!ShellExecuteNormal (7656e6ce)指令之前的參數(shù)操作。
呵呵,這回我盯上了push esi指令了。
windbg里面查看esi對應的內(nèi)存內(nèi)容以后發(fā)現(xiàn)可能是一個結構體,由于是ShellExecuteExW函數(shù)里面執(zhí)行的,因此我猜測這個結構體是 SHELLEXECUTEINFO,對照SHELLEXECUTEINFO結構體的定義,果然和esi內(nèi)容相符。最后一步就是檢查結構體里面各個參數(shù)的情況了。當我發(fā)現(xiàn)LPCTSTR lpVerb指向的參數(shù)內(nèi)容(db 0xe5d93c命令)是“runas”這個字符串的時候,Taskmgr 將自身提示為完全admin權限的方法也就揭曉了:
在Windows Vista里面,ShellExecuteExW lpVerb的參數(shù)可以傳入runas命令,使得系統(tǒng)調用 ShellExecuteExW 的時候,會強制將目標文件以完全admin模式啟動,即使目標文件的manifest沒有申明需要完全admin權限。
效果等同于在目標程序上右鍵點擊,然后選擇 run as administrator 菜單內(nèi)容。
幕后:當全部搞定以后,我上網(wǎng)google了一下,發(fā)現(xiàn)這個方法早有人提及了,而且還是在 Vista Compatibility Team Blog 上面,我花的1個多小時全部白費了,為啥先前都沒有搜索到呢??郁悶
但是不是所有的程序一開始就需要運行在完整admin模式下的,例如任務管理器TaskMgr.EXE。在Windows Vista里面,啟動任務管理器以后,默認只能顯示當前賬戶相關的進程信息,只有當點擊下面這個按鈕并回應UAC提示以后才能顯示所有用戶的進程信息:
Show processes from all users 按鈕前面有一個Windows 安全中心的圖標。這個表示這個操作需要觸發(fā)UAC。這個倒是沒有什么特別的。問題的關鍵在于:TaskMgr是怎么觸發(fā)UAC的?
我們知道,一個沒有完全admin權限的進程是沒法直接創(chuàng)建更高權限進程的,也就是說一般權限下的進程是沒法直接創(chuàng)建完全Admin權限進程的。因此CreateProcess API函數(shù)肯定是不能使用的。如果使用CreateProcessAsUser函數(shù),那么需要提供一個比較高的令牌才能完成,這個需要有額外的來源,而TaskMgr顯然不具備這種能力。那TaskMgr是怎么完成這個神秘的動作呢?
上述問題我思考了數(shù)個月,上網(wǎng)搜索也沒有搜索到有價值的內(nèi)容。直到昨天晚上才有空去調試一把,看看到底是怎么玩的。
我用windbg attach到 taskmgr 進程上,然后把所有的進程創(chuàng)建相關函數(shù)全部設置了斷點,然后點擊Show processes from all users 按鈕,結果ShellExecuteExW函數(shù)被斷下了,難道ShellExecuteExW有什么特殊的地方嗎?查閱最新的MSDN關于ShellExecuteExW的說明文檔,什么介紹都沒有。是斷點有問題嗎?
繼續(xù)使用windbg單步調試,當程序執(zhí)行的時候,有一個看起來很關鍵的函數(shù)調用:
call SHELL32!ShellExecuteNormal (7656e6ce),看到這個名字我的第一個直覺是這個是真正的執(zhí)行函數(shù),前面還有很多操作僅僅是一些檢查步驟。當執(zhí)行完call SHELL32!ShellExecuteNormal (7656e6ce)指令以后,UAC框彈出了??吹経AC框的彈出,我已經(jīng)可以確認任務管理器是使用ShellExecuteExW某個在MSDN上面沒有公開的操作觸發(fā)UAC的。根據(jù)前面的描述,call SHELL32!ShellExecuteNormal (7656e6ce)指令是一個關鍵指令,因此需要檢查call SHELL32!ShellExecuteNormal (7656e6ce)指令之前的參數(shù)操作。
呵呵,這回我盯上了push esi指令了。
windbg里面查看esi對應的內(nèi)存內(nèi)容以后發(fā)現(xiàn)可能是一個結構體,由于是ShellExecuteExW函數(shù)里面執(zhí)行的,因此我猜測這個結構體是 SHELLEXECUTEINFO,對照SHELLEXECUTEINFO結構體的定義,果然和esi內(nèi)容相符。最后一步就是檢查結構體里面各個參數(shù)的情況了。當我發(fā)現(xiàn)LPCTSTR lpVerb指向的參數(shù)內(nèi)容(db 0xe5d93c命令)是“runas”這個字符串的時候,Taskmgr 將自身提示為完全admin權限的方法也就揭曉了:
在Windows Vista里面,ShellExecuteExW lpVerb的參數(shù)可以傳入runas命令,使得系統(tǒng)調用 ShellExecuteExW 的時候,會強制將目標文件以完全admin模式啟動,即使目標文件的manifest沒有申明需要完全admin權限。
效果等同于在目標程序上右鍵點擊,然后選擇 run as administrator 菜單內(nèi)容。
幕后:當全部搞定以后,我上網(wǎng)google了一下,發(fā)現(xiàn)這個方法早有人提及了,而且還是在 Vista Compatibility Team Blog 上面,我花的1個多小時全部白費了,為啥先前都沒有搜索到呢??郁悶