Share via


Dynamic-Link程式庫安全性

當應用程式動態載入動態連結程式庫而不指定完整路徑名稱時,Windows 會嘗試以特定順序搜尋一組定義完善的目錄來尋找 DLL,如 動態連結程式庫搜尋順序中所述。 如果攻擊者取得 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 預先載入攻擊:

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

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

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

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

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

  • 使用標準搜尋順序時,請確定已啟用安全的 DLL 搜尋模式。 這會在搜尋順序稍後將使用者的目前目錄放在搜尋順序中,增加 Windows 在惡意複製之前會找到 DLL 合法複本的機會。 從 Service Pack 2 (SP2) 的 Windows XP 開始,預設會啟用安全 DLL 搜尋模式,並由safeDllSearchMode登錄值HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\ 控制。 如需詳細資訊,請參閱 動態連結程式庫搜尋順序

  • 請考慮使用空字串 (「」「) 呼叫 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。 這種呼叫可能表示應用程式中的弱點。