Siofra 是一款旨在识别和利用 Windows 程序中 DLL 劫持漏洞的工具。它能够模拟 Windows 加载器,从而揭示磁盘上 PE 文件的所有依赖项(以及相应的漏洞),或者与活动进程相对应的内存中的映像文件。更重要的是,该工具能够通过动态 shellcode 生成的 PE 感染,轻松生成 DLL 以利用此类漏洞。这些被感染的 DLL 保留了 DLL 的代码(DllMain、导出函数)和资源,从而无缝保持加载它们的应用程序的功能,同时允许研究人员指定一个可执行载荷,作为独立进程运行或作为模块加载到目标中。此外,该工具还包含自动化方法,将 UAC 自动提升标准与上述功能相结合,以扫描 UAC 绕过漏洞。
目前,该工具暴露了大量漏洞。在测试该工具时,在我测试的数百个应用程序中,只有少数几个不存在漏洞。请注意,即使启用了 SafeDllSearchMode,这些漏洞仍可被利用。一个常见的误解是将“当前目录”(由 SafeDllSearchMode 修复)与“应用程序目录”(包含 .exe 本身的文件夹)混淆。目前 Windows 程序中的绝大多数 DLL 劫持漏洞都源于应用程序目录(它在 Windows 搜索顺序中排在第一位)。下面列出了该工具中扫描器生成的一些突出结果。这些漏洞最后一次测试是在 2017 年 7 月中旬。
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 集、程序集依赖项和显式加载的库,以确定每个模块在运行时进程初始化期间将被加载的路径。凭借此信息,该工具能够识别易受劫持的模块。在 PE 处理和加载器模拟期间,该工具能够处理: 1. 使用主 PE 导入节导入的模块。 2. 通过延迟加载导入的模块。 3. WinSxS 程序集依赖项解析(解析 PE 清单资源,提取程序集依赖项 ID,并使用自定义实现识别 WinSxS 模块路径)。 4. 通过运行时 LoadLibrary 导入的显式加载模块。 5. 上述所有导入类型的 API 集解析。这是通过自定义实现的解析器来完成的,该解析器用于解析 ApiSetSchema.dll 中未文档化的数据结构(请注意,仅测试了版本 2、4 和 6)。 6. 按名称搜索特定导入模块。 7. 识别可被利用进行 UAC 绕过攻击的 Windows 组件(以自动化方式将 UAC 自动提升标准应用于指定目标 PE,如果存在劫持攻击,则与劫持攻击结合使用)。 8. 自动检测并筛选不存在漏洞的模块依赖项,依据如下: * KnownDLLs * 豁免(“Base”)DLL 状态。例如 Kernelbase.dll、ntdll.dll 等。 * 清单覆盖安全机制(Microsoft 在 sysprep.exe 中使用)
在内存扫描模式下,该工具可以枚举本地进程名称/ID,也可以指定一个进程 ID 进行扫描。该工具不会解析磁盘上与给定 PID 对应的映像文件,而是枚举当前加载到进程中的模块,并识别其中哪些可能易受劫持。这在磁盘上的可执行文件被加壳/混淆且无法通过解析 PE 头识别其导入时非常有用。
要显示工具使用信息,只需不带任何参数运行它(输出如下所示)。非常重要的一点是,根据目标是 32 位 PE 还是 64 位 PE 文件,为所需目标使用相应的工具编译版本(32 位或 64 位)。同样,32 位版本的工具只能枚举和/或定位 32 位进程(x64 操作系统上的 Wow64),而 64 位版本只能枚举和/或定位 64 位进程。此原则同时适用于扫描(Siofra64.exe 将跳过 32 位 PE,Siofra32.exe 将跳过 64 位 PE)和 PE 感染。Siofra32.exe 应用于感染 32 位 DLL,Siofra64.exe 应用于感染 64 位 DLL。
当 32 位版本的工具在 x64 系统上运行时,工具会显式禁用 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。