プロセスインジェクションは、サイバーセキュリティにおいて最も重要な技術の一つです。この技術は、既に実行中の別のプロセスのアドレス空間にコードを挿入し、その空間内でコードを実行することで機能します。セキュリティの観点では、これはまさに災難です。なぜなら、コードがターゲットプロセスの権限で実行されるため、ターゲットプロセスが持つ既存の権限昇格や検知メカニズムなどを利用してセキュリティ制御を迂回できる可能性があるからです。
プロセスインジェクションは脅威ベクトルとして、インターネットや高度持続的脅威(APT)。ソフトウェア開発環境ではアプリケーションのデバッグや拡張に有効な手法ですが、脅威アクターはこれを悪用し、無許可でコードを実行したり、永続化を回避したり、検知を逃れたりします。
本ブログでは、プロセスインジェクションの原理、中核的なメカニズム、一般的な手法、検知方法、および防止策を分析します。また、メモリ操作、インジェクション手法、検知方法、攻撃の実例など、いくつかの基礎的な事項についても探求します。
プロセスインジェクションとは?
プロセスインジェクションは、他の実行中のプロセスのメモリ空間にコードを注入することを可能にします。この手法では、攻撃者は標的プロセスのアドレス空間に自身のコードを書き込むことで、任意のコードを実行させます。注入されたコードは脆弱なプロセスのコンテキストと権限で実行されるため、そのアクセス権限とシステム上の信頼レベルをすべて継承します。
プロセスインジェクションの中核をなす技術的構成要素は以下の通りです:プロセスハンドル取得、ターゲットプロセス内でのメモリ割り当て、コード書き込み操作、実行トリガー機構。これらは、OpenProcess()、VirtualAllocEx()、WriteProcessMemory()、CreateRemoteThread() などの Windows API 関数を使用して、注入プロセスを実行します。
プロセス注入が危険な理由
この攻撃タイプは、いくつかの技術的側面から比較的危険です。注入されたスレッドから実行されるコードは、ターゲットプロセスと同じ特権を持つため、事実上、システムへの昇格アクセスにつながります。この方法は、安全でないコードがメモリ内にのみ存在するため、ファイルベースのセキュリティスキャンをすべて回避します。
また、システムの安定性とセキュリティにも深刻な影響を与えます。インジェクション操作はターゲットプロセスによってクラッシュされる可能性があり、システム全体に不安定性をもたらします。セキュリティ製品のプロセスを終了させ、保護されたアプリケーションからデータを盗み出し、一般的なクリーンアップ手法を回避する永続的なシステムアクセスを確立することで、これを実現します。
プロセスメモリの基礎
プロセスインジェクション技術の技術的基盤は、プロセスメモリ構造と操作の理解にあります。Windows OSのメモリ管理モデルには、プロセス間のメモリ相互作用とアクセスを可能にすると同時に制限する内部特性があります。これらはプロセスインジェクションの動作方法と、防御側がそれを検知・防御する方法を即座に変えます。
仮想メモリとプロセスアドレス空間
各Windowsプロセスは独自の仮想アドレス空間を持ち、同じシステム上で動作する他のプロセスから隔離されています。この仮想アドレス空間の範囲は、32ビットプロセスでは0から0x7FFFFFFF、64ビットプロセスでは0から0x7FFFFFFFFFFです。仮想アドレスから物理メモリ位置へのマッピングは、Windowsメモリマネージャによるページング技術を用いて行われます。
プロセスは、アドレス空間内に複数の領域(プロセス実行コード、ロード済みDLL、ヒープ割り当て領域、スタック領域など)を有します。これらの領域はそれぞれ特定の機能とデータ型を持ちます。Windowsは、メモリフレームのページがどこにあるか、またそれらが仮想アドレス空間内にあるかどうかを記述するページテーブルを持っています。
メモリのアクセス権限と保護
メモリ領域にはアクセス権限が存在し、プロセスがそれらとどのように相互作用すべきかを規定します。これらの権限には以下が含まれます:
- PAGE_EXECUTE:メモリをコードとして実行可能
- PAGE_READ: メモリを読み取り可能
- PAGE_WRITE:メモリへの書き込みが可能
- PAGE_EXECUTE_READ:メモリの実行と読み取りが可能
- PAGE_EXECUTE_READWRITE:メモリの実行、読み取り、書き込みが可能
これらの権限は、Windows メモリマネージャによってページレベルで強制されます。アプリケーション(またはプロセス)が許可されていない方法でメモリにアクセスしようとすると、システムはアクセス違反を発生させます。
メモリ操作における重要な Windows API
Windows にはメモリ操作のための重要な API がいくつか存在します。これらの API はプロセスインジェクションの基盤となります。これらの関数の「Ex」バージョンは外部プロセス向けであり、通常の後継関数は呼び出し元プロセスのメモリ空間向けです。これらのAPIを理解することで、潜在的なインジェクション活動の検出と追跡が可能になります。
- VirtualAlloc/VirtualAllocEx:プロセス内でメモリを予約・コミットします
- VirtualProtect/VirtualProtectEx: メモリ領域のアクセス権限を変更します
- ReadProcessMemory: 他のプロセスのメモリ空間からデータを読み取る
- WriteProcessMemory: 別のプロセスのメモリ空間にデータを書き込む
- VirtualFree/VirtualFreeEx: 割り当てられたメモリ領域を解放する
プロセス注入手法の種類
プロセス注入は、ターゲットプロセスに対して何らかの形でコード実行を行う、さまざまな手法で構成されています。Windows API 呼び出しとメモリ操作の違いにより、各手法には固有の動作パターンと検出シグネチャがあります。
これらの手法を分析することは、セキュリティチームが特定の注入方法を特定し対応するのに役立ちます。
1.DLL インジェクション
DLL インジェクションとは、プロセスに悪意のある DLL ファイルを強制的にロードさせるプロセスです。OpenProcess()、VirtualAllocEx()、CreateRemoteThread() といった一連の API 関数を使用します。まず、標的プロセスの内部メモリを予約し、そこに DLL のパスを保持します。次に、リモートスレッドを開始し、そのスレッドが LoadLibrary() を呼び出して、悪意のある DLL のパスをパラメータとして渡すことで、標的プロセスに悪意のある DLL をロードするよう指示します。
注入されたDLLは、ターゲットプロセスの全メモリ空間およびターゲットがメモリにロードした他のすべてのモジュールのメモリアドレスを通じて、ターゲットプロセスの機能/プロセスへの完全なアクセス権を持ちます。
2.コードインジェクション
コードインジェクションは、悪意のあるコードをプロセスのメモリ空間に注入し、そのコードを実行させる攻撃手法です。これは単にプロセスのメモリ空間のアドレスにコードを書き込む行為です。この手法は複数のステップから成り、プロセスのハンドルを取得し、VirtualAllocEx()でメモリを割り当て、WriteProcessMemory()でコードを書き込み、最後にCreateRemoteThread()で実行する手順を踏みます。
実行されるコードは、実行先のターゲットプロセスの権限を持ち、全てのセキュリティ特権とアクセス権が継承されます。
3. スレッド実行ハイジャック
スレッド実行ハイジャックは、ターゲットプロセス内のスレッドを一時停止させ、その実行コンテキストを攻撃者コードを指すように変更し、実行を継続します。この手法では、攻撃者はSuspendThread()、GetThreadContext()、SetThreadContext()、ResumeThread() APIを利用します。
正当なスレッドを利用するため、ハイジャックされたスレッドは既存の権限で悪意のあるコードを実行するため、検出が困難になります。
4. APC(非同期プロシージャコール)インジェクション
APCインジェクションは、スレッドが待機状態に入った際に実行される悪意のあるコードをキューに追加します。この手法では、QueueUserAPC()を使用してコードをスレッドにキューイングします。注入されたコードは、スレッドがAPCキューを処理する際に実行されます。これは通常、特定のシステムコールや待機操作中に発生します。この手法は、可変状態を繰り返し訪れるスレッドに特に適している。
5. リフレクティブ DLL インジェクション
リフレクティブ DLL インジェクションの手法は、Windows ローダーの助けを借りて DLL をロードし、ファイルシステムのアーティファクトを書き込まない。これは、メモリ内でマッピングおよびアドレス指定する方法に関する指示を含むカスタム DLL です。この手法では、ローダーコードと DLL をターゲットプロセスのメモリに注入し、ローダーを実行して DLL を準備します。これにより、通常の DLL ロードメカニズムや監視による検出を回避します。
6.プロセス・ホローイング
プロセス・ホローイングはステルス的な注入手法であり、攻撃者は正当なプロセスを一時停止状態(CREATE_SUSPENDED付きCreateProcessを使用)で作成し、元のメモリ空間をアンマップ(NtUnmapViewOfSection/ZwUnmapViewOfSection経由)、新規メモリを割り当て(VirtualAllocEx)、悪意のあるコードを書き込み(WriteProcessMemory)、PEヘッダーとリロケーションを修正し、プロセス環境ブロック(PEB)を更新し、最後にエントリポイントをリダイレクト(SetThreadContext)してから実行を再開(ResumeThread)します。これにより、悪意のあるコードが正当なプロセスの身元と特権の下で実行されるようになります。
プロセスインジェクションの仕組みとは?
プロセスインジェクションは、ターゲットプロセス内でコードを実行しようとする一連のステップに従います。インジェクションの方法にかかわらず、技術的な実装では、プロセスメモリを操作し、プロセスフローの実行方法を変更する特定の手順が踏まれます。
最初は、ターゲットプロセスの識別とアクセス取得の操作です。悪意のあるプロセスはOpenProcess()を使用してターゲットプロセスのハンドルを取得します。このハンドルに必要なアクセス権限は、PROCESS_CREATE_THREAD、PROCESS_QUERY_INFORMATION、PROCESS_VM_OPERATION、PROCESS_VM_WRITE、およびPROCESS_VM_READです。
第二の重要なステップは、ターゲットプロセス内でのメモリ割り当てです。VirtualAllocEx()は仮想メモリのページを予約・コミットすることで、ターゲットプロセスのアドレス空間内にメモリ領域を割り当てます。
第三のステップは、割り当てられたメモリ領域へのシェルコードのコピーです。WriteProcessMemory() はソースバッファからターゲットプロセスのメモリ領域へコードバイトをコピーします。この操作ではアラインメントとサイズ要件を考慮する必要があります。
実行トリガーの最終ステップは、中核となるコンポーネントを表します。各手法は以下のいずれかのメカニズムを採用する:
- CreateRemoteThread() は注入されたコードを実行する新規スレッドを生成する
- QueueUserAPC() は既存スレッド内でコード実行をキューイングする
- SetThreadContext() は既存スレッドの実行フローを変更します
- 関数ポインタやフックの直接的な改変
実行が開始されると、注入されたコードはターゲットプロセスのコンテキスト内で実行され、ターゲットプロセスのリソースとセキュリティトークンにアクセスできます。このコードは、ターゲットプロセスの特権と信頼レベルの下で動作し、設計された任意の動作を実行できます。
プロセスインジェクション攻撃を検出する方法?
プロセスインジェクションは、システムの複数のコンポーネントや動作が関与するため、検出が困難です。インジェクション活動を特定するには、セキュリティシステムがメモリ移動、API呼び出し、およびすべてのプロセス動作を監視する必要があります。
これらの検出手法を組み合わせることで、包括的な検出戦略が形成されます。
メモリパターン分析
メモリ分析は、プロセスのメモリ領域における一般的なパターンの検索に焦点を当てています。これは、セキュリティツールがプロセスメモリの権限設定と期待される内容を検証するために、プロセスメモリのこれらの領域をスキャンするためです。これには、プロセス内で典型的なコンテンツシグネチャに適合しない異常な実行可能領域やページの検出などが含まれます。メモリスキャナは、通常は静的なプロセスメモリ構造の変化を監視するか、動的なコードセグメントを探すことで、元のプロセスバイナリからの逸脱を探します。
API呼び出しの監視
メモリ操作呼び出しの疑わしいシーケンスは、Windows APIの監視によって検出されます。セキュリティツールは、プロセスアクセスにはOpenProcess()、メモリ割り当てにはVirtualAllocEx()、メモリ書き込みにはWriteProcessMemory()を監視します。スレッドの作成や操作(例:CreateRemoteThread())は、注入の明らかな兆候となります。
SuspendThread() や SetThreadContext() などの API によるプロセスおよびスレッドの状態変更も監視すべきです。これらは注入チェーンで頻繁に見られるためです。
行動指標
プロセスの行動を監視するのは、これらの注入試行を示唆する予期しない活動パターンを特定するためです。侵入検知システムは、比較的安定した稼働プロセス内のスレッドや、プロセスメモリマップの変更を監視し、こうしたプロセスを追跡します。
インポートアドレステーブルの変更やプロセス間メモリ操作と併せて、これらの動作は検知に関連する指標となります。
検出ツール
プロセスインジェクションの検知には、深い監視機能を備えたセキュリティツールが必要です。リアルタイム分析は、API呼び出しやシステム動作を監視するプロセスモニターによって行われ、メモリ分析ツールはプロセスメモリ空間の詳細な分析を実行します。イベントログアナライザーは、システム内のセキュリティイベント履歴を記録し、過去の状況を把握することを可能にします。
SentinelOne などのエンタープライズ検知・対応(EDR)ソリューションは、監視手法と分析機能を組み合わせています。プロセスモニターやプロセスエクスプローラーなどのシステム管理ツールは、プロセスを詳細に表示するだけでなく、プロセスごとのメモリ割り当ても確認できます。プロセスインジェクション攻撃を防ぐ方法とは?
プロセスインジェクションの防止は単一のセキュリティ対策では実現できず、システムレベル、プロセスレベル、コードレベルでの対策が必要です。これらの対策は、プロセスインジェクションの能力を制限すること、および潜在的な標的プロセスへのインジェクションを困難にすることに焦点を当てています。
システムレベルでの防止策
システムレベルでの予防措置は、アクセス権と特権の適切な管理から始まります。システムでは、非管理者ユーザーがシステム上の機密プロセスに対してハンドルを開くことしかできないよう、プロセス作成および操作権限を制限する設定を行う必要があります。これらの制限は、ユーザーアカウント制御 (UAC) および AppLocker ポリシーによって、どのプロセスをどの特権レベルで実行できるかを管理することで実施されます。
コード署名
もう 1 つの重要な予防策は、コード署名の実施です。モジュールは、デジタル署名が検証された状態でロードされるべきであり、不適切に署名されたコードや署名のないコードはシステムによって拒否されるべきです。Windows Defender アプリケーション制御 (WDAC) ポリシーは、コードの整合性要件を適用し、署名のない DLL および実行ファイルのロードを無効にします。
メモリ保護
防御の重要な部分であるメモリ保護メカニズム。データ実行防止 (DEP) はデータページからのコード実行を防止し、アドレス空間配置ランダム化 (ASLR) は特定のメモリを標的にすることを困難にします。
中程度の保護プロセス対策には、間接呼び出しのターゲットをチェックする制御フローガード(CFG)や、メンバー署名レベルに基づいてプロセスが既存プロセスを開く能力を制限するプロテクトプロセスライト(PPL)が含まれます。
アプリケーション強化
アプリケーション強化においても、セキュリティチームはセキュアコーディング手法とコンパイラオプションを遵守する必要があります。開発者は/DYNAMICBASEや/NXCOMPATなどのセキュリティ機能を設定し、例外処理を実装し、アプリケーションデバッグプロセス内でメモリ操作を検証すべきです。
結論
プロセスインジェクションは、悪意のあるコードを他の実行中のプロセスと並行してメモリ空間に注入します。攻撃者はターゲットプロセスに任意のコードを実行させるとともに、自身のコードをアドレス空間に書き込むのです。これが危険な理由は、従来の脅威検知技術を回避できる点にあります。これを検知するには、高度なセキュリティソリューションと予防戦略が必要です。
これにはメモリ保護、行動制御、アクセス制御などが含まれます。プロセスインジェクション技術の仕組みを理解することで、組織はシステムを適切に強化し、セキュリティ制御をより効果的に展開できます。
プロセスインジェクションに関するよくある質問
プロセスインジェクションとは、攻撃者がコードをコピーし、プロセスのメモリ内で実行する攻撃手法です。これにより悪意のある攻撃者は、標的プロセス内で自身のコードを実行できるようになり、セキュリティ対策を回避することが可能になります。
プロセスインジェクションは、主に活動の隠蔽や永続化、より高い特権でのコード実行のために使用される手法です。Windows DLLが通常のプロセスを通じて別のプロセスに注入されると、実行されるコードはターゲットプロセスと同じ信頼レベルで操作を行い、同じアクセス権を持つため、セキュリティツールによる悪意のある動作の検出が困難になります。
プロセスインジェクションの検出には、メモリ、API、プロセス動作の監視が必要です。静的プログラム解析ツールは、異常なメモリ割り当て、スレッド作成、異常なプロセス操作APIシーケンスなどのパターンを検知することで、このようなインジェクション試行をマークします。
プロセスインジェクションは主にマルウェアによって使用されますが、デバッグ、マルウェア分析、監視技術、アプリケーション機能の拡張など、正当な目的で使用される場合もあります。
APT(高度持続的脅威) スタイルの攻撃キャンペーンにおいて、プロセスインジェクションは持続性の確保と検知回避に極めて重要な役割を果たします。APT攻撃者は高度なインジェクション技術を用いて感染システムへの恒久的なアクセス権を獲得し、長期にわたる活動中に決して発見されないことを保証します。
