
DLLHijackHunter v2.5.0
自動化されたDLLハイジャックの発見、検証、確認。ローカルの設定ミスを武器化された確定した攻撃経路に変換します。
DLLHijackHunter
By ProjectMerai
Windows向けのDLLハイジャックの自動検出、検証、確認
「このDLLはハイジャック可能かもしれない」から「標準ユーザーがSYSTEMにこのDLLを読み込ませられる — これがその証拠だ」まで。
目次
- 概要
- クイックスタート
- 仕組み
- 検出対象
- 誤検知の削減
- 検証: ロードプローブとカナリア
- スコアリング、ティア、攻撃チェーン
- 使用法リファレンス
- 安全性と運用への影響
- ソースからのビルド
- テストラボ (HijackRange)
- 既知の制限
- 比較
概要
DLLHijackHunterはWindowsホスト上のDLLハイジャックの機会を発見し、単に列挙するだけでなく、それを証明することに取り組みます。具体的には:
- 発見 — バイナリが自動的に起動されるあらゆる箇所(サービス、スケジュールタスク、Runキー、スタートアップフォルダー、COMサーバー、AppInit/AppCert DLL、IFEOエントリ、自動昇格するUACバイナリ)を特定し、インポートされた各DLLがどこで検索されるかを計算します。
- フィルタリング — 攻撃者が実際には利用できない位置(APIセット、KnownDLLs、標準ユーザーが書き込めないディレクトリ、保護されたプロセスなど)を除外します。
- 検証(任意) — 実際のWindowsローダーを使用し、無害なプローブDLLを配置して、どのコピーが検索に勝つかを確認します。
- 確認(任意) — 無害なカナリアDLLを展開し、サービス/タスク/COMオブジェクトをトリガーして、実際に実行されたIDを記録します。
- スコアリングとレポート — 各検出結果を信頼度と影響度で評価し、検出結果を攻撃チェーン(例えば標準ユーザー → SYSTEM)に関連付けます。
すべての判断は、スキャナー自体が昇格して実行されているかどうかに関係なく、攻撃者の視点 — 権限のない標準ユーザー — から行われます。Administratorとして実行すると、ツールの可視性(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 ランタイム検出 | はい | DLL の読み込みを誘発するため、自動起動サービス(最大100件)を起動し、スケジュールされたタスク(最大30件)を実行する |
ロードプローブ(--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 DLLs | AppInit_DLLs が書き込み可能な DLL を指している | user32.dll を読み込むすべてのプロセスに読み込まれる |
| AppCert DLLs | AppCertDLLs が書き込み可能な DLL を指している | すべての CreateProcess/WinExec 呼び出し元に読み込まれる |
IFEO の Debugger および SilentProcessExit\MonitorProcess バイナリは、他の起動ポイントと同様に列挙・分析される。CWD ベースのハイジャックは現在生成されない。
ターゲットが実行されるユーザー
正しい識別情報が、特権昇格の判定と影響スコアの両方を左右する:
- サービス —
ObjectName(LocalSystem、Local Service、Network Service、またはアカウント)。svchost サービスはServiceDllも分析する。 - スケジュールされたタスク — タスクのプリンシパル。
S-1-5-18のような SID 形式はNT AUTHORITY\SYSTEMにマッピングされる。グループプリンシパルはログオンしているメンバーとして実行される(Administrators + 最高特権のみが昇格済みとみなされる)。rundll32、cmd /c、またはpowershell -Fileでラップされたペイロードも分析される。 - Run キー / スタートアップフォルダー — 読み込まれているすべてのユーザープロファイル(
HKEY_USERS)と各プロファイルのスタートアップフォルダーについて列挙され、スキャナーを実行しているアカウントだけでなく、そのユーザーに帰属される。 - COM — アウトプロセスサーバーは
AppID→RunAs/LocalServiceに従う。インプロセスサーバーは、それを読み込むクライアントとして実行される。
ナレッジベースと PATH の武器化
- HijackLibs データセットのバンドルされたスナップショット(約700の実行ファイルにわたる約590の DLL、
Resources/hijacklibs.json)が照合される。一致すれば信頼度が上がり参照がリンクされる。一致しなければ何も示さない。ファイルをhttps://hijacklibs.net/api/hijacklibs.jsonに置き換えることで更新できる。データセット © HijackLibs プロジェクトおよび貢献者。 - マシンの PATH 上の各書き込み可能なディレクトリについて、存在しない DLL を求めて PATH を探索する既知の SYSTEM サービス(
IKEEXT → wlbsctrl.dll、Spooler → ualapi.dll、Schedule → WptsExtensions.dll、SessionEnv → tsmsisrv.dll、WlanSvc → wlanhlp.dll)の候補が生成される。
誤検知の削減
ハードゲート(候補は除外される):
- API セット — すべての
api-ms-*/ext-ms-*コントラクト名は、検索順序ではなく API set スキーマを通じて解決されます。 - KnownDLLs — レジストリのシードリストだけでなく、ライブの
\KnownDllsおよび\KnownDlls32オブジェクトディレクトリから読み取られ、さらに常に最初にマップされるntdll.dllも含まれます。 - 攻撃者相対の書き込み可能性 — ある位置が該当するのは、
Users、Authenticated Users、Everyone、またはINTERACTIVE(加えてLOCAL SERVICEのような非特権サービスアカウント)が、重要な権限を保持している場合のみです。すなわち、DLL ドロップの場合はファイル作成、.localディレクトリの場合はフォルダ作成です。これはスキャナ自身のトークンとは独立して ACL から計算されるため、昇格したスキャンがSystem32、Program Files、またはドライブのルート(C:\)を書き込み可能と見なすことは決してありません。
ソフトゲート(信頼度が調整され、その理由が検出結果のノートに記録されます):
- DLL のマニフェスト / WinSxS バインディング。
- 特権差分 — 標準ユーザー攻撃者を基準に測定されます。SYSTEM、LOCAL/NETWORK SERVICE、および UAC で昇格されたターゲットは特権昇格です。同一特権のターゲットは、永続化 / 防御回避の検出結果として保持されます。
- LoadLibraryEx の緩和策 —
SetDefaultDllDirectories、AddDllDirectory、SetDllDirectoryのインポート。 - 保護されたプロセス — 既知の PPL バイナリ、SCM 構成で
LaunchProtectedが設定されたサービス(新しい Windows およびサードパーティの AV/EDR サービスをカバー)、およびFORCE_INTEGRITYイメージ。 - エラー処理されたオプションのロード。
ゲートの評価に失敗した場合、候補はペナルティを受けませんが、その失敗は隠されることなくノートおよびログに記録されます。
検証: ロードプローブとカナリア
ロードプローブ (--verify-load)
Phantom、検索順序、およびサイドロードの候補については、無害なプローブ DLL が書き込み可能な位置にコピーされ、短命の子プロセスが実際の Windows ローダーに名前の解決を要求します: