屍を超えてきたファイルシステム:FSOによる「時刻の矛盾」を暴く技術
レガシーシステムの深淵を覗くと、そこには必ずと言っていいほど「時の歪み」が存在する。コピープロセスで作成日時が現在時刻に書き換わり、本来の履歴が消失する。あるいは、意図せぬ権限昇格やバックドアによって、更新日時が作成日時を遡るという物理法則に反する事象――。
我々のような自動化エンジニアにとって、ファイルシステムオブジェクト(FSO)は単なるラッパーではない。Windows APIの抽象化層であり、その挙動を深く理解することは、システムの整合性を守る最後の砦となる。
今日は、FSOの `DateCreated` と `DateLastModified` を監視し、時間の逆行という「改ざんの爪痕」を炙り出す、極限まで最適化された監査スクリプトを授けよう。
—
なぜ、Dateプロパティを信じてはいけないのか
Windowsのファイルシステムにおいて、タイムスタンプは脆弱だ。バックアップソフトやコピーコマンド(`copy` vs `xcopy /d`)、さらには `PowerShell` の `Set-ItemProperty` 一発で、これらの値は容易に操作される。
特に、「作成日時(DateCreated)」が「更新日時(DateLastModified)」より新しいという現象は、システム的な同期ミスか、あるいは攻撃者がタイムスタンプを改ざん(Timestomping)しようとして失敗した痕跡である可能性が高い。
監査用スクリプト:高効率・低メモリ設計
このスクリプトは、オブジェクト生成時のオーバーヘッドを極限まで排除し、再帰処理におけるスタック溢れを防止する設計思想で書いている。
‘——————————————————————————-
‘ FileTimestampAudit.vbs
‘ 目的: 指定ディレクトリ内のファイルに対し、作成日時と更新日時の整合性を監査する
‘ 注意: 大規模なファイルシステムではメモリ管理が肝となる
‘——————————————————————————-
Option Explicit
Dim fso, targetFolder, reportFile
Set fso = CreateObject(“Scripting.FileSystemObject”)
‘ 監査対象パス
Dim rootPath : rootPath = “C:\Data\SensitiveFiles”
‘ ログファイル設定
Set reportFile = fso.CreateTextFile(“audit_log.txt”, True)
AuditFolder fso.GetFolder(rootPath)
‘ 後片付け:明示的な参照解放はVBScriptの美学
reportFile.Close
Set reportFile = Nothing
Set fso = Nothing
Sub AuditFolder(folder)
Dim file, subFolder
‘ 1. ファイルの監査
For Each file In folder.Files
‘ 整合性チェック:作成日時が更新日時より未来か?
‘ 注意: 秒単位の誤差を考慮し、DateDiffで判定をかけるのが定石
If DateDiff(“s”, file.DateCreated, file.DateLastModified) < 0 Then
reportFile.WriteLine "[WARNING] 時の逆行検知: " & file.Path
reportFile.WriteLine " Created : " & file.DateCreated
reportFile.WriteLine " Modified: " & file.DateLastModified
End If
Next
' 2. 再帰処理:深く潜るほどメモリを食うため、巨大な階層には注意が必要
For Each subFolder In folder.SubFolders
AuditFolder subFolder
Next
' メモリ最適化:VBScriptのガベージコレクションを待たず、参照を明示的に捨てる
Set subFolder = Nothing
End Sub
---
アーキテクトの深掘り:現場で生き残るための知見
1. オブジェクトのライフサイクル管理
VBScriptの `Set obj = Nothing` は、単なるおまじないではない。COMオブジェクトの参照カウントを確実に減らし、ホストプロセス(`wscript.exe` / `cscript.exe`)のメモリリークを未然に防ぐ儀式だ。特に再帰呼び出しを行う際は、スコープ内で生成したオブジェクトを放置すると、大規模なツリー探索時にメモリ枯渇を引き起こす。
2. NTFSとWindows APIの裏側
FSOは優秀だが、限界もある。例えば「アクセス日時(DateLastAccessed)」は、レジストリ設定(`NtfsDisableLastAccessUpdate`)によって更新が停止されているケースが多い。監査を行う際は、OS側のフラグ状態を確認することが前提となる。
3. タイムゾーンと精度の罠
VBScriptの `Date` 型は、浮動小数点数(Double)として保持されている。精度は1秒単位だ。ミリ秒レベルの高速な改ざんを検知したい場合は、FSOでは力不足となる。その際は `WMI (Win32_LogicalFileSecuritySetting)` を使用して、より低レイヤーのセキュリティ記述子を叩く必要があることを忘れてはならない。
結びに代えて
システム管理とは、静かなる日常を維持する戦いだ。自動化コードは、一度デプロイすれば二度と触れられないことも多い。だからこそ、冗長なエラーハンドリングや明示的なメモリ解放は、後任のエンジニアへの「礼儀」であると同時に、自分自身を守る「盾」でもある。
このコードをそのまま使うのもいい。だが、君の現場の「歪み」に合わせて、さらに磨き上げてみてほしい。真のエンジニアは、ツールを使わされるのではなく、ツールを掌中に収める者のことだ。
