Excelのマクロやアドオンなどを利用する際に「これ使っても大丈夫なんだよね」と気になる事は無いでしょうか?
と言いますか、基本的には素性のしれないマクロやアドオンは使用禁止にしているのが一般的であると思います。
ただそうなると、本当は悪くないマクロやアドオンに対しても門を閉ざしてしまう事になります。
では、「悪くない安全なマクロやアドオンとは?どのようなコーディンクになるのか?」という疑問が沸いてくるのですが、Microsoft ドキュメントの中を探してみても、これに答えてくれるページを見つける事はできませんでした。
そこで今回は「Excel VBAコーディングの安全性」についてシリーズで考えて行きたいと思います。
とは言いながら、現段階ではどのくらいの回数のシリーズになるかは?(2回なのか10回なのか)現時点ではハッキリと見通せていないというのが正直なところで、出来上がった文字量を見ながら回数は決めて行きたいと思います。
なお、結論を先に述べて置きますが結局のところ安全性の要点(ポイント)としては下記の4点になる認識です。
- 解り易いモジュール構造・コーディング構造になっている。
- ネーミングルールや記述の仕方に一貫性があり、読み易いコーディングになっている。
- 「使い方によっては危険性のあるメソッドやファンクション」に関しては使用量を極力少なくした上で、使用用途を解り易く・確認し易くコーディングしている。
- 危険性が入り込み難いように、ネットワーク・パソコン・ユーザも含めて「Excelの環境」を正しい状態に保っている。
上記の中で3.が一番のポイントになる認識ですが、1.と2.及び4.につきましては本シーズでは詳しくは 言及しませんが、機会が有れば別途ご説明したく存じます。
※動作は32bit版Excel 2016と64bit版Excel 2021の バージョン2301(ビルド 16026.20146)を使用して検証しています。
「安全ではない」/「危険性のある」VBAコーディングとは
使い方によっては危険性のあるメソッドやファンクションの具体的な説明に入る前に『「安全ではない」VBAコーディングとはどのようなものか?』について考えて見たいと思います。
ご存じのように世の中にはExcelのマクロやアドインを使用したマルウェア(マクロウィルス・アドインウィルス)が存在します。
そこで問題となるマルウェアの「悪意のある行為」には下記のようなコーディングが含まれている認識です。
- 別プログラムや別プロセスを起動する。
- 別ファイルやレジストリーを操作(削除・変更・追加)する。
- 外部とプロトコルで通信をする。
- インターネット(HTTPS)、メール、FTP、データベースなど
- Dos攻撃、スパム攻撃、不正なサイトへのアクセスなどの悪いおこないをする。
一般的なマルウェアとしては、ネットワークからバイナリーファイルをダウンロードして、それを起動させるような道筋をたどって「悪意のある行為」を仕組むものが多いのではないでしょうか?
一方「安全ではない」・「危険性のある」VBAコーディングというのは、中には何かしらのバックドアを使用しているものがあるかもしれませんが、むしろそれよりも正面の入り口から入って来て「悪意のあるコーディンクを分からないように実行している」ものが多いと思います。
言い換えると例えばマイクロソフトが公開しているドキュメントやインターネット上に溢れている情報を悪意を持ってプログラムにするのでもマルウェアを作る事ができてしまう事になります。
ただそうだからと言って「上記の行為は問題だからマクロはすべてNGだ」としてしまうとコーディングの有用性を享受できなくなってしまいます。
従って本シリーズでは、上記1~3の行為について、「こんな方法がある・あんな方法がある」というトピックを、Google検索で入手できる情報を元に一通り大まかにピックアップしたうえで、「これだけは確認した方が良い」というポイントを整理して行きたいと思います。
なお「ポイントがいくつになる」かは現時点では分かっていませんが多すぎると収集が付かなくなるので、できるだけブラシュアップしてスタンダードな形にしたいと思います。
参照設定とTypeLib(COMクラス)
VBAコーディングの危険性を語る上でTypeLib(COMクラス)の存在は欠かす事ができません。
※COMクラスにつきましては「Excel VBAで使えるCOMクラスのクラスIDとレジストリTypeLibとの対比表」をご参照いただければ幸いです。
ネイティブなVBAだけでも十分「危険性のある」コーディングをする事はできますが、TYpeLib(COMクラス)を使用する事でその危険性がより広く深く複雑なものに進化させます。
そのためにまずは参照設定にまつわるところから話を進めて参ります。
参照設定ダイアログボックスに表示される「参照可能なライブラリ」をどう考えるか?
Visual Basic Editor(VBE)のツールメニューにある「参照設定」を見ると「参照可能なライブラリ ファイル」には沢山のライブラリが表示されるので「危険性があるライブラリが含まれているのでは?」と心配になる場合がある事と存じます。
別記事になりますが「Excel VBA の参照設定に表示される参照可能なライブラリとは?」の中で、「参照設定ダイアログボックスにデフォルトで表示されるオブジェクトは、どのような情報に基づいているのか?」について、つぎのような仮説を立ててご説明しています。
仮説を踏まえて弊社のパソコン環境を調べると次のような事が確認できました。
- 参照設定ダイアログボックスに表示されるオブジェクトでチェックボックスをオンにできるものはすべて、Registryの中の「TypeLib」、「Office TypeLib」のどちらかに存在している。
- なお「Office TypeLib」につきましては、「Excel VBAでOfficeが使用するTypeLibをレジストリから取得?」をご参照いただければ幸いです。
- 参照設定ダイアログボックスに表示されていないオブジェクトでも、手動で登録する事ができるものがある。(すべてを確認していないので曖昧な表現にしています)
以上から、「参照可能なライブラリ」については次のように考えます。
ただ、そうなるとTypeLibのオブジェクトの数は合わせると300に近い数になり話の収集が付かなくなってしまうので、「デフォルトでチェックされている参照設定」と「世間一般で良く使われている参照設定」に絞って説明する事に致します。
デフォルトでチェックされている参照設定
Visual Basic Editor(VBE)では現在フォーカスが当たっているプロジェクトで使われているライブラリにはチェックマークが付くのですが、弊社で使用しているパソコン環境ではデフォルトで下記4つのライブラリでチェックボックスがオンになっていました。
ライブラリ | 場所 | |
---|---|---|
1 | Microsoft Excel 16.0 Object Library | 2016 C:\Program Files\WindowsApps\Microsoft.Office.Desktop_160…\Office16\EXCEL.EXE 2021 C:\Program Files\Microsoft Office\root\Office16\EXCEL.EXE |
2 | Microsoft Office 16.0 Object Library | (2016/2021)\OFFICE16\MSO.DLL |
3 | OLE Automation | 2016 C:\Windows\SysWOW64\stdole2.tlb 2021 C:\Windows\System32\stdole2.tlb |
4 | Visual Basic For Applications | (2016/2021)\VBA\VBA7.1\VBE7.DLL |
※表中の(2016)、(2021)の記載は下記のディレクトリに置き換える事で実際のファイルパスになります。
(2016) | C:\Program Files\WindowsApps\Microsoft.Office.Desktop_160…\VFS\ProgramFilesCommonX86\Microsoft Shared |
(2021) | C:\Program Files\Common Files\Microsoft Shared |
ところで「上記以外のライブラリーが使用されていたら問題があるのか?」というと一概にそのような事は言えません。
参照設定については下記のようないろいろな観点から注意する必要があります。
- デフォルト以外のライブラリーが設定されている場合は、「何のために使われているか?」を見極める必要があります。
- 参照設定をしていなくてもコーディングでCreateObject関数を使えばCOMクラスを使用する事ができるので、参照設定がデフォルト以外にされていないからと言って安心してはいけません。逆にコーディングにCreateObject関数が使われていないからと言って安心してもいけません。参照設定がされていないか?を事前に確認する必要があります。
ただし参照設定でもCOMクラスでも危険性は変わらないわけで、そうなると後は「良く知られているものを使うか?知られていないものを使うか?」になるのですが、利用者側からすると「良く知られているもの」の方が情報量が多いので「調べるのが容易である」という利点があります。
良く使われる「参照可能なライブラリ ファイル」
「良く使われているから安全」という訳ではありません。危険な使い方をすれば「悪意のある行為」はできてしまいます。
とどのつまり「危険な使い方ではない事を分かってもらう」事の方が大切になりますが、ここでは、良く使われているライブラリにおける注意点をご説明して参ります。
なお記載している内容に関して次の点にご注意ください。
- Windows10と11ではライブラリファイル(主にDll)の扱いが異なるところがあります。
- ライブラリのバージョンは現時点での最新を表記しています。
- 後述しております参考文献などを加味して「良く使われるライブラリ」を選別していますが、この一覧表に載っていないから「危険がある」という訳ではありません。皆様のご利用状況に合わせてご判断いただければ幸いです。
- Office関係のライブラリにつきましては最小限でのピックアップにしています。
No | 参照設定 | COMクラス(ProgID) | 備考 | 悪意のある行為 |
---|---|---|---|---|
1 | Microsoft ActiveX Data Objects 6.1 Library | ADODB.Connection ADODB.Recordset ADODB.Stream | 3 | |
2 | Microsoft CDO for Windows 2000 Library | CDO.Message | 3 | |
3 | Microsoft DAO 3.6 Object Library | DAO.DBEngine.36 | Windows11ではチェックするとエラー | 3 |
4 | Microsoft Forms 2.0 Object Library | Forms.XXXXX.1 | プロジェクトにUserFormを挿入時 有効化。XXXXXはコントロールごと | 該当しない |
5 | Microsoft HTML Object Library | htmlfile | 3 | |
6 | Microsoft Internet Controls | InternetExplorer.Application | 対比表非掲載 | 1 |
7 | Microsoft Outlook 16.0 Object Library | Outlook.Application | 対比表非掲載 | 1 |
8 | Microsoft Script Control 1.0 | MSScriptControl.ScriptControl | Windows11では使用できない(注) | 1・2・3 |
9 | Microsoft Scripting Runtime | Scripting.Dictionary Scripting.FileSystemObject | 2 | |
10 | Microsoft Shell Controls And Automation | Shell.Application | 1 | |
11 | Microsoft VBScript Regular Expressions5.5 | VBScript.RegExp | 2 | |
12 | Microsoft Word 16.0 Object Library | Word.Application Word.Document | 対比表非掲載 | 1 |
13 | Microsoft WinHTTP Services, version 5.1 | WinHttp.WinHttpRequest.5.1 | 3 | |
14 | Microsoft WMI Scripting V1.2 Library | WbemScripting.SWbemLocator | 対比表非掲載 | 2 |
15 | Microsoft XML, v6.0 | Msxml2.ServerXMLHTTP.6.0 Msxml2.XMLHTTP.6.0 | 3 | |
16 | Windows Script Host Object Model | WScript.Shell | 1 |
「悪意のある行為」…1.「別プログラムや別プロセスを起動」,2.「別ファイルやレジストリーを操作」,3.「外部とプロトコルで通信」
※上記以外の参照設定とCOMクラスの対比表は「Excel VBAで使えるCOMクラスのクラスIDとレジストリTypeLibとの対比表」にまとめてご紹介していますので合わせてご参照いただければ幸いです。
※表上の備考で「対比表非掲載」と記載されているものは「Excel VBAで使えるCOMクラスのクラスIDとレジストリTypeLibとの対比表」に出てこないのですが、その理由は対比表を作成する際のマッチングで上手く突合できなかったためで、ProgIDとしては存在していますので、あらかじめお含み置きください。
なお上記の表を作成するにあたり、下記のサイトを参照しております。
また次の「えくせるちゅんちゅん」サイトも参考にさせていただきました。
https://www.excel-chunchun.com/entry/20200419-vba-createobject-reference
「悪意のある行為」に気付くために備えるべきポイント
ITの世界において、特にハードウェアでは二重障害を考慮する事が求められたりしますが、今回の話は「現状は正しい状態にある」事を前提にしています。
この理由としては、例えば現状で「プログラムや接続先が不正に書き換えられている事を考慮しなければならない」としたら「正しいと判定する事」など何もできなくなってしまうためです。
この前提に立った上で「悪意のある行為」の1~3に関して気付くため備えるべきポイントを考えてみる事にします。
1.「別プログラムや別プロセスを起動」
起動の仕方はいくつかやり方があったとして、問題になるのはやり方よりも「起動する対象」になります。(もちろん、やり方を知らなければ「起動する対象」を特定する事はできませんが…)
可能な限り「別プログラム」や「別プロセス」を起動する事は少なくしたり、やり方を統一したりした上で、対象が「何のプログラムなのか?」や「何のプロセスか?」について、解り易くコーディングして置く事がポイントになります。
「プログラム」や「プロセス」の名前については、動的に変える必要は少ないと思いますので「Const」ステートメントで定数として宣言して置くのも一考です。
なお対象を確認する際に注意しなければならないのは、「良く見る名前が一部だけ異なる」ような見誤り易い名前の付け方がしてあるケースをスルーしないようにする事です。
言ってしまえば「悪意のある」場合には、そのような名前の付け方をしてあるのではないか?と思います。
また「名前」を関数で変換していたり、名前を計算したりする事は避けた方が無難です。(そもそも名前を計算する事自体「疑わしい行為」なのですが…)
後は3.「外部とプロトコルで通信」と組み合わせて、外部からダウンロードした圧縮ファイルを解凍して起動するなどの場合は、「プログラム」の名前だけでは判断できないので、このような組み合わせにも注意を払う必要があります。
2.「別ファイルやレジストリーを操作」
単純にファイルを削除するような愉快犯的マルウェアよりも、勝手に暗号化したりパスワードを付けたりした上で対価を要求する形のものが多い事と存じます。
もっとも消されたり、書き換えられたりした場合でも、それをリカバリするのは大変ではありますので、どんな操作をするのかが解り易くコーディングされている事がポイントです。
どうしても操作が必要になる場合は、操作はFunction(関数)にして使いまわしできる(やり方が統一された)形にして置くのが良いと思います。
なおこの場合はもFunction名は解り易い名前にして、見誤り易い名前の付け方がされないような工夫をした方が無難です。
例えば英単語の組み合わせで名前を付けて、数字が入らない形にするなども一考ですが長くなりすぎるのもマイナス効果になる認識です。やはりネーミングルールを決めて、そこから逸脱していないか?が判断し易いようにするべきです。
またFunction(関数)の中で別のFunction(関数)を呼ぶような構造はなるべく避けた方が良いと思います。(コーディングの冗長性を避けるために子Functionを使う事は良いとは思いますが…)
3.「外部とプロトコルで通信」
通信のやり方はいろいろとあるのですが、一つのプロトコルに対してコーディングの仕方が異なるのは避けるべきかと存じます。
コーディング標準の中でやり方を決めて置くのも一考です。
ただ外部との通信で一番のポイントは何と言っても「どこと通信するか?」で、それと合わせて「どのくらいの頻度で通信するか?」になります。
例えば「悪意のあるサーバ」と通信をするという事は危険を伴います。ただ「良く知られているサイト」に対してだったとしても、それがとんでもない回数になってしまうとDOS攻撃になります。
なお「どこと通信するか?」を動的に指定したい時に、「外部のサーバ」から宛先を取得するようなケースもある事と存じます。
この場合は「外部のサーバ」が絶対的な信用を置けない時は使用する事は難しくなります。例えば「外部のサーバ」から宛先を取得して事前に確認したとして、その時は問題がなかったとしても、あるタイミングでは「悪意のある宛先」に変わっているかもしれません。
このようなケースでは宛先は手動で取得して、そのデータを読み込んで動かすような仕組みにしないと、安心して利用してもらう事ができないはずです。
「外部とプロトコルで通信」するようなアプリケーションの場合は、「安心して利用する事ができる仕組み」で提供する事が必要になる認識です。
今まで述べてきた事にすべて対応できていたとしても安心する事はできない
一般的に「見た目は良くできているのだけど、実は中身は良くなかった」という事は良くある話であると存じます。
ここまで述べてきた内容にすべて対応できていたとしても、一ヶ所「悪意のある行為」を忍ばせて有って、それに気づかずに見逃してしまったら取り換えの付かない事になりかねません。
ここまでの内容はあくまでも「気付くための備え」であって、「未然に防ぐ」ためのものではありませんのでご注意ください。
見た目には惑わされずに、気を抜くことなく漏れなくチェックをする事が肝要です。
なお、文章の単語数が1万字に近づいてきたので今回は次の章で終わりにしたいと思います。
この後の本シリーズで皆様にお伝えしたい事
悪意のある人が、一般的に知られていない方法で悪意のあるコーディングをしたとしてら、それを事前に検知する事はできない認識です。
もしも仮にそのようなコーディング手法を発見したとしたも、その手法を公開する事は「悪意のある人」にヒントを与える事になってしまうかもしれないので、公開は控えるべきだと思います。
では「何をお伝えしたいか?」というと、一般的に使われているコーディング事例を使って悪意のある人が悪意のあるコーディングをするとしたら、「どのような点に注意をしなければならないのか?」という点です。
その際に「解り易い構造で、読み易いコーディングになっていれば安全なコーディングである」とは言えない話です。
では実際にどこに注意をするべきか?は具体的なコーディング事例の中で「これだけは確認した方が良い」というポイントを整理ながらお伝えして行きたいと考えています。
なお今回は具来的なコーディング事例についてご説明できて居ませんが、それが最終的にどのくらいの分量になるのか?、またどのくらいの期間が必要になるのか?は現時点では想像できてません。
取敢えず一通り書く事を目指して進んでいきたいと思いますので、長い目で見守っていただければ幸いです。
「今回のまとめ」と「次回の予告」
今回はExcel VBAコーディングの安全性の要点(ポイント)と参照設定についてお話してきました。
明確に「ポイントはここだ」と言う事はできなくて、雲をつかむような内容になってしまいましたが、「悪意のある行為」をする場合には「如何に人に気付かれずに実装するか?」という事を考えてくるはずです。
そうなると当然「ポイントの裏をかく」必要があり、「見た目は良くできている」というように「人間が間違えやすいところを巧みに突いてくる」はずです。
コーディングがあまりにも乱雑で読む気もしないような場合は、ソースコードを見ただけで「これは使えない」と思われてしまい、入り口にも入れづに終わってしまいます。
(良く使われているExcelアドインのソースコードを見てガッカリする事はありますが…。良く使われるようになると改修する回数が増えて乱雑化してしまうのかもしれませんが…)
また参照設定につきましても同じような事が言えて、「良く使われていないライブラリ」を使っていたとしたら逆に怪しまれてしまいます。
当然「良く使われているライブラリ」であっても、使い方によっては危険性がありますので、注意を払う必要があります。
次回ですが、前章で『「悪意のある行為」に気付くために備えるべきポイント』についてご説明しましたが、そのための拠り所になっているコーディング自体が「隠蔽されている」とか「外部から取得している」といったようなケースについてお話をする予定です。
以上、最後までご一読いただき誠にありがとうございました。