返回更新列表
新发布Sep 18, 2026

DLLHijackHunter v2.5.0

自动化的DLL劫持发现、验证和确认。将本地错误配置转化为武器化的、已确认的攻击路径。

分享

DLLHijackHunter

作者:ProjectMerai

面向 Windows 的自动化 DLL 劫持发现、验证与确认
从“这个 DLL 可能被劫持”到“标准用户可以诱使 SYSTEM 加载它——这里是证据。”


目录


概述

DLLHijackHunter 在 Windows 主机上发现 DLL 劫持机会,并致力于证明这些机会,而不仅仅是列出它们。它会:

  1. 发现二进制程序被自动启动的每一处位置——服务、计划任务、Run 注册表键、启动文件夹、COM 服务器、AppInit/AppCert DLL、IFEO 条目以及自动提升权限的 UAC 二进制程序——并计算每个导入的 DLL 会在哪些位置被搜索。
  2. 过滤掉攻击者实际无法利用的位置:API set、KnownDLLs、标准用户无法写入的目录、受保护进程等。
  3. 验证(可选):使用真实的 Windows 加载器,放置一个无害的探测 DLL,并检查哪一份副本在搜索中胜出。
  4. 确认(可选):部署一个无害的金丝雀 DLL,触发服务/任务/COM 对象,并记录它实际运行时所使用的身份。
  5. 评分并报告每项发现的置信度和影响,并将发现关联成攻击链(例如 标准用户 → SYSTEM)。

每一项判断都从攻击者的视角——即无特权的标准用户——作出,无论扫描器本身是否以提升权限运行。以管理员身份运行可以让工具获得更多可见性(ETW、金丝雀、服务触发);它绝不会让受保护目录看起来可写,也不会夸大所获得的权限。


快速开始

下载或构建 DLLHijackHunter.exe(自包含;无需安装 .NET),然后在提升权限的命令提示符中运行:

# Passive, read-only triage: no file drops, no service/task starts
.\DLLHijackHunter.exe --profile safe

# Full static analysis without touching the system, JSON report
.\DLLHijackHunter.exe --profile aggressive --no-canary --no-etw -o report.json

# Static analysis + real-loader verification (writes probe DLLs transiently)
.\DLLHijackHunter.exe --profile aggressive --no-canary --no-etw --verify-load -o report.html

# Everything, including ETW and canary confirmation — lab / authorised targets only
.\DLLHijackHunter.exe --profile aggressive -o report.html

# Focus on one application
.\DLLHijackHunter.exe --target "C:\Program Files\MyApp\app.exe" --no-canary

杀毒软件: 金丝雀 DLL 和探测 DLL 均未签名,且行为类似劫持载荷,因此 Microsoft Defender 可能会将其隔离。该工具会检测到这种情况,并将这些结果报告为不确定,而非“不可劫持”。在测试机上,请将目标目录和 %ProgramData%\DLLHijackHunter 加入排除项,以获得确定的结果。


工作原理

flowchart TB
    subgraph S1["1 · Discovery"]
        direction LR
        EN["Launch points<br/>services · tasks · Run keys<br/>startup · COM · AutoElevate"] --> PE["PE analysis<br/>imports · delay loads<br/>manifest"] --> SO["Search order<br/>identity-aware PATH"]
        ETW["ETW runtime trace<br/>optional, elevated"]
    end
    subgraph S2["2 · Filter pipeline"]
        direction LR
        HG["Hard gates<br/>API sets · KnownDLLs<br/>writability"] --> SG["Soft gates<br/>manifest · privilege<br/>PPL · LoadLibraryEx"] --> DD["Dedup and<br/>profile filters"]
    end
    subgraph S3["3 · Verification (optional)"]
        direction LR
        LP["Load probe<br/>real Windows loader"] --> CN["Canary<br/>deploy, trigger, confirm"]
    end
    subgraph S4["4 · Output"]
        direction LR
        SC["Scoring and tiers"] --> AC["Attack chains"] --> RP["Console · JSON · HTML"]
    end
    S1 --> S2 --> S3 --> S4
阶段需要管理员权限修改系统
静态发现 + 过滤否(管理员可见更多)否
ETW 运行时发现是启动自动启动服务(最多 100 个)并运行计划任务(最多 30 个)以触发 DLL 加载
加载探测(--verify-load)否在每个候选位置短暂写入一个无害的探测 DLL,然后将其删除并恢复任何原始文件
金丝雀确认是写入一个金丝雀 DLL,停止/启动服务,运行任务,激活 COM 对象,然后进行清理

检测内容

劫持类型

类型含义备注
幻影(Phantom)该 DLL 在搜索路径中的任何位置都不存在可将其放置于二进制文件搜索的任何位置
搜索顺序在合法副本之前搜索了可写目录包括覆盖可写目录中的 DLL
ENV PATH在 PATH 中的可写目录中搜索缺失的 DLL服务仅针对机器 PATH 进行评估——服务永远不会搜索用户自己的 PATH 条目
.local 重定向<app>.exe.local\<dll> 重定向仅对没有清单的可执行文件报告(或当 IFEO DevOverrideEnable=1 时);否则加载器会忽略 .local,并且它永远不会重定向 KnownDLLs
侧加载(UAC)将自动提升的 EXE 复制到植入的 DLL 旁边仅适用于清单中包含 <autoElevate>true</autoElevate> 的 EXE。自动提升需要受信任的位置,因此副本必须通过该检查(例如模拟的 C:\Windows \System32\ 文件夹)
AppInit DLLsAppInit_DLLs 指向一个可写的 DLL加载到每个加载 user32.dll 的进程中
AppCert DLLsAppCertDLLs 指向一个可写的 DLL加载到每个 CreateProcess/WinExec 调用方中

IFEO Debugger 和 SilentProcessExit\MonitorProcess 二进制文件会像任何其他启动点一样被枚举和分析。目前不会产生基于 CWD 的劫持。

目标以谁的身份运行

正确的身份决定了权限提升判定和影响评分:

  • 服务 — ObjectName(LocalSystem、Local Service、Network Service 或某个账户);svchost 服务还会分析其 ServiceDll。
  • 计划任务 — 任务主体。诸如 S-1-5-18 的 SID 形式会映射到 NT AUTHORITY\SYSTEM;组主体以登录成员身份运行(只有管理员 + 最高权限才计为已提升)。包装在 rundll32、cmd /c 或 powershell -File 中的载荷也会被分析。
  • Run 键 / 启动文件夹 — 针对每个已加载的用户配置文件(HKEY_USERS)和每个配置文件的启动文件夹进行枚举,并归属于该用户——而不仅仅是运行扫描器的账户。
  • COM — 进程外服务器遵循 AppID → RunAs / LocalService;进程内服务器以加载它们的客户端身份运行。

知识库与 PATH 武器化

  • 会交叉引用捆绑的 HijackLibs 数据集快照(约 590 个 DLL,覆盖约 700 个可执行文件,Resources/hijacklibs.json)。匹配会提高置信度并链接参考;不匹配则无影响。可通过将文件替换为 https://hijacklibs.net/api/hijacklibs.json 来刷新。数据集 © HijackLibs 项目及贡献者。
  • 对于机器 PATH 上的每个可写目录,会为已知的 SYSTEM 服务生成候选,这些服务会探测 PATH 以查找缺失的 DLL(IKEEXT → wlbsctrl.dll、Spooler → ualapi.dll、Schedule → WptsExtensions.dll、SessionEnv → tsmsisrv.dll、WlanSvc → wlanhlp.dll)。

减少误报

硬性门槛(候选被丢弃):

  • API 集 — 每个 api-ms-* / ext-ms-* 契约名称都通过 API 集架构解析,绝不依赖搜索顺序。
  • KnownDLLs — 从活动的 \KnownDlls 和 \KnownDlls32 对象目录读取(不仅仅是注册表种子列表),外加 ntdll.dll,后者始终最先映射。
  • 攻击者相对可写性 — 仅当 Users、Authenticated Users、Everyone 或 INTERACTIVE(外加非特权服务账户,如 LOCAL SERVICE)持有相关权限时,该位置才被计入:DLL 投放需要创建文件权限,.local 目录需要创建文件夹权限。此计算基于 ACL,独立于扫描器自身的令牌,因此提权扫描绝不会将 System32、Program Files 或驱动器根目录(C:\)视为可写。

软性门控(置信度会被调整,原因记录在发现的备注中):

  • DLL 的 Manifest / WinSxS 绑定。
  • 权限增量 — 以标准用户攻击者为基准衡量:SYSTEM、LOCAL/NETWORK SERVICE 和 UAC 提权目标属于权限提升;同等权限目标则保留为持久化 / 防御规避发现。
  • LoadLibraryEx 缓解措施 — SetDefaultDllDirectories、AddDllDirectory、SetDllDirectory 导入。
  • 受保护进程 — 已知 PPL 二进制文件、在 SCM 配置中设置了 LaunchProtected 的服务(涵盖新版 Windows 及第三方 AV/EDR 服务),以及 FORCE_INTEGRITY 映像。
  • 错误处理的可选加载。

如果某个门控无法评估,候选者不会被扣分,但失败会记录在其备注和日志中,而非被隐藏。


验证:加载探测与金丝雀

加载探测(--verify-load)

对于 Phantom、Search-order 和 Side-load 候选者,一个良性的探测 DLL 会被复制到可写位置,一个短生命周期的子进程会请求真实的 Windows 加载器解析该名称:

结果含义影响
Wins加载器选择了可写位置搜索顺序得到证实;发现可能达到 High
LosesToProtectedKnownDLL、System32 或 SxS 副本胜出可能是误报;−40 置信度
NotResolved名称未能解析;加载器错误被记录无定论
Error探测无法运行——包括探测被杀毒软件隔离无定论,不扣分
Skipped.local、PATH、AppInit/AppCert 使用不同的机制—

该探测模拟位置的真实所在:二进制文件自身目录中的 DLL 会在 System32 之前被测试(正如加载器所做的那样);其他位置则根据情况使用经典或现代搜索顺序。以标准用户身份运行;每个探测都会被移除,任何原始文件都会被恢复。

金丝雀确认

sequenceDiagram
    autonumber
    participant H as DLLHijackHunter
    participant P as Hijack position
    participant T as Service / task / COM
    Note over H: Pick canary for target bitness,<br/>or build an export-forwarding proxy
    H->>P: Back up original DLL, write canary
    H->>T: sc start / schtasks /run / COM activation
    T->>P: Load DLL by name (search order)
    Note over P,T: Canary DllMain records user,<br/>integrity level and SeDebug
    T-->>H: Confirmation file written
    Note over H: Finding marked CONFIRMED
    H->>P: Remove canary, restore original DLL
    H->>T: Restore original service state

分类