適用於平台安全性的控制流程防護
什麼是控制流程防護?
控制流程防護 (CFG) 是一項高度優化的平臺安全性功能,旨在對抗記憶體損毀弱點。 藉由對應用程式執行程序代碼的位置施加嚴格的限制,利用緩衝區溢位等弱點執行任意程式代碼會變得困難得多。 CFG 延伸了先前的惡意探索風險降低技術,例如 /GS(緩衝區安全性檢查)、數據執行預防 (DEP)和地址空間配置隨機化 (ASLR)。
使用 CFG 有助於:
- 防止記憶體損毀和勒索軟體攻擊。
- 將伺服器的功能限制為只有特定時間點需要的功能,以減少受攻擊面。
- 透過緩衝區溢位等弱點,更難利用任意程序代碼。
這項功能可在Visual Studio Microsoft中使用,並在CFG感知 Windows 版本上執行;用戶端和 Windows Server 2019 和更新版本的 Windows 10 和 Windows 11 在伺服器端。
強烈建議開發人員為其應用程式啟用 CFG。 您不需要針對程式碼的每個部分啟用 CFG,因為已啟用 CFG 且非 CFG 的程式碼會正常執行。 不過,無法啟用所有程式碼的 CFG 可能會開啟保護中的間距。 此外,已啟用 CFG 的程式代碼可在 CFG-Unaware 版本的 Windows 上正常運作,因此與它們完全相容。
如何啟用 CFG?
在大部分情況下,不需要變更原始程式碼。 您只需要將選項新增至 Visual Studio 專案,編譯程式和連結器就會啟用 CFG。
最簡單的方法是流覽至 Project |屬性 |組態屬性 |C/C++ |程式代碼產生 ,然後選擇 [是] (/guard:cf) 來控制流程防護。
或者,將 /guard:cf 新增至 Project |屬性 |組態屬性 |C/C++ |命令行 |其他選項(適用於編譯程式)和 /guard:cf 至 Project |屬性 |組態屬性 |鏈接器 |命令行 |其他選項(適用於連結器)。
如需其他資訊,請參閱 /guard (啟用控制流程防護)。
如果您要從命令行建置專案,您可以新增相同的選項。 例如,如果您要編譯名為 test.cpp 的專案,請使用 cl /guard:cf test.cpp /link /guard:cf。
您也可以選擇使用記憶體管理 API 中的 SetProcessValidCallTargets ,動態控制 CFG 視為有效的一組 icall 目標位址。 您可以使用相同的 API 來指定 CFG 的頁面無效或有效目標。 VirtualProtect 和 VirtualAlloc 函式預設會將指定的可執行文件和認可頁面區域視為有效的間接呼叫目標。 您可以藉由在呼叫 VirtualAlloc 時指定 PAGE_TARGETS_INVALID,或在呼叫 VirtualAl PAGE_TARGETS_NO_UPDATE loc 或呼叫 VirtualProtect 時,如記憶體保護常數下詳述,來覆寫此行為,例如實作 Just-In-Time 編譯程式時。
如何判斷二進位檔在控制流程防護下?
使用 /headers 和 /loadconfig 選項,從 Visual Studio 命令提示字元執行 dumpbin 工具(包含在 Visual Studio 安裝中),並test.exe dumpbin /headers /loadconfig。 CFG 下二進位的輸出應該會顯示標頭值包含 「Guard」,且負載設定值包含 「CF Instrumented」 和 「FID 數據表存在」。
CFG 如何真正運作?
軟體弱點通常是藉由將不太可能、不尋常的或極端數據提供給執行中的程式來利用。 例如,攻擊者可以藉由對程式提供比預期更多的輸入來利用緩衝區溢位弱點,藉此過度執行程式保留的區域來保存回應。 這可能會損毀可能保存函式指標的相鄰記憶體。 當程式透過此函式呼叫時,它可能會跳至攻擊者指定的非預期位置。
不過,CFG 的編譯和運行時間支援有力組合會實作控制流程完整性,以嚴格限制間接呼叫指令可執行的位置。
編譯程式會執行下列動作:
- 將輕量型安全性檢查新增至已編譯的程序代碼。
- 識別應用程式中有效的函式集合,這些函式是間接呼叫的有效目標。
Windows 核心提供的運行時間支援:
- 有效率地維護可識別有效間接呼叫目標的狀態。
- 實作可驗證間接呼叫目標的邏輯是否有效。
為了說明:
當 CFG 檢查在運行時間失敗時,Windows 會立即終止程式,從而中斷任何嘗試間接呼叫無效位址的惡意探索。