VBAにロック機能があること自体最近まで知りませんでしたが、果たして本当にコードの閲覧を防げるのか、検証してみたいと思います。
概要
VBAには「プロジェクトをロック」という機能が付いており、コードの表示にパスワード入力を要求できます。
パスワード設定されたファイルでもマクロの実行はできますが、Visual Basic Editor(VBE)でのコードの閲覧にはパスワード入力が必要になります。
ソースコードを隠しながら実行可能なファイルを配布できるというわけです。
環境
- Windows 10 Home
10.0.17134
- Excel 2010
14.0.7214.5000
- Python
3.7.0
macOSでもロックができるとサポートページには書いてあるのですが、私のExcel for MacではそもそもVBEに「ツール」メニューが出現しないので諦めました
※ Excel for Macのバージョンが古いだけでした
プロジェクトをロックする
検証のためシンプルなマクロ入りファイルを作成します。
VBEを立ち上げ、MsgBox
を出すだけの関数を書いてみます。
プロジェクトを右クリックして「VBAProjectのプロパティ」を開きます。
「保護」タブで「プロジェクトを表示用にロックする」にチェックし、パスワードを入力するとロックが掛かります。
ブックを開き直してプロジェクトを見ようとすると、パスワードを要求されました。
ロックされたファイルの中身を見てみる
ロック状態の.xlsm
ファイルでは、ソースコードは暗号化されているのでしょうか?
XML形式のOfficeファイルの実態はZIPファイルなので、拡張子をリネームして中を見てみます。
"xl/vbaProject.bin"
にVBAのコードが入っていそうなので、バイナリエディタのStirlingで見てみましょう。
関数名のHiddenSourceTest
を検索します。普通に平文ですね。MsgBoxを呼び出しているらしいのも分かります。
ロックされたソースコードを取り出す
平文で保存されていることがわかったので、特に工夫せずに抽出ができるはずです。
ツールがないかググってみると、oletoolsというPythonツール群のolevba
がコードの抽出をしてくれるようです。
早速インストールして使ってみます。Python3の場合はolevba3
を使う必要があるようです。
$ pip install oletools
$ olevba3 HiddenSourceTest.xlsm -c
olevba3 0.53.1 - http://decalage.info/python/oletools
Flags Filename
----------- -----------------------------------------------------------------
OpX:M-S-H--- HiddenSourceTest.xlsm
===============================================================================
FILE: HiddenSourceTest.xlsm
Type: OpenXML
-------------------------------------------------------------------------------
VBA MACRO ThisWorkbook.cls
in file: xl/vbaProject.bin - OLE stream: 'VBA/ThisWorkbook'
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(empty macro)
-------------------------------------------------------------------------------
VBA MACRO Sheet1.cls
in file: xl/vbaProject.bin - OLE stream: 'VBA/Sheet1'
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Sub HiddenSourceTest()
MsgBox "\x82\xb1\x82̃\\x81[\x83X\x83R\x81[\x83h\x82\xf0\x8c\xa9\x82Ă͂\xa2\x82\xaf\x82܂\xb9\x82\xf1"
End Sub
無事ソースコードを取り出せましたが、SHIFT-JISな部分は読めません。olevba
はUTF-8でエラーになる文字をバックスラッシュでエスケープするようなので、こちらの記事を参考にsjisに戻します。
$ olevba3 HiddenSourceTest.xlsm -c > result.txt
$ python
>>> f = open('result.txt')
>>> print(f.read().encode().decode('unicode_escape').encode('raw_unicode_escape').decode('sjis'))
# (筆者注:上と同じなので省略)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Sub HiddenSourceTest()
MsgBox "このソx81[スコードを見てはいけません"
End Sub
"ー"
だけ取り残されたものの、無事取り出せました。
まとめ
VBAの「プロジェクトを表示用にロック」機能はVBEからの閲覧を禁止するだけで、コード自体は平文で保存されています。本機能を使ってソースコードを非公開にしたつもりでいても、実際には閲覧されてしまう可能性があるので注意が必要です。
逆に、マクロを使ったウイルスを配布する攻撃者がソースコードを閲覧禁止にしていても、ファイルからその内容を抽出できることも分かります。実際、今回ご紹介したolevba
はマルウェア解析機能を主目的としたツールで、マルウェア解析の現場でも使用されたり、
CTF競技で使用されたりしているようです。