VBAの「ソースコードをロック」ではソースコードをロックできない

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に「ツール」メニューが出現しないので諦めました :sob:

※ Excel for Macのバージョンが古いだけでした


プロジェクトをロックする

検証のためシンプルなマクロ入りファイルを作成します。

VBEを立ち上げ、MsgBoxを出すだけの関数を書いてみます。

source.PNG

無事実行されました。

run.PNG

プロジェクトを右クリックして「VBAProjectのプロパティ」を開きます。

保護」タブで「プロジェクトを表示用にロックする」にチェックし、パスワードを入力するとロックが掛かります。

set-lock-password.PNG

ブックを開き直してプロジェクトを見ようとすると、パスワードを要求されました。

locked-project.PNG


ロックされたファイルの中身を見てみる

ロック状態の.xlsmファイルでは、ソースコードは暗号化されているのでしょうか?

XML形式のOfficeファイルの実態はZIPファイルなので、拡張子をリネームして中を見てみます。

xlsm-to-zip.PNG

"xl/vbaProject.bin"にVBAのコードが入っていそうなので、バイナリエディタのStirlingで見てみましょう。

vbaProject-bin.PNG

関数名のHiddenSourceTestを検索します。普通に平文ですね。MsgBoxを呼び出しているらしいのも分かります。


ロックされたソースコードを取り出す

平文で保存されていることがわかったので、特に工夫せずに抽出ができるはずです。

ツールがないかググってみると、oletoolsというPythonツール群のolevbaがコードの抽出をしてくれるようです。

- decalage2/oletools

- olevba · decalage2/oletools Wiki

早速インストールして使ってみます。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競技で使用されたりしているようです。