天天看點

基于檔案過濾驅動的透明加密那點事兒

 檔案透明加密這點事兒,從2001年開始出現基于API HOOK的方式開始到現在,已經十幾年了,有細心人按技術實作的方式将其細分為4代,分别是基于API HOOK的第一代技術、基于檔案過濾驅動(加清緩存)的第二代技術、使用Layerfsd的雙緩沖第三代技術和基于微軟新一代minifilter架構的Layerfsd雙緩沖第四代技術。第一代和第二代的技術劃分基本上沒有異議,所謂的第四代很多人并不認同,認為使用minifilter架構算不上是技術突破,其技術實作仍然是基于Layerfsd的雙緩沖技術,沒有新意。

        我們從2009年開始研究并實作了基于Layerfsd的雙緩沖技術,并應用于自己的産品中,這些本來都是老生長談,隻是最近幾天根據使用者回報修改了幾個BUG,忽然覺得還可以說道說道。Layerfsd的雙緩沖技術最早出現在驅網論壇上的時候,讨論可謂是熱烈,随着一些開發者逐漸從理論到實踐,完成了具體的實作之後,就開始了有意無意的技術封鎖,一些技術理論和部分公開的源代碼都無影無蹤,不過從側面也可以看出來,這個技術其實還是有一定的門檻的。其門檻并不在于技術有多難,關鍵在于細節和穩定性,根據理論做出一個實作不難,網上很多号稱出售Layerfsd的雙緩沖技術實作源代碼的,叫價8-40萬的都有,不過都隻能算是一個理論研究系統,穩定性都很難保證,更不用說實用性了。

        為了了解同行的技術成熟度,我們經常找來同行的産品進行測試,今年上半年測試了兩個驅動,一個驅動是對Visual Studio不相容,每次儲存檔案後都會提示檔案被外部修改,需要再确認一次,都是做這個的,我們當然清楚這個是layerfsd層的檔案時間沒有處理好,不過用VC編譯一個加密的工程源代碼時,總是藍屏,這個應該就是實作者的技術實力問題了,還有對NTFS檔案系統還馬馬虎虎,但是隻要操作FAT分區的檔案系統就沒有反應,根據我們的經驗應該是内部有死鎖産生。還有一個驅動是不支援動态磁盤系統和可解除安裝的媒體(比如U盤),用WORD打開的文檔,在編輯狀态時居然可以從資料總管中删除,這個是緻命的layerfsd層檔案權限管理失敗,和作者溝通這個問題,作者認為這是雙緩沖驅動實作的特征,隻要是使用雙緩沖技術實作的驅動都有這個問題,對此我們不敢苟同。

        這樣的實作買回去也沒辦法用,想做出實用的商業軟體至少還要2-3年的時間開發功能并做好穩定性。如果有錢,可以直接購買OSR的DMK,穩定性有一定的保證,但是要在上面做二次開發實作自己的功能。pfp也公開過一份源代碼,是個半成品系統(現在驅網所有的下載下傳連結都失效了),但是距離實作還有很遠的距離,當然還是有很多人的實作都是基于這個源代碼做的,這個一測試就能感覺出來。

        使用第二代技術實作的商業應用很多,隻要能做穩定,基本都有市場,但是這個技術有幾個緻命的問題,就是檔案操作效率低下,容易損壞檔案,并且和反病毒軟體不相容。檔案操作效率低下的原因在于為了防止非授信程序通路檔案系統緩存的檔案明文,每次打開和關閉檔案時都要清理檔案緩存。這對相當于屏蔽了系統檔案緩存帶來的性能優化,對大檔案的操作影響尤其明顯。我們測試過一個使用這種技術實作的商業軟體,用word打開一個100多M的大檔案後,用另一個非授信程序每隔15-30秒鐘隻讀通路一次這個檔案(這會促使驅動實作每隔15-30秒鐘就清一次緩存),結果卡的基本上沒辦法操作這個word文檔,如果是雙緩沖,就沒有這個問題。損壞檔案的原因主要是對于延遲寫入的緩沖檔案,使用者的寫入操作是寫入了緩存,但是負責延遲寫入的system程序還沒有将其寫入檔案,此時如果有非授信程序打開檔案,會導緻緩存被清除,這導緻使用者的修改沒有寫入,很多情況下都會造成檔案資料丢失或檔案格式損壞,與防毒軟體不相容也基本上是這個原因。

        第二代技術的實作,在處理加密檔案辨別的問題上也很棘手,我們測試過的很多實作都是使用影子檔案的方式,所謂影子檔案,就是構造一個檔案名與加密檔案有一定的關聯的影子檔案,比如在原始檔案名前增加一個固定辨別的字首,或字尾,或使用一個特殊的檔案擴充名。當打開一個檔案時,加密驅動首先看看是否存在影子檔案,如果是就說明是一個加密檔案,需要做解密處理。影子檔案的管理也是一個很麻煩的地方,需要在驅動中對IRP_MJ_DIRECTORY_CONTROL進行過濾處理,對上層應用過濾掉這些檔案名,使得使用者在資料總管中看不到這些影子檔案,感覺不到他們的存在。但是隻要使用者停止驅動,這些檔案就原型畢露,一些安全軟體,比如冰刃,可以繞過驅動直接删除影子檔案,會帶來一些不穩定因素。此外,檔案的複制和删除都要考慮影子檔案,維護上也挺麻煩的。也有一些商業實作将影子檔案集中在某個系統目錄中進行管理,但是也要解決同名的問題,也不是完美的方案。

        從理論上所,使用雙緩沖技術可以回避上面提到的清緩存問題,同時,雙緩沖也可以解決檔案加密辨別的存放問題。雙緩沖技術可以将加密資訊構造成一個特殊的資料塊直接存放在檔案中,至于是放在檔案頭部還是檔案尾部(從理論上說,也可以放在檔案中間某個位置,不過是自找麻煩),不同意見還是很多的,各有各的理論依據,有人認為放在檔案頭部容易破壞檔案,不過這是沒有根據的,如果驅動實作不成熟,這塊資訊放在什麼地方都可能破壞檔案。傾向于将這塊資訊放在檔案尾部的人覺得檔案完成最後的寫入,關閉之前補上一塊加密資訊是順理成章的事情,傾向于将這塊資訊放在檔案頭部的人則是秉承傳統的思想,畢竟很多檔案格式都是将檔案的特殊資訊構造成一個特殊的檔案頭存放的,不過就實作而言,這二者沒有優劣之分。

        雙緩沖技術需要在一個layerfsd層通路真實檔案,這就帶來一個驅動的(IRP_MJ_CREATE)重入問題,這個解決不好就直接遞歸到棧溢出了。防止重入有多重方法,使用minifilter架構的有個優勢,就是可以直接使用FltCreateFile系列函數繞開驅動直接打開和讀寫檔案,這個後面再說。如果不使用minifilter架構,常用的兩種方法就是構造影子卷進行檔案通路,或直接構造IRP進行檔案操作。構造影子卷的原理就是通過影子卷重定向檔案的通路,因為過濾驅動不會attach影子卷,是以就規避了重入問題。使用影子卷的好處是可以使用ZwCreateFile等核心API直接操作檔案,友善、安全。但是attach實體卷的時候要避開影子卷,一旦不小心attach了影子卷就會死的很慘。直接構造IRP進行檔案操作應該是一個很優雅的方案,但是實作起來需要考慮比較多的細節,網上也有一些現成的源代碼實作,不過或多或少都有一些問題,需要修改一下才能用。關于這方面的資料首先是OSR的“Rolling Your Own - Building IRPs to Perform I/O”一文,此外,還有baiyuanfan的“Windows平台核心級檔案通路”一文也有很不錯的介紹。

        minifilter是微軟引入的一個輕量級微過濾驅動模型,簡化了檔案過濾驅動的實作細節,使得微過濾驅動可以忽略一些細枝末節的東西,将注意力集中在業務實作上。這比采用遺留驅動模型的sfilter架構有一定的優勢,但是就透明加密驅動而言,并沒有進步到說使用minifilter架構就比sfilter技術先進的程度,要知道,第二代透明加密技術的驅動也可以用minifilter架構實作,是以鼓吹minifilter+layerfsd更先進是沒有依據的,重要的還是誰的驅動更穩定,畢竟動不動就藍屏,或者損壞檔案是使用者最不能接受的。

        最後要說一些細節問題,比如雙緩沖,所謂的雙緩沖就是對同一個檔案的通路形成兩個cache緩存,對于授信程序,可以使用解密資料的明文cache,對于非授信程序,則使用密文的cache,二者共存且互相不幹擾。使用雙緩沖對系統記憶體的使用肯定是會增加的,但是帶來的安全性和檔案通路效率的提升是不言而喻的。至于cache的實作方式,可以使用windows的檔案緩存系統,也可以自己實作檔案緩存系統,據我所知,很多資料庫軟體就沒有使用windows的檔案緩存系統,而是根據需求自己實作的緩存系統。極端的說,你甚至可以不實作緩存,所有加密檔案的讀寫都是實時操作實際檔案,不支援一切緩存讀寫和fastio,我們在測試時遇到過這樣的實作,也号稱是支援layerfsd的雙緩沖技術,雖然沒有雙緩沖的檔案通路效率,但是也算是回避了第二代驅動技術的幾個難題。還有比如授信程序的識别問題,簡單地根據程式檔案名稱進行識别是非常幼稚的做法,對程式改個名字就可以欺騙加密驅動得到解密後的明文。還有授信程序的識别問題,對于有的應用程式,通常是一個圖形的前端加上幾個沒有界面的背景程式配合工作,如果授信程序隻有前端的UI程序,還是無法通路加密檔案,對這種情況也要做程序父子關系的識别和處理。當然還有經典的線程注入問題,通過遠端線程注入,可以在授信程序中啟動一個線程通路加密檔案,并将解密的明文通過共享記憶體或socket接口傳遞給另一個非授信程序。解決之道就是阻止線程注入,核心和應用層都可以做,當然也會對正常需要線程注入的程式産生影響,比如本人的TabSiPlus外挂插件,需要注入到Source Insight程序内部啟動一個tab标簽欄,就因為這個原因與加密軟體産生沖突。對于一些支援插件的軟體,比如office,還需要對插件進行識别和屏蔽,方法也很多,方式也很流氓,經常弄得使用者莫名其妙。我的建議是對這種支援插件的軟體不要做特殊處理,安全性由使用者自己管理,使用者有時候并不是那麼傻,不要什麼事情都替使用者做了。

繼續閱讀