共用方式為


Dynamic-Link 連結庫安全性

當應用程式動態載入動態連結庫而不指定完整路徑名稱時,Windows 會依特定順序搜尋一組定義完善的目錄,嘗試尋找 DLL,如 Dynamic-Link 連結庫搜尋順序中所述。 如果攻擊者取得 DLL 搜尋路徑上其中一個目錄的控制權,它可以在該目錄中放置 DLL 的惡意複本。 這有時稱為 DLL 預先載入攻擊二進位植入攻擊。 如果系統在搜尋遭入侵的目錄之前找不到 DLL 的合法複本,則會載入惡意 DLL。 如果應用程式是以系統管理員許可權執行,攻擊者可能會以本機許可權提升成功。

例如,假設應用程式的設計目的是要從使用者的目前目錄載入 DLL,並在找不到 DLL 時正常失敗。 應用程式只會使用 DLL 的名稱呼叫 LoadLibrary,這會導致系統搜尋 DLL。 假設已啟用安全的 DLL 搜尋模式,且應用程式未使用替代搜尋順序,系統會依下列順序搜尋目錄:

  1. 應用程式從中載入的目錄。
  2. 系統目錄。
  3. 16 位系統目錄。
  4. Windows 目錄。
  5. 目前目錄。
  6. PATH 環境變數中所列的目錄。

繼續進行此範例,具備應用程式知識的攻擊者會取得目前目錄的控制,並將 DLL 的惡意複本放在該目錄中。 當應用程式發出 LoadLibrary 呼叫時,系統會搜尋 DLL、在目前目錄中尋找 DLL 的惡意復本,並加以載入。 DLL 的惡意複本接著會在應用程式內執行,並取得用戶的許可權。

開發人員可遵循下列指導方針,協助保護其應用程式免於 DLL 預先載入攻擊:

  • 盡可能使用 LoadLibraryLoadLibraryExCreateProcessShellExecute 函式時,指定完整路徑。

  • 使用 LOAD_LIBRARY_SEARCH 旗標搭配 LoadLibraryEx 函式,或使用這些旗標搭配 SetDefaultDllDirectories 函式來建立進程的 DLL 搜尋順序,然後使用 AddDllDirectorySetDllDirectory 函式來修改清單。 如需詳細資訊,請參閱 Dynamic-Link 連結庫搜尋順序

    Windows 7、Windows Server 2008 R2、Windows Vista 和 Windows Server 2008: 這些旗標和函式可在已安裝 KB2533623 的系統上使用。

  • 在安裝 KB2533623 的系統上,使用 LOAD_LIBRARY_SEARCH 旗標搭配 LoadLibraryEx 函式,或使用這些旗標搭配 SetDefaultDllDirectories 函式來建立進程的 DLL 搜尋順序,然後使用 AddDllDirectorySetDllDirectory 函式來修改列表。 如需詳細資訊,請參閱 Dynamic-Link 連結庫搜尋順序

  • 請考慮使用 DLL 重新導向指令清單,以確保您的應用程式使用正確的 DLL。

  • 使用標準搜尋順序時,請確定已啟用安全的 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 載入作業

  1. 啟動行程監視器。
  2. 在 [行程監視器] 中,包含下列篩選:
    • 作業為 CreateFile
    • 作業為 LoadImage
    • 路徑包含 .cpl
    • 路徑包含 .dll
    • 路徑包含 .drv
    • 路徑包含 .exe
    • 路徑包含 .ocx
    • 路徑包含 .scr
    • 路徑包含 .sys
  3. 排除下列篩選:
    • 進程名稱 procmon.exe
    • 進程名稱 Procmon64.exe
    • 進程名稱為系統
    • 作業從IRP_MJ_開始
    • 作業的開頭為 FASTIO_
    • 結果為 SUCCESS
    • 路徑結尾為 pagefile.sys
  4. 嘗試使用目前目錄設定為特定目錄來啟動您的應用程式。 例如,按兩下擴展名為的應用程式指派檔案處理程式的檔案。
  5. 檢查行程監視器輸出中是否有看起來可疑的路徑,例如呼叫目前目錄以載入 DLL。 這種呼叫可能表示應用程式中的弱點。