2014年10月的週二修補程式日的其中一項是MS14-063,用來解決FAT32磁碟分割區驅動程式中的漏洞,此漏洞讓攻擊者可以取得受影響系統上的管理者權限,只需要一個具備特製檔案系統的USB磁碟。這個漏洞也被編號為CVE-2014-4115。
為什麼此漏洞並不尋常?
我們特別注意檔案系統驅動程式,因為它們可以被用來透過USB磁碟機來攻擊系統。想想看之前的Stuxnet漏洞:它透過Windows捷徑漏洞來散播,能夠輕易地執行Windows shell程式碼;再利用第二個漏洞來取得管理者權限。檔案系統驅動程式漏洞可以一次就達到原本需要兩步驟的效果。
CVE-2014-4115存在於Windows Vista、Server 2003、Server 2008的檔案系統驅動程式(FASTFAT.SYS)。此驅動程式負責處理Fast FAT檔案系統(如 FAT32)。當處理FAT32格式磁碟中帶有特殊BIOS參數區塊(BPB)的開機磁區時,就可能觸發此漏洞。
FAT32今日仍被普遍地用在USB隨身碟上。正因如此,針對性攻擊可以利用此漏洞。假設一個特製的USB隨身碟以某種方式插入高階主管的筆記型電腦或公司內部網路的電腦。這些系統就會被外部惡意份子所控制,就有可能被用來進行針對性攻擊。 系統管媒體的政策。
系統管理員及時進行修補可以減少成為攻擊受害者的風險。企業系統管理員也該重新考慮在公司內部網路使用USB媒體的政策。
這個漏洞是什麼,出現在哪裡?
如前所述,此漏洞出現在FASTFAT.SYS。比較過有漏洞的版本和修補過的版本,唯一區別在於:函數 FatCommonWrite()。
當呼叫函數 ExAllocatePoolWithTag時,第二個參數(NumberOfBytes)在修補版本被乘以0x18。
函數ExAllocatePoolWithTag()的原型如下:
PVOID ExAllocatePoolWithTag(
_In_ POOL_TYPE PoolType,
_In_ SIZE_T NumberOfBytes,
_In_ ULONG Tag
);
漏洞本身很簡單。開發者錯誤計算所需分配的記憶體大小:忘了將結構數量乘以單一指令大小。這可能導致越界堆積寫入錯誤。
利用該漏洞的虛擬程式碼可以描述如下:
NTSTATUS FatCommonWrite (
IN PIRP_CONTEXT IrpContext,
IN PIRP Irp
)
{
……
if (TypeOfOpen == VirtualVolumeFile)
{
….
ULONG Fat;
ULONG BytesPerFat;
IO_RUN StackIoRuns[2];
PIO_RUN IoRuns;
BytesPerFat = FatBytesPerFat( &Vcb->Bpb );
if ((ULONG)Vcb->Bpb.Fats > 2) {
IoRuns = FsRtlAllocatePoolWithTag(
PagedPool,
(ULONG)(Vcb->Bpb.Fats), //Actual vulnerability, missing ×sizeof(IO_RUN)
TAG_IO_RUNS );
} else
{
IoRuns = StackIoRuns;}
for (Fat = 0; Fat < (ULONG)Vcb->Bpb.Fats; Fat++)
{
IoRuns[Fat].Vbo = StartingDirtyVbo;
IoRuns[Fat].Lbo = Fat * BytesPerFat + StartingDirtyVbo;
IoRuns[Fat].Offset = StartingDirtyVbo – StartingVbo;
IoRuns[Fat].ByteCount = WriteLength;
}
……
}
……
}
顯然地,當Bpb.Fats為 3及以上時,FsRtlAllocatePoolWithTag()分配給IoRuns的記憶體會小於預期大小。所以當IoRuns再度被呼叫時,通常會導致崩潰 – 例如,當它在「for」敘述中被初始化。然而,駭客可以用它來故意的覆寫某些核心元件,設置階段來執行任意程式碼。
觸發此漏洞
任何使用VirtualVolumeFile檔案類型的FAT32檔案寫入請求都可能會觸發FatCommonWrite,關鍵在於如何控制Vcb->Bpb.Fats滿足漏洞條件(Vcb->Bpb.Fats > 2)。
在fastfat實作中,Vcb(卷區控制區段)記錄對應于檔案系統所掛載的每個卷區。在FatCommonWrite中,Vcb隨著FileObject被初始化(FAT32卷區的記憶體呈現),就在漏洞之前。
Vcb回溯詳情如下:
_USBSTOR是我們測試USB磁碟機的FAT32檔案系統卷區標籤。
什麼是Bpb.Fats?
通常情況下,MBR(主開機記錄)位於磁柱0、磁頭0、磁區1,而第一個FAT32卷區的開機磁區位於磁柱0、磁頭1、磁區 1。
FAT卷區的第一個重要資料結構稱為BPB(BIOS參數區塊),它位於保留區域,卷區的第一個磁區(開機磁區)。
BPB結構定義可以在Microsoft Windows Driver Kit中找到,如下所示:
typedef struct BIOS_PARAMETER_BLOCK {
USHORT BytesPerSector;
UCHAR SectorsPerCluster;
USHORT ReservedSectors;
UCHAR Fats; //Number of FAT tables, default 2
USHORT RootEntries;
USHORT Sectors;
UCHAR Media;
USHORT SectorsPerFat;
USHORT SectorsPerTrack;
USHORT Heads;
ULONG32 HiddenSectors;
ULONG32 LargeSectors;
ULONG32 LargeSectorsPerFat;
union {
USHORT ExtendedFlags;
struct {
ULONG ActiveFat:4;
ULONG Reserved0:3;
ULONG MirrorDisabled:1;
ULONG Reserved1:8;
};
};
USHORT FsVersion;
ULONG32 RootDirFirstCluster;
USHORT FsInfoSector;
USHORT BackupBootSector;
} BIOS_PARAMETER_BLOCK, *PBIOS_PARAMETER_BLOCK;
如何控制 Bpb.Fat?
Bpb.Fat 位在磁碟的固定位元,可以直接由磁區讀寫工具進行修改。
在此測試中,我們使用二進位編輯器FAT32範本來找出Bpb(即圖4中的BPB_FAT32結構)結構和Fat欄位(圖4中的NumberOfFats)。
概念證明測試導致崩潰
我們僅只修改FAT32 USB磁碟機的BPB來進行概念證明測試。我們使用磁區讀寫工具將BPB_FAT32.NumberOfFATs修改成大於2的數字。
經過以下步驟很快就造成崩潰:
- 將此USB磁碟機插入任一台具備有漏洞SYS的電腦。
- 對此磁碟機執行寫入動作(即複製檔案進去)。
結論
這個漏洞存在於舊版本的Windows – Vista、Server 2003和Server 2008。較新的版本像是Windows 7、Windows 8、Server 2008 R2和Server 2012並不會受到影響。
修補這些平台漏洞的修補程式基本上跟較新版本上的一樣。我們假設此漏洞是在編寫程式碼或合併程式碼時的人為錯誤。這表示可以透過對Windows 7和其他平台FASTFAT.SYS的二進位比較來找出更多漏洞或臭蟲。
至今尚未見到對此漏洞的攻擊公開出現。然而也不能排除有出現在現實世界的漏洞攻擊碼存在。這類事件突顯出將增強修補程式管理作為企業一部分的必要性,甚至是不會立即導致在受影響系統上執行程式碼的漏洞都會造成危害,就如同此次分析所顯示的一樣。此外,像Deep Discovery這樣的網路層解決方案可以幫助減少某些類型漏洞所帶來的風險。
@原文出處:CVE-2014-4115 Analysis: Malicious USB Disks Allow For Possible Whole System Control作者:Moony Li(威脅分析師)