マルウェアの動作原理と検知技術(静的・動的・挙動)
なぜ既知シグネチャだけでは新種を逃すのか。静的・動的・挙動の各検知が見るものと弱点、パッカーや難読化が回避を狙う仕組み、EDR が振る舞いを相関させる原理まで一気に分かる。
- 1.検知は大きく静的解析(実行せずバイト列や構造を見る)と動的解析(実際に走らせて挙動を見る)に分かれる。シグネチャは既知マルウェアを正確に捕まえるが新種・亜種に弱く、ヒューリスティックや挙動ベースは未知を捕まえる代わりに誤検知を伴う。両者は精度と汎化のトレードオフにある。
- 2.攻撃者はパッカー・暗号化・難読化で静的シグネチャを無効化し、サンドボックス検知やスリープによるタイムアウト回避で動的解析を欺く。だから現代の検知は「ファイルの姿」ではなく「実行中に何をしたか」――API 呼び出し列やプロセス系譜という振る舞いへ軸足を移す。
- 3.EDR はエンドポイント各所のテレメトリ(プロセス生成・ファイル操作・ネットワーク・レジストリ)を時系列で収集し、単発では無害なイベントを系譜で相関させて攻撃の連鎖を再構成する。検知ルールは ATT&CK の技術にマッピングされ、点ではなく筋で悪性を判定する。
「ファイルが悪い」をどう判定するか
マルウェア検知の根本問題は単純です。手元のファイルやプロセスが悪性か良性かを、有限の計算で判定したい。だが一般にこれは決定不能で、完璧な判定器は存在しません。現実の検知器はすべて近似であり、**未知を捕まえる力(汎化)と誤検知を抑える力(精度)**のトレードオフ上のどこかに置かれます。この記事では、その近似を実現する三本柱――静的解析・動的解析・挙動ベース検知――の内部動作と、攻撃側の回避、そして EDR による相関までを原理で辿ります。
扱うのは検知エンジンの内部動作です。シグネチャ照合、ヒューリスティック、サンドボックス、挙動相関の各原理と、パッカー・難読化・アンチ解析がそれをどう崩すかに絞ります。実際の検証は許可された隔離環境でのみ行ってください。
静的解析:実行せずに「姿」を読む
静的解析は、ファイルを実行せずにそのバイト列や構造から悪性を推定します。最大の利点は安全(マルウェアを走らせない)と高速さです。
最も古典的なのがシグネチャ照合です。既知マルウェアから抽出した固有のバイト列パターン(しばしばワイルドカード付き)を、走査対象に対して照合します。多数のパターンを同時に高速照合するため、エンジンは Aho-Corasick のような多パターン文字列マッチングオートマトンを使い、入力 1 パスで全シグネチャを検査します。研究者が書くルールには YARA が広く使われ、バイト列・文字列・条件式の組み合わせでファミリを記述します。
シグネチャの本質的弱点は、既知のものしか捕まえられないことです。1 バイト変えただけの亜種、あるいは新種は素通りします。そこでヒューリスティック解析が加わります。これは「悪性によく現れる特徴」に点数を付けて閾値で判定する手法で、たとえば次のような兆候を見ます。
- PE ヘッダの異常:宣言された区画と実体のサイズ不一致、エントロピーの異常な高さ(暗号化・圧縮の痕跡)。
- 怪しい API のインポート:
VirtualAllocEx+WriteProcessMemory+CreateRemoteThreadの組(プロセスインジェクションの定番)。 - 実行可能区画の書き込み可能フラグ、エントリポイントが通常の
.text外を指す、など構造の不自然さ。
さらにエミュレーションを用い、CPU 命令を仮想的に少しだけ実行して、メモリ上に展開された後のコードへシグネチャを当てる手法もあります。これは次に述べるパッカー対策の入口です。
パッカー・難読化・アンチ解析:静的の前提を崩す
攻撃者の第一目標は、静的シグネチャに一致しないことです。中心技術が**パッカー(packer)**です。
パッカーは元の実行コードを圧縮・暗号化してデータとして格納し、先頭に小さな**展開スタブ(unpacking stub)**だけを置きます。実行されると、スタブがメモリ上で本体を復号・展開し、制御を渡します。結果、ディスク上のバイト列は元と全く異なり、既知シグネチャは無力化されます。区画のエントロピーが高くなるのはこのためで、ヒューリスティックの手掛かりにもなります。
| 回避技術 | 狙い | 仕組みの要点 | 検知側の対抗 |
|---|---|---|---|
| パッカー/暗号化 | 静的シグネチャ無効化 | 本体を暗号化データ化し展開スタブだけ露出。ディスク上の姿が毎回変わる | メモリ展開後をダンプして照合、高エントロピー検出、アンパック |
| メタモーフィズム | コード自体を毎世代書換 | 等価な命令列へ自己書換(NOP挿入・レジスタ入替・命令置換)し固定パターンを消す | 意味的特徴・制御フローグラフ、エミュレーション |
| 文字列/API難読化 | 怪しい手掛かりを隠す | 文字列を実行時復号、APIを名前でなくハッシュで動的解決(GetProcAddress相当) | 動的解析でのAPI監視、復号後メモリ走査 |
| アンチサンドボックス | 動的解析の回避 | VM痕跡・少コア・操作不在を検知したら無害動作。長時間スリープでタイムアウト誘発 | 解析環境の偽装強化、スリープ短縮フック、滞在時間延長 |
**多態性(polymorphism)**は復号鍵やスタブを世代ごとに変え、暗号化された本体の見た目を毎回変化させます。変性(metamorphism)はさらに進み、復号後の本体コード自体を等価な別の命令列へ自己書換するため、メモリ展開後ですら固定パターンが残りません。これらに対し、検知側は意味(semantics)――制御フローグラフの形や API 呼び出しの並び――という、表層の書換で消えにくい特徴へ寄っていきます。
区画エントロピーが高いのは暗号化・圧縮の痕跡ですが、正規の保護ツール(商用パッカー、難読化された保護対象ソフト)も同じ特徴を持ちます。エントロピーや「パックされている」事実は悪性の必要条件でも十分条件でもなく、あくまでスコアの一要素です。これだけで判定すると誤検知が噴出します。
動的解析とサンドボックス:走らせて見る
静的が姿を読めなくなると、実際に実行して挙動を観測する動的解析が要になります。中核が**サンドボックス(sandbox)**です。
サンドボックスは、隔離された仮想環境(VM やエミュレータ)で検体を実行し、その間のAPI 呼び出し・ファイル操作・レジストリ変更・ネットワーク通信・生成プロセスを記録します。観測の実装には主に二系統があります。
ユーザモードフック : 監視対象APIの入口にフックを置き、引数・戻り値を記録(軽量だが回避されやすい)
カーネル/VMI : OS外(ハイパーバイザ)からゲストを観測。ゲスト内から検知・改ざんしにくい
ユーザモードのインラインフックは、ntdll/kernel32 などの API 先頭を書き換えて監視コードへ飛ばす方式で軽量ですが、マルウェアがフックの存在を検知したり、フックを回避してシステムコールを直接発行したりできます。より頑健なのが**VMI(Virtual Machine Introspection)**で、ハイパーバイザ層からゲスト OS のメモリと実行を外側から観測します。ゲスト内に監視エージェントを置かないため、検体からは監視そのものが見えにくくなります。これはハイパーバイザによる分離という点で、コンテナ分離の原理が扱う隔離境界の議論と地続きです。
動的解析の弱点は**アンチサンドボックス(環境認識回避)**です。マルウェアは実行環境を観察し、解析環境だと判断したら無害な振る舞いだけを見せます。典型的な手口は次の通りです。
- 環境フィンガープリンティング:VM 固有のデバイス名・MAC アドレス・レジストリキー、CPU コア数の少なさ、メモリ・ディスクの小ささを調べる。
- 人間の不在検出:マウス移動・最近開いたファイル・起動からの経過時間がないと「自動解析」と判断する。
- タイムアウト誘発:サンドボックスの観測時間(数分)を超える長時間スリープや、膨大な無意味ループで「何も起きないまま」解析を終わらせる。
- 時限・条件起爆(ロジックボム):特定日時や特定ドメイン参加など、解析環境では満たされない条件下でのみ本体を起動する。
検知側はこれに対し、解析環境を本物の業務端末に近づけて偽装し(操作履歴・現実的なスペック)、スリープ呼び出しをフックして短縮し、観測時間を延ばすなどで対抗します。だが「環境を完全に見破られない」保証はなく、ここでも軍拡競争が続きます。
挙動ベース検知:姿ではなく「やったこと」で見る
パッカーで姿が変わり、サンドボックスを見破られても、マルウェアが目的を達するには必ず何かの操作をする――この一点が挙動ベース検知の拠り所です。判定の対象を静的な姿から、実行中の振る舞いの列へ移します。
具体的には、API 呼び出しやシステムコールの並び(シーケンス)と引数を特徴量とします。たとえば「自プロセスに実行可能メモリを確保 → 外部から取得したバイト列を書き込み → そのアドレスへ制御を移す」という列は、実行ファイルが何であれシェルコード実行の振る舞いです。これは攻撃者が突くメモリ破壊の典型的な帰結(メモリ破壊攻撃の原理を参照)であり、ファイルの見た目とは独立に観測できます。
良性プロセスでは稀/悪性で頻出する振る舞いの例:
- 正規プロセス(例: ブラウザ)が突然 powershell を子プロセスとして起動
- ユーザ文書を一括で開いて暗号化し拡張子を変える(ランサムウェアの兆候)
- lsass プロセスのメモリを読み出す(認証情報の窃取)
- 自身を起動キー・サービス・タスクスケジューラへ登録(永続化)
判定には、ルールベース(特定の振る舞いパターンに一致したら検知)と、機械学習(API 列・呼び出し頻度ベクトルを特徴に分類器を学習)の両方が使われます。ML は未知の亜種に汎化しやすい反面、敵対的回避(特徴を薄めるノイズ操作)や特徴ドリフト(時間経過で正常分布が変わる)に弱く、説明性も課題です。だからこそ単一モデルではなく、ルールと統計と評判(レピュテーション)を多層で重ねます。
シグネチャは「既知を、誤検知ほぼゼロで、安全・高速に」捕まえます。挙動ベースは「未知を、ある程度の誤検知と引き換えに」捕まえます。実運用のエンジンは両者を直列・並列に組み、まず安価な静的判定で既知と明白な良性を捌き、残りを動的・挙動の重い分析へ回す段階的なパイプラインを組みます。どちらか一方では現代の脅威を覆えません。
EDR:テレメトリと振る舞いの相関
単一の端末上で振る舞いを見るだけでは、単発では無害に見えるが連鎖すると攻撃になる操作を逃します。ここを担うのが **EDR(Endpoint Detection and Response)**です。
EDR エージェントは各端末のカーネル付近にセンサを置き、プロセス生成(親子関係を含む)・ファイル操作・レジストリ変更・ネットワーク接続・モジュールロード・認証イベントを時系列のテレメトリとして継続収集します。Windows なら ETW(Event Tracing for Windows)やカーネルコールバック、Linux なら eBPF や監査サブシステムが情報源です。
EDR の核心は**相関(correlation)です。個々のイベントは良性かもしれませんが、それをプロセス系譜(process lineage)**と時間軸でつなぐと攻撃の筋が浮かびます。
単発では無害なイベントの連鎖が、系譜でつながると攻撃に見える例:
winword.exe (ユーザが文書を開く)
└─ powershell.exe -enc <base64> (マクロが難読化スクリプトを起動) ← 異常な親子関係
└─ ネットワーク接続: 外部IP (C2サーバへ)
└─ rundll32.exe (取得ペイロードを実行)
└─ lsass メモリ読出 (認証情報窃取)
この連鎖は、各ステップを ATT&CK のような攻撃技術の分類(初期実行・防御回避・認証情報アクセス・永続化…)へマッピングして判定されます。検知ロジックは「winword の子が powershell で、その子が外部通信し…」という関係の条件として書かれ、点ではなく**筋(chain)**で悪性を評価します。誤検知を抑えつつ深く捕まえられるのは、文脈(誰が誰を、いつ、どの順で起動したか)を保持しているからです。
検知後の Response も EDR の役割です。該当プロセスの強制終了、端末のネットワーク隔離、改変ファイルのロールバックを行い、収集済みテレメトリを使って遡及調査(retro-hunt)――過去ログを新しい IOC で再走査し、既に侵入済みの痕跡を探す――を実施します。
(1) 検知は静的(実行せず姿を見る)と動的(走らせて挙動を見る)に大別。(2) シグネチャは既知を高精度・低誤検知で捕まえるが新種に弱く、ヒューリスティック/挙動ベースは未知を捕まえる代わりに誤検知を伴う(精度と汎化のトレードオフ)。(3) パッカー/多態/変性は静的シグネチャを無効化し、検知側は意味的特徴やメモリ展開後照合で対抗。(4) サンドボックスは隔離実行で API 列を観測するがアンチサンドボックス(VM 検知・スリープ・条件起爆)で回避され得る。(5) EDR はプロセス系譜とテレメトリの相関で、単発無害なイベントの連鎖を ATT&CK 技術へマップして攻撃の筋を検知する。
実務での位置づけ:多層で時間軸を持つ
ここまでの技術は、どれか一つで完結しません。攻撃側が一つの軸を崩すたびに、検知側は別の軸へ重心を移してきました――静的シグネチャをパッカーが崩せば動的解析へ、動的解析をアンチサンドボックスが崩せば挙動と系譜の相関へ、というように。だから現実の防御は、安価な静的判定で大半を捌き、残りを重い動的・挙動分析へ回し、最後に EDR が端末横断・時間横断の文脈で筋を読む、という多層パイプラインになります。
- 既知は安く速く:シグネチャと評判で大量の既知を低コストに排除し、計算資源を未知の分析へ集中させる。
- 未知は振る舞いで:姿が変わっても残る API 列・プロセス系譜という意味的特徴に軸足を置き、ファイルの見た目に依存しない。
- 時間軸で見る:単発イベントではなく系譜と時系列の相関で、潜伏や段階実行を捕まえる。侵入後の横展開を前提にゼロトラストの発想で常時監視する。
- 供給網も視界に:正規署名された配布物に紛れる脅威もあるため、サプライチェーン攻撃の経路を含めて、配布元と振る舞いの両面で評価する。
マルウェア検知が教えるのは、「ファイルが悪いか」という静的な問いには完全な答えがなく、「実行中に何をしたか」という動的・文脈的な問いへ言い換えてようやく実用的な精度に近づく、という一点です。姿は容易に変えられても、目的を達するための振る舞いは消せない――そこに検知の足場があります。
セキュリティ Article
マルウェアの動作原理と検知技術(静的・動的・挙動)を実務で読む
TL;DRは入口です。実際に選ぶ・使う段階では、何を解決するか、何と比較するか、導入後にどこで詰まるかまで見る必要があります。
解決すること
マルウェア検知
比較で見る軸
難易度: advanced / カテゴリ: セキュリティ / タグ数: 5
導入後に効く点
攻撃者はパッカー・暗号化・難読化で静的シグネチャを無効化し、サンドボックス検知やスリープによるタイムアウト回避で動的解析を欺く。だから現代の検知は「ファイルの姿」ではなく「実行中に何をしたか」――API 呼び出し列やプロセス系譜という振る舞いへ軸足を移す。
先に潰すリスク
用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。
- 難易度
- advanced
- カテゴリ
- セキュリティ
- タグ数
- 5
判断チェックリスト
- 自社の用途が「マルウェア検知 / EDR」に近いか確認する。
- 強みである「検知は大きく静的解析(実行せずバイト列や構造を見る)と動的解析(実際に走らせて挙動を見る)に分かれる。シグネチャは既知マルウェアを正確に捕まえるが新種・亜種に弱く、ヒューリスティックや挙動ベースは未知を捕まえる代わりに誤検知を伴う。両者は精度と汎化のトレードオフにある。」が本当に評価軸になるか確認する。
- 注意点の「用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。」を運用で吸収できるか確認する。
- 公開値や仕様値は、対象プラン・対象機種・対象リージョンまで確認する。
- 既存システム、ID、ネットワーク、監視、バックアップとの接続方法を先に洗い出す。
- 小さく試してから、本番移行、権限設計、障害時手順、コスト監視を決める。