NTFS 檔案系統支援 **替代資料流 (Alternate Data Streams, ADS)**,允許單一檔案包含**多個資料流**。主流為 :$DATA (預設無名流),額外建立的具名流對使用者透明,**エクスプローラ/Dir/檔案大小皆不顯示**,成為惡意軟體隱藏資料、Rootkit 持久化、資料洩漏的溫床。本文深入解析 ADS 機制、命令列操作、API 偵測與取證工具。
檔案名:流名:$DATA (完整) 或 檔案名:流名 (簡寫)echo Secret > visible.txt:hidden.txt 或 type secret.exe > visible.txt:malware.exemore < visible.txt:hidden.txt 或 notepad visible.txt:hidden.txt (需完整路徑)wmic process call create "cmd /c visible.txt:malware.exe" (舊版 Windows 支援,新版受限)C:\> echo "Hi Reader" > XX.TXT:MyStream
C:\> dir XX.TXT
Volume in drive C is Wizard
Directory of C:\
03/18/98 08:36a 0 XX.TXT <-- 主流大小為 0
1 File(s) 0 bytes
0 Dir(s) 3,399,192,576 bytes free
主流 XX.TXT 大小為 0,但實際佔用磁碟空間包含 :MyStream:$DATA 的資料。
streams.exe -s C:\ 遞迴列出所有 ADSSE_BACKUP_NAME 特權CreateFile(..., FILE_FLAG_BACKUP_SEMANTICS) → BackupRead 迴圈讀取流標頭 (WIN32_STREAM_ID) 與資料查詢 FileStreamInformation (InfoClass = 22) 可直接列舉所有流名稱與大小。
// 關鍵結構 (來自 ntdll.h / phnt.h)
typedef struct _FILE_STREAM_INFORMATION {
ULONG NextEntryOffset; // 下一項偏移 (0 表結束)
ULONG StreamNameLength; // 流名稱長度 (bytes, 含結束 null)
LARGE_INTEGER EndOfStream; // 流大小
LARGE_INTEGER AllocationSize; // 磁碟配置大小
WCHAR StreamName[1]; // 變長:如 ":MyStream:$DATA"
} FILE_STREAM_INFORMATION, *PFILE_STREAM_INFORMATION;
// 呼叫
NtQueryInformationFile(hFile, &IoStatus, Buffer, BufferSize, FileStreamInformation);
// 解析迴圈:依 NextEntryOffset 遍歷,StreamName 需移除尾端 ":$DATA"
| 面向 | 說明 |
|---|---|
| 惡意軟體持久化 | 將惡意程式寫入 system32\legit.exe:evil.exe,配合排程工作/登錄執行 |
| 資料竊取 | 將機密文件寫入無害圖片的 ADS,繞過 DLP 檢查 |
| 偵測策略 | 定期掃描關鍵目錄 ADS、監控 CreateFile 開啟具名流、EDR 行為分析 |
| 清除方法 | streams.exe -d 檔案 刪除所有 ADS,或複製檔案至 FAT32/ReFS/網路共享 (不支援 ADS) 再複製回 |
| 跨檔案系統 | 複製至 FAT32、exFAT、ReFS、ZIP 壓縮、Email 附件、雲端同步**會自動剝離 ADS** |
:Zone.Identifier、Mac 資源分支相容)BackupRead/BackupWrite 或 NtQueryInformationFile 完整列舉NTFS ADS 是把雙面刃:為相容性保留的特性,卻成資安盲點。掌握其機制、偵測 API 與清除方法,是系統管理員、防毒廠商、數位取證人員的必修課。