Безопасность библиотеки Dynamic-Link

Когда приложение динамически загружает библиотеку динамической компоновки без указания полного имени пути, Windows пытается найти библиотеку DLL путем поиска в четко определенном наборе каталогов в определенном порядке, как описано в разделе Порядок поиска библиотек динамической компоновки. Если злоумышленник получает контроль над одним из каталогов в пути поиска DLL, он может поместить вредоносную копию библиотеки DLL в этот каталог. Иногда это называется атакой предварительной загрузки DLL или атакой на установку двоичных файлов. Если система не находит законную копию библиотеки DLL перед поиском в скомпрометированном каталоге, она загружает вредоносную библиотеку DLL. Если приложение выполняется с правами администратора, злоумышленник может успешно получить локальное повышение привилегий.

Например, предположим, что приложение предназначено для загрузки библиотеки DLL из текущего каталога пользователя и корректно завершается сбоем, если библиотека DLL не найдена. Приложение вызывает LoadLibrary только с именем библиотеки DLL, что приводит к тому, что система выполняет поиск библиотеки DLL. Если включить безопасный режим поиска DLL и приложение не использует альтернативный порядок поиска, система выполняет поиск в каталогах в следующем порядке:

  1. Каталог, из которого загружено приложение.
  2. Системный каталог.
  3. 16-разрядный системный каталог.
  4. Каталог Windows.
  5. Текущий каталог.
  6. Каталоги, перечисленные в переменной среды PATH.

Продолжая пример, злоумышленник, зная приложение, получает контроль над текущим каталогом и помещает вредоносную копию библиотеки DLL в этот каталог. Когда приложение выполняет вызов LoadLibrary , система ищет библиотеку DLL, находит вредоносную копию библиотеки DLL в текущем каталоге и загружает ее. Затем вредоносная копия библиотеки DLL запускается в приложении и получает привилегии пользователя.

Разработчики могут помочь защитить свои приложения от атак предварительной загрузки DLL, следуя следующим рекомендациям:

  • По возможности укажите полный путь при использовании функций LoadLibrary, LoadLibraryEx, CreateProcess или ShellExecute .

  • Используйте флаги LOAD_LIBRARY_SEARCH с функцией LoadLibraryEx или используйте эти флаги с функцией SetDefaultDllDirectories , чтобы установить порядок поиска DLL для процесса, а затем использовать функции AddDllDirectory или SetDllDirectory для изменения списка. Дополнительные сведения см. в разделе Dynamic-Link Library Search Order.

    Windows 7, Windows Server 2008 R2, Windows Vista и Windows Server 2008: Эти флаги и функции доступны в системах с установленным обновлением KB2533623 .

  • В системах с установленным обновлением KB2533623 используйте флаги LOAD_LIBRARY_SEARCH с функцией LoadLibraryEx или используйте эти флаги с функцией SetDefaultDllDirectories , чтобы установить порядок поиска DLL для процесса, а затем используйте функции AddDllDirectory или SetDllDirectory для изменения списка. Дополнительные сведения см. в разделе Dynamic-Link Library Search Order.

  • Рассмотрите возможность использования перенаправления DLL или манифеста , чтобы убедиться, что приложение использует правильную библиотеку DLL.

  • При использовании стандартного порядка поиска убедитесь, что включен безопасный режим поиска DLL. Это помещает текущий каталог пользователя позже в порядок поиска, что повышает вероятность того, что Windows найдет законную копию библиотеки DLL до вредоносной копии. Безопасный режим поиска DLL включен по умолчанию, начиная с Windows XP с пакетом обновления 2 (SP2) и управляется HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\ значением реестра SafeDllSearchMode. Дополнительные сведения см. в разделе Dynamic-Link Library Search Order.

  • Попробуйте удалить текущий каталог из стандартного пути поиска, вызвав SetDllDirectory с пустой строкой (""). Это следует делать один раз на ранних этапах инициализации процесса, а не до и после вызовов LoadLibrary. Имейте в виду, что SetDllDirectory влияет на весь процесс и что несколько потоков, вызывающих SetDllDirectory с разными значениями, могут привести к неопределенному поведению. Если приложение загружает сторонние библиотеки DLL, тщательно протестируйте их, чтобы выявить несовместимость.

  • Не используйте функцию SearchPath для получения пути к библиотеке DLL для последующего вызова LoadLibrary , если не включен безопасный режим поиска процессов. Если режим безопасного поиска процессов не включен, функция SearchPath использует порядок поиска, отличный от LoadLibrary , и, скорее всего, сначала выполняет поиск указанной библиотеки DLL в текущем каталоге пользователя. Чтобы включить безопасный режим поиска процессов для функции SearchPath , используйте функцию SetSearchPathMode с BASE_SEARCH_PATH_ENABLE_SAFE_SEARCHMODE. Текущий каталог перемещается в конец списка поиска SearchPath для жизненного времени процесса. Обратите внимание, что текущий каталог не удаляется из пути поиска, поэтому если система не находит законную копию библиотеки DLL до того, как она достигнет текущего каталога, приложение по-прежнему уязвимо. Как и в случае с SetDllDirectory, вызов SetSearchPathMode должен выполняться на ранней стадии инициализации процесса, и это влияет на весь процесс. Если приложение загружает сторонние библиотеки DLL, тщательно протестируйте их, чтобы выявить несовместимость.

  • Не делайте предположений о версии операционной системы на основе вызова LoadLibrary , который ищет библиотеку DLL. Если приложение выполняется в среде, где библиотека DLL отсутствует, но в пути поиска находится вредоносная копия библиотеки DLL, может быть загружена вредоносная копия библиотеки DLL. Вместо этого используйте рекомендуемые методы, описанные в разделе Получение версии системы.

Средство Монитор процессов можно использовать для определения операций загрузки DLL, которые могут быть уязвимы. Средство Монитор процессов можно скачать по ссылке https://technet.microsoft.com/sysinternals/bb896645.aspx.

В следующей процедуре описывается использование монитора процессов для проверки операций загрузки DLL в приложении.

Использование монитора процессов для проверки операций загрузки DLL в приложении

  1. Запуск монитора процессов.
  2. В мониторе процессов включите следующие фильтры:
    • Operation is CreateFile
    • Операция — LoadImage.
    • Путь содержит .cpl
    • Путь содержит .dll
    • Путь содержит DRV-файл
    • Путь содержит .exe
    • Путь содержит OCX-файл
    • Путь содержит SCR-файл
    • Путь содержит .sys
  3. Исключите следующие фильтры:
    • Имя процесса — procmon.exe
    • Имя процесса — Procmon64.exe
    • Имя процесса — System
    • Операция начинается с IRP_MJ_
    • Операция начинается с FASTIO_
    • Результат — SUCCESS
    • Путь заканчивается pagefile.sys
  4. Попробуйте запустить приложение с текущим каталогом, заданным в определенном каталоге. Например, дважды щелкните файл с расширением, обработчик которого назначен вашему приложению.
  5. Проверьте выходные данные монитора процессов на наличие подозрительных путей, таких как вызов текущего каталога для загрузки библиотеки DLL. Такой вызов может указывать на уязвимость в приложении.