マルウェアの作者の多くは、複雑なコードを開発するために多大な時間と労力をかけています。彼らの成功は、脅威として長時間検出されず、サンドボックス での解析、アンチウイルス対策、またはマルウェアの解析者を回避できるかにかかっています。このブログでは、検知を回避するためにマルウェアが使用するメカニズムの概要を紹介します。
マルウェアが簡単に検知されると、データを盗み取りインパクトを最大化するための時間がなくなります。ITセキュリティの市場は成熟しており、現在のセキュリティ対策ツールやアプリケーションの性能は非常に向上しています。ただし、攻撃者もセキュリティツールの動作を理解し、監視を続けています。また、企業や組織は必ずしもベストプラクティスを実践していません。マルウェア対策ツールが最新状態ではない場合も多く、サンドボックスが設定ミスにより簡単に検知されることもあります。
マルウェアの自己防衛機能
マルウェアは検出や解析を回避するために複数のメカニズムを利用しています。メカニズムの技術は、以下の3つのカテゴリに分類することができます。
- アンチセキュリティツール:ウイルス対策、ファイアウォール、および環境を保護するその他のツールによる検出を回避するために使用されます。
- アンチサンドボックス:自動解析機能の検知を行い、マルウェアの挙動を報告するエンジンを回避するために使用されます。
- アンチアナリスト:マルウェア解析者を検知し、欺くために使用されます。たとえば、リバースエンジニアリングを回避するため、Process ExplorerやWiresharkなどの監視ツールを検知すると同時に、いくつかのプロセス監視の手法やパッカーを使用します。
これら3つのカテゴリに共通するマルウェアの技術もいくつかあります。RunPE(メモリ上の自身とは異なるプロセスで実行する)などの技術を使用すると、マルウェアはウイルス対策ソフトウェア、サンドボックス、または解析者を回避することができます。
サンドボックスの回避
サンドボックスはマルウェアを迅速に検出し把握する上で効果的なツールですが、適切に構成しなければ、マルウェアにより簡単にサンドボックスを検知されます。マルウェアは以下の複数の基本的なチェックを実施する場合があります。
MACアドレスの検知:VMwareやVirtualBoxなどの仮想環境では既知のMACアドレスが使用されます。このアドレスはしばしばレジストリの次の場所に保存されます(HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\{4D36E972-E325-11CE-BFC1-08002BE10318}\0000\NetworkAddress)。マルウェアは、レジストリキーを要求するか、GetAdapterInfo APIを使用するかの2つのいずれかの方法でMACアドレスを検知できます。
DWORD GetAdaptersInfo(
_Out_ PIP_ADAPTER_INFO pAdapterInfo,
_Inout_ PULONG pOutBufLen
);
プロセスの検知:マルウェアはサンドボックスと関連する動作中のプロセスが存在するかを検知することができます。たとえば、VmwareService.exeなどのプロセスの場合、CreateToolHelp32Snapshot APIを使って現在動作中のプロセスのスナップショットを取得してから、API関数のProcess32FirstとProcess32Nextでスナップショットの各プロセスを一覧化することで、容易に検知することができます。
HANDLE WINAPI CreateToolhelp32Snapshot(
_In_ DWORD dwFlags,
_In_ DWORD th32ProcessID
);BOOL WINAPI Process32First(
_In_ HANDLE hSnapshot,
_Inout_ LPPROCESSENTRY32 lppe
);BOOL WINAPI Process32Next(
_In_ HANDLE hSnapshot,
_Out_ LPPROCESSENTRY32 lppe
);
レジストリの検知:マルウェアが検知可能なシステムのレジストリキーは、仮想環境により作成されます。以下のリストは完全ではありませんが、マルウェアがチェックする可能性があるレジストリキーの一覧です。
“HARDWARE\\DEVICEMAP\\Scsi\\Scsi Port 0\\Scsi Bus 0\\Target Id 0\\Logical Unit Id 0”
“SOFTWARE\\VMware, Inc.\\VMware Tools”
“HARDWARE\\Description\\System”
“SOFTWARE\\Oracle\\VirtualBox Guest Additions”
“SYSTEM\\ControlSet001\\Services\\Disk\\Enum”
“HARDWARE\\ACPI\\DSDT\\VBOX__”
“HARDWARE\\ACPI\\FADT\\VBOX__”
“HARDWARE\\ACPI\\RSDT\\VBOX__”
“SYSTEM\\ControlSet001\\Services\\VBoxGuest”
“SYSTEM\\ControlSet001\\Services\\VBoxMouse”
“SYSTEM\\ControlSet001\\Services\\VBoxService”
“SYSTEM\\ControlSet001\\Services\\VBoxSF”
“SYSTEM\\ControlSet001\\Services\\VBoxVideo”
また、マルウェアは以下のいくつかの高度な技術を使用してサンドボックスの検知を行う場合があります。
フック関数のチェック:フック関数は、OSやアプリケーションの内部関数の振る舞いを変更するための基本的なテクニックです。サンドボックスはフックの技術を使用してサンプルの挙動の変更を行います。たとえば、DeleteFile関数にフックすることで、サンドボックスに捕まったファイルをマルウェアは削除しようとします。このような種類の関数はメモリ上(カーネル空間)の特定の場所に配置されています。
マルウェアは、呼び出す関数のアドレスをチェックしてフックを検知する場合があります。たとえば、返されるアドレスがカーネルの中にない場合、現在その関数はフックされていることになります。
マルウェアはハードウェアのサイズチェックや特殊な命令など別の技法を使用して、特定のレジスタを検知することができます(「Red Pill」手法、または「No Pill」手法)。これらのテクニックは、マシン上にあるレジスタは一意なものであり、仮想環境では再配置する必要があるという事実に基づいています。
ウイルス対策の回避
ウイルス対策ツールが使用する基本機能は、シグネチャ、スキャン、およびヒューリスティックの3つです。
- シグネチャは、サンプルのハッシュ値を変更することで回避することができます。これは非常に簡単であり、実行ファイルを1バイト変更するだけで実現可能です。
- スキャンは、大きなファイルを作成してエミュレータを混乱させることで回避することができます。
- ヒューリスティック分析はより複雑ですが、背後にある関数をフックすることで回避することができます。
マルウェアがウイルス対策ツールを回避するための別の方法は、ツールを無効化するか例外を追加することです。ポリモーフィック型のコードは特に検知が困難です。
アンチデバッグ
コード解析時、マルウェア解析者はしばしば深く調査する必要があります。アンチデバッグは、デバッガによるリバースエンジニアリングを回避するための別の技法です。Windows APIを使用すると、デバッガの存在を検知することは比較的容易です。
IsDebuggerPresent関数:この関数は、PEB(Process Environment Block)構造体の中の特定のフラグであるIsDebuggedをチェックし、デバッガ内でプロセスが実行されていない場合、0を返し、デバッガがアタッチされている場合、0以外を返します。
BOOL WINAPI IsDebuggerPresent(void);
FindWindow関数:この関数は名前やクラスからウィンドウを検索することができます(例:OllyDbg)。この関数は、WiresharkやProcess Explorerなどのツールを検知することもできます。
HWND WINAPI FindWindow(
_In_opt_ LPCTSTR lpClassName,
_In_opt_ LPCTSTR lpWindowName
);
CsrGetProcessId関数:この関数は、システムプロセスの1つであるcsrss.exeのプロセスIDを検索することができます。デフォルトではプロセスのアクセストークンのSeDebugPrivilegeの権限は無効になっています。しかし、OllyDbgやWinDbgなどのデバッガによりプロセスがロードされると、SeDebugPrivilegeの権限が有効化されます。プロセスによりcsrss.exeが開かれていることは、プロセスのアクセストークンの権限がSeDebugPrivilegeであることを意味し、対象のプロセスはデバッガであることが推測されます。
アンチ逆アセンブル
アンチ逆アセンブルは、リバースエンジニアリングによる解析を回避するための別の手法です。逆アセンブルツールを妨害する方法は以下のように数多くあります。
- APIの難読化を行うと、特定の関数の呼び出しを隠すことができます。その結果、たとえば、API関数の名前を使わずに関数が呼び出されます。解析者はどの関数が利用されたか把握するためにリバースエンジニアリングする必要があります。この作業には時間がかかります。
- ジャンクコードの挿入:ジャンクコードをマルウェアに挿入することで解析者を欺き、使用しないコードのリバースエンジニアリングに時間を浪費させることができます。ジャンクコードは全く実行はされないため、サンプルの挙動には変化ありません。
「Unprotect Project」について
マルウェアの解析を回避する方法はたくさんあります。これらの技法は公開されているいくつかのプロジェクトで一覧化されています。Unprotect Projectは、マルウェアの保護と自己防衛技術を集めて一覧化した公開のWikiです。このプロジェクトには、マルウェアの保護機能の理解を促すため、技法を一覧化したマインドマップが載っています。
このプロジェクトの目標は、コミュニティに対して、検出されずに滞在し、セキュリティ保護を迂回し、解析を回避するためにマルウェアで使用される技術への理解を深めるサポートをすることです。このウェブサイトには次のようなカテゴリがあります。
- サンドボックスの回避テクニック:サンドボックス解析を回避する。
- ウイルス対策の回避テクニック:ウイルス対策の検出を回避する。
- アンチデバッグのテクニック:デバッガを欺き、解析を回避する。
- アンチ逆アセンブル:逆アセンブルツールを使用したリバースエンジニアリングの回避、およびマルウェアの挙動を理解する。
- プロセスのトリック:システム上でマルウェアのプロセスを隠ぺいし、検出を回避する。難読化とデータのエンコード:マルウェア内のデータや一部のコードを隠ぺいする。
- パッカー:マルウェアのコードの保護、および他の回避機能を追加する。
このWikiは継続的に更新されています。
まとめ
マルウェアは検出を回避するため、ますます賢くなり、技術の進化が続いています。これらの技法を理解し、情報セキュリティのコミュニティで体験を共有することはマルウェアと戦う上で効果的な方法です。
※本ページの内容は 2016年12月19日更新のMcAfee Blog の抄訳です。
原文: An Overview of Malware Self-Defense and Protection
著者: Thomas Roccia(Principal Consultant at Intel Security Foundstone Services)
【参考資料】
Unprotect Project