【上級プロフェッショナル向け】Windowsイベントログ連携によるFSO重要データ削除・改変のリアルタイムSIEM通知スクリプト
レガシーシステムの深淵において、VBScript(Visual Basic Scripting Edition)は未だにインフラストラクチャの神経系として静かに、しかし強靭に稼働し続けている。
特にFile System Object(以下、FSO)を用いたファイル・フォルダの操作は、その手軽さゆえに乱用されがちだが、プロフェッショナルの手にかかれば、これは強力なセキュリティ監査・監視の武器へと変貌する。
本稿では、FSOによるクリティカルなファイル削除・改変検知をトリガーとし、OSの心臓部であるWindowsイベントログへ構造化された監査証跡を刻み込み、さらに外部SIEM(Security Information and Event Management)基盤へとリアルタイムに連携するための極限のアーキテクチャを提示する。
—
1. アーキテクチャの思想:なぜFSOとイベントログなのか
モダンなEDR(Endpoint Detection and Response)やSIEMエージェントが導入されている環境であっても、レガシーなファイルサーバーや特定業務端末では、自律的な監視機構が求められる。
VBScriptの`Scripting.FileSystemObject`は、カーネルモードのファイルシステムフィルタードライバーに比べればプリミティブだが、「追加のサードパーティ製エージェントを一切インストールできない極限の閉域環境」において、無類の信頼性を発揮する。
ここで重要なのは、単に「ファイルを消した・変えた」をログに残すことではない。
- 誰が・いつ・どのプロセスで(あるいはどのコンテキストで)
- どの重要データに対し
- どのような破壊的変更(削除・上書き)を加えたか
これをWindowsイベントログのアプリケーションログ(またはカスタムログ)に`WshShell.LogEvent`を用いて正確に流し込み、SysmonやNXLog、あるいはWindows標準のイベントコレクタ(WEC)経由でSIEMへ転送するパイプラインを構築する。
—
2. メモリリークとCOMコンポーネントのライフサイクル管理
VBScriptにおける最大の悪夢は、COMオブジェクトの不適切な解放によるメモリリークと、それに伴うプロセス空間の肥大化だ。特に常駐型の監視スクリプトにおいて、`CreateObject`の乱用は致命傷となる。
プロフェッショナルは、メモリを汚さない。オブジェクトの参照は最小限のスコープにとどめ、用済みになった瞬間には明示的に `Nothing` を代入してRC(リファレンス カウンタ)をデクリメントしなければならない。
—
3. 実装コード:リアルタイム監査・イベント通知スクリプト
以下のコードは、指定された重要ファイルを監視し、削除または改変(サイズ変更やタイムスタンプの強制変更など)を検知した瞬間に、Windowsイベントログへセキュリティ警告を出力するプロダクション品質のスクリプトである。
‘ ==============================================================================
‘ Script Name: FSO_SecurityAuditor.vbs
‘ Description: Critical File Deletion/Modification Detector with Windows Event Log Bridge
‘ Architecture: Enterprise VBScripting & SIEM Integration
‘ ==============================================================================
Option Explicit
‘ ——————————————————————————
‘ 定数定義
‘ ——————————————————————————
Const EVENT_SUCCESS = 0
Const EVENT_ERROR = 1
Const EVENT_WARNING = 2
Const EVENT_INFO = 4
Const TARGET_FILE = “C:\SecureData\Confidential_Master.dat”
Const CHECK_INTERVAL_MS = 5000 ‘ 5秒おきのポーリング(必要に応じてWMI/FileSystemWatcher代替)
‘ ——————————————————————————
‘ メイン実行ブロック
‘ ——————————————————————————
Sub Main()
Dim objFSO, objFile, targetExists
Dim lastSize, lastModified, currentSize, currentModified
Dim wshShell
‘ WshShellのインスタンス生成(イベントログ書き込み用)
Set wshShell = CreateObject(“WScript.Shell”)
Set objFSO = CreateObject(“Scripting.FileSystemObject”)
‘ 初期状態のキャプチャ
If objFSO.FileExists(TARGET_FILE) Then
Set objFile = objFSO.GetFile(TARGET_FILE)
lastSize = objFile.Size
lastModified = objFile.DateLastModified
Set objFile = Nothing
targetExists = True
Call WriteAuditLog(wshShell, EVENT_INFO, _
“FSO監視エージェントが起動しました。対象: ” & TARGET_FILE)
Else
targetExists = False
Call WriteAuditLog(wshShell, EVENT_WARNING, _
“警告: 監視対象ファイルが存在しません。初期作成を監視します: ” & TARGET_FILE)
End If
‘ オブジェクトの早期解放(スコープ管理)
Set objFSO = Nothing
‘ 監視ループ(実運用ではタスクスケジューラやサービスラッパー併用を推奨)
Do
WScript.Sleep CHECK_INTERVAL_MS
Set objFSO = CreateObject(“Scripting.FileSystemObject”)
If objFSO.FileExists(TARGET_FILE) Then
Set objFile = objFSO.GetFile(TARGET_FILE)
currentSize = objFile.Size
currentModified = objFile.DateLastModified
Set objFile = Nothing
If Not targetExists Then
‘ 復元・新規作成検知
Call WriteAuditLog(wshShell, EVENT_WARNING, _
“【重大インシデント】監視対象ファイルが新規作成または復元されました: ” & TARGET_FILE)
targetExists = True
ElseIf (lastSize <> currentSize) Or (lastModified <> currentModified) Then
‘ 改変検知
Call WriteAuditLog(wshShell, EVENT_ERROR, _
“【セキュリティ警告】重要データの改変を検知! Path: ” & TARGET_FILE & _
” | 旧サイズ: ” & lastSize & “B -> 新サイズ: ” & currentSize & “B” & _
” | 変更時刻: ” & currentModified)
lastSize = currentSize
lastModified = currentModified
End If
Else
If targetExists Then
‘ 削除検知
Call WriteAuditLog(wshShell, EVENT_ERROR, _
“【セキュリティ警報】重要データが削除されました! Path: ” & TARGET_FILE)
targetExists = False
End If
End If
‘ 厳格なメモリ解放:次ループへのゴミ持ち越しを完全に阻止
Set objFSO = Nothing
Loop
End Sub
‘ ——————————————————————————
‘ Windowsイベントログ出力関数
‘ ——————————————————————————
Sub WriteAuditLog(ByRef shellObj, ByVal eventType, ByVal message)
On Error Resume Next
‘ WshShell.LogEvent タイプ
‘ 1: 誤差(Error), 2: 警告(Warning), 4: 情報(Information)
‘ イベントソース名としてスクリプト名を刻む
Dim logMessage
logMessage = “[FSO-SIEM-Auditor] ” & message & ” [User: ” & shellObj.ExpandEnvironmentStrings(“%USERNAME%”) & “]”
shellObj.LogEvent eventType, logMessage
If Err.Number <> 0 Then
‘ イベントログ書き込み失敗時のフォールバック(極限環境ではローカルファイルへ緊急退避)
Call EmergencyFileFallback(logMessage)
Err.Clear
End If
On Error GoTo 0
End Sub
‘ ——————————————————————————
‘ 緊急フォールバック機構(イベントログ書き込み異常時)
‘ ——————————————————————————
Sub EmergencyFileFallback(ByVal failMessage)
Dim fsoErr, errLog
Set fsoErr = CreateObject(“Scripting.FileSystemObject”)
‘ ローカルの保護されたディレクトリにTSV形式で吐き出す
Const FOR_APPEND = 8
On Error Resume Next
Set errLog = fsoErr.OpenTextFile(“C:\SecureData\Audit_Emergency.log”, FOR_APPEND, True)
errLog.WriteLine Now & vbTab & failMessage
errLog.Close
Set errLog = Nothing
Set fsoErr = Nothing
On Error GoTo 0
End Sub
‘ エントリポイントの呼び出し
Main()
—
4. チーフアーキテクトによるコード解説と極限の知見
1. 例外処理の局所化 (`On Error Resume Next`)
グローバルにエラーを無視する素人プログラミングはバグの温床となる。ここではイベントログ書き込みという「外部リソース依存の危うい処理」の直前でのみ `On Error Resume Next` を適用し、即座に `Err.Clear` でクリアしている。
2. フォールバック機構の搭載
万が一、セキュリティ権限の変更やイベントログサービスの停止によって `LogEvent` が失敗した場合、システムが沈黙しては監査の意味がない。極限環境を想定し、ローカルのフォールバックログへバイパスする二重化設計を取り入れている。
3. SIEM連携のためのメッセージフォーマット
ログメッセージ内に `[FSO-SIEM-Auditor]` というプレフィックスや `%USERNAME%` などの環境変数を埋め込むことで、Syslog転送時(NXLogやFluentdなどを使用)に、SIEM側で正規表現パース(Regex Parsing)を容易に行える構造化テキストとして機能させる。
—
5. レガシー保守・運用上の注意点
- 実行権限の制約: `WshShell.LogEvent` は、イベントログのセキュリティポリシー(レジストリ `HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\EventLog` のアクセス権)に依存する。スクリプト実行ユーザーに適切な権限(Administrators または Event Log Readers / Writers 相当)が与えられていることを確認せよ。
- CPU負荷の最適化: ループ内の `WScript.Sleep 5000` は、CPUコアを不当に占有しないための処置である。より厳密なリアルタイム性が求められる場合は、WMIの `__InstanceModificationEvent` クエリを用いた非同期イベント駆動型(`WScript.ConnectObject`)へのリファクタリングを検討すべきだが、コードの複雑性と保守性を天秤にかけた場合、このポーリングモデルが最も「壊れにくい」という現実解をもたらすこともある。
VBScriptは過去の遺物ではない。アーキテクトの知見と堅牢な設計思想を纏うことで、モダンなセキュリティインフラの最前線で、今なお堅固にシステムを守り抜く盾となるのだ。
