Vectored Overloading PE Injection

Tip

AWSハッキングを学び、実践する:HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する:HackTricks Training GCP Red Team Expert (GRTE) Azureハッキングを学び、実践する:HackTricks Training Azure Red Team Expert (AzRTE)

HackTricksをサポートする

テクニック概要

Vectored Overloading は、古典的な Module Overloading と Vectored Exception Handlers (VEHs) および ハードウェアブレークポイントを融合させた Windows の PE インジェクション手法です。LoadLibrary をパッチしたり独自のローダを実装したりする代わりに、攻撃者は次を行います。

  1. 正規の DLL(例: wmp.dll)をバックエンドに持つ SEC_IMAGE セクションを作成する。
  2. マップされたビューを完全にリロケート済みの悪意ある PE で上書きするが、セクションオブジェクトはディスク上の善性イメージを指すままにしておく。
  3. VEH を登録し、デバッグレジスタを設定して NtOpenSectionNtMapViewOfSection、および必要なら NtClose への呼び出しごとにユーザーモードのブレークポイントを発生させるようにする。
  4. LoadLibrary("amsi.dll")(または他のターゲット)を呼び出す。Windows ローダがこれらの syscall を呼ぶと、VEH はカーネル遷移をスキップして、準備した悪意あるイメージのハンドルとベースアドレスを返します。

ローダは要求された DLL をマップしたと信じ続けるため、セクションのバックファイルを参照するツール群は wmp.dll を見ますが、実際のメモリは攻撃者のペイロードに置き換えられています。一方で、imports/TLS コールバックは genuine loader によって解決されるため、攻撃者が維持すべきカスタムな PE 解析ロジックを大幅に減らせます。

Stage 1 – 偽装されたセクションの構築

  1. デコイ DLL のためのセクションを作成してマップする
NtCreateSection(&DecoySection, SECTION_ALL_ACCESS, NULL,
0, PAGE_READWRITE, SEC_IMAGE, L"\??\C:\\Windows\\System32\\wmp.dll");
NtMapViewOfSection(DecoySection, GetCurrentProcess(), &DecoyView, 0, 0,
NULL, &DecoySize, ViewShare, 0, PAGE_READWRITE);
  1. 悪意ある PE をそのビューにセクションごとにコピーするSizeOfRawData/VirtualSize を尊重し、後で保護を更新する(PAGE_EXECUTE_READPAGE_READWRITE など)。
  2. リロケーションを適用しインポートを解決する — reflective loader と同様に正確に行う。ビューは既に SEC_IMAGE としてマップされているため、セクションのアラインメントやガードページは後で Windows ローダが期待するものと一致します。
  3. PE ヘッダを正規化する:
  • ペイロードが EXE の場合は IMAGE_FILE_HEADER.Characteristics |= IMAGE_FILE_DLL を設定し、エントリポイントをゼロにして LdrpCallTlsInitializers が EXE 固有のスタブへジャンプしないようにする。
  • DLL ペイロードはヘッダをそのままにしておけます。

この時点でプロセスはバックエンドが依然として wmp.dll の RWX 対応のビューを持ち、メモリ上のバイトは攻撃者が制御しています。

Stage 2 – VEH でローダをハイジャック

  1. VEH を登録してハードウェアブレークポイントを設定する: Dr0(または別のデバッグレジスタ)に ntdll!NtOpenSection のアドレスをセットし、DR7 を設定して実行ごとに STATUS_SINGLE_STEP が発生するようにする。後で NtMapViewOfSection と必要に応じて NtClose に対しても繰り返す。
  2. DLL ロードをトリガする: LoadLibrary("amsi.dll") を実行する。LdrLoadDll は最終的に NtOpenSection を呼んで実際のセクションハンドルを取得しようとする。
  3. NtOpenSection に対する VEH フック:
  • [out] PHANDLE SectionHandle 引数のためのスタックスロットを特定する。
  • そのスロットに先に作成した DecoySection ハンドルを書き込む。
  • RIP/EIPret 命令へ進め、カーネル呼び出しが実行されないようにする。
  • 次に NtMapViewOfSection を監視するようハードウェアブレークポイントを再設定する。
  1. NtMapViewOfSection に対する VEH フック:
  • [out] PVOID *BaseAddress(およびサイズ/保護の出力)を既にマップされた悪意あるビューのアドレスで上書きする。
  • 前と同様に syscall 本体をスキップする。
  1. (オプション)NtClose の VEH フックは偽のセクションハンドルがクリーンアップされることを検証し、リソースリークを防ぎ最後の整合性チェックを提供する。

syscall が実行されないため、カーネル側のコールバック(ETWti、minifilter など)は疑わしい NtOpenSection / NtMapViewOfSection イベントを観測せず、テレメトリが大幅に低下します。ローダの観点ではすべて成功したと見なされ、amsi.dll はメモリ上にあるとされるため、ローダは攻撃者のバイトに対して import/TLS の解決を続行します。

Stage 3 – ペイロードの実行

  • EXE ペイロード: インジェクタはリロケーション完了後に単純に元のエントリポイントへジャンプします。ローダが DllMain を呼ぶと思っている時に、カスタムコードが代わりに EXE スタイルのエントリを実行します。
  • DLL ペイロード / Node.js addon: 目的のエクスポートを解決して呼び出します(Kidkadi は JavaScript に名前付き関数を公開している)。モジュールは既に LdrpModuleBaseAddressIndex に登録されているため、その後のルックアップはそれを善性 DLL として認識します。

Node.js ネイティブアドオン(.node ファイル)と組み合わせると、Windows 内部の複雑な処理は JavaScript レイヤ外に留まり、脅威アクターは多くの異なる難読化された Node ラッパと同じローダを配布しやすくなります。

References

Tip

AWSハッキングを学び、実践する:HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する:HackTricks Training GCP Red Team Expert (GRTE) Azureハッキングを学び、実践する:HackTricks Training Azure Red Team Expert (AzRTE)

HackTricksをサポートする