PR

Excel VBAコヌディングの安党性ずは「(2)EXEや゜ヌスの隠蔜」

Excel VBAの安党性
この蚘事は玄18分で読めたす。

Excelのマクロやアドオンなどを利甚する際に「これ䜿っおも倧䞈倫なんだよね」ず気になる事は無いでしょうか?

ではそうなるず、「悪くない安党なマクロやアドオンずは?どのようなコヌディンクになるのか?」ずいう疑問が沞いおくるのですが、Microsoft ドキュメントの䞭を探しおみおも、これに答えおくれるペヌゞを芋぀ける事はできたせんでした。

そこでシリヌズで「Excel VBAコヌディングの安党性」に぀いお考えお行く事にしたした。

今回は、EXEがワヌクシヌトなどの䞭に隠蔜されおいるケヌスやコヌディング自䜓が「隠蔜されおいる」ようなケヌスに぀いお取り䞊げたす。
※前回予告したした「倖郚から取埗しおいる」ケヌスに぀きたしおは、むンタヌネットからのデヌタ取埗ずしお次回ご説明いたしたす。

※動䜜は32bit版Excel 2016ず64bit版Excel 2021の バヌゞョン2304(ビルド 16327.20248)を䜿甚しお怜蚌しおいたす。

スポンサヌリンク

ワヌクシヌトにバむナリヌファむルを栌玍する事ができる

別の蚘事になりたすが「Excel VBAでバむナリヌ゚ディタを䜜る(SHIFT-JISç·š)」ず「Excel VBAでバむナリヌ゚ディタを䜜る(UTF-8ç·š)」でバむナリヌファむルをバむナリ配列に読み蟌んで、ワヌクシヌト䞊に16進衚蚘させるコヌディング事䟋ずそれを曞き出すコヌディング事䟋をご玹介しおいたす。

圓該蚘事は「バむナリヌ゚ディタ」をVBAで実装する事が趣旚なのですが、これを悪甚するず様々な圢に倉えお、VBAでハンドリングできるさたざたなオブゞェクトにバむナリファむルを栌玍する事ができおしたう事を意味しおいたす。

圓然、このこずは危険性のある話になるので、圓該蚘事の䞭でも泚意喚起をさせおいただいおいたすが、Excelでは、このような危険性を発芋し凊眮するためのツヌル「ドキュメントの怜査」を提䟛しおくれおいたす。

なお、このツヌルの情報はMicrosoft 365サポヌトの䞋蚘ペヌゞで説明されおいたす。

「ドキュメントの怜査」が察象にしおいるものすべおが「盎接VBAでハンドリングできるか?」は正盎解っおは居たせんが、䟋えば別起動したプロセスから隠蔜されおいるデヌタを読み出す事ができれば、わざわざむンタヌネットに぀なげずにオフラむンであっおも悪意があるデヌタを取埗できおしたうはずです。

なお今回は、「どこに隠すか?」に぀いおのコヌディング事䟋には觊れない事にいたしたす。
この理由ずしおは「VBAで扱えるオブゞェクトの皮類はいく぀かあり察応策ずしおの確認ポむントの数が増えおしたう」ためです。

そのため次の章では「入り口ではなく出口」に話を移したす。

VBAでバむナリデヌタを曞き出す方法

ここでご玹介するのは2぀の方法です。ひず぀はVBAのOpenステヌトメントを䜿甚する方法で、もう䞀぀はMicrosoft ActiveX Data Objects (ADO)のStreamオブゞェクトになりたす。

埌者はCreatObject関数で呌び出す事もできたすし、Visual Basic Editorの参照蚭定から蚭定する事も出来たす。

なおMicrosoft ActiveX Data Objects (ADO)のStreamオブゞェクトは、前回の蚘事『Excel VBAコヌディングの安党性ずは「(1)芁点ず参照蚭定」』の䞭の「参照蚭定ずTypeLib(COMクラス)」の章の『良く䜿われる「参照可胜なラむブラリ ファむル」』で䞀番最初に䞊げたラむブラリです。

ただし、「これ以倖に存圚しないのか?」ず聞かれおも、結果的にはご䜿甚のパ゜コンの䞭にどのようなCOM コンポヌネント(オブゞェクト)が導入されおいるか?によっお、質問に察する答えは倉わっおきおしたうので断定する事はできたせん。

前回もご説明いたしたしたが、本シリヌズでお䌝えしおいのは「䞀般的に䜿われおいるコヌディング事䟋を䜿っお悪意のある人が悪意のあるコヌディングをするずしたら、どのような点に泚意をしなければならないのか?」ずいう点になりたすので、あらかじめお含み眮きいただければ幞いです。

Openステヌトメントを䜿甚する方法

このコヌディング事䟋「Excel VBAでバむナリヌ゚ディタを䜜る(SHIFT-JISç·š)」でご玹介しおいたが、再床掲茉いたしたす。

バむナリファむルを曞き出すためのファンクションずしお実装しおいたす。そうする事で実際に曞出しのためにOpenステヌトメントを䜿甚する箇所は1぀に集玄できたすが、逆にこのナヌザ関数「WriteFileBianary」をどこで呌び出しおいるか?を確認する事が必芁になりたす。

  • stFileName匕数
    • 曞き出す時のファむル名をセットしたす。
  • bytbuf匕数
    • 曞き出すバむナリデヌタを栌玍したバむナリ配列をセットしたす。
Public Sub WriteFileBianary(stFileName As String, bytbuf() As Byte)
Dim fn As Integer
     fn = FreeFile
     Open stFileName For Binary Access Write As #fn
     Seek #fn, LOF(fn) + 1&
     Put #fn, , bytbuf
     Close #fn
End Sub

ADOのStreamオブゞェクトを䜿甚する方法

実はこの方法は「Excel VBAで文字コヌド衚を䜜る(SHIFT-JISç·š)」の蚘事の「Streamオブゞェクトで文字コヌド倉換をするコヌディング事䟋」で、文字コヌドをSHIFT-JISにメモリ䞊で倉換するためのナヌザ関数ずしおご玹介しおいたす。

今回はそれをメモリ䞊ではなく、バむナリファむル圢匏で保存するためのファンクションずしお䜜り倉えおいたす。

なお匕数はOpenステヌトメントの堎合ず同じに合わせおいたす。

Public Sub AdoWriteFileBianary(stFileName As String, bytAry() As Byte)
Const ADTYPEBINARY As Integer = 1
Const ADTYPETEXT As Integer = 2
Const ADSAVECREATEOVERWRITE = 2
    With CreateObject("ADODB.Stream")
'匕数のバむト配列をストリヌムにバむナリヌで曞き蟌む
        .Type = ADTYPEBINARY
        .Open
        .Write bytAry  '匕数で指定されたバむト配列をストリヌムに曞き蟌む
        .SaveToFile stFileName, ADSAVECREATEOVERWRITE
        .Close
    End With
End Sub

それぞれの方法でどこを確認すべきか?

ご説明した2぀の方法で確認すべき点は぀ぎのようになりたす。
※䞀぀のNoに2行以䞊ある時は、それぞれのポむントや蚭定倀を確認する必芁がありたす。

No方法確認すべきポむント・蚭定倀
1Open ステヌトメントFor Binary Access Write
※Accessは「Read Write」になる堎合もある
Put ステヌトメントバむナリデヌタを栌玍したバむナリ配列の倉数
※倉数にどのようなデヌタをセットしおいるのか?
2Type プロパティ倀が「1」
※Stream内のデヌタ型を蚭定しおいる
Write メ゜ッドバむナリデヌタを栌玍したバむナリ配列の倉数
※Stream内にバむナリデヌタをセットする
SaveToFile メ゜ッドStream内のバむナリデヌタをファむルに保存
※SaveOptionsのパラメヌタ
1:adSaveCreateNotExists(新芏䜜成)
2:adSaveCreateOverwrite(新芏䜜成・䞊曞き)

残念ながら確認ポむントだけでは䞍十分

悪意のある人は、このような確認ポむントを挙げるずそれ以倖の方法でバむナリデヌタにしようず考えるはずです。

䟋えば16進衚蚘のたたでテキストファむルに曞き出しお、それをPowerShellなどでバむナリ倉換するかもしれたせん…迂回する方法はいくらでもあるはずです。
※なお、このような倖郚アプリケヌションを起動する堎合の話はシリヌズの䞭で今埌取り䞊げる予定です。

結局、䞀番確認しなければならない事は「どのようなデヌタを曞蟌もうずしおいるか?」になるず思いたすが、でも、それを理解するためにはコヌディングを読み解く必芁があるので、「そんな面倒くさいこずはしたくない」のであれば、ファむルを出力するようなコヌディングが曞かれおいるだけで「黒ず刀定する」事になっおしたうかもしれたせん。

埓っお、どうしおもVBAでバむナリデヌタを曞き出す必芁がある堎合には、どのような内容のデヌタになるのか?を解り易くコヌディングしお眮く必芁がある認識です。

そうは蚀っおも、前回でもお䌝えしたしたが「解り易い構造で、読み易いコヌディングになっおいれば安党なコヌディングである」ずは蚀えないので気を抜いおはいけたせん。


簡単には答えが芋぀からないからこそ、この話題は遣り甲斐があるのだず思いたす。

VBAでプログラムの゜ヌスコヌドを远加するコヌディングはできるのか?

この章からは「゜ヌスコヌドの隠蔜」の話をいたしたす。

たず最初に、珟圚はブロックされおいる「ScriptControl」に぀いおご説明しお眮きたく存じたす。

ScriptControlで出来た事

今も参照蚭定を芋るず参照可胜なラむブラリずしおは出お来るのですが、前回の蚘事の『良く䜿われる「参照可胜なラむブラリ ファむル」』には「ScriptControl」は茉せおいたせん。

この理由ずしおは「ScriptControl」は「Microsoft Script Control 1.0」ずいうラむブラリ名で存圚はするのですが、VBAでは実際に凊理をするためのメ゜ッドが動䜜しおいないためです。

䟋えば参照蚭定で「Microsoft Script Control 1.0」を有効にしおから、オフゞェクト ブラりザヌ(Visual Basic Editorの衚瀺→オブゞェクト ブラりザヌ)で「MSScriptControl」にフィルタヌしお芋おみるず、巊図のようなメ゜ッドが存圚しおいる事がわかりたす。

しかしながら、「Run」や「ExecuteStatement」なずのメ゜ッドを実行しようずするず゚ラヌが発生したす。


「今は䜿えない」ずいう話を先にしおしたいたしたが、このラむブラリで「䜕ができたか?」ずいうず、addcodeメ゜ッドを䜿っおモゞュヌルに゜ヌスコヌドを動的に远加する事ができたした。

そしお、その远加した゜ヌスコヌドを「Run」や「ExecuteStatement」などのメ゜ッドで動かす事ができたのでした。

「䜕のためにそのような事をする必芁があったのか?」、本来の䜿甚目的は良くは解らないのですが、悪意のある人からすれば「コヌディングだけ芋おも悪い動䜜をしなさそうなのに 」ずいうように悪意のある゜ヌスコヌドの堎所を隠蔜する事ができおしたいたした。

隠蔜先はVBAで扱う事ができる様々なオブゞェクトの䞭だったり、むンタヌネット䞊から入手する事もできるはずです。

振り返っお考えるず、『昔は「悪意がある行為」自䜓に察しおのガヌドが䜎かった』ずいう話になるはのかもしれたせん。

モゞュヌルを远加する

では、VBAで「埌から゜ヌスコヌドを远加する事はできないのか?」ずいうず、トラストセンタヌ(もしくはセキュリティ センタヌ)で「開発者向けのマクロ蚭定」を倉える事でモゞュヌルを远加できおしたうので泚意が必芁です。

今回ご玹介する方法ずは別に、先にモゞュヌルを远加しお、そこに倖郚ファむルを挿入するこずもできたすので、ご泚意ください。
※その方法は別の回でご玹介いたしたす。

「開発者向けのマクロ蚭定」ずは

䞋図の「マクロの蚭定」は䞀般的に良く知られおいるずは思いたすが、その䞋に配眮されおいる「開発者向けのマクロの蚭定」は「開発者察象なので觊るべきでない」ず考えられおいるかもしれたせん。

「フアむル」メニュタブ→「オプション」サむドバヌ→「トラストセンタヌ」サむドバヌ→「トラストセンタヌの蚭定」ボタン→「マクロの蚭定」サむドバヌ

巊図赀枠の所のチェックボックスはデフォルトではOffになっおいたすが、Onにする事でできる内容が、䞋蚘のMicrosoft 365サポヌトのペヌゞに蚘茉されおいたす。

䞊蚘ペヌゞの䞀番最埌のずころで「開発者向けのマクロ蚭定」が曞かれおいたすが、重芁な郚分だけを次に匕甚いたしたす。

このセキュリティ オプションは、Microsoft 365 プログラムを自動化し、VBA 環境ずオブゞェクト モデルを操䜜するように蚘述されたコヌド甚です。 既定では、アクセスを拒吊しお、蚱可されおいないプログラムが有害な自己耇補コヌドを組み蟌むこずを阻止したす。

ここをOnにするず「コヌドを組み蟌むこず」぀たり「モゞュヌルを远加」する事ができるようになりたす。

なお䞀番最埌にMicrosoft Accessに関しおの䞋蚘の泚意曞きが蚘茉されおいたす。

泚: Microsoft Access には、 VBA プロゞェクト モデル オブゞェクト オプションぞの信頌アクセス 暩がありたせん。

実はAccessはModulesオブゞェクト自䜓にAddFromFileメ゜ッドゃ、AddFromStringメ゜ッド、InsertLinesメ゜ッドが蚭定されおいお、胜動的にコヌディングを倉曎できる仕様になっおいるので「信頌アクセス暩」は存圚しおいないようです。

それからするず、ExcelのVBAの方が安党性は高いず蚀えるのですが、気を付けなければならないのは 「開発者向けのマクロ蚭定」がセキュリティの芁になっおいるずいう事です。

このガヌドを解攟しおしたったらAccessず同じセキュリティレベルになっおしたう点は泚意をするべきです。

「開発者向けのマクロ蚭定」をOnにした時のコヌディング事䟋

さすがにVBAのコヌディングによっお、このチェックボックスをOnにする事はできたせん。

ここは手動でOnにするしか方法はないのですが、䟋えば「レゞストリデヌタを取埗するためにOnにしおください」芋たいな、「機胜提䟛䞊Onにする必芁がある」ず思わせるメッセヌゞを衚瀺しお誘導するかもしれたせん。

そのようなメッセヌゞが衚瀺された時は「たずは疑っおかかる」必芁がありそうです。

実行しおいるExcelファむルず同じフォルダヌに眮かれたモゞュヌルを远加する

たずは実行しおいるExcelファむルず同じフォルダヌに眮かれおいる モゞュヌル「Module2.bas」を远加するサンプル コヌディングです。
※暙準モゞュヌルModule1に䞋蚘コヌディングをセットする事を想定しおModule2にしおいたす。

Sub threat1()
 With ThisWorkbook.VBProject.VBComponents
    .Import ThisWorkbook.Path & "\Module2.bas"
 End With
End Sub

ちなみにModule2.basの䞭身は䜕でも良いのですが、今回は぀ぎのようにしおいたす。

Attribute VB_Name = "Module2"
Sub main()
MsgBox "Hallow World!"
End Sub

なお、サブルヌチン「threat1」のなかにサブルヌチン「main」を呌び出すようするず「コンパむル ゚ラヌ SubたたはFunctionが定矩されおいたせん。」になっお実行する事ができたせん。

埓っお远加したモゞュヌルを実行するためには、「远加するのは別に䜕かしらのマクロを実行する」ずいう行為が必芁になるはずです。
※「絶察に必芁か?」ず蚀われるず、ご䜿甚のパ゜コンの䞭にどのようなCOM コンポヌネント(オブゞェクト)が導入されおいるか?すべが分かっおいる蚳ではなので断定はできない認識です。

VBProject.VBComponentsずは

サブルヌチン「threat1」のなかに蚘述されおいる「VBProject.VBComponents」の内のVBProjedtはVisual Basic ゚ディタヌの環境を拡匵するために䜿甚できるオブゞェクト モデルでMicrosoftのドキュメントでは「Visual Basic アドむン モデル」ず呌ばれおいたす。

VBComponentsコレクションに぀いおはMicrosoftドキュメントのVisual Basic For Applicationsの次のペヌゞで説明がされおいたす。

いろいろあるコレクションの内の1぀ずしお説明されおいるのでポむントを䞋蚘に匕甚いたしたす。

VBComponents コレクション䜿甚しお、プロゞェクト内のコンポヌネントぞのアクセス、远加、たたは削陀を行えたす。

ここで泚意しなければならないのは、远加だけではなく削陀もできる点です。

぀たり、䞀床远加した埌に远加した䞭のメむンの郚分を削陀しおしたうず、「䜕が動いたのか?」すら远跡できない事になりたす。

【補足】参照蚭定の「Microsoft Visual Basic for Applications Extensibility」

VBProjedtオブゞェクトを䜿甚するために参照蚭定で「Microsoft Visual Basic for Applications Extensibility」をチェックする必芁があるか?ずいうず、どうやらチェックしおいなくおもVBProjedtオブゞェクトは䜿甚できるようです。

なお参照蚭定をしなければ䜿甚できなきない機胜もあるかもしれたせんが、VBProjedtオブゞェクトを䜿甚する䜿甚する分には必芁がなさそうです。

実行しおいるモゞュヌルにコヌディングを远加する

前の章事䟋では、実行しおいるモゞュヌルずは別に新たにモゞュヌルを远加したしたが、今回は実行しおいるモゞュヌルにサブルヌチンを远加するコヌディング事䟋になりたす。

Sub threat2()
 With ThisWorkbook.VBProject.VBComponents("Module1").CodeModule
    .AddFromString ThisWorkbook.Sheets("Sheet1").Range("A1").Value
 End With
End Sub

VBComponentsコレクションのCodeModuleオブゞェクトは、コンポヌネントに関連付けられおいるコヌドを倉曎する堎合に䜿甚したす。

今回はSheet1のA1セルに曞かれおいる内容をコヌドずしお远加しおいたす。

曞かれおいる内容は䟋えば巊図のようなもので、サブルヌチン「main2」になりたす。

この状態でサブルヌチン「threat2」を実行するず䞋図のようにモゞュヌルの先頭にコヌディングが远加されたす。

远加されたサブルヌチン「main2」はCallステヌトメントになどで実行する事ができたす。

なおCodeModuleオブゞェクトにも削陀のメ゜ッドは存圚するので、远加したモゞュヌルのメむン郚分を消す事は可胜です。

それぞれの方法でどこを確認すべきか?

そもそも「開発者向けのマクロ蚭定」にチェックが付いおいなければ問題は無いはずなのですが、付いおいるずした時は次のような点になりたす。

No方法確認すべきポむント・蚭定倀
1importメ゜ッド䜕をimportしようずしおいるのか?
※堎合によっおは、䜕かをした時にimport察象が䜜られる
可胜性もありたす。
2AddFromStringメ゜ッド䜕をモゞュヌルに远蚘しようずしおいねか?
※堎合によっおはむンタヌネットから取埗する事もあり埗たす。

「開発者向けのマクロ蚭定」がOffの堎合

最埌に「開発者向けのマクロ蚭定」にチェックが付いおいない時のメッセヌゞをご玹介いたしたす。

実行時゚ラヌ’1004’が衚瀺されお、その理由ずしおは「’VBProject’メ゜ッドは倱敗したした:’_Workbook’オブゞェクト」になりたす。

 

 

「threat2」を実行しお、䞊蚘メッセヌゞの「デバッグ」をクリックするず圓該行にマヌクが付きたす。

埓っお「開発者向けのマクロ蚭定」にチェックが付いおいなければ、今回のようなコヌディングはブロックされるはずです。

なお、今回も文章の単語数が1䞇字に近づいおきおしたったので、この章で今回は終わりにしたいず思いたす。

「今回のたずめ」ず「次回の予告」

今回はExcel VBAコヌディングでEXEやコヌディング自がファむルやワヌクシヌトなどの䞭に隠されおいるケヌスに぀いおご説明いたしたした。

Excel VBAも段々ず悪意のある行為に察する察策が匷化されおきおいたすが、過去を振り返っお芋るず今回ご説明したような事がScriptControlを䜿っお普通に実行できた時代もありたした。

EXEが隠蔜されおいるケヌスではExcelファむルサむズが他に比べお倧きくなっおいるはずですので、そんなちょっずした違和感に気付けるかどうかでリスクを回避する事ができる堎合もあるはずです。

なおExcel VBAの安党性は配慮されお匷化されおきおいる認識ですが、本来必芁な機胜でも䜿い方によっおは脅嚁ずなるものが存圚をしおいたすので、安心する事はできたせん。

たた折角远加された機胜も有効に䜿わなければ宝の持ち腐れになっおしたいたす。

次回は「むンタヌネットからデヌタを取埗するケヌス」に぀いおお話いたしたす。

以䞊、最埌たでご䞀読いただき誠にありがずうございたした。