WriteProcessMemoryを使わずにEDRの監視を回避する、新たなWindowsプロセスインジェクション手法

新たに公開されたWindowsのプロセスインジェクション手法は、リダイレクトしたコンソール入力と名前付きパイプを利用し、厳重に監視されているAPIのVirtualAllocExやWriteProcessMemoryを呼び出すことなく、ペイロードのデータを子プロセスへ転送します。

GetDatabase Tools

「コンソール名前付きパイプインジェクション(console named-pipe injection)」と呼ばれるこの手法は、エンドポイント防御が単一の不審なAPI呼び出しに頼るのではなく、プロセス、メモリ保護、スレッドコンテキスト、プロセス間通信をまたいでイベントを相関分析する必要があることを示しています。

EDRを回避するWindowsプロセスインジェクション手法

リモートプロセスインジェクションは、Windows環境で古くから使われてきた手法で、別のプロセス内でコードを実行できます。この手法を使うと、悪意ある活動が、信頼されたアプリケーションのコンテキストや見かけ上の正当性を引き継げる場合があります。従来のリモートスレッドインジェクションは、通常次の手順で行われます。

  • OpenProcess/CreateProcess
  • VirtualAllocEx
  • WriteProcessMemory
  • CreateRemoteThread、またはスレッドハイジャック

EDR(Endpoint Detection and Response)製品は、この一連の流れを主な検知対象とするのが一般的です。プロセス間で直接メモリを割り当てて書き込む処理が含まれており、いずれもコードインジェクションの強力な指標となるためです。そのため、MicrosoftのプロセスAPIやメモリAPIは、ユーザーモードフック、カーネルテレメトリ、振る舞いルールの検知ポイントとして頻繁に使われています。

今回の研究は、最も目立つ2つの要素、つまりVirtualAllocExによるリモートメモリの割り当てと、WriteProcessMemoryによるペイロードのコピーを取り除くことで、このモデルを崩します。別プロセスの仮想メモリに直接書き込む代わりに、この手法は、リダイレクトされた標準入力をコンソールアプリケーションが処理する際に、WindowsとアプリケーションがすでにS保存しているデータを再利用します。

手法はまず、nslookup.exeやnetsh.exeなどの対話型コンソールアプリケーションを、標準入力ハンドルをパイプにリダイレクトした状態で起動します。親プロセスはパイプの書き込み側を保持し、WriteFileを使ってペイロードのバイト列を送信します。

対象のコンソールプロセスがリダイレクトされた入力を処理すると、バイト列は自身のアドレス空間に格納されます。この仕組みにより、従来のようなリモートメモリへの書き込み操作を行わなくても、任意のデータを子プロセスのメモリへ運び込めます。

概念実証(PoC)では、ペイロードの先頭に特徴的なマーカーを置いているとされています。インジェクターは子プロセスのアクセス可能なメモリからこのマーカーを探索し、直後にあるペイロードのアドレスを特定します。その後、VirtualProtectExで既存のメモリ領域の保護属性を変更し、スレッドの命令ポインタをペイロードの位置へ向け直します。

このプロセスには、リモートメモリの保護属性の変更やスレッドコンテキストの改変といった、攻撃後の典型的な動作がいくつか残っています。一方で、一般的なインジェクション手法と最も結び付きの強いテレメトリ上の手がかりは回避できます。

この手法は有効ですが、制約もあります。バイト列はコンソールの入力経路で送られるため、ペイロードにはWindowsのコンソールサブシステムが特別に解釈する文字を含められません。

  • 0x0D:キャリッジリターン
  • 0x0A:ラインフィード
  • 0x1A:置換文字(歴史的にCtrl+Zやファイル終端の挙動と関連)

これらのバイトがデータストリームに含まれると、コンソールプログラムがデータをコマンドと誤認したり、入力処理を終了したりする可能性があります。その結果、意図したペイロードの配置が壊れるおそれがあります。

研究者らは、このアプローチが関連するプロセスパラメータポイズニング手法の制約の一部を回避できると指摘しています。同手法では、対象プロセスをサスペンド状態で作成するか、通常とは異なるコマンドラインや環境変数の値を用意する必要があります。

SensePostの研究者であるMax Hirschberger氏とOgulcan Ugur氏は以前、プロセスパラメータポイズニング(Process Parameter Poisoning)を調査しています。この手法も同様に、標準的なリモートメモリ書き込みに頼らず、Windowsが管理するプロセスデータを使ってコードを転送します。

GetDatabase Tools

検知と緩和策

防御側は、これをシグネチャの問題ではなく、振る舞い検知の課題として捉えるべきです。WriteProcessMemoryやVirtualAllocExのブロックやアラートだけに頼ると、Windowsのプロセス間通信(IPC)やプロセス初期化データをペイロードの代替配送経路として使う手法に対して、検知の穴が残ります。

主な検知のポイントは次のとおりです。

  • 通常とは異なる親プロセスが、標準ハンドルをリダイレクトした対話型コンソールユーティリティを起動する
  • コンソールプログラムの標準入力パイプへの、バイナリのような、または異常に大きな書き込み
  • 新たに作成されたコンソールの子プロセスを対象とするメモリスキャン
  • VirtualProtectExによる、リモートプロセス内のメモリを実行可能にする変更
  • スレッドの一時停止とSetThreadContextなどによるコンテキスト変更、その後のスレッド再開
  • 名前付きパイプの作成・接続テレメトリの相関分析(該当する場合はSysmonのイベントID 17および18を含む)

防御上の重要な教訓は、ペイロードがWriteProcessMemoryではなく名前付きパイプ経由で届けられたとしても、リモートプロセス内でメモリが実行可能に切り替わり、その後に命令ポインタがリダイレクトされる挙動は、依然として疑わしいという点です。

SOCのアラート調査を1件あたり21分短縮。即時のIOCコンテキストでSOCを強化し、迅速な対応を実現します。 SOCにTI Lookupを導入する

翻訳元: https://gbhackers.com/new-windows-process-injection-technique-bypasses-edr/

本記事は gbhackers.com の記事を翻訳・要約したものです。