VBAマクロが既定でブロックされる為の対策方法

2022年2月に、Microsoftより現在リリースされているMicrosoft365(Build 2203)のExcel, Access, Power Point, Visio, WordおよびOffice2021、過去の版である単品版のOffice 2019, Office 2016, Office 2013, Office LTSCに対してもアプデが実行される(Windows版のみ)ことになった「VBA実行をデフォルトでブロック」する機能。既にその前よりv4.0のExcelのVBAのブロックなどが実施済みです。

この結果として、外部からダウンロードしたファイルだけでなく、社内で業務改善として配布してるVBA入りのファイルの実行が阻害されて使えなくなる恐れがあります。この問題点に関しての対策をまとめてみました。

変更される内容の詳細

今回の処置で措置が実施される内容は以下の通り。こちらに公式の資料が掲示されています。VBA実行にあたって「もう一段階実行確認が増えた」という事になりますが、何が何でも実行を阻止するという類のものでもありません。故にクリアしてしまえば、実行は可能なのでウイルス入りのものをクリアしてしまうと、感染する事になります。

  • これまでのような、VBAの実行ブロックとは異なり、「コンテンツを有効化」のボタンが表示されずブロックされたままとなる
  • この問題を解決する為の各種対策法を実施しなければ、VBAを実行する事は出来ない
  • その対策内容も誤った運用をした場合、今回の保護目的が無意味となってしまう
  • 特にインターネットからダウンロードしたファイルに対してフラグが付けられて直接VBA実行は阻止される(Mark of the Webと呼ばれる)
  • 但しこのフラグは、NTFSの機能を利用して制御されているため、FAT32上では付与されない
  • VBA入りのxlsm形式等ではない、xlsx形式では影響は無い

表示されるメッセージは「セキュリティリスク このファイルの出自は信頼できないため、Microsoftはマクロの実行をブロックしました」といった内容で、以下の図のような赤いバーが出てくるので、このままでは一切VBAもマクロも実行は不可能となる。

これはこれまで長年、ウイルスの温床となっていたVBA・マクロに対して、Microsoftが遂に強力な手段でガードする行動に出た結果であって、むしろこれまでウイルスチェッカー等に依存していた状態からの脱却を測ったものです(Emotetなどが最近でも流行っています)。

※EmotetですがVBAでのやり方から、lnkファイルを利用した方法に移ったようで。VBAは対策が出来るのですが、lnkファイルはパスワード付きZIPファイルに入れて送りつける手法のようなので、別の対策法が必要になります(PPAPな事をやっていると、サーバ側でウイルススキャン出来ず、逆にこのような攻撃に対して無力になりますので、早々にPPAPなど廃止してパスワード付きZIPでのメール添付は排除するようにすべきです。まともな企業は既に対策されてると思いますが)

図:これまで表示されていた内容

図:赤いバーが出て許可もできなくなる

実行できるようにする対策

メール上であったり、ウェブ上にあるファイルをダウンロードされた時点で「MOTW属性」が付与され、チェック対象となります。評価される手順の順番に応じて記述してます。ここでは、Excelを基準として対策法を記述しています(Microsoft365 E3のExcelで検証しています)。

なお、今回の措置はアドイン形式であってもチェックされますので、アドインならバイパス出来るというものでもありません。

ブロック解除を実行する

今回の措置の結果追加された設定で、解除自体はとても簡単です。主にこの方法が今後行う必要のあるものになるとは思います。

  1. 対象のファイルを右クリック⇒プロパティを開く
  2. 下の方に新たに「セキュリティ」の項目で、「このファイルは他のコンピュータから取得したものです。このコンピュータを保護するため、個のファイルへのアクセスはブロックされる可能性があります」というメッセージとともに、「許可する」のチェックを入れてOKを押す
  3. 改めて開くと、マクロの設定に従って評価され実行が可能になる

信頼できる場所への追加

対象のファイルを実行する場所を「信頼できる場所」として登録する事で、そのフォルダ内のVBAマクロが入ったファイルは実行する事ができ、その場所へ移動した時点でMOTW属性は解除されます。

信頼できる場所の追加手順は以下の通り。

  1. ファイル⇒オプション⇒トラストセンター⇒トラストセンターの設定を開く
  2. 信頼できる場所をクリックし、「新しい場所の追加」をクリック
  3. この場所のサブフォルダーも信頼するをチェック入れてOKすると、サブフォルダ以下全てが対象になります。

但し、不便だからといってなんでもかんでも、信頼できる場所へ登録したり、デスクトップがダウンロード場所として指定してるからといって、デスクトップを信頼できる場所として追加してしまうと、今回のMicrosoftの措置が無意味となってしまい、マクロウイルスに感染する可能性が増大します。

図:但しこの運用は慎重を要します

対象のVBAファイルに証明書を付ける

自己署名デジタル証明書

現在のmacOSやWindowsでは、多くのアプリケーションの実行に際して「デジタル証明書」がついていないアプリの実行を阻止する機能が搭載されていたりします。Excel VBAでもこのデジタル証明書を付けてあり、且つそのPCに対象の証明書がインストール済みの場合には、マクロの実行を許可するという仕組みが元から備わっています。このデジタル証明書は、SELFCERT.EXEにて付与することは可能ですが、本来はデジタル証明書は有償で入手する必要があるものなので、開発者も利用者もひと手間が必要となり、一般的なサイトで配布するには向いていません(社内配布ならば出来なくもないですが)- 年間数万円はちょっと手が出ない。

オレオレ証明書」を付ける事も可能ですが、その場合そのPC内の自分のアカウントでだけ有効になるので、第三者利用では利用不可。さらに言えばそのPC内でしか有効じゃない為、外部に持ち出すこと出来ない。

自己署名デジタル証明書を作成する手順は以下の通り

  1. C:\Program Files\Microsoft Office\root\Office16のフォルダ内にある「SELFCERT.EXE」を起動する(存在しない場合があります)
  2. デジタル証明書の作成画面が開くので、適当な名前を追加する
  3. OKを押すと作成完了

続いて、デジタル証明書をVBAを含んだファイルに適用する手順は以下の通り

  1. xlsmファイルを開く
  2. 開発タブ⇒Visual Basicを開く
  3. ツール⇒デジタル証明書を開く
  4. 選択をクリック
  5. Windowsセキュリティが開かれるので、「その他」をクリックする
  6. 前項で作ったデジタル証明書等が出てくるので、選んでOKをクリックすると付与される

なお、作成した証明書は、ファイル名を指定して実行⇒certmgr.mscを実行すると、「個人」の中に「コード署名」として確認出来る。この証明書をエクスポートしても、他のコンピュータに取り込んで使うことは出来ません(よって動きません。2003くらいまでは、証明書をインストールで行けたようなのですが)。

証明書付きのプロジェクトを変更すると、証明書が破棄されて再度付与が必要です

※また、マクロの実行に関して「デジタル署名されたマクロを除き、すべてのマクロを無効にする」の設定の場合、動作するようになります。

図:証明書作成プログラムの場所

図:この証明書の有効範囲は限定的

図:デジタル証明書付与画面

図:証明書の実体

PowerShellで証明書を作成

前述の方法の場合、そのPCそのアカウントでなければ証明書が有効にならないので、他人に使ってもらうことが不可能です。しかし、PowerShellにて自己署名デジタル証明書を作成した場合は、証明書をエクスポートし、相手方にインポートして貰えれば、対象のデジタル署名をしたVBAの含まれたブックが実行可能になります。社内配布で他の人に証明書付きで使ってもらう場合はこちらの方法が良いのではないかと思います。

以下の手順でデジタル証明書を作成します。

  1. Powershellを管理者権限で実行する
  2. 以下のコマンドを入力して、実行すると証明書が作成される(下の事例だと5年有効の証明書が出来る)
  3. Excel VBAに上記2.で作成された証明書が出てくるので、署名をして保存する
  4. certmgr.mscを実行する
  5. 個人⇒証明書の中に生成されてるので、これを右クリック⇒すべてのタスク⇒エクスポートを実行
  6. 次へすすんで、秘密鍵はエクスポートをしないを選んで次に進む
  7. DER Encoded Binary X.509を選択して、次へ
  8. パスとファイル名を指定して次に進む
  9. 完了すると証明書ファイルがエクスポートされる
  10. 別のマシンに於いて、9.のファイルをダブルクリックする
  11. 証明書のインストールをクリックする
  12. 現在のユーザを選んで次に進む
  13. 証明書をすべて次のストアに配置するを選び、参照では信頼されたルート証明機関を選択する
  14. 次へをクリックすると、初回は警告画面が出るのでそれに従いインストールを進める
  15. これで、3.のファイルを別のマシンに於いて実行すると、証明書が存在するのでVBAが実行出来るようになる。

ちなみに、このエクスポートした証明書は秘密鍵は含めていないので、別のマシンに於いてこれを流用して別のファイルに署名を付けるといった事は出来ません

また、他のマシンで作成した秘密鍵入のファイルは、パスワードを付けて暗号化の上で、「PFXファイル」としてエクスポート可能です。署名をしたいマシンに持ち込み、インポートをする場合、「証明書ストア」は「個人 – 証明書」にインポートする事で署名する事が可能になります。

図:証明書のエクスポート画面

図:証明書のインポート画面

図:インポート時の警告画面

OpenSSLで証明書を作成

前述のPowerShellで簡単に秘密鍵と公開鍵による証明書は作成できてしまうのでアレなんですが、OpenSSLでも自己署名証明書を作成する事が可能です。以下の手順でOpenSSLをインストールし、作成します。

  1. Win64 OpenSSL v3.0.2 Lightをダウンロードし、インストールする
  2. VC++2019再頒布パッケージをダウンロードしてインストール。
  3. インストールが完了したら、設定アプリ⇒システム⇒バージョン表示を開く
  4. システムの詳細設定を開く
  5. 詳細設定の中にある環境変数を開く
  6. ユーザ環境設定のPathを選んで、編集をクリック
  7. 新規をクリックして、パスは「C:\Program Files\OpenSSL-Win64\bin」を入れてOK。そして閉じる
  8. 一旦OSを再起動する
  9. コマンドプロンプトを開く
  10. 以下のコマンドを入力して、ドキュメント直下にsslフォルダを作って移動する
  11. sslフォルダに移動したら、以下のコマンドを入力して証明書を作成する
  12. 途中色々、証明書に記載する内容を問われますが、Common Nameの所だけを適当に入力してEnterで進める
  13. 以下のコマンドを入力して、5年有効の証明書を作成する

    1825は、5年 * 365日の日数です。
  14. 以下のコマンドを入力して、証明書をsslフォルダに生成する
  15. 作成されたserver.pfxが秘密鍵と公開鍵をパックしたもので、大切に保管する。インポートする場合は個人の所へ。
  16. 作成されたserver.crtが公開鍵の証明書。これは配布する用で、インポートする場合は信頼されたルート証明機関へ。
  17. あとはExcel上でデジタル署名として署名をするだけ

ただ色々インストールの手間がある為、こちらはお手軽とは言えないですが、細かく色々指定ができます。

図:環境変数に手動でコマンドのパスを登録する必要がある

図:10年先の期限という証明書も作れる

信頼されたドキュメント

今回の措置前に既にそのPCで実行し、「コンテンツの有効化」をクリックしていた場合、そのファイルは「信頼されたドキュメント」として登録されている為、今回の措置が発動しません。トラストセンターからそのクリアをすることは可能ですが全部クリアされてしまいます。

個別にファイルを信頼したり、信頼対象から除外が出来ませんのでご注意を。この場合、マクロの実行に関する設定が「無効」となっている場合は、開いても実行されることはありません。これは、信頼された場所に移動したファイルにも適用されます。

図:この画面からクリア出来る

OneDriveやSharepointから開く場合

ファイルをローカルPCではなく、OneDriveやSharepointにダウンロードした場合には、インターネットオプションのインターネットセキュリティゾーンの設定次第となります。但しOneDriveやSharepointにアップされてるファイルを「デスクトップアプリで開く」とした場合には、MOTW属性がついていないので、通常のマクロセキュリティによる判定となる。また、前述の通り信頼できる場所にダウンロードした場合は、実行出来てしまうので注意が必要です。

図:セキュリティゾーンの設定

推奨される運用方法

運用方法概要

今回の措置は主眼はメールやウェブにアップされてる出どころ不明の謎のファイルを開いたが為に、感染するといったようなことを阻止する為の関門が1個増やしたというものなので、社内で開発し、社内で使用するようなファイルに限って、VBAやマクロの実行を許可する場合は

  1. 信頼できる場所を極めて限定的なフォルダを作成して、そのパスを追加するようにする
  2. アドインやマクロ入りブックなどはそこに配置してから利用するようにする(これで信頼されたドキュメントとなる)
  3. マクロセキュリティは「デジタル署名されたマクロを除き、すべてのマクロを無効にする」として、不要なユーザは完全無効にしておき、信頼できる場所の設定を追加しない
  4. スポットで使う人は、3.の信頼できる場所を設定せず、都度ブロック解除するか?デジタル署名での運用を行う(個人的にはこの方法が一番良いと思います)
  5. また、VBAプロジェクトは変更出来ないようにロックを掛けておく作業もしておきましょう

信頼できる場所にファイルを入れるとマクロセキュリティが「無効」であっても、そのフォルダ内ではVBAやマクロが確認ナシで実行出来てしまうようになるのでデジタル署名も、マクロセキュリティも意味がなくなってしまいます。

図:証明書の無いPCでは署名があっても実行不可

マクロセキュリティ設定

前述のマクロセキュリティ設定についてですが、各個人でやってもらうというのはちょっと面倒です。この設定はレジストリに存在するので、コマンドライン等から一括で変更を掛けてあげる事が可能です。

VBAWarningsの値を3にすることで、「デジタル署名されたマクロを除き、すべてのマクロを無効にする」となるので、起動スクリプトなどでBATファイルに記述して実行するように仕掛けておくと良いでしょう。但しこの方法だとユーザが設定を変更出来てしまうので、それを阻止する場合には、こちらのサイトを参考に、管理テンプレートを追加してgpedit.mscからVBAのセキュリティポリシーを制御出来るようです(但し、Active Directoryが必要)

図:レジストリから操作する

一律でマクロセキュリティを変更するレジストリエントリ

Office2016以降のWord, Excel, PowerPoint, Accessのマクロセキュリティを「デジタル署名されたマクロを除き、すべてのマクロを無効にする」に変更するレジストリエントリは以下の通り。テキストファイルに記述して、regファイルとして保存し、ダブルクリックすれば一括してマクロセキュリティを変更する事が可能です。

Accessにデジタル署名を付ける?

署名を付ける手順

Excel等は前述の通り、Visual Basicの画面上から署名を選んで付けるだけでOKです。しかし、Accessの場合は同じ手順で署名をつけようとすると以下の図のような「デジタル署名を保存できません」エラーが出て証明書を付けることが出来ません。

Accessの場合は以下の手順でパッケージ化して署名を利用します。但しこれは期待している動作ではありません。

  1. 署名したいaccdbファイルを開く
  2. ファイル⇒名前をつけて保存⇒パッケージ化と署名をダブルクリックする
  3. 証明書選択画面となるので、「その他」をクリックして、証明書を選び、OKをクリックする
  4. 保存画面で、署名済みパッケージであるaccdcファイルとして保存する

これでとりあえず署名は完了しました。

図:同じ手法では署名が出来ない

図:パッケージ化と署名から行う

ACCDCファイルを実行してみる

作成したaccdcファイルはAccessのプログラム実行本体ではありません。よって、これを実行したからと言っていつものAccessの画面が出るわけではありません。実行してみると、「データベースの抽出」という画面が出てきて保存場所を指定する画面が出てきます。

保存場所を指定して抽出するとプログラム本体のaccdbファイルが取り出されます。しかしこのaccdbは署名が出来なかったハズ

実はこの署名はパッケージに対して付ける署名であって、抽出したaccdbには一切署名がついていない上に実行すると、VBAの実行は阻害されます。結論から言えば「Accessのファイルにはデジタル署名が付けられないので、信頼できる場所を追加しそこでのみ実行するようにするしかない」という事です。

故にAccessを社内配布するようなケースでは、ユーザに信頼できる場所を手動で追加するか?VBS等を別途用意して対象のフォルダを信頼できる場所に追加するようにし、インストーラにてインストール後にそのVBSを実行するように仕組みを用意する必要があります。

信頼できる場所を追加するVBS

前述の通り、Accessデータベースは「署名」をすることが出来ません。しかし、VBAの措置として署名してるVBA以外実行させないという方針なので、信頼できる場所を個別に指定が必要。けれどこれを手動でやらせるというのは考えもの。ということで、以下のような仕組みを構築します

  1. インストーラを使いインストール後にVBSを実行させるようにする
  2. インストーラにはaccdbファイルとvbsファイルを同梱する
  3. インストール先は今回はドキュメントフォルダ直下の「appname」というフォルダに固定する
  4. VBSのコードは以下のようなものを利用する
  5. Accessの信頼できる場所にユーザ名\ドキュメント\appnameで登録される

また、インストーラにレジストリエントリを操作出来、且つユーザが選んだインストール先を取得できるような機能があれば、それを利用しても良いでしょう。上記のentryにもあるように、Trusted Location以下に1つロケーションのキーを追加し、その中にRegWriteにて各エントリーを追加するようにするだけです。

図:レジストリエントリーの場所と内容

図:無事に追加されました

図:EXEPressを使ったインストーラの事例

Inno Setupの事例

自分は普段からインストーラには「Inno Setup」を利用しています。このインストーラはオープンソースながら非常に高機能でレジストリの操作も可能です。インストール先の取得も可能ですので、これをもってしてインストールスクリプトを構築する事例を紹介します。Inno Setupについては過去に以下のエントリーでも書いています。

スクリプトに以下の行を追加すると、インストール後にレジストリ操作が行われ前述と同じエントリーが追加されます。ValueTypeに於いて、stringがREG_SZ、dwordがREG_DWORDとなります。

このインストーラにaccdbのファイル含めて、{app}に該当するフォルダが信頼できる場所として追加される為、ユーザが選んだ場所が追加されることになります。もちろん、インストール先固定の場合には、DefaultDirNameでパスを指定しておき(例:{userdocs}\appname)、DisableDirPageをyesにしておけば固定のインストール先となります。

Windows10 SDKが入っているならば、今回作成した秘密鍵の証明書であるPFXファイルをもって、Configure Sign Toolsより設定してインストーラに証明書で署名をすると尚良いでしょう。

自分がよくつかってるインストーラの使い方

関連リンク

共有してみる:

コメントを残す

メールアドレスが公開されることはありません。

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください