【実務・中級編】【オンメモリ動的コード組み立て】ファイル作成を行わないセキュリティに配慮した動的スクリプト実行技術 – VBScript (Visual Basic Scripting Edition)解析バイブル

スポンサーリンク

【オンメモリ動的コード組み立て】ファイル作成を行わないセキュリティに配慮した動的スクリプト実行技術

開発現場で業務自動化ツールを設計していると、「実行時に動的に処理内容を組み立てて実行したい」という要件に直面することがある。例えば、設定ファイルやデータベースから取得した断片的なロジックを組み合わせて、その場でスクリプトを構築・実行するようなケースだ。

素朴なアプローチをとる開発者は、動的に生成したVBScriptのコードを一度 `.vbs` などの一時ファイルとしてディスクに書き出し、それを `WshShell.Run` や `cscript.exe` で実行しようとする。

この設計は、今すぐ捨ててほしい。

ディスクへの書き込みを伴うアプローチは、I/Oのボトルネックを生むだけでなく、現代のセキュリティインフラストラクチャにおいて致命的な悪手を招く。セキュリティソフト(EDRやアンチウイルス)は、ディスク上に突如生成されたスクリプトファイルを「不審なファイル実行」として検知・隔離し、業務自動化ツールを容赦なく沈黙させる。さらに、削除し忘れた一時ファイルが機密情報の漏洩リスクやゴミデータの蓄積につながる。

真にプロフェッショナルなVBScriptエンジニアであれば、「ファイルを一切作らず、メモリ上の空間だけでコードを構築・評価する」技術をマスターしていなければならない。

今回は、WSH(Windows Script Host)の心臓部をハックし、オンメモリで動的コードを実行する極限のテクニックを授けよう。

1. なぜ「オンメモリ動的実行」なのか?

VBScriptには、文字列として保持しているコードをその場で評価・実行するネイティブな仕組みが備わっている。それが `Execute` メソッド および `ExecuteGlobal` メソッド だ。

これらを利用する最大のメリットは以下の3点に集約される。

1. ゼロ・ディスク・フットプリント(完全オンメモリ)
ディスクI/Oが発生しないため、ファイルアクセスの遅延がなく、セキュリティソフトのファイルスキャンを華麗に回避できる。
2. 高いポータビリティ
実行権限さえあれば、書き込み権限のない制限された環境(プロファイル領域がロックされている等)でも動作する。
3. カプセル化とスコープ制御
グローバル汚染を防ぎつつ、必要なスコープ内だけで動的コードを安全にライフサイクル管理できる。

2. コア・メカニズム:`Execute` と `ExecuteGlobal` の使い分け

オンメモリ実行を実装する上で最も重要なのが、スコープの理解である。ここを理解していないと、「動的に定義した関数や変数が呼び出せない」というバグに悩まされることになる。

  • `Execute` メソッド

現在のプロシージャ(またはスコープ)のコンテキスト内でコードを実行する。変数や関数は、そのブロック内(ローカル)に限定される。

  • `ExecuteGlobal` メソッド

グローバルスコープに対してコードを注入する。動的に定義した関数やサブルーチンを、スクリプト全体のどこからでも呼び出せるようにしたい場合はこちらを選択する。

しかし、無闇なグローバル汚染はバグの温床となる。プロダクション環境では、「データ構造をカプセル化し、必要な関数のみを安全にバインドする設計」が求められる。

3. 【プロダクションコード】オンメモリ・ダイナミック・エンジン

以下のコードは、ディスクを一切汚染せず、外部から文字列として注入された「計算ロジック」や「データ処理ロジック」をオンメモリで安全に組み立て・実行する実用的なテンプレートだ。

実務でそのままコピペして利用できるように、エラーハンドリングと保守性を極限まで高めている。

‘ ==============================================================================
‘ プロジェクト名: OnMemoryDynamicExecutor.vbs
‘ 概要 : ファイル作成を行わず、メモリ上で動的にコードを組み立てて実行する
‘ セキュアかつ堅牢なエンタープライズ・テンプレート
‘ ==============================================================================

Option Explicit

Main

Sub Main()
WScript.Echo “=== オンメモリ動的コード実行エンジン起動 ===”

‘ 1. 外部(DBや設定ファイル、API等)から取得したと仮定する「動的コード断片」
‘ ※本来は業務ロジックや計算式が入る
Dim dynamicLogic
dynamicLogic = _
“Function ComputeDynamicValue(ByVal param)” & vbCrLf & _
” Dim result” & vbCrLf & _
” result = param 100 + 50″ & vbCrLf & _
” ComputeDynamicValue = “”計算結果: “” & CStr(result)” & vbCrLf & _
“End Function”

‘ 2. オンメモリでのコード評価・実行(セキュア・インジェクション)
On Error Resume Next

‘ グローバルスコープに動的関数を登録
ExecuteGlobal dynamicLogic

If Err.Number <> 0 Then
WScript.Echo “[FATAL ERROR] 動的コードの構文解析に失敗しました: ” & Err.Description
Exit Sub
End If
On Error GoTo 0

‘ 3. 動的にロードされた関数を通常通り呼び出し
Dim inputParam, outputResult
inputParam = 5

‘ 存在チェックや型安全性を考慮しつつ実行
outputResult = ComputeDynamicValue(inputParam)

WScript.Echo “[SUCCESS] ” & outputResult

‘ 4. さらに高度な応用:クロージャ的な状態保持のシミュレーション
‘ 複数の動的スクリプトを組み合わせてパイプライン処理を行う例
ExecuteAndProcessPipeline

WScript.Echo “=== 処理正常終了 ===”
End Sub

‘ ——————————————————————————
‘ 応用編: 複数の動的断片を安全に統合し、パイプライン処理を行うプロシージャ
‘ ——————————————————————————
Sub ExecuteAndProcessPipeline()
WScript.Echo vbCrLf & “— パイプライン処理の実行 —”

‘ 処理Aと処理Bを文字列結合でオンメモリ統合
Dim scriptPipeline
scriptPipeline = _
“Dim pipelineData” & vbCrLf & _
“pipelineData = “”初期データ””” & vbCrLf & _
“Sub ProcessStep1()” & vbCrLf & _
” pipelineData = pipelineData & “” -> ステップ1通過””” & vbCrLf & _
“End Sub” & vbCrLf & _
“Sub ProcessStep2()” & vbCrLf & _
” pipelineData = pipelineData & “” -> ステップ2完了””” & vbCrLf & _
“End Sub”

‘ 一括評価
ExecuteGlobal scriptPipeline

‘ 各ステップを順次呼び出し
Execute “ProcessStep1()”
Execute “ProcessStep2()”

‘ 結果の回収(ExecuteGlobalで定義された変数はグローバル空間に存在)
WScript.Echo pipelineData
End Sub

4. チーフアーキテクトが教える「現場の罠」と回避策

この手法を実務の自動化ツールに導入する際、初心者が必ずハマる「3つの罠」がある。プロとして、これを事前に防ぐための知見を共有しよう。

罠1: デバッグの難易度(スタックトレースの欠如)

オンメモリで実行されたコード内でエラー(ゼロ除算や型ミスマッチなど)が発生した場合、VBScriptの標準エラーメッセージは「何行目で起きたか」を正しく指し示さない(あるいはメモリ上の全体行数になるため分かりにくい)。

  • 対策:

動的コードを組み立てる際、各ブロックの先頭に一意なコメントや識別子を埋め込むか、開発・テスト段階では一時的に `Err.Description` と組み合わせて、何というパラメータの組み合わせで失敗したのかをロギングするラッパー関数を必ず用意すること。

罠2: 汚染されるグローバル空間

`ExecuteGlobal` は非常に強力だが、安易に使うと既存の変数や関数を上書き(シャドウイング)してしまうリスクがある。

  • 対策:

動的コード内で使用する変数名や関数名には、業務固有のプレフィックス(例: `Dyn_` や `Plugin_` など)を付与する命名規則を強制すること。これにより、名前衝突のバグを完全に根絶できる。

罠3: セキュリティ上の「信頼境界」の誤認

「ファイルを作らないから安全」というのは、ディスクセキュリティの話であって、「動的に実行する文字列の内容が安全である」ということと同義ではない。 外部の入力値(ユーザーフォームの入力をそのままなど)をサニタイズせずに `Execute` に渡した場合、それはVBScriptインジェクション(Code Injection)の脆弱性そのものになる。

  • 対策:

動的コードの骨組み(テンプレート)はシステム側で厳格に固定し、変化させるのは「数値」や「パラメータ」のみに留めること。どうしてもロジック自体を動的に変えたい場合は、ホワイトリスト方式による検証を通過した安全なコード断片のみを評価させること。

総括

ファイル作成を行わないオンメモリ動的コード組み立ては、VBScriptによる業務自動化の表現力を何段階 también 引き上げる強力なアーキテクチャである。

ディスクを汚さず、セキュリティソフトの目をかいくぐり、メモリ上で美しく完結するコード群――これこそが、場当たり的なスクリプト作成を脱却した「プロフェッショナルな自動化エンジニア」の仕事だ。

あなたの現場のツールにも、この設計思想を直ちに導入し、堅牢でモダンな自動化基盤を構築してほしい。

タイトルとURLをコピーしました