やりたいこと
JPCERTからEmoCheckというEmotet感染チェックツールが無償で提供されているのはご承知のとおりです。
基本的には感染が疑われるときに実行するものですが、社内のPCを毎日チェックし、チェック結果は一か所に集約して感染PCを検知したくなりました。
ただ、単純にBATファイルから実行するとDOS窓が表示されてユーザーを驚かせてしまいます。事前に周知しても毎回DOS窓が表示されるのはやはり煩わしい。
つまり要件は以下のとおり。
- UIを表示させずにEmoCheckを実行
- 実行結果のログは一か所に集約
- ログから感染PCを特定
大前提としてチェック対象のPCは社内ネットワークにあり、EmoCheckを自動配布、自動実行する環境はあるものとします。
UIを表示させずに実行
BATファイルからEmoCheckを実行すると/quiet
-quiet
オプションをつけてもDOS窓は表示されてしまいます。
そこで追加のインストールが不要なVBScriptでDOS窓を抑止します。以下の例ではEmoCheckがC:\temp\
に配布してあると仮定します。結果ログは後で扱いやすいようにJSONにします。
Set objShell = CreateObject("WScript.Shell")
Call objShell.Run("c:\temp\emocheck_v2.1.1_x64.exe /quiet /json /output c:\temp", 0, True)
自動実行するのはEmoCheck本体ではなくこのLaunchEmoCheck.vbsになります。
実行結果のログは一か所に集約
上記のコードでは実行結果ログをc:\temp\
に書き出していますが、これを一か所に集約します。
対象PCは社内ネットワークにある前提のため、適当な社内サーバーに共有フォルダを作成し、ユーザーに書き込み権限を与えておきます。
仮にSERVER01
にEmoCheckResults
という共有フォルダを作成したとして、上のVBScriptでEmoCheckの出力先を以下のように変更します。
Set objShell = CreateObject("WScript.Shell")
Call objShell.Run("c:\temp\emocheck_v2.1.1_x64.exe /quiet /json /output \\SERVER01\EmoCheckResults", 0, True)
EmoCheckの仕様上、結果ログファイル名は[computer name]_yyyymmddhhmmss_emocheck
となり事実上ファイル名の重複は起こりません。
ログから感染PCを特定
共有フォルダ\\SERVER01\EmoCheckResults
に全PCの実行結果ログが集まりますので、サーバー側で定期的にバッチ処理を自動実行するなどして感染したPCを探します。
追加インストールが不要という点にこだわってPowerShellを使うと以下のようになります。あくまで一例です。
$logFullName = $PSCommandPath -replace ".ps1", ".log"
foreach ($item in (Get-ChildItem -Path "\\SERVER01\EmoCheckResults\")) {
$json = ConvertFrom-Json -InputObject (Get-Content -Path $item.FullName -Raw)
if ($json.is_infected -eq "yes") {
$item.Name | Out-File -FilePath $logFullName -Append
}
Remove-Item -Path $item.FullName -Force
}
共有フォルダに書き出された実行結果ログを1つずつJSON形式として読み込み、is_infected
がyes
ならログファイルにファイル名を追記、チェック済み実行結果ログファイルは削除するという処理です。
さらに言えば、このPowerShellスクリプトにシステム管理者あてのメール送信処理を追加して、サーバーでタスクスケジューラーに登録して実行するなどになるでしょう。
まとめ
以上、「何でも屋さん」社内情シスならではの地味なお仕事でした。