分析 MFT 以還原已刪除檔案 是做什麼的?
概述
NTFS 主檔案表 ($MFT) 是 NTFS 磁碟區中每個檔案和目錄的核心中繼資料儲存庫。每個檔案由至少一個 1024 位元組的 MFT 記錄表示,其中包含諸如 $STANDARD_INFORMATION(時間戳記、權限)、$FILE_NAME(名稱、父目錄、時間戳記)和 $DATA(檔案內容或叢集執行指標)等屬性。當檔案被刪除時,其 MFT 記錄會被標記為非使用中(InUse 旗標清除),但中繼資料會保留到該項目被新檔案重新配置。這種持久性使得 MFT 分析成為還原已刪除檔案證據、重建檔案系統時間線以及偵測反鑑識活動(如時間戳偽造)的主要技術。
使用時機
- 調查需要分析 MFT 以還原已刪除檔案的安全事件時
- 為此領域建置偵測規則或威脅狩獵查詢時
- SOC 分析師需要此類分析類型的結構化程序時
- 驗證相關攻擊技術的安全性監控覆蓋範圍時
先決條件
- 鑑識磁碟映像(E01、raw/dd、VMDK 或 VHDX 格式)
- MFTECmd(Eric Zimmerman)或 analyzeMFT(基於 Python)
- FTK Imager、Arsenal Image Mounter 或類似工具用於掛載映像
- Timeline Explorer 或 Excel 用於 CSV 分析
- Python 3.8+ 用於自訂分析腳本
- 了解 NTFS 檔案系統內部結構
MFT 結構與記錄佈局
MFT 記錄標頭
每個 MFT 記錄以簽名 "FILE" (0x46494C45) 開頭,並包含:
| 偏移量 | 大小 | 欄位 |
|---|---|---|
| 0x00 | 4 位元組 | 簽名 ("FILE") |
| 0x04 | 2 位元組 | 更新序列的偏移量 |
| 0x06 | 2 位元組 | 更新序列的大小 |
| 0x08 | 8 位元組 | $LogFile 序號 |
| 0x10 | 2 位元組 | 序號 |
| 0x12 | 2 位元組 | 硬連結計數 |
| 0x14 | 2 位元組 | 第一個屬性的偏移量 |
| 0x16 | 2 位元組 | 旗標 (0x01 = InUse, 0x02 = 目錄) |
| 0x18 | 4 位元組 | MFT 記錄的已使用大小 |
| 0x1C | 4 位元組 | MFT 記錄的已配置大小 |
| 0x20 | 8 位元組 | 基底檔案記錄參考 |
| 0x28 | 2 位元組 | 下一個屬性 ID |
關鍵 MFT 屬性
| 類型 ID | 名稱 | 描述 |
|---|---|---|
| 0x10 | $STANDARD_INFORMATION | 時間戳記、旗標、擁有者 ID、安全性 ID |
| 0x30 | $FILE_NAME | 檔案名稱、父 MFT 參考、時間戳記 |
| 0x40 | $OBJECT_ID | 檔案的唯一 GUID |
| 0x50 | $SECURITY_DESCRIPTOR | ACL 權限 |
| 0x60 | $VOLUME_NAME | 磁碟區標籤(僅限磁碟區中繼資料檔案) |
| 0x80 | $DATA | 檔案內容(若 <700 位元組則為駐留資料)或叢集執行清單 |
| 0x90 | $INDEX_ROOT | 目錄的 B 樹索引根 |
| 0xA0 | $INDEX_ALLOCATION | 大型目錄的 B 樹索引項目 |
| 0xB0 | $BITMAP | 索引或 MFT 的配置點陣圖 |
已刪除檔案還原技術
技術 1:使用 MFTECmd 進行 MFT 記錄分析
# 使用 KAPE 或 FTK Imager 從鑑識映像中擷取 $MFT
# 使用 MFTECmd 解析 $MFT
MFTECmd.exe -f "C:\Evidence\$MFT" --csv C:\Output --csvf mft_full.csv
# 在 Timeline Explorer 中篩選已刪除的檔案 (InUse = FALSE)
# 尋找 InUse 欄位為 False 的項目
在 CSV 輸出中識別已刪除的檔案:
InUse= False 表示已刪除或已重新配置的記錄ParentPath顯示刪除前的原始檔案位置FileSize顯示原始大小(可能仍可還原)$STANDARD_INFORMATION和$FILE_NAME屬性中的時間戳記會保留
技術 2:USN 日誌 ($UsnJrnl:$J) 分析
USN 日誌記錄 NTFS 磁碟區上檔案的所有變更,包括建立、刪除、重新命名和資料修改事件。
# 使用 MFTECmd 解析 USN 日誌
MFTECmd.exe -f "C:\Evidence\$J" --csv C:\Output --csvf usn_journal.csv
# 用於刪除證據的關鍵 USN 原因代碼:
# USN_REASON_FILE_DELETE = 0x00000200
# USN_REASON_CLOSE = 0x80000000
# USN_REASON_RENAME_OLD_NAME = 0x00001000
# USN_REASON_RENAME_NEW_NAME = 0x00002000
技術 3:$LogFile 交易分析
$LogFile 儲存 NTFS 交易記錄,即使在 USN 日誌已被循環的情況下,也能揭露檔案操作。
# 使用 LogFileParser 解析 $LogFile
LogFileParser.exe -l "C:\Evidence\$LogFile" -o C:\Output
# 尋找指示檔案刪除的 REDO 和 UNDO 操作:
# - DeallocateFileRecordSegment
# - DeleteAttribute
# - UpdateResidentValue(清除 InUse 旗標)
技術 4:MFT 間隙空間分析
MFT 間隙空間存在於 MFT 記錄已使用部分的結尾與已配置的 1024 位元組結尾之間。此區域可能包含先前檔案記錄的殘留。
import struct
def parse_mft_slack(mft_path: str, output_path: str):
"""提取並分析 MFT 間隙空間,尋找已刪除檔案的殘留。"""
with open(mft_path, "rb") as f:
record_size = 1024
record_num = 0
slack_findings = []
while True:
record = f.read(record_size)
if len(record) < record_size:
break
# 驗證 FILE 簽名
if record[:4] != b"FILE":
record_num += 1
continue
# 從偏移量 0x18 取得已使用大小
used_size = struct.unpack("<I", record[0x18:0x1C])[0]
if used_size < record_size:
slack = record[used_size:]
# 檢查間隙空間是否包含可讀字串或屬性標頭
if any(c > 0x20 and c < 0x7F for c in slack[:50]):
slack_findings.append({
"record": record_num,
"used_size": used_size,
"slack_size": record_size - used_size,
"slack_preview": slack[:100].hex()
})
record_num += 1
return slack_findings
與輔助成品的交叉比對
交叉比對 MFT 與 $Recycle.Bin
# 使用 RBCmd 解析資源回收筒
RBCmd.exe -d "C:\Evidence\$Recycle.Bin" --csv C:\Output --csvf recycle_bin.csv
# 比對:$I 檔案包含原始路徑和刪除時間戳記
# 將 $R 檔案中的 MFT 項目編號對應回原始 MFT 記錄
交叉比對 MFT 與磁碟區陰影複製
# 列出磁碟區陰影複製
vssadmin list shadows
# 掛載陰影複製並從每個複製中提取 $MFT
# 比較跨陰影複製的 MFT 記錄,以追蹤檔案隨時間的變更
鑑識價值
- 已刪除檔案中繼資料還原:原始檔案名稱、路徑、大小和時間戳記
- 時間線重建:檔案建立、修改、存取和刪除事件
- 時間戳偽造偵測:比較 $SI 與 $FN 時間戳記
- 資料雕刻指引:MFT 叢集執行指向磁碟上的檔案內容
- 反鑑識偵測:識別已清除或遭操縱的 MFT 記錄
參考資料
- NTFS MFT 進階鑑識分析:https://www.deaddisk.com/posts/ntfs-mft-advanced-forensic-analysis-guide/
- MFT 間隙空間的鑑識價值:https://www.sygnia.co/blog/the-forensic-value-of-mft-slack-space/
- MFTECmd 文件:https://ericzimmerman.github.io/
- SANS FOR500:Windows 鑑識分析
範例輸出
$ MFTECmd.exe -f "C:\Evidence\$MFT" --csv /analysis/mft_output
MFTECmd v1.2.2 - MFT Parser
==============================
輸入:C:\Evidence\$MFT (大小:384 MB)
MFT 項目總數:395,264
正在解析 MFT 項目... 完成 (12.4 秒)
--- 已刪除檔案還原摘要 ---
項目總數: 395,264
活躍檔案: 245,832
已刪除檔案: 149,432
可還原: 87,234 (駐留資料或叢集尚未重新配置)
部分可還原: 31,456 (部分叢集已覆寫)
無法還原: 30,742 (所有叢集已重新配置)
--- 最近刪除的檔案 (事件時間範圍:2024-01-15 至 2024-01-18) ---
MFT 項目 | 檔案名稱 | 路徑 | 大小 | 刪除時間 (UTC) | 可還原
----------|-----------------------------------|------------------------------------|-----------|-----------------------|------------
148923 | exfil_tool.exe | C:\ProgramData\Updates\ | 1,258,496 | 2024-01-17 02:45:12 | 是
148924 | exfil_tool.log | C:\ProgramData\Updates\ | 45,312 | 2024-01-17 02:45:14 | 是
149001 | passwords.txt | C:\Users\jsmith\Desktop\ | 2,048 | 2024-01-17 02:50:33 | 是
149150 | scan_results.csv | C:\Users\jsmith\AppData\Local\Temp | 892,416 | 2024-01-17 03:00:01 | 部分
149200 | mimikatz.exe | C:\Windows\Temp\ | 1,250,816 | 2024-01-18 01:15:22 | 是
149201 | sekurlsa.log | C:\Windows\Temp\ | 32,768 | 2024-01-18 01:15:25 | 是
149302 | .bash_history | C:\Users\jsmith\ | 4,096 | 2024-01-18 03:00:00 | 否
149400 | ClearEventLogs.ps1 | C:\Windows\Temp\ | 1,536 | 2024-01-18 03:01:12 | 是
--- $STANDARD_INFORMATION 與 $FILE_NAME 時間戳記分析 (時間戳偽造偵測) ---
MFT 項目 | 檔案名稱 | $SI 建立時間 | $FN 建立時間 | 差異 | 判定
----------|---------------------|----------------------|----------------------|-----------|----------
148923 | exfil_tool.exe | 2023-06-15 10:00:00 | 2024-01-15 14:34:02 | -214 天 | 已偽造
149200 | mimikatz.exe | 2022-01-01 00:00:00 | 2024-01-16 02:30:15 | -745 天 | 已偽造
已還原的檔案匯出至:/analysis/mft_output/recovered/
完整 CSV 報告:/analysis/mft_output/mft_analysis.csv (395,264 行)
時間線 CSV:/analysis/mft_output/mft_timeline.csv