Dynamic-Link 連結庫安全性
當應用程式動態載入動態連結庫而不指定完整路徑名稱時,Windows 會依特定順序搜尋一組定義完善的目錄,嘗試尋找 DLL,如 Dynamic-Link 連結庫搜尋順序中所述。 如果攻擊者取得 DLL 搜尋路徑上其中一個目錄的控制權,它可以在該目錄中放置 DLL 的惡意複本。 這有時稱為 DLL 預先載入攻擊 或 二進位植入攻擊。 如果系統在搜尋遭入侵的目錄之前找不到 DLL 的合法複本,則會載入惡意 DLL。 如果應用程式是以系統管理員許可權執行,攻擊者可能會以本機許可權提升成功。
例如,假設應用程式的設計目的是要從使用者的目前目錄載入 DLL,並在找不到 DLL 時正常失敗。 應用程式只會使用 DLL 的名稱呼叫 LoadLibrary,這會導致系統搜尋 DLL。 假設已啟用安全的 DLL 搜尋模式,且應用程式未使用替代搜尋順序,系統會依下列順序搜尋目錄:
- 應用程式從中載入的目錄。
- 系統目錄。
- 16 位系統目錄。
- Windows 目錄。
- 目前目錄。
- PATH 環境變數中所列的目錄。
繼續進行此範例,具備應用程式知識的攻擊者會取得目前目錄的控制,並將 DLL 的惡意複本放在該目錄中。 當應用程式發出 LoadLibrary 呼叫時,系統會搜尋 DLL、在目前目錄中尋找 DLL 的惡意復本,並加以載入。 DLL 的惡意複本接著會在應用程式內執行,並取得用戶的許可權。
開發人員可遵循下列指導方針,協助保護其應用程式免於 DLL 預先載入攻擊:
盡可能使用 LoadLibrary、LoadLibraryEx、CreateProcess或 ShellExecute 函式時,指定完整路徑。
使用 LOAD_LIBRARY_SEARCH 旗標搭配 LoadLibraryEx 函式,或使用這些旗標搭配 SetDefaultDllDirectories 函式來建立進程的 DLL 搜尋順序,然後使用 AddDllDirectory 或 SetDllDirectory 函式來修改清單。 如需詳細資訊,請參閱 Dynamic-Link 連結庫搜尋順序。
Windows 7、Windows Server 2008 R2、Windows Vista 和 Windows Server 2008: 這些旗標和函式可在已安裝 KB2533623 的系統上使用。
在安裝 KB2533623 的系統上,使用 LOAD_LIBRARY_SEARCH 旗標搭配 LoadLibraryEx 函式,或使用這些旗標搭配 SetDefaultDllDirectories 函式來建立進程的 DLL 搜尋順序,然後使用 AddDllDirectory 或 SetDllDirectory 函式來修改列表。 如需詳細資訊,請參閱 Dynamic-Link 連結庫搜尋順序。
使用標準搜尋順序時,請確定已啟用安全的 DLL 搜尋模式。 這會將使用者的目前目錄置於搜尋順序之後,增加 Windows 在惡意複製之前找到 DLL 合法複本的機會。 從 Windows XP 搭配 Service Pack 2 (SP2) 開始,預設會啟用安全 DLL 搜尋模式,並由 HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\SafeDllSearchMode 登錄值控制。 如需詳細資訊,請參閱 Dynamic-Link 連結庫搜尋順序。
請考慮使用空字串呼叫 SetDllDirectory,以從標準搜尋路徑中移除當前目錄。 這應該會在進程初始化初期完成一次,而不是在呼叫 LoadLibrary 之前和之後完成。 請注意,SetDllDirectory 會影響整個進程,而且呼叫 setDllDirectory 且具有不同值的多個線程可能會導致未定義的行為。 如果您的應用程式載入第三方 DLL,請仔細測試以識別任何不相容。
除非啟用安全進程搜尋模式,否則請勿使用 SearchPath 函式來擷取後續 LoadLibrary 呼叫 DLL 的路徑。 未啟用安全進程搜尋模式時,SearchPath 函式會使用與 LoadLibrary 不同的搜尋順序,而且可能會先搜尋使用者目前目錄的指定 DLL。 若要啟用 SearchPath 函式的安全進程搜尋模式,請使用 SetSearchPathMode 函式搭配 BASE_SEARCH_PATH_ENABLE_SAFE_SEARCHMODE。 這會將目前目錄移至 SearchPath 搜尋清單的結尾,以取得程式的存回時間。 請注意,目前目錄不會從搜尋路徑中移除,因此如果系統在到達目前目錄之前找不到 DLL 的合法複本,應用程式仍然容易受到攻擊。 如同 SetDllDirectory,呼叫 SetSearchPathMode 應在程式初始化初期完成,而且會影響整個程式。 如果您的應用程式載入第三方 DLL,請仔細測試以識別任何不相容。
請勿根據搜尋 DLL 的 LoadLibrary 呼叫來假設作系統版本。 如果應用程式在 DLL 合法不存在的環境中執行,但 DLL 的惡意復本位於搜尋路徑中,可能會載入 DLL 的惡意復本。 請改用 取得系統版本中所述的建議技術。
進程監視器工具可用來協助識別可能易受攻擊的 DLL 載入作業。 您可以從 https://technet.microsoft.com/sysinternals/bb896645.aspx下載行程監視器工具。
下列程式說明如何使用行程監視器來檢查應用程式中的 DLL 載入作業。
使用行程監視器檢查應用程式中的 DLL 載入作業
- 啟動行程監視器。
- 在 [行程監視器] 中,包含下列篩選:
- 作業為 CreateFile
- 作業為 LoadImage
- 路徑包含 .cpl
- 路徑包含 .dll
- 路徑包含 .drv
- 路徑包含 .exe
- 路徑包含 .ocx
- 路徑包含 .scr
- 路徑包含 .sys
- 排除下列篩選:
- 進程名稱 procmon.exe
- 進程名稱 Procmon64.exe
- 進程名稱為系統
- 作業從IRP_MJ_開始
- 作業的開頭為 FASTIO_
- 結果為 SUCCESS
- 路徑結尾為 pagefile.sys
- 嘗試使用目前目錄設定為特定目錄來啟動您的應用程式。 例如,按兩下擴展名為的應用程式指派檔案處理程式的檔案。
- 檢查行程監視器輸出中是否有看起來可疑的路徑,例如呼叫目前目錄以載入 DLL。 這種呼叫可能表示應用程式中的弱點。