脅威の調査

攻撃者の潜伏を阻止するメモリスキャン

Sophos X-Ops がメモリスキャンの概要とその意義について説明します。

** 本記事は、Memory scanning leaves attackers nowhere to hide の翻訳です。最新の情報は英語記事をご覧ください。**

ソフォスのテクノロジーや研究の裏側を読者に詳しくお伝えする Technical Thought Leadership の新シリーズ第一弾として、ソフォスのメモリスキャン保護およびその仕組みについて、概要をご紹介します。

メモリスキャンとは、プロセスのメモリ内 (プロセスイメージや疑わしいモジュール、スレッド、ヒープ領域) で脅威を捜索することを指します。メモリスキャンは、セキュリティ製品によって、さまざまな方法、あるいはタイミングで実行されます。新しいプロセスが作成されたときに実行されることもあれば、システム上の全プロセスまたは一部のプロセスに対して定期的に実行されることもあります。たとえば、マルウェアがプロセスに注入された悪意のあるペイロードを実行しようとする際に CreateRemoteThread (またはその亜種) を呼び出すことや、VirtualAllocEx や WriteProcessMemory など、プロセスインジェクションや関連する手法で一般的に使用される、メモリを割り当てたりペイロードをコピーしたりするための不審な API コールなどにより、メモリスキャンが実行される場合があります。より高度なマルウェアは、文書化されていない API 関数を呼び出したり、API 関数の使用自体を避けて、直接システムコールや他の手法を用いる場合があります。このような手法に対抗するには、少し異なるアプローチでメモリスキャンを行う必要があります。メモリスキャンの実行理由となる動作は、プロセス作成、ファイルの読み書き、IP アドレスへの接続など、他にもさまざまです。

およそ四半世紀にわたり、ソフォスはさまざまな形式のメモリスキャンを開発するために、かなりの量の研究と努力を費やしてきました。その歴史は 2000 年まで遡ります。当時のソフォスは定期的なスキャンやオンデマンドスキャンを実行していました。その後、HIPS (ホストベースの侵入防御システム) による動作ベースのメモリスキャンへと進化し、現在では脅威の状況に応じて進化を続ける、より高度な行動テクノロジーを採用しています。特に、最新のソフォスはパターンマッチングに依存せず、アルゴリズム的アプローチを採用したチューリング完全定義言語など、より複雑な理論を採用しています。

メモリスキャンの必要性

ウイルス対策やエンドポイント検出ソリューションの普及が進んでいることから、攻撃者は悪意のあるファイルを標的のディスクに配信することに対して、これまで以上に慎重になっています。攻撃者の立場からすると、悪意のあるファイルの配信は攻撃が阻止されるリスクだけでなく、マルウェアが分析され、シグネチャが作成され、リバースエンジニアリングされると、攻撃の再調整が必要になるというリスクを負うことにもなります。

その結果、悪意のあるペイロードを実行するために、プロセスインジェクション、パッカー、仮想化コード、クリプターなど、いわゆる「ファイルレス」テクニックを使用する攻撃者が増えています。たとえば、最近のテレメトリでは、ランサムウェアサンプルの 91%、RAT サンプルの 71% が、カスタム圧縮されているか、何らかのコード難読化を使用していることがわかりました。

重要なのは、これらの手法の多くでは、標的のディスクにアクセスしても、ペイロード自体は暗号化された形に保たれており、その真の意図および能力はメモリ上でしか読み取れないということです。そのため、セキュリティソリューションが正規のファイルと悪意のあるファイルを区別するのは困難です。また、たとえば圧縮指示をエミュレートすることで圧縮されたファイルを解凍するなどの対策は多くの場合、かなりの計算コストがかかります。

これらのツールや手法の多くは、オープンソースのコードリポジトリや、正規の侵入テスト用に設計された商用フレームワークの中で利用可能です。そのため、多くの場合、少し改変するだけで簡単に攻撃に活用できます。(本シリーズの次回以降の記事では、デモを交えつつ、複数の異なるプロセスインジェクション手法をご紹介し、攻撃者が既存のソリューションをいかに簡単に利用できるかを説明する予定です。)もちろん、より高度な攻撃者は、新たな手法を発見したり、既存の手法を組み合わせたり、改良を加えたりすることがあります。

メモリ内攻撃は、悪意のあるペイロードをディスクに書き込まずに実行することで、検出を回避できます。このことは攻撃者にとって決定的な利点となります。特定の形式のプロセスインジェクションのように、ある種のテクニックは、インシデント発生後のフォレンジック分析を複雑にし、攻撃者がメモリに保存された認証情報などの機密情報を窃取したり、権限を昇格させたりするのを可能にします。

しかし、メモリスキャンは、マルウェアはメモリにロードされた時点で本来の形式に戻らなければいけないという重大な事実を利用しています。最終的な目的を達成するために、マルウェアは解凍されたり、難読化を解除されたり、復号化されるのです。この活動が発生するメモリ領域をリアルタイムで調査・評価することで、特定のスレッドやプロセスに悪意のあるコードが含まれているかどうかを判断できます。

メモリスキャンは、特にシステム全体のメモリをスキャンする場合には計算コストのかかるプロセスだと見なされてきましたが、特定のインシデントやその他の要因に関するコンテキストに関連する手がかりに基づき、範囲を限定してメモリスキャンを実行するさまざまな方法があります。そのため、状況に柔軟に対応し、パフォーマンスを最大化できます。

メモリスキャンの種類

システム全体のメモリをスキャンすることは、パフォーマンス上の問題を引き起こす可能性があります。さらに、必ずしも必要なものでもありません。メモリスキャンは、より大規模な検出・防止ツールのサブセット内の機能であるため、スキャンしたい場所やタイミングがわかっていることが多く、(複数の) プロセスが不審な挙動を示した時点で、そのプロセスを対象にしたメモリスキャンを実行できます。

たとえば、実行中の正規のプロセス内のスレッドをハイジャックするマルウェア (Suspend、Inject、Resume、SIR による攻撃など) や、正規のプロセスを起動し、悪意のあるペイロードを注入するマルウェア (さまざまな形態のプロセスインジェクションなど) に対するアラートが発出されたと仮定します。この場合、そのスレッドやプロセスをスキャンするだけで、パフォーマンスのオーバーヘッドを削減し、特定のメモリ領域の評価にリソースを集中できます。

An image showing types of memory scanning, arranged as circular diagrams.

図 1: 対象を限定したメモリスキャンの概要

場所によるターゲティング

親プロセス/子プロセス

不審なプロセスが別のプロセスを生成し、そのプロセスにインジェクションを行うような場合には、親プロセスと子プロセスの両方をスキャンして悪意のあるコードを検出できます。

シングルスレッド

攻撃者の多くは、lsass.exe (権限昇格に利用できる機密情報を含みます) や explorer.exe など、特定のプロセスを狙ってインジェクションを行います。通常、これらのプロセスには何百ものスレッドがあります。このような場合、悪意のあるペイロードを見つけるために、プロセス内のすべてのスレッドをスキャンする必要はありません。その代わりに、たとえば CreateRemoteThread などの API コールによって開始/再開されようとしているスレッドを特定することで、ID を介して特定のスレッドに対象を絞り込み、スキャンを実行します。

時期によるターゲティング

インライン

このスキャンはプロセスの生成など、特定の動作によってトリガーされます。単体ではプロセスを停止させるほどではない一方で、スキャンを開始するのには十分な理由となる不審な動作に基づいてアナリストが動作検知ルールを設定します。ソフォスは、指定された動作が完了する前に停止し、スキャンが完了し、問題が無いことが確認された場合にのみ、動作を再開させます。

非同期スキャン

非同期スキャンは、動作が完了し、より多くのコンテキストが得られるまでは特定の活動について判断できない状況に適したもので、スキャンを実行しながらプロセスを継続させ、継続的に評価を更新します。

待機状態

ファイルレスのマルウェアの中には、防御策を回避するため、あるいは C2 サーバーからの応答を待つため、メモリ内で待機状態になるものがあります。待機時間は、数分、数時間からそれ以上までとさまざまです。この動作に対抗するため、定期的にメモリスキャンを行い、悪意のある動作を検索します。

定期的なスキャン

この場合、ユーザーはメモリ消費量を急増させないよう、特定の時間帯または特定の間隔ですべてのマシンをスキャンします。

検出後のクリーンアップ

動作検知ルールがトリガーされた結果としてプロセスがブロックされた場合、メモリ内に悪意のあるプロセスが残存していないかどうか確認するため、メモリスキャンも実行されます。たとえば、一部のマルウェアは「ウォッチャースレッド」と呼ばれる手法を採用しており、あるスレッドが待機状態のまま、別のスレッドでの悪意のあるペイロードの実行を監視します。主要なスレッドが停止されると、ウォッチャースレッドが引き継いで活動を再開します。検出後のクリーンアップメモリスキャンは、マルウェアが再度実行されないように、関連するすべてのスレッドを終了させます。

実際のメモリスキャン

上記で説明したメモリスキャンの一部を実証するため、あるマルウェアのサンプルを、ソフォスの保護下にある実験環境で実行して、数回のメモリスキャン後に報告される動作保護の詳細をキャプチャしました。実環境では、以下の保護機能のいずれかがマルウェアによってトリガーされた時点で、ソフォス製品が実行をブロックします。

本テストに使用したマルウェアは Agent Tesla RAT です。このマルウェアは主に悪意のあるスパムメールを介して配布される、よく見られる脅威です。攻撃者は、スクリーンショットやキーロギングを通じて認証情報を窃取する目的で Agnet Tesla を使用します。また、最近のバージョンでは、さまざまなサンドボックス対策および解析対策の技術が採用されています。

便宜上、Agent Tesla の実行時にトリガーされるメモリスキャンと保護について説明する際に、対応する MITRE ATT&CK テクニックについても詳述します。

An image showing five memory protections against the Agent Tesla RAT

図 2: Agent Tesla RAT サンプルのテスト実行中に開始されたスキャンの概要

Evade_7a (T1055.012) (2019 年 6 月リリース)

このメモリスキャンルールは、不審なプロセスが (おそらくは) プロセスインジェクションのために、レピュテーションの高い正規プロセスを起動したときにトリガーされます。このルールは ProcessCreate イベント中にトリガーされるため、新しく作成されたプロセスは開始されず、悪意のあるコードが無いか、疑わしいプロセスがスキャンされます。実環境では、ソフォスの保護機能が親プロセスと子プロセスの両方を停止し、関連する疑わしいファイルを削除します。

Evade_34b (T1055.012) (2023 年 2 月リリース)

このルールは使用される攻撃手法ベースのもので、特にプロセスハロウイングに焦点を当てています。プロセスハロウイングでは、特定のプロセスメモリの特性を推定し、標的プロセスが空洞化されて悪意のあるコンテンツが注入されていないかどうかを評価します。このルールは、特定のコードではなく、攻撃の手法に焦点を当てているため、追加の動作保護と保証を提供します。

Exec_14a (T1055.012) (2019 年 10 月リリース)

この動作検知ルールでは、上述の SIR シーケンスの一部として、悪意のあるコードが子プロセスに注入されたときに発生する特定のイベントが確認された際に、メモリスキャンが実行されます。このイベントは保護をトリガーします。

A screenshot of computer code, with a memory dump on the left and dnSpy output on the right

図 3: SIR ワークフローの一部に対応する Tesla RAT コード。実行されると、保護機能がトリガーされます。

スキャン対象のプロセスは、別の不審なプロセス (上述の親プロセス) によって実行されるため、すでに不審なプロセスとしてマークされています。典型的なプロセスインジェクション攻撃に対しては、注入されたプロセスをできるだけ早くブロックすることを目標としています。そのためには、悪意のあるコードが注入された直後のプロセスをスキャン対象とすることが必要です。最初のスキャンで親プロセスに悪意のあるコードが確認されなかった場合は、次にこのスキャンが実行されます。これにより、マルウェアが悪意のあるコードを解凍したり、コードの難読化を解除したりしたかどうかを確認できます。

C2_1a (T1071.001 and T1095) (2020 年 2 月リリース)

この時点で、Agent Tesla は C2 サーバーへのアウトバウンド接続を行います。

A screenshot of computer code

図 4: アウトバウンド C2 接続を行う Tesla RAT コードの一部

ポート番号も確認されているため、ここでは異なる 2 件の MITRE ATT&CK テクニックを対応させています。ポート 80 および 443 については T1071 が、その他のポートについては T1095 が対応するテクニックです。このスキャンは主に非同期スキャンです。上述の 2 種類のスキャンとは異なり、意図的にプロセスの実行は停止しませんが、メモリ検出がトリガーされると、プロセスは即座に停止されます。

Creds_2c (T1555.003) (2021 年 9 月リリース)

このルールは、プロセスがディスク上の認証情報 (ブラウザの認証情報など) を保持するファイルにアクセスした際にトリガーされます。通常、ブラウザ以外のプロセスがこれらのファイルにアクセスすることは無いため、即座に疑わしい活動としてみなされます。

A screenshot of computer code

図 5: ローカルストレージ内の認証情報を探す Tesla RAT

Memory_1b (2021 年 9 月リリース)

最後に、このスキャンは定期的なバックグラウンドメモリスキャンであり、システム上で実行中のすべてのプロセスを定期的にスキャンします。活動によるトリガーが設定されていなくても、すべてのプロセスがスキャンされることを保証する、新たな保証レイヤを追加します。

今回の例で示されているように、異なるイベントやトリガーに対して複数のスキャンレイヤを持ち、さらにシステム全体にわたる定期的なスキャンによって補完することは、悪意のあるプロセスを終了させる機会を複数設けることになり、メモリ内の脅威に対する重要な防御となります。

結論

メモリスキャンは、すべてのメモリ内攻撃に対する万能薬ではありませんが、巧妙化するマルウェアとの戦いにおいて重要な武器となります。他のあらゆる形式の保護と同様に、攻撃者は新しい手法を開発したり、すでに存在する手法をもとに構築したりするため、メモリスキャン技術も常に現実世界の進展に適応し、対応する必要があります。

上述の通り、ソフォスは長期にわたって対応を続けています。脅威の状況が変化し、進化するにつれて、お客様を脅威から保護するために技術を適応させ続けてきました。その一方で、パフォーマンスのオーバーヘッドを最小限に抑え、詳細な保護を提供するため、さまざまな種類のスキャンに冗長性を組み込んできました。これらは、ソフォスのメモリスキャン機能の中心的な考え方であり、最近の研究にもこの考え方が反映されています。

たとえば、私たちが現在研究している分野のひとつでは、インシデント、リサーチ、分析のすべてを通じて収集したデータとインテリジェンスを使用して、特定の種類のマルウェアを示唆するメモリ内のパターンを統計的に同定しています。たとえば、ランサムウェアファミリによって、ファイルの列挙や暗号化に対するコードベースやアプローチは完全に異なるかもしれません。しかし、メモリ内攻撃として見ると、これらの多くに共通点があるため、この共通点を利用してより汎用的な保護を組み込めます。同様に、RAT や情報窃取マルウェアは、全く別のマルウェアかもしれませんが、メモリレベルでは、特定のスレッドやプロセスが RAT や情報窃取マルウェアにハイジャックされたことを示唆する、一連の動作を生成することが少なくありません。

コメントを残す

Your email address will not be published. Required fields are marked *