Share via


控制平臺安全性的流程防護

什麼是控制流程防護?

控制流程防護 (CFG) 是高度優化的平臺安全性功能,其建立是為了對抗記憶體損毀弱點。 藉由將嚴格的限制放在應用程式可執行程式碼的位置,讓惡意探索透過緩衝區溢位等弱點來執行任意程式碼會變得更困難。 CFG 擴充先前的惡意探索防護技術,例如 /GSDEPASLR

  • 防止記憶體損毀和勒索軟體攻擊。
  • 將伺服器的功能限制為特定時間點所需的任何功能,以減少受攻擊面。
  • 透過緩衝區溢位等弱點,更難利用任意程式碼。

這項功能可在 Microsoft Visual Studio 2015 中使用,並在 Windows 的「CFG 感知」 版本上執行,這是適用于桌面和伺服器 Windows 10 和 Windows 8.1 更新版 (KB3000850) 的 x86 和 x64 版本。

我們強烈建議開發人員為其應用程式啟用 CFG。 您不需要為程式碼的每個部分啟用 CFG,因為已啟用 CFG 且未啟用 CFG 的程式碼會正常執行。 但無法為所有程式碼啟用 CFG,可能會開啟保護中的間距。 此外,已啟用 CFG 的程式碼可在 Windows 的 「CFG-Unaware」 版本上正常運作,因此與它們完全相容。

如何啟用 CFG?

在大部分情況下,不需要變更原始程式碼。 您只需要將選項新增至 Visual Studio 2015 專案,編譯器和連結器將會啟用 CFG。

最簡單的方法是流覽至 Project |屬性 |組態屬性 |C/C++ |產生程式碼 並選擇 [ 是] (/guard:cf) 控制流程防護。

Visual Studio 中的 cfg 屬性

或者,將 /guard:cf 新增至 Project |屬性 |組態屬性 |C/C++ |命令列 | 編譯器) 和 /guard:cf 至 Project 的其他選項 (|屬性 |組態屬性 |連結器 |命令列 |連結器) 的其他選項 (。

連結器之編譯程式 cfg 屬性的 cfg 屬性

如需詳細資訊 ,請參閱 /guard (啟用控制流程防護)

如果您要從命令列建置專案,您可以新增相同的選項。 例如,如果您要編譯名為 test.cpp 的專案,請使用 cl /guard:cf test.cpp /link /guard:cf

您也可以選擇使用來自記憶體管理 API 的 SetProcessValidCallTargets ,以動態方式控制 CFG 視為有效的一組 icall 目標位址。 您可以使用相同的 API 來指定頁面是否無效或有效的 CFG 目標。 VirtualProtectVirtualAlloc函式預設會將指定的可執行檔和認可頁面區域視為有效的間接呼叫目標。 您可以藉由在呼叫VirtualAlloc時指定PAGE_TARGETS_INVALIDPAGE_TARGETS_NO_UPDATE或在呼叫VirtualProtect時指定 ,例如實作 Just-In-Time 編譯器時,可以覆寫此行為,如記憶體保護常數下所述。

如何告訴二進位檔處於控制流程防護之下?

使用/headers/loadconfig選項,從 Visual Studio 命令提示字元執行傾印系結工具 (包含在 Visual Studio 2015 安裝) :dumpbin /headers /loadconfig test.exe。 CFG 下二進位檔的輸出應該會顯示標頭值包括 「Guard」,而載入組態值則包含 「CF Instrumented」 和 「FID 資料表存在」。

dumpbin /headers 的輸出

dumpbin /loadconfig 的輸出

CFG 如何運作?

軟體弱點通常是藉由將不太可能、不尋常的或極端資料提供給執行中的程式來惡意探索。 例如,攻擊者可以藉由提供比預期更多的輸入給程式來利用緩衝區溢位弱點,藉此過度執行程式所保留的區域來保存回應。 這可能會損毀可能保存函式指標的相鄰記憶體。 當程式透過此函式呼叫時,可能會跳到攻擊者指定的非預期位置。

不過,CFG 的編譯和執行時間支援組合會實作控制流程完整性,以嚴格限制間接呼叫指令可執行檔位置。

編譯器會執行下列動作:

  1. 將輕量型安全性檢查新增至已編譯的程式碼。
  2. 識別應用程式中的一組函式,這些函式是間接呼叫的有效目標。

Windows 核心所提供的執行時間支援:

  1. 有效率地維護可識別有效間接呼叫目標的狀態。
  2. 實作可驗證間接呼叫目標的邏輯是否有效。

為了說明:

cfg 虛擬程式碼

當 CFG 檢查在執行時間失敗時,Windows 會立即終止程式,因而中斷任何嘗試間接呼叫無效位址的惡意探索。