Skip to content
KitploitKITPLOIT
ツールブログ
提出
ツールブログ
提出

ハッキング、侵入テスト、サイバーセキュリティツールをあなたのセキュリティアーセナルに!

Kitploitはハッキング、サイバーセキュリティ、ペネトレーションテストのツールディレクトリです。最新のプロジェクトアップデートを見つけて、脆弱性の発見、システム分析、テストの自動化、セキュリティの強化を行いましょう。

··フィード·お問い合わせ·プライバシー·© 2026 Kitploit

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
CLR-Unhook — 最新のセキュリティ製品(CrowdStrike、Bitdefender、SentinelOne など)は、clr.dll 内の nLoadImage 関数をフックして、メモリ内の .NET アセンブリ読み込みをインターセプトし、スキャンします。このツールは、その関数のフックを解除します。 | Kitploit
ツール/GitHubGitHub/hwbp/clr-unhook
防御ツールエクスプロイトポストエクスプロイトペネトレーションテストレッドチーミングペイロード開発
GitHubhwbp/clr-unhook

CLR-Unhook

最新のセキュリティ製品(CrowdStrike、Bitdefender、SentinelOne など)は、clr.dll 内の nLoadImage 関数をフックして、メモリ内の .NET アセンブリ読み込みをインターセプトし、スキャンします。このツールは、その関数のフックを解除します。

リポジトリを見る
217228ヶ月前Kitploit レビュー済み

人気

すべて見る →

コミュニティで最も使われているツールを見つけましょう。

すべてのツールを探索

ツールコレクションを閲覧

すべてのツールを見る →
共有

CLR アンフッキングツール

  • 注: これをクリーンな CLR として機能させるには、ディスクから DLL を手動でメモリにマップする必要があります。LoadLibraryA/W は使用できません。アンチウイルスソリューションが DLL のロードイベントを検出し、即座にフックする可能性があるためです。この動作が必要な場合は、GitHub で既存の手動マッパーを探してコードベースに統合してください。AV ベンダーは一般的にこれを好まないため、ここには含めていません。

.NET 共通言語ランタイム(CLR)における EDR/AV フックを、元の nLoadImage 関数の実装を復元することで回避するネイティブ C++ ユーティリティです。

概要

このツールは、セキュリティ製品による CLR の nLoadImage 関数へのフックを除去します。nLoadImage は、インメモリの .NET アセンブリ読み込みをすべて処理する重要なネイティブエントリポイントです。ディスクからクリーンな clr.dll を読み取り、メモリ内のフックされた関数バイトを上書きすることで、元の CLR の動作を復元し、Assembly.Load(byte[]) が EDR による検査やスキャンなしで実行できるようにします。

これは何をするのか?

最新のセキュリティ製品(BitDefender、CrowdStrike、SentinelOne など)は、clr.dll 内の nLoadImage 関数をフックして、インメモリの .NET アセンブリ読み込みを傍受・スキャンします。このツールは以下の方法でその関数をアンフックします:

  1. ディスクからクリーンな clr.dll を読み取る
  2. 元の nLoadImage バイトを見つける
  3. メモリ内のフックされたバージョンを上書きする

アンフック後、Assembly.Load(byte[]) は EDR による検査なしで実行されます。

nLoadImage について

nLoadImage は、.NET ランタイムにおけるすべてのインメモリアセンブリ読み込みを処理する重要なネイティブ関数です。マネージドコードでは InternalCall として宣言されており、C# による実装は存在せず、ネイティブ CLR コードへの直接的なブリッジとなっています。

呼び出しチェーン:

root@kitploit:~
Managed Code (C#)
    ↓
Assembly.Load(byte[])
    ↓
RuntimeAssembly.nLoadImage(...) [InternalCall - no managed body]
    ↓
clr.dll!AssemblyNative::LoadImage (Native C++ implementation)
    ↓
Assembly loaded into AppDomain

なぜ重要なのか:

ほぼすべてのインメモリアセンブリ読み込みは nLoadImage を経由します。Assembly.Load(byte[]) メソッドとそのオーバーロード(シンボルバイトを伴う読み込みを含む)はすべて、内部で nLoadImage を呼び出します。Assembly.Load(byte[]) を呼び出すと、mscorlib.dll 内のマネージドコードがバイト配列を RuntimeAssembly.nLoadImage() に渡します。このメソッドは [MethodImpl(MethodImplOptions.InternalCall)] でマークされているため、C# での本体は空で、実行は即座にネイティブ CLR コードへジャンプします。

実行時にアセンブリを生成するシリアライゼーションフレームワーク、XML シリアライザの生成、Cobalt Strike の execute-assembly のようなレッドチームツールなど、動的コード生成のシナリオでさえ、すべてこの単一の関数を通ります。

ネイティブ実装:

mscorlib.dll 内の nLoadImage InternalCall スタブは、clr.dll 内のネイティブ C++ 関数 AssemblyNative::LoadImage を指しています。この関数は以下の処理を行います:

  • バイト配列から PE ヘッダーを解析する
  • メタデータと IL コードを検証する
  • アセンブリ用のメモリを割り当てる
  • AppDomain にアセンブリを登録する
  • ロード後イベントをトリガーする(.NET 4.8+ の ETW、AMSI スキャン)
  • 混合モードアセンブリ(ネイティブ + マネージド)を処理する
  • 厳密名の検証を強制する

.NET Framework 4.8+ では、nLoadImage の呼び出しごとにアセンブリバイトが実行前に Windows Defender の AMSI(AmsiScanBuffer)に自動的に渡されてスキャンされるため、セキュリティ製品にとって重要なチョークポイントとなっています。

関数シグネチャ(.NET Framework 4.7+):

root@kitploit:~
[MethodImpl(MethodImplOptions.InternalCall)]
static internal extern Assembly nLoadImage(
    byte[] rawAssembly,              // PE bytes
    byte[] rawSymbolStore,           // Optional PDB bytes
    Evidence evidence,               // CAS evidence (obsolete)
    ref StackCrawlMark stackMark,    // Security stack marker
    bool fIntrospection,             // Reflection-only flag
    bool fSkipIntegrityCheck,        // Skip integrity validation
    SecurityContextSource securityContextSource  // Security context
);

Assembly.Load(byte[]) を呼び出すと、nLoadImage が以下の一般的なパラメータで呼び出されます:

root@kitploit:~
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
return RuntimeAssembly.nLoadImage(
    rawAssembly,                            // Your byte array
    null,                                   // rawSymbolStore
    null,                                   // evidence
    ref stackMark,                          // LookForMyCaller
    false,                                  // fIntrospection
    SecurityContextSource.CurrentAssembly   // securityContextSource
);

fIntrospection パラメータは、アセンブリが実行用に読み込まれるか(false)、リフレクション専用の検査用に読み込まれるか(true)を制御します。Assembly.ReflectionOnlyLoad(byte[]) メソッドは fIntrospection=true で nLoadImage を呼び出し、コードを実行せずにメタデータを検査できるようにします。

EDR がフックする理由:

nLoadImage はすべてのインメモリアセンブリ読み込みの単一のエントリポイントであるため、EDR 製品は clr.dll 内でネイティブレベルでこれをフックします。これにより、以下のことが可能になります:

  • 読み込み前にすべてのアセンブリを検査する
  • 悪意のあるパターンをバイト配列からスキャンする
  • .NET がアセンブリを処理する前に実行をブロックする
  • AMSI/ETW 回避テクニックを迂回する(フックはそれらのレイヤーより下にあるため)

従来のバイパス(AMSI パッチ、ETW 無効化)は、スタックのより上位のレイヤーで動作するため、CLR レベルのフックには影響しません。フックは AMSI が呼び出される前に、CLR 自体の内部で行われます。

使用方法

ローカルプロセス(現在のプロセス)

root@kitploit:~
CLRUnhook.exe

現在のプロセスで CLR をアンフックします。注: これは CLR がすでに読み込まれている場合にのみ機能します(つまり、.NET アプリケーションから実行されているか、CLR を手動で読み込んだ後である必要があります)。

リモートプロセス(別のプロセスをターゲットにする)

root@kitploit:~
CLRUnhook.exe powershell.exe

CLRUnhook.exe 1234

リモートプロセス内の CLR をアンフックします。

出力例

リモートアンフックの成功例

root@kitploit:~
=== CLR Unhooking Tool ===

[*] Mode -> Remote Process Unhooking
[*] Target -> PID 21436
[+] Found PID -> 21436
[*] Unhooking CLR->nLoadImage in remote process...
[DEBUG] Remote mode enabled
[DEBUG] Found clr.dll at 0x00007FFD38CB0000
[DEBUG] CLR path -> C:\Windows\Microsoft.NET\Framework64\v4.0.30319\clr.dll
[DEBUG] CLR module size -> 10108928 bytes
[DEBUG] Read 10108928 bytes from remote process
[DEBUG] Searching for 'nLoadImage' in module (size: 10108928)
[DEBUG] Remote base address: 0x00007FFD38CB0000
[DEBUG] Scanning for string 'nLoadImage' (11 bytes)...
[DEBUG] Found string at RVA 0x7c12b8
[DEBUG] Searching for remote pointer: 0x7ffd394712b8
[DEBUG] Found pointer at offset 0x7a4340
[DEBUG] Valid function pointer found at RVA 0x5e4f30
[DEBUG] Found nLoadImage at RVA 0x00000000005E4F30
[DEBUG] Hooked function address -> 0x00007FFD39294F30
[DEBUG] Clean function at offset 0x00000000005E4F30 in disk file
[DEBUG] Reading hooked bytes before patch...
[DEBUG] First 16 bytes BEFORE unhook:
       4C 8B DC 49 89 5B 08 49 89 73 10 4D 89 4B 20 57
[DEBUG] Clean bytes from disk:
       8B 4B 78 E8 88 A9 EA FF C6 44 24 28 00 80 3D A4
[DEBUG] Wrote 30 bytes successfully
[DEBUG] First 16 bytes AFTER unhook:
       8B 4B 78 E8 88 A9 EA FF C6 44 24 28 00 80 3D A4
[DEBUG] VERIFICATION SUCCESS: Patched bytes match clean bytes!
[+] SUCCESS -> CLR nLoadImage unhooked in remote process!
[+] EDR/AV hooks bypassed

[*] Press Enter to exit...

フックチェーン

root@kitploit:~
Managed Code (C#)
    ↓
Assembly.Load(byte[])
    ↓
RuntimeAssembly.nLoadImage(...) [InternalCall]
    ↓
clr.dll!AssemblyNative::LoadImage
    ↓
[EDR HOOK] ← We bypass this
    ↓
Original CLR Code

アンフックのプロセス

  1. フックされた関数を特定する - 読み込まれた clr.dll 内で nLoadImage を見つける(現在フックされている)
  2. クリーンなコピーを読み込む - C:\Windows\Microsoft.NET\Framework64\v4.0.30319\ から元の clr.dll を読み取る
  3. クリーンなバイトを抽出する - 元の関数の最初の 30 バイトを取得します。.NET は JIT であるため、問題を引き起こしたくないからです。
  4. フックを上書きする - フックされたバージョンをクリーンなバイトでパッチする

関数の発見

パターンスキャンを使用して nLoadImage を特定します:

  1. モジュールメモリ内で「nLoadImage」文字列を検索する
  2. その文字列へのポインタを見つける
  3. 文字列ポインタに隣接する関数ポインタを見つける
  4. アドレスがモジュール境界内にあることを検証する

クレジット

技術調査:

  • Matthew Graeber (@mattifestation) - InternalCall メソッドと CLR 内部構造のリバースエンジニアリング

実装:

  • HWBP - メモリ復元による CLR アンフック
  • @Evilbytecode - アンフックを手伝ってくれました。.NET が JIT であることに関していくつか問題がありました。

免責事項

教育目的および許可されたセキュリティ研究専用です。

このツールをセキュリティ管理を回避するために不正に使用すると、コンピュータ詐欺に関する法律(CFAA および同等の法令)に違反する可能性があります。所有しているシステム、またはテストするための明示的な書面による許可を得たシステムでのみ使用してください。

参考資料

  • Reverse Engineering InternalCall Methods - Matthew Graeber
  • Microsoft .NET リファレンスソース
  • CLR アセンブリ読み込みパイプラインのドキュメント
ツールをダウンロード