Impacketは、ネットワークプロトコルを扱うためのPythonクラスのコレクションであり、セキュリティ専門家やペネトレーションテスターにとって強力なツールキットです。SMB、MSRPC、Kerberosなど、さまざまなプロトコルを低レベルで操作できる機能を提供します。Impacketには多くの便利なスクリプトが含まれており、その中でも wmipersist.py
は、Windows Management Instrumentation (WMI) を利用して永続化(Persistence)を実現するためのスクリプトです。
永続化とは、攻撃者が一度システムへのアクセス権限を得た後、システムが再起動されたり、ユーザーがログオフしたりしても、継続的にアクセスを維持する技術のことです。wmipersist.py
は、WMIのイベントサブスクリプション機能を利用してこれを実現します。具体的には、特定のシステムイベント(例:ユーザーログオン、特定のプロセス起動、一定時間経過)が発生した際に、指定したコマンドやスクリプト(VBScript)を実行させることができます。これにより、攻撃者はバックドアを設置したり、定期的に情報を収集したりすることが可能になります。
この記事では、wmipersist.py
の基盤技術であるWMI永続化の仕組み、スクリプトの具体的な使い方、そして検知・対策方法について詳しく解説します。
WMI永続化の仕組み
wmipersist.py
が利用するWMI永続化(WMI Event Subscription Persistence)は、Windowsが標準で持つ強力な管理機能であるWMIのイベント監視メカニズムを悪用するものです。この手法は、ファイルレスマルウェアや高度な持続的標的型攻撃(APT)で利用されることがあります。なぜなら、正規のWindows機能を利用するため検知が難しく、ディスク上に悪意のあるファイルを残さずに永続化を実現できる場合があるためです。
WMI永続化は、主に以下の3つのコンポーネントで構成されます。
-
イベントフィルタ (__EventFilter):
どのようなイベントが発生したときにアクションを実行するかの「条件」を定義します。WMI Query Language (WQL) というSQLに似た言語で記述されます。例えば、「特定のプロセス(例:notepad.exe)が起動した時」や「ユーザーがログオンした時」、「システム起動から5分経過した時」といった条件を指定できます。
-
イベントコンシューマ (__EventConsumer):
イベントフィルタで定義された条件が満たされたときに、実際に実行される「アクション」を定義します。攻撃者が永続化目的でよく利用するのは以下の2種類です。
ActiveScriptEventConsumer
: VBScriptやJScriptで記述されたスクリプトを実行します。スクリプト自体はWMIリポジトリ内に保存されるため、ファイルシステム上には残りません。CommandLineEventConsumer
: 指定されたコマンドラインを実行します。任意の実行ファイルやコマンドを実行させることが可能です。
他にも、ログファイルへの書き込み (
LogFileEventConsumer
) やメール送信 (SMTPEventConsumer
) など、いくつかの標準コンシューマが存在します。 -
フィルタとコンシューマのバインディング (__FilterToConsumerBinding):
上記のイベントフィルタとイベントコンシューマを結びつける役割を担います。「この条件(フィルタ)が満たされたら、このアクション(コンシューマ)を実行する」という関連付けを行います。このバインディングが存在しない限り、フィルタやコンシューマを個別に作成してもアクションは実行されません。
攻撃者はこれら3つのコンポーネントを標的システム上に作成することで、特定のイベント発生時に任意のコード(マルウェアの実行、コマンドの実行など)を自動実行させ、永続的なアクセスを確保します。多くの場合、WMIサブスクリプションによって実行されるプロセスは、WMI Provider Hostプロセス (wmiprvse.exe
) の子プロセスとして実行され、SYSTEM権限などの高い権限で動作することがあります。
Impacket-wmipersist の使い方
wmipersist.py
は、上記で説明したWMI永続化のメカニズムを簡単に利用できるようにしたImpacketのスクリプトです。ターゲットシステムに対してWMIイベントフィルタ、コンシューマ、およびバインディングを作成または削除する機能を提供します。
前提条件
- Impacketのインストール (https://github.com/fortra/impacket)
- ターゲットシステムへのネットワークアクセス
- ターゲットシステムに対する管理者権限を持つ有効な認証情報(ユーザー名/パスワードまたはハッシュ)
基本構文
wmipersist.py [domain/]username[:password]@targetHost {install|remove} [options]
主なオプション
オプション | 説明 |
---|---|
target |
ターゲットシステムの指定。[domain/]username[:password]@<address> の形式。パスワードを省略すると対話的に尋ねられます。ドメインはオプションです。 |
install |
WMI永続化コンポーネント(フィルタ、コンシューマ、バインディング)をインストールします。 |
remove |
指定された名前のWMI永続化コンポーネントを削除します。 |
-name <event_name> |
作成または削除するイベントの名前を指定します (必須)。インストール時と削除時で同じ名前を指定する必要があります。 |
-vbs <vbs_file> |
(install 時必須) 実行させたいVBScriptが書かれたファイルへのパスを指定します。このスクリプトは ActiveScriptEventConsumer として登録されます。 |
-filter <wql_filter> |
(install 時、-timer と排他) VBScriptを実行するトリガーとなるWQLフィルタ文字列を指定します。例: 'SELECT * FROM __InstanceCreationEvent WITHIN 5 WHERE TargetInstance ISA "Win32_Process" AND TargetInstance.Name = "calc.exe"' (calc.exeが起動してから5秒以内にトリガー) |
-timer <milliseconds> |
(install 時、-filter と排他) 指定したミリ秒ごとにVBScriptを実行するタイマーベースのトリガーを作成します。 |
-h , --help |
ヘルプメッセージを表示します。 |
-debug |
デバッグ出力を有効にします。 |
-hashes LMHASH:NTHASH |
パスワードの代わりにLMおよびNTハッシュを使用して認証します。 |
-no-pass |
パスワードを要求しません(Kerberos認証 -k と併用する場合などに便利)。 |
-k |
Kerberos認証を使用します。-dc-ip オプションでKDCのIPアドレスを指定する必要があります。 |
-aesKey <hex_key> |
Kerberos認証で使用するAESキー(128ビットまたは256ビット)。 |
-dc-ip <ip_address> |
Kerberos認証で使用するドメインコントローラーのIPアドレス。 |
-com-version <MAJOR:MINOR> |
使用するDCOMバージョンを指定します(例: 5.7 )。 |
注意: wmipersist.py
は現在、アクションとしてVBScriptファイル (ActiveScriptEventConsumer
) の実行のみを直接サポートしています。CommandLineEventConsumer
を使いたい場合は、他のツールを使用するか、手動で作成する必要があります。
実践例
ここでは、wmipersist.py
を使用した具体的なコマンド例を示します。
例1: 特定プロセス起動時にVBScriptを実行する永続化の作成
まず、実行したいアクションを記述したVBScriptファイルを作成します。ここでは、C:\Temp\pwned.txt
というファイルを作成する簡単なスクリプト (payload.vbs
) を用意します。
Dim objFS, objFile
Set objFS = CreateObject("Scripting.FileSystemObject")
Set objFile = objFS.CreateTextFile("C:\Temp\pwned.txt", True)
objFile.WriteLine "You have been pwned! " & Now()
objFile.Close
次に、wmipersist.py
を使って、notepad.exe
が起動されたときにこのVBScriptが実行されるように設定します。イベント名は MyPersistence
とします。
python wmipersist.py LAB/administrator:Password123@192.168.1.100 install -name MyPersistence \
-vbs payload.vbs \
-filter 'SELECT * FROM __InstanceCreationEvent WITHIN 5 WHERE TargetInstance ISA "Win32_Process" AND TargetInstance.Name = "notepad.exe"'
成功すると、以下のようなメッセージが表示され、ターゲットシステム上で notepad.exe
を起動すると、C:\Temp\pwned.txt
が作成されるようになります。
Impacket v0.x.x - Copyright 20xx Fortra
[*] Connecting to 192.168.1.100
[*] Installing Filter
[*] Installing Consumer
[*] Installing Binding
[*] Installation finished
例2: タイマーで定期的にVBScriptを実行する永続化の作成
上記と同じ payload.vbs
を、60秒(60000ミリ秒)ごとに実行するように設定します。イベント名は MyTimerPersistence
とします。
python wmipersist.py LAB/administrator:Password123@192.168.1.100 install -name MyTimerPersistence \
-vbs payload.vbs \
-timer 60000
これにより、ターゲットシステム上で60秒ごとに C:\Temp\pwned.txt
の内容が更新されるようになります。
例3: 作成した永続化の削除
例1で作成した永続化 (MyPersistence
) を削除します。
python wmipersist.py LAB/administrator:Password123@192.168.1.100 remove -name MyPersistence
成功すると、以下のようなメッセージが表示され、関連するフィルタ、コンシューマ、バインディングが削除されます。
Impacket v0.x.x - Copyright 20xx Fortra
[*] Connecting to 192.168.1.100
[*] Removing Filter MyPersistence
[*] Removing Binding MyPersistence
[*] Removing Consumer MyPersistence
[*] Removal finished
検知と対策
WMI永続化は正規の機能を利用するため検知が難しい側面がありますが、いくつかの方法で検知・対策が可能です。
検知方法
-
PowerShellによる確認: 以下のPowerShellコマンドレットを使用して、システム上のWMIイベントサブスクリプション関連オブジェクトを列挙できます。疑わしい名前やスクリプト内容を持つものがないか確認します。
# イベントフィルタの確認 Get-WmiObject -Namespace root\Subscription -Class __EventFilter # イベントコンシューマの確認 (ActiveScriptEventConsumer と CommandLineEventConsumer) Get-WmiObject -Namespace root\Subscription -Class __EventConsumer | Where-Object { $_.__CLASS -eq 'ActiveScriptEventConsumer' -or $_.__CLASS -eq 'CommandLineEventConsumer' } # フィルタとコンシューマのバインディングの確認 Get-WmiObject -Namespace root\Subscription -Class __FilterToConsumerBinding
- Sysmonの利用: Sysmon (System Monitor) を導入し、WMI関連のイベントID(19: WmiEventFilter activity detected, 20: WmiEventConsumer activity detected, 21: WmiEventConsumerToFilter activity detected)を監視することで、永続化コンポーネントの作成・削除をログに記録できます。
-
WMIアクティビティログの監視: Windowsイベントログの
Microsoft-Windows-WMI-Activity/Operational
ログ (特にイベントID 5861: Permanent WMI event subscription) を監視することで、永続的なWMIイベントサブスクリプションの作成を検知できます。 -
プロセスの親子関係の監視: WMIイベントサブスクリプションによって起動されるプロセスは、多くの場合
WmiPrvSE.exe
の子プロセスとして実行されます。特に、ActiveScriptEventConsumer
を利用する場合はscrcons.exe
(Script Consumer) がWmiPrvSE.exe
の子プロセスとして現れることがあります。これらのプロセスの異常な活動を監視します。 - Autorunsの使用: Microsoft Sysinternals の Autoruns ツールは、「WMI」タブでシステム上のWMI永続化エントリを表示・削除できます。
- EDR/SIEMソリューション: EDR (Endpoint Detection and Response) や SIEM (Security Information and Event Management) 製品の多くは、不審なWMIアクティビティや既知のWMI永続化パターンを検出するルールを備えています。
対策方法
- 最小権限の原則: ユーザーやサービスアカウントに不必要な管理者権限を与えないようにします。WMIをリモートから操作するには通常管理者権限が必要です。
- 攻撃表面の縮小 (Attack Surface Reduction – ASR): Microsoft Defender for Endpoint などのセキュリティ製品が提供するASRルールの中には、「WMI イベント サブスクリプションを使用して永続化をブロックする」ルール(GUID: e25f42a8-6541-4f6f-a99a-68f1ac378341)があり、これを有効にすることでWMI永続化を試みるマルウェアの活動を防ぐことができます。
-
スクリプト実行の制限: 不要であれば、
ActiveScriptEventConsumer
が利用する VBScript や JScript の実行を制限または監視します。AMSI (Antimalware Scan Interface) は、スクリプト実行時の悪意のあるコード検出に役立ちます。 - ネットワークセグメンテーションとファイアウォール: WMIがリモートアクセスに使用するポート(DCOM/RPC: TCP 135など、WinRM: TCP 5985/5986)へのアクセスを適切に制限し、不要な横展開(Lateral Movement)を防ぎます。
- 定期的な監査: 上記の検知方法を用いて、定期的にシステム上のWMI永続化設定を監査します。
まとめ
impacket-wmipersist.py
は、Impacket スイートの一部として提供される強力なスクリプトであり、WMI イベントサブスクリプションを利用して Windows システム上に永続化を確立することができます。攻撃者はこの手法を悪用し、検知を回避しながらシステムへのアクセスを維持しようとします。
WMI永続化は、イベントフィルタ、イベントコンシューマ、そしてそれらを結びつけるバインディングという3つの要素で構成されます。これらのコンポーネントを理解することは、攻撃手法を把握し、効果的な検知・防御策を講じる上で非常に重要です。
PowerShell コマンド、Sysmon、Windows イベントログ、Autoruns、EDR/SIEM などのツールやログを活用することで、不審な WMI 永続化アクティビティを検知することが可能です。また、最小権限の原則の適用、ASR ルールの有効化、スクリプト実行の制限などの対策を講じることで、この種の攻撃リスクを低減できます。
セキュリティ担当者は、wmipersist.py
のようなツールとその基盤技術である WMI 永続化について理解を深め、自組織の環境を保護するための適切な監視と対策を継続的に実施していく必要があります。