• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            yehao's Blog

            UAC的前世今生

            http://www.xiangwangfeng.com/2010/10/20/uac%E7%9A%84%E5%89%8D%E4%B8%96%E4%BB%8A%E7%94%9F/

            前言:

                 當初弄這么個博客純粹出于蛋疼,想體會體會自己買空間,建站的樂趣。現在差不多體會完了,不過也不能就這么關了吧?于是考慮著要定期整點東西,充實充實這個博客。按照我以往的表現來看,除了QQ空間目前還存活著,絕大多數我寫過的博客都半途而廢了,一來懶,二來也沒那么多東西好寫:人總不能每天都在傷春悲秋—-畢竟不是靠賣愁滋味賺錢的人,就算寫出來也意義不大,過個個把月哪還記得當年在傷啥悲啥,就算記得,感受也不深,而且有時翻出來回味卻發現當年的自己如此感性,悶騷—-燥得很,不如難得糊涂,忘了算了。

                 于是考慮整點技術性的東西(當然以學習筆記和某些蛋疼的技術點為主),主要是我這人一般懶得記筆記,初中到現在唯一記筆記本的還是高三復習物理那會,主要原因是物理實在差得離譜。以至于記筆記給我的感覺很不好,而且很多東西一旦我理解了基本不會忘—-好記性不如爛筆頭,但是好的理解力就不同了,記下的東西畢竟是死的。

                 言歸正傳,說這次的主題:UAC。這東西很是煩人,轉到我手里的bug和問題,估計有5%與它有關,很是煩人,于是在這一篇日志里面詳細記錄一些我理解的UAC知識。

             

            UAC的基本概念

            • 什么是UAC

                   UAC即User Account Control(用戶帳號控制),是微軟從Windows Vista開始為提高安全性而引入的一項新技術。用戶通過這項技術既可以以非管理員身份,也能夠以管理員身份執行常見的任務,而不需要切換賬戶或者注銷。在大多數的情況下,用戶都是以標準用戶的狀態來執行日常任務,而只有當需要設置系統特定資源的操作的任務才會需要用戶以管理員的身份執行,以此來確保進程對系統的“傷害”達到最低。

            • 為什么使用UAC

                   簡單地說使用UAC的理由很簡單:保護系統資源和數據的安全。在XP時代,在系統安裝完畢后任何新建的賬戶都會默認劃入系統管理員組,于是用戶有了安裝,卸載,修改,刪除系統任何地方任何數據的權限,而這正是萬惡之源。而如果能夠控制不同程序的權限,那么大部分的惡意軟件和病毒就不能起作用了。

                   UAC正是基于這種思路進行設計的:嚴格控制進程所能獲得的權限。讓一個進程無時無刻都擁有管理員權限是無法容忍的:一個惡意程序如果被自動運行于我們的系統,且肆無忌憚地執行某些會進行系統資源讀寫操作的代碼而不為我們所知曉那是多么恐怖的事。(XP正是這么做的)所以UAC的策略就是給予進程盡可能低的權限,如果程序需要管理員權限則需要知會當前用戶。同時通過一系列的措施來保障程序的正確運行:

              1.在可行的情況下,進行操作的權限將從系統管理員調整為標準用戶。(給予最低權限)

              2.利用虛擬化技術在沒有獲得系統管理員權限的情況下協助程序運行。(例如對注冊表訪問的重定向,保證舊版本程序的兼容性)

              3.對程序進行再處理,這樣用戶帳戶控制功能就可以知道在什么情況下需要系統管理員權限。(可執行文件的UAC頭,來控制和判斷程序所需要的權限,默認是asInvoker或None)

              4.確保在系統管理員權限下運行的程序和在標準用戶權限下運行的程序是分離的(如UIPI)

            • UAC帶來的影響

                   對普通用戶而言,UAC的引入可能并沒有帶來多大的影響,更多的可能只是在啟動特定程序的時候有時候會跳出提示通知用戶以管理員身份運行,僅此而已。但是這個地方有個比較尷尬的問題:UAC(或者其他類似的安全措施)是基于如下假設的:

                   1.個人用戶對于系統安全有一定的認識,能夠分辨哪些程序是好的,哪些是壞的。但是實際上對于大多數網民來說,這個假設未必成立,即使惡意軟件跳出提示要以管理員身份運行,他們往往也是點確定讓它運行。那么UAC的意義又在哪呢?

                  2.企業用戶可以對系統安全一無所知,但是考慮到企業內部會有IT部門幫忙進行安全屬性配置和軟硬件的安裝,UAC對他們來說是很有效的:只需要分配給他們標準用戶帳號進行日常任務處理既可。但現實情況卻是: 如果企業用戶安裝軟件或其他需要管理員權限的事務都需要知會IT,那整個溝通成本太高,不現實。更何況很多軟件產品都有不兼容UAC的問題。(比如部分公司開發的程序為了“繞過”UAC,直接把程序設為必須以管理員帳戶運行)

                   對于開發人員來說可能影響會更大。如何讓自己新老程序兼容和適應UAC的規則是一個不大不小的課題。

                

              開發所需要了解的UAC

            • UAC的基本實現原理

                   在Windows中有兩項比較重要的概念:ACL和Access Token。ACL即Access Control List(直譯成:訪問控制列表),對于Wdinows中的所有資源來說都會有自己的ACL,這個列表決定了這個資源可以被具有哪些權限的用戶/進程所訪問。而Access Token即用戶的訪問令牌,這決定了用戶對資源的訪問屬性。在Vista之前的系統中,如果用戶使用了標準用戶(如XP中所謂的受限用戶),用戶就會得到一個和之相對應的Access Token,只能訪問和修改有限的用戶資源。但只要用戶用了管理員組的帳號進行登入,用戶就能夠獲取一個所謂的"Full Access Token",即可以獲取到對任意資源的訪問權。這顯然是多余而且不安全的,于是從Vista起的UAC就做了如下的調整:

                   1.如果用戶是標準用戶,那么還是和以前一樣分配給用戶一個標準的訪問令牌。

                   2.而如果用戶是以管理員用戶登入,則有所不同:系統不再是和以前一樣分配個萬能的訪問令牌,而是生成兩份訪問令牌:一個完整的管理員訪問令牌和一份經“和諧”的標準用戶令牌。在默認的情況下,管理員權限會被移除(或者說被保存到某個地方,等用戶主動請求),而用戶只拿到了他所需要的標準用戶訪問權限,并通過它創建了Explorer.exe程序,并以其為父進程創建所有基于標準用戶的進程。

              具體的流程可參考如圖(從MSDN上盜得):

              cc709628.3be4da3f-8384-466f-b1ff-2185844c139c(en-us,WS.10)

            • UAC影響到的資源

                    從上文我們已經可以知道UAC會使得我們的程序運行在一個盡可能低的權限下,而這個權限可能過低,而不在某些敏感資源的ACL允許范圍。那么從技術角度來說,搞清楚哪些資源是所謂的敏感資源就很重要—-知己知彼,百戰不殆。從Wiki摘抄的需要UAC授權的操作:

              • 配置Windows Update
              • 增加或刪除用戶帳戶
              • 改變用戶的帳戶類型
              • 改變UAC設置
              • 安裝ActiveX
              • 安裝或移除程序
              • 安裝設備驅動程序
              • 設置家長控制
              • 將文件移動或復制到Program Files或Windows目錄
              • 查看其他用戶文件夾

                    基本上,只要有涉及到訪問系統磁盤的根目錄(例如C:),訪問Windows目錄,Windows系統目錄,Program Files目錄,訪問Windows安全信息以及讀寫系統登錄數據庫(Registry)的程序訪問動作,都會需要通過UAC的認證。

            • UAC帶來的程序啟動選項的變化和注意事項

                    對于普通用戶來講,UAC最直觀的感受就是在很多程序圖標多了個小盾,且雙擊后會出來個用戶賬戶控制的窗口。而對于技術人員來說當然更需要關心真正的內幕:啟動的時候進程做了提權的動作,獲取了更高權限的用戶令牌。(而這又可能導致這個進程的用戶相關上下文直接改變,當然這是后話)在Vista以后的程序在默認情況下會有3種啟動選項:asInvoker(None),highestAvailable和requireAdministrator。其中highestAvailable最不為大家熟知:這種啟動方式請求當前賬戶可以獲取到的最高權限:如果本身是管理員組內成員,則可以得到完整的管理員訪問令牌,呼風喚雨。而如果是標準用戶則只能得到它這個用戶能夠得到的最高權限。(具體如何設置程序啟動選項在下面的Tips中繼續說)上一幅MSDN提供的開啟UAC狀態下程序啟動的流程圖:

              IC25707

            • MS為支持UAC引入的新技術和注意事項

                 為實現UAC的所有功能,微軟可謂煞費苦心,整了很多新的技術和新概念出來。(雖然個人覺得這個技術對于一般用戶來說還是很雞肋)下面就羅列一部分我們平常開發中可能會碰到或者遇到的技術:

                  1.Installer Dection

                   這個技術最大的作用是為了兼容以前的以前版本系統中的程序(尤其是安裝程序,顧名思義嘛),在UAC下安裝程序做的很多事情可能都是十惡不赦,需要最高權限的(如寫注冊表,寫敏感文件目錄),而舊版本的程序壓根沒有做任何特殊處理(或者說是只是填充了一些默認信息),所以一種行之有效的安裝程序檢測技術是很必要的,否則很多程序安裝都不成功,更毋論運行了。

                  MSDN上總結了一些Installer Dection的原則:

                  1.文件名包含關鍵字:"install”,“setup”,"update”等關鍵字

                  2.在版本資源的以下字段內包含關鍵字:Vendor,CompanyName,ProductName,File Description,Original Filename,Internal Name,Export Name。(這兩條應該是最SB卻又最有效的一個方法,當年閃電郵的UpdateExec沒有做任何處理卻一直要求能夠以管理員權限運行的事讓我迷茫了很久)

                  3.可執行文件的manifest文件中包含關鍵字

                  4.在鏈接到可執行文件的特定String Table中包含關鍵字 (這個我很迷茫,求解釋)

                  5.鏈接到可執行文件的資源文件數據包含關鍵屬性

                 6.可執行文件包含特定的字節序列(這個意思應該是用戶在manifest中寫入特定屬性,然后鏈接到可執行文件中并填充了某個字段—-現在基本上所有的安裝程序/需要提權的程序都是這么做的)

                    2.Virtualization(虛擬化)

                   這是一項比較扯同時也是為了保證兼容性設計出來的技術。簡單地來說(這個只能簡單來說了,具體的原理沒有相應的參考資料),就是對老程序所進行的“非法”的 訪問系統敏感數據進行重定向,可以分為文件虛擬化和注冊表虛擬化。當用戶對一個需要管理員權限才能夠訪問的文件目錄或者注冊表項進行讀寫都會被重定向。

                                     IC18372                                        

            如左圖,用戶對%ProgramFiles%的讀寫會被定向到%LocalAppData%VirtualStore下,而對于HKLMSoftware的讀寫會被重定向到HKCUSoftwareClassesVirtualStore下。

               特別需要注意的是:因為在XP下養成的習慣,我們對于注冊表的讀寫很多直接就是用KEY_ALL_ACCESS的選項,而到了Vista和Win7后,因為分配給用戶的權限低了(即使管理員帳號登入拿到的權限也是經過“和諧”的,上文已經提到),對注冊表的訪問需要按需設置,如果只是讀取一些注冊表項值就沒必要設置ALL_ACCESS,大多時候READ甚至QUERY的權限就夠了。

              

             

                   3.UIPI

                   這是唯一一項純粹是出于提高安全性而不是確保兼容性引進的新技術。UIPI即User Interface Privilege Isolation,直譯過來就是用戶界面特權隔離。在XP時代到處充斥著各種消息粉碎攻擊,最典型的就是通過發送WM_CLOSE消息使得接收者退出或者發送WM_SETTEXT給其他窗口輸入信息(QQ尾巴算是這種攻擊的典型應用)。大多數程序對于這種攻擊都是無能為了,很多程序(比如QQ,POPO之類的IM)往往只能自己對信息做特殊的過濾和判斷來防范,很是繁瑣。而UIPI的基本作用就是使進程可以攔截接受比自身進程MIC等級低的進程發來的消息。在UIPI開啟的情況下,只要是低MIC等級的進程向高MIC等級的進程發送消息,所有高于WM_USER的消息都默認被攔截,而低于WM_USER的消息也只有部分能夠被選擇性地發送成功,一些比較危險的消息也是直接被攔截掉。

                  所謂MIC即Mandatory Integrity Control,全稱為強制完整性控制,是微軟對Vista以上的系統做的安全性拓展,主要基于Biba模型。其核心在于達到"no write up,no read down"的效果。(這個no read down貌似在Vista里面反映得不是很明顯,或者是沒怎么注意到吧)在Vista和Win7里,MIC共分為6級:不可用,低級,中級,高級,系統級別和手保護級別。一般我們的進程包括Explorer.exe是中級,通過管理員身份運行的進程為高級,而值得注意的是IE的MIC級別是低級別—-這個理由就很明顯了,不贅述,娃哈哈。

                  特別聲明,某個賤人碰到的問題就和UIPI有關,誰叫IE的MIC等級低呢,可憐的XX寶……

            • 個人總結的一些關于UAC的Tips

                

                  1.何時需要提高進程的權限?

                   答案是:在進程啟動的時候。這個問題貌似很SB,卻是很多bug會產生的根源。在程序運行的過程是不能再對當前進程進行提權的:如果程序執行過程中和操作系統說:哥要提權。這個時候系統是不會理你的,當然也沒有相應的API提供。

               

                  2.如何設置一個程序的啟動選項

                  一種比較簡單的方法就是通過API啟動某個進程的時候帶上啟動選項,比如ShellExecuteEx有個runas選項

                  而如果需要讓一個程序一直以管理員身份啟動的方法就很多了:上文提到的Installer Dection的原則大多可以滿足這個需求,讓系統認為你的程序是安裝程序,給加上小盾盾。不過個人感覺前面的5項都不太靠譜。最標準的做法是在可執行文件中嵌入UAC頭。在VS08之后的工程選項Manifest File設置里面有了對啟動等級的設置。而05之前則需要自己建立一個manifest文件,并通過Mt.exe向目標進程插入manifest。詳見《Create and Embed an Application Manifest (UAC)》

               

                   3.UAC對文件系統和窗口消息的影響

                   因為對HKLM等注冊表項和系統文件目錄的讀寫會被重定向,所以盡量不要在非管理權限進程中進行這方面的讀寫—-合理安排用戶數據的存儲,而不是像以前一樣所有數據都存在程序目錄下。(當然也有猥瑣的方法可以繞開這個限制,但是不推薦)

                   啟動一個需要提權的進程后需要注意這個進程的環境變量上下文:標準用戶下以管理員身份啟動某進程后,該進程的環境變量上下文是管理員身份相關的,而非當前標準用戶的。(登入用戶本身是管理員組成員不會有這個問題)

                       UIPI的存在使得對于進程間窗口消息傳遞的控制更嚴格了,稍不留神一個消息可能就被吃掉了,所以進程間通信最萬不得已的情況還是盡量少使用窗口消息—-安全性和可靠性太差。(在管理員權限環境上下文中,拖曳消息會被UIPI給屏蔽掉……)

                       4.降權的需求和實現

                       降權的需求來自于更新程序:更新程序為保證能夠正常運行往往是以管理員身份運行,但這樣有個問題, 當更新成功后更新進程啟動主程序會將自己的權限傳遞下去,這會帶來兩大麻煩:

                      1.主程序獲得了不該有權限,

                       2.主程序的用戶環境變量上下文可能被修改了。

                       第一項問題可能不大,而第二項就比較要命了:主程序在更新后讀取的文件路徑都會變成管理員相關的而非當前用戶的(通過查看進程管理器可以發現主程序也變成了管理員進程)    

                       推薦的做法是在程序啟動更新程序進行更新的同時保證有一個當前用戶權限下的監控程序存在,在更新完畢后通過監控程序來啟動主程序。

                        當然也有比較猥瑣的做法,可以參考《High elevation can be bad for your application: How to start a non-elevated process at the end of the installation》,基本原理還是通過一個已存在的當前用戶權限的進程來啟動主程序,不同的是采用了進程內代碼注入的方法,比較巧妙,但不推薦。

            posted on 2014-05-27 15:09 厚積薄發 閱讀(595) 評論(0)  編輯 收藏 引用 所屬分類: Windows編程

            導航

            <2025年5月>
            27282930123
            45678910
            11121314151617
            18192021222324
            25262728293031
            1234567

            統計

            常用鏈接

            留言簿

            隨筆分類

            文章分類

            文章檔案

            搜索

            最新評論

            97久久久久人妻精品专区| 久久亚洲天堂| 日本道色综合久久影院| 久久综合久久综合九色| 久久久精品国产Sm最大网站| 欧美午夜精品久久久久久浪潮| 国产免费久久精品丫丫| 免费无码国产欧美久久18| 九九久久99综合一区二区| 久久综合久久鬼色| 久久精品a亚洲国产v高清不卡| 久久精品无码一区二区三区日韩| 国产A三级久久精品| 精品国产91久久久久久久a| 香蕉久久av一区二区三区| 久久精品国产亚洲精品| 丰满少妇人妻久久久久久| 亚洲欧美另类日本久久国产真实乱对白 | 色综合久久最新中文字幕| 久久夜色撩人精品国产| 久久夜色tv网站| 日本人妻丰满熟妇久久久久久| 国内精品久久久久久99蜜桃| 四虎国产精品成人免费久久| 伊人久久大香线蕉精品| 久久婷婷成人综合色综合| 影音先锋女人AV鲁色资源网久久 | 97超级碰碰碰久久久久| 欧美一区二区久久精品| 亚洲国产成人久久一区WWW| 精品欧美一区二区三区久久久| 久久中文娱乐网| 欧美亚洲国产精品久久蜜芽| 久久精品国产亚洲av麻豆色欲 | 久久男人AV资源网站| 国产精品狼人久久久久影院| 狠狠色丁香婷综合久久| 91精品国产综合久久婷婷| 国产亚洲婷婷香蕉久久精品| 99久久99久久| 国产激情久久久久影院小草|