/*算法
Skogkatt 開始翻譯於2015-02-01,僅做爲學習研究之用,謝絕轉載。數據結構
2015-09-26 更新第六節全景ide
譯註:我翻譯這本書的這三章雖然蓄謀已久,但並非一個計劃好的工做。由於以前和vczh、mili、darkfall曾討論過everything這個軟件,也曾想過要寫一個開源的everything,因而就出來一個坑。everything這個軟件實際上是從底層直接parse了NTFS MFT,而後parse類每個FILE entry,從裏面拆出來了每個文件的信息,這個操做速度遠快於Win32 FindFirstFile和FindNextFile。道理雖然簡單,可是實現起來代碼不會不多。工具
又,我從2013年原由工做緣由開始研究和分析NTFS文件系統,而且看過數遍《File System Forensic Analysis》這本書的NTFS三章。這三章的信息已經略顯過期而且存在一些技術細節謬誤,翻譯出來僅僅是給英語很差的朋友們作爲拓展知識所用。若是想認真研究NTFS實現細節,建議看看泄露的Windows源代碼、開源的NTFS3g庫並使用磁盤編輯工具實際看看磁盤的佈局。佈局
另外,NTFS3g目前公開的代碼坑不少,在高負荷壓力測試中會出現嚴重的數據丟失損壞甚至文件系統掛掉,,不建議做爲一個嚴謹的NTFS實現來使用。學習
*/測試
這是有關NTFS的第二章,咱們如今將要開始討論分析技術和注意事項,咱們將會使用第8章「文件系統分析」中使用的五分類模型。NTFS與其餘文件系統很是不一樣,所以咱們在深刻這些材料以前,在上一章咱們覆蓋了NTFS的核心概念。若是你對NTFS並不熟悉而且跳過了第11章,我建議你在開始閱讀本章以前返回先閱讀第11章。第13章「NTFS數據結構」覆蓋了NTFS的數據結構。本書的大部分被組織爲你能夠並行的閱讀文件系統分析和數據結構章節。可是這對於NTFS來講是很是困難的,由於一切都是文件,很難在查閱元數據分類的屬性以前看有關文件系統分類的文件系統元數據部分。也就是說,在開始閱讀第13章以前閱讀本章會令你有較少的困惑。操作系統
文件系統分類翻譯
內容分類設計
簇
NTFS文件由一系列的屬性構成,有些屬性爲常駐保存在MFT entry之中,其餘很是駐屬性保存在簇之中。簇是一組連續的扇區,每一個簇含有的扇區數量是2的冪(例如,1,2,4,8,16)。
每一個簇都有一個地址,從0開始。簇0從文件系統的第一個扇區開始,相較FAT的計算方式而言更加清晰明瞭。要想將簇地址換算爲扇區地址,能夠將簇地址乘以每簇的扇區數:
扇區號 = 簇編號*每簇扇區數
NTFS沒有嚴格的佈局要求,除了$Boot始終分配第一個簇之外,任意一個簇能夠被分配給任意一個文件或者屬性。微軟有一些通用的佈局策略,這些策略將會在」分配算法「一節中討論。若是一個卷的大小不是簇大小的整數倍,這個磁盤末尾的一些扇區不會成爲一個簇的一部分。這個區域的大小小於一個簇。
$Bitmap文件概況
使用$Bitmap文件系統元數據文件能夠得到一個簇的分配狀態,這個文件在MFT entry 6。這個文件有一個$DATA屬性,它的每個bit表明了文件系統中的一個簇;例如,bit 0表明了簇0,bit1表明了簇1。若是這個bit被設置爲1,簇被標記爲分配;0表明沒有被分配。能夠在第13章$Bitmap文件這一節來了解bitmap的佈局細節和例子討論。
咱們例子文件系統鏡像中的$Bitmap文件的細節以下:
# istat -f ntfs ntfs1.dd 6
[REMOVED]
Attributes:
Type:$STANDARD_INFORMATION (16-0) Name:N/A Resident size:72
Type:$FILE_NAME (48-2) Name:N/A Resident size:80
Type:$DATA (128-1) Name:$Data Non-Resident size:128520
514113 514114 514115 514116 514117 514118 514119 514120
514121 514122 514123 514124 514125 514126 514127 514128
[REMOVED]
咱們能夠看到$Bitmap文件具備標準文件的屬性, 它的當前數據和咱們以前分析的文件系統元數據是一致的。
$BadClus文件概況
NTFS跟蹤壞簇的狀態,並將其保存在$BadClus文件系統元數據文件的$DATA屬性中,這個文件在MFT entry 8。這個$DATA屬性名字叫作$Bad,是一個稀疏文件,當一個簇被報告爲損壞的時候,它被標記在這個屬性中。回憶在Chapter 11章中所介紹的,稀疏文件若是被填充爲0,它使用不分配簇來節約空間。$Bad屬性的大小等於整個文件系統的大小,可是一開始並無爲其分配任何簇。Windows將其發現的壞簇添加到$Bad屬性中,可是不少硬盤會在文件系統發現壞簇前就發現壞扇區了(譯註:這是硬盤的自檢功能)。
咱們例子文件系統鏡像中的$BadClus文件的細節以下:
# istat -f ntfs ntfs1.dd 8
[REMOVED]
Attributes:
Type:$STANDARD_INFORMATION (16-0) Name:N/A Resident size:72
Type:$FILE_NAME (48-3) Name:N/A Resident size:82
Type:$DATA (128-2) Name:$Data Resident size:0
Type:$DATA (128-1) Name:$Bad Non-Resident size:1052803072
注意這個文件有兩個$DATA屬性,缺省的那個$Data是常駐的,大小爲0。名叫$Bad的那個$DATA屬性是很是駐的,大小爲1,052,803,072字節,可是沒有顯示簇地址,由於這個文件系統沒有壞簇。這個屬性的大小和文件系統的大小相同,和咱們看到的fsstat的輸出一致。
分配算法
這一節記錄了我所觀察到的,當Windows XP分配一個新的NTFS簇的時候,它所使用的策略。與其餘文件系統相似,分配策略是操做系統相關的,不一樣的NTFS實現可能會使用不一樣的策略。我觀察到Windows XP使用最佳適配算法。最佳適配算法指的是,數據將會被放置在最有效使用可用空間的位置上,即使這個位置不是第一個或者下一個可用的。也就是說,若是有少許的數據要被寫入磁盤,它將會被寫入到一小組未分配的簇中而不是那些大的未分配的簇中,這樣能夠爲大文件留下空間。例如,圖12.1顯示了咱們須要爲一個文件分配10個簇的情形。有三塊未分配簇。第一塊從簇100到199,第二塊從簇280到319,第三塊從簇370到549。最佳適配算法將把簇280到289分配給新文件,由於這是最小的可放下文件的可用簇組。
圖12.1 最佳分配算法將把10個新簇放在能夠放下它們的最小空間中。
文件系統佈局
NTFS文件系統並無嚴格的佈局要求,可是Windows使用一些通用的策略來格式化文件系統。大部分版本的NTFS的佈局都不相同,但基本概念仍是共同的。
一個全部版本NTFS的基本概念是MFE Zone。Windows在建立MFT時儘量的小,並僅在須要更多的entry時才擴展它。也就是說,這樣作有一個風險,當MFT後面的空間被分配給一個文件以後,MFT很容易碎片化。爲了不這種狀況,微軟將文件系統的一部分保留給了MFT。MFT Zone是不會被用來保存的文件或者目錄的一系列連續的簇,除非磁盤的其餘部分已經滿了纔會用到這部分空間。缺省狀況下,微軟爲MFT預留了12.5%的文件系統空間。若是文件系統的其餘部分已經用掉了,MFT Zone將會被使用、
全部版本的NTFS和Windows都把第一個簇分配給$Boot文件。Windows NT和2000將他們的文件系統元數據文件分配在$Boot文件以後和文件系統中部。例如,若是文件系統的簇大小是1 KB,前八個簇將會被分配給$Boot文件,而且$MFT文件的簇可能會從簇16或者32開始。MFT Zone將會佔據接下來的12.5%的文件系統空間。文件系統中部的簇將會被分配給$MFTMirr文件和剩餘的文件系統元數據文件,如$LogFile, $Root, $Bitmap和$Upcase,一個接一個。一個我所觀察到的Windows NT和2000之間的差別是NT將$AttrDef文件放在文件系統的末尾,而Windows 2000將其放在$MFT文件的前面。
我發現Windows XP將一些數據移動到了文件系統的三分之一處。$LogFile,$AttrDef,$MFT和$Secure文件的簇被分配到了文件系統的三分之一處。其餘文件系統元數據文件被放在了文件系統的一半的位置。只有$Boot文件被放在了文件系統起始的幾個簇的位置。全部的在文件系統元數據文件之間的簇均可以被分配用於存放用戶文件和目錄。圖12.2顯示了Windows 2000或XP格式化的文件系統的不一樣的文件系統元數據文件的位置。
圖12.2一個由Windows 2000和Windows XP格式化的文件系統的文件系統元數據佈局。
分析的技巧
內容分類的分析涉及到定位一個指定的簇,檢查它的分配狀態,以某種形式處理它的內容。查找一個指定的從很容易,由於第一個簇在文件系統的開始處,而且簇的大小在第一個扇區給出。
一個簇的分配狀態能夠經過定位$Bitmap文件而後處理它的$DATA屬性來獲知。屬性中的每個bit都表明了文件系統中的一個簇。
一個常見的分析技巧是獲取文件系統的未用空間。咱們能夠經過檢查$Bitmap文件,而且獲取每個0bit的簇來完成這個任務。全部的NTFS文件系統管理數據都是放在文件裏面的,所以在這個分析過程當中不該認爲會有任何的數據在這些未分配空間中。
分析的考量
當分析NTFS的內容分類的時候,與其它文件系統相比並無必需要作的獨特的考量。簇地址從第一個簇開始,因此只須要一種地址格式。微軟通常只將必要數量的扇區分配給文件系統,所以在文件系統的末尾不該該有沒有粗地址的任何扇區。從另外一方面來講,這也意味着在文件系統以後卷結束以前可能會有一些扇區隱藏有數據。
當執行關鍵字搜索的時候,邏輯卷搜索和邏輯文件系統搜索並無什麼不一樣,由於被文件系統使用的每個扇區都被分配到了一個簇中。因爲文件系統分類中的全部數據搜被分配到了文件中,哪一個簇被分配了哪一個沒有是很清晰的。回一下FAT,一個工具將FAT area和reserved areas認爲是分配的仍是未分配的並非很明確。
和全部現代系統同樣,你應該檢查那些被文件系統標記爲損壞的簇,由於不少的硬盤會在文件系統發現扇區損壞以前就將它們作了重映射。
分析的場景
在這個例子中,咱們將會定位簇9,900,009。第一步是檢查簇大小。咱們讀取文件系統的第一個扇區,並確認每一個扇區都是512字節大小,每個簇由8個扇區組成,大小爲4,096字節。
NTFS的簇0從扇區0開始。也就是說,咱們能夠經過將咱們的簇編號乘以每簇的扇區數來計算咱們的簇的扇區地址。計算得知,咱們獲得了扇區編號792,00,072。爲了獲得字節位置,咱們將扇區地址乘以512計算出字節地址40,550,436,864。能夠將這個過程和在FAT中查找一個簇的扇區或者字節地址的諸多步驟作一個比較。
元數據分類
文件名分類
應用程序分類
全景
在這盡是不一樣的數據結構和複雜交互的一章的最後,讓咱們看看當一個文件建立和刪除的時候會經歷哪些步驟。但願這將一切(以前介紹的)合在一塊兒。注意這些步驟的順序並不必定是實際上發生的。
文件分配示例
咱們將會建立 \dir1\file1.dat 這個文件,而且假設 dir1 這個目錄是已經存在於根目錄的。文件的大小是 4,000 字節,每個簇的大小是 2,048 字節。
咱們讀取文件系統的第一個扇區,處理引導扇區來肯定簇的大小,MFT的起始地址以及每個 MFT entry 的大小。
咱們讀取MFT的第一個 entry ,也就是 $MFT 文件,用$DATA 屬性來肯定 MFT 剩餘部分的佈局。
咱們首先爲新文件分配一個 MFT entry 。爲了查找一個未分配的 entry,咱們處理 $MFT 文件的 $BITMAP 屬性。第一個可用的 entry,entry 304 被分配給新文件而且相應的位被置爲1。(譯註:$BITMAP中的位)
咱們在 MFT 中定位到 MFT entry 304 的位置,經過清理它的內容來初始化它。$STANDARD_INFORMATION 和 $FILE_NAME 屬性被建立出來,時間被設置爲當前時間。MFT entry 頭部中的在用標誌被設置。
咱們下一步要作的是爲文件分配兩個簇,這將經過 MFT entry 6的 $Bitmap 文件的 $DATA 屬性來完成。這個文件須要兩個簇,因此最佳適配算法找到兩個連續的簇692和693。這些簇相應的位被置爲1。(譯註:$BITMAP文件$DATA屬性中的位)文件的內容被寫入簇中,而且將簇的地址更新到 $DATA 屬性中。MFT entry 被更改了,因此文件修改時間被更新。
咱們下一步是給這個文件增長一個文件名入口。MFT entry 5,也就是根目錄,被用於定位 dir1。咱們讀取 $INDEX_ROOT 和 $INDEX_ALLOCATION 屬性,遍歷排序樹。能夠發現 dir1 的索引入口,而且它的 MFT entry 地址是200。目錄的最後訪問時間被更新。
咱們定位到 MFT entry 200 而且處理它的 $INDEX_ROOT 屬性來肯定 file1.dat 應該放在哪裏。給這個文件建立一個新的索引入口,而且從新排序樹。這可能會發生在節點的索引入口中。新的索引入口在它的文件引用地址中含有 MFT entry 304,而且設置相應的時間和標誌。目錄的最後寫入,修改,訪問時間被更新。
在前述的步驟中,可能會在文件系統日誌文件 $LogFile 和修改日誌文件 \$Extend\$UsrJrnl 中建立新的入口。若是配額是強制的,新文件的大小將會加入到用戶的配額文件 \$Extend\$Quota 中。
圖12.13增長 '\dir1\file1.dat' 文件後的最終狀態。
文件刪除示例
如今咱們將會看看 \dir1\file1.dat 文件刪除時會發生什麼。
咱們讀取文件系統的第一個扇區,處理引導扇區來肯定簇的大小,MFT的起始地址以及每個 MFT entry 的大小。
咱們讀取MFT的第一個 entry ,也就是 $MFT 文件,用$DATA 屬性來肯定 MFT 剩餘部分的佈局。
咱們須要找到 dir1 目錄,因此咱們處理 MFT entry 5 根目錄,遍歷 $INDEX_ROOT 和 $INDEX_ALLOCATION 屬性中的索引。咱們發現 dir1 入口,它的 MFT entry 地址是200。目錄的最後訪問時間被更新。
咱們處理 MFT entry 200 的 $INDEX_ROOT 屬性,查找 file1.dat 的入口。咱們能夠發現文件的 MFT 地址是entry 304。
咱們刪除索引中的入口,致使節點中的入口都將被移動並覆蓋掉原來的入口。目錄的最後寫入,修改,訪問時間被更新。
咱們將 MFT entry 304 的在用標誌清除來釋放它。咱們還將 $Bitmap 文件的 $DATA 屬性中這個MFT entry的標記清除。
處理 MFT entry 304 的非駐留屬性,在 \$Bitmap 文件中相應的簇被標記爲未分配狀態。在這個例子總,咱們釋放了簇 692 和 693。
在前述的步驟中,可能會在文件系統日誌文件 $LogFile 和修改日誌文件 \$Extend\$UsrJrnl 中建立新的入口。若是配額是強制的,文件的大小將會從用戶的配額文件 \$Extend\$Quota 中減掉。
最終的狀態在圖12.14中。注意當一個文件在 NTFS 中被刪除後,Windows 並不清除任何指針。也就是說,MFT entry 和簇之間的聯繫依然存在,文件和 MFT entry 之間的聯繫可能因爲重排序並無覆蓋入口項而依然存在。
圖12.14刪除 '\dir1\file1.dat' 文件後的最終狀態。灰色的方框表示已經被釋放。
其餘話題
本節討論一些不適合放進特定數據分類的話題。咱們將會討論恢復刪除的文件和文件系統一致性檢查。
文件恢復
在NTFS中恢復被刪除文件相較其餘文件系統來講比較容易。當一個文件被刪除後,名字被從父目錄索引中刪除,MFT entry被釋放,所使用的簇也被釋放。微軟沒有清除任何指針,儘管在將來他們有可能會這麼作。
NTFS最大的不利之處是,當一個文件名被從父目錄索引中刪除之後,索引被從新排序,名字信息可能丟失。也就是說,你可能在文件所在的原目錄裏看不到它的名字了。不過,這一缺點因爲全部的MFT entry都在一個表裏,全部的未分配的entry均可以很容易被找到而抵消。進一步說,每個entry都有一個$FILE_NAME屬性含有其父目錄的引用地址。也就是說,當發現一個未分配的entry,咱們一般能夠獲知其完整路徑,除非其父目錄中有一些被從新分配到了新文件或者目錄。
恢復已刪除的 NTFS 文件的另外一個考慮因素是尋找額外的 $DATA 屬性。你可使用一個從DFTT站點下載的測試鏡像來測試你的NTFS恢復工具。這個鏡像包含有一些帶有多個$DATA屬性的已刪除文件,沒有任何索引指向這些文件。
爲了恢復NTFS中全部的已刪除文件,應該檢查MFT中的未分配entry。當發現這種entry時,它們的名字能夠經過$FILE_NAME屬性和父目錄引用來得到。簇指針應該還存在,這樣數據在沒有被覆蓋的狀況下還能夠恢復。即使文件很是碎片化,被恢復也是頗有可行的。若是屬性值是常駐的,數據不會被覆蓋,除非MFT entry被從新分配了。若是文件須要多一個MFT entry來保存它的屬性,其它的MFT entry也須要進行恢復,Windows使用第一個可用的分配策略來分配MFT entry,因此低序號的MFT entry比高序號的更常常被分配。
當恢復文件或檢查已刪除內容的時候,文件系統日誌或者變動日誌可能對於新近的刪除比較有用。變動日誌不是始終打開的,可是它顯示了文件是什麼時候被刪除的以及最後編輯的時間。
一致性檢查
一致性檢查用於在調查中找出損壞的鏡像,或來檢測篡改行爲。本節描述了一些能夠用於NTFS文件系統鏡像的檢查方法。第一個能夠檢查的是引導扇區。NTFS引導扇區只有不多的數據,可是Microsoft強制一些無用值必須爲零。我發如今$Boot文件中的引導代碼以後常常有不少未用的簇。與其它文件系統相似,$BadClus文件中所標記出來的壞簇用該被檢查,由於不少硬盤在文件系統發現壞簇以前就修正了這些壞簇(譯註:也就是說,文件系統中的壞簇一般是人爲的)。
$MFT文件,也就是MFT它本身的文件,僅隨Windows的須要而增長大小。一個高級的攻擊者可能會試圖使這個表變得很是長,而後在它的末端隱藏數據,可是當新文件被建立的時候這些數據可能會被覆蓋。前16個MFT entry是保留的,可是目前有些並無被使用。其它文件系統的保留的和未用的元數據結構有被用於隱藏數據的歷史,一樣的事情也會發生在NTFS文件系統上。
每一個已分配的簇都應該是某個文件的簇run的一部分。每一個已分配的NTFS簇都是文件或者目錄的一部分,一致性檢查應該驗證這點。每一個已分配的MFT entry都應該設置了其在用標誌,而且在$BITMAP屬性中設置了標誌位。每一個已分配的MFT entry的每個文件名還應該有一個目錄索引。文件系統的元數據文件在根目錄中有一個名稱。
就每個目錄索引和MFT entry來講,每一個entry都有太多的標誌和選項,檢查每個標誌是不值得的。處理NTFS的一個難點是它很是靈活而且提供數量衆多的選項。在沒有一個官方規範的狀況下,哪些值組合是合法的哪些是不合法的是沒法肯定的。
總結
讀到這裏,或許你已發現NTFS是如此複雜和強大的文件系統。當咱們檢查FAT文件系統的時候,它的複雜是因爲它最初並非被設計爲適應如今的數據大小或者應用需求。就NTFS而言,它的複雜性是因爲它被設計爲應對如今的需求和不少將來的需求。NTFS還將不少應用級別的功能增長進來,這進一步增長了複雜性。
在寫做本書的時候,NTFS已成爲支配地位的Windows文件系統。安裝XP的家庭用戶已將他們的磁盤格式化爲NTFS而不是FAT。NTFS幫助了調查人員,由於它很容易恢復被刪除的文件,而且若是各類日誌被開啓,歷史事件也會存在。從另外一方面來講,它的複雜性也使調查人員描述證據被發現的地方更加困難。
參考資料
略,請看原著。