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

VBAにロック機能があること自体最近まで知りませんでしたが、果たして本当にコードの閲覧を防げるのか、検証してみたいと思います。

# 概要

VBAには「**プロジェクトをロック**」という機能が付いており、コードの表示にパスワード入力を要求できます。

- [ソリューションの VBA プロジェクトをロックする(Microsoft Office 2000/Visual Basic プログラマーズ ガイド)](https://msdn.microsoft.com/ja-jp/library/cc376595.aspx)

パスワード設定されたファイルでもマクロの実行はできますが、Visual Basic Editor(VBE)でのコードの閲覧にはパスワード入力が必要になります。
**ソースコードを隠しながら実行可能なファイルを配布できる**というわけです。

# 環境
- Windows 10 Home `10.0.17134`
- Excel 2010 `14.0.7214.5000`
- Python `3.7.0`

~~macOSでもロックができると[サポートページには書いてある](https://support.office.com/ja-jp/article/23b73fb9-0467-46b1-b996-0a3453474881)のですが、私のExcel for MacではそもそもVBEに「ツール」メニューが出現しないので諦めました :sob:~~

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

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

検証のためシンプルなマクロ入りファイルを作成します。
VBEを立ち上げ、`MsgBox`を出すだけの関数を書いてみます。
![source.PNG](https://qiita-image-store.s3.amazonaws.com/0/150557/655b30d2-dde9-f5a3-f208-494f9ee9996e.png)

無事実行されました。
![run.PNG](https://qiita-image-store.s3.amazonaws.com/0/150557/7a6eb687-961f-8cf0-c09a-c581146f0e32.png)

プロジェクトを右クリックして「**VBAProjectのプロパティ**」を開きます。
「**保護**」タブで「プロジェクトを表示用にロックする」にチェックし、パスワードを入力するとロックが掛かります。
![set-lock-password.PNG](https://qiita-image-store.s3.amazonaws.com/0/150557/7feca77a-bcf9-8efb-cf72-0ed737b2325d.png)

ブックを開き直してプロジェクトを見ようとすると、パスワードを要求されました。
![locked-project.PNG](https://qiita-image-store.s3.amazonaws.com/0/150557/38241f8c-c622-72a3-0de5-64fc1585abcb.png)

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

ロック状態の`.xlsm`ファイルでは、ソースコードは暗号化されているのでしょうか？
XML形式のOfficeファイルの実態はZIPファイルなので、拡張子をリネームして中を見てみます。
![xlsm-to-zip.PNG](https://qiita-image-store.s3.amazonaws.com/0/150557/a3409d0c-d64d-7021-e2f1-9f48c666c507.png)

`"xl/vbaProject.bin"`にVBAのコードが入っていそうなので、バイナリエディタの[Stirling](https://www.vector.co.jp/soft/win95/util/se079072.html)で見てみましょう。
<img src="https://qiita-image-store.s3.amazonaws.com/0/150557/af9b994b-c2d0-b5ed-755a-cd19d7998fec.png" alt="vbaProject-bin.PNG" width=500px>

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

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

平文で保存されていることがわかったので、特に工夫せずに抽出ができるはずです。
ツールがないかググってみると、**oletools**というPythonツール群の`olevba`がコードの抽出をしてくれるようです。
- [decalage2/oletools](https://github.com/decalage2/oletools)
- [olevba · decalage2/oletools Wiki](https://github.com/decalage2/oletools/wiki/olevba)

早速インストールして使ってみます。Python3の場合は`olevba3`を使う必要があるようです。

```bash
$ 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に戻します。

- [[Python3] Shift_JISとUTF-8とASCIIを行き来する](https://qiita.com/inoory/items/aafe79384dbfcc0802cf)

```bash
$ 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`は**マルウェア解析機能**を主目的としたツールで、マルウェア解析の現場でも使用されたり、

- [オンライン・バンキングを狙うマルウェア「Dridex」の進化](https://www.fireeye.jp/company/press-releases/2015/evolution-of-dridex.html)
- [防衛関連のファイルを装うマクロマルウェアの新しい手口](http://blog.macnica.net/blog/2017/12/post-8c22.html)

CTF競技で使用されたりしているようです。

- [LabyREnthセキュリティ コンテスト: ドキュメント種目の解答](https://www.paloaltonetworks.jp/company/in-the-news/2016/160820_labyrenth-capture-the-flag-ctf-document-track-solutions)