Binary Pulsar

技術寄りなセキュリティの話題について書きます

rundll32.exeを悪用した命令の実行

概要

攻撃者がWindowsシステムへの侵入に成功し、悪意のあるファイルを実行する際に、EXEファイルだと都合が悪いため様々な手法でファイルの実行を試みます。アンチウイルスソフトにファイルが検知されてしまうことはもちろんですが、侵入したWindowsシステムがAppLockerのような「ファイルの実行を制限するソフトウェア」を導入しておりpowershell.exeやcmd.exeなどの実行を制限している場合は、何かしらの手法で制限を回避してコマンドを実行させる必要があります。今回はAppLockerのようなソフトウェアにより制限されている環境で、制限を回避して命令を実行させるために攻撃者が悪用する手法の一つとして、rudll32.exeを悪用した手法を解説します。

rudll32.exeとは

DLLにはEXE形式のファイルに実装するライブラリ関数が含まれており、Windows OSの根幹をなす機能が含まれているものが多く存在します。Windowsで実行されるプログラムは、DLLから必要な機能を取り出した機能を活用して構成されています。しかし、「DLLからほんの一部の機能だけ取り出して実行したい」という場合に、わざわざC#などによりDLLを読み込んで実行するプログラムを書くのは面倒です。そこで活用できるプログラムがrundll32.exeです。rundll32.exeは「DLLに実装されている関数を取り出して実行するための実行ファイル」であり、Windowsシステムに標準実装されています。以下の書式で実行することにより、対象のDLLに実装されている関数を取り出し実行することが可能です。

rundll32.exe [対象のDLL], [実行したい関数名] [関数の引数]

ただし、rundll32.exeでは、DLLに実装されているすべての関数を呼び出せるわけではありません。これについては本題から離れるため、本記事では割愛します。

例えば、user32.dllに実装されているLockWorkStation関数を実行する場合を考えます。LockWorkStation関数はWindowsに実装されている標準的な関数の一つであり、画面をロックする機能を持ちます。LockWorkStation関数は引数を必要としない関数であるため、以下のようにrundll32.exeを実行することで、画面にロックをかけることが可能です。

rundll32.exe user32.dll, LockWorkStation

命令の呼び出し

それでは、攻撃者が実際にどのような手法でrundll32.exeを悪用して、AppLockerなどのソフトウェア実行制限を回避するかを示します。

単純な呼び出し

もっとも単純な例として、悪意のある関数を実装したDLLからそのまま関数を呼び出す手法を示します。

まずはMetasploitの一部であるmsfvenomを用いて、電卓を起動するDLLを作成します。Kali LinuxなどのMetasploitがインストールされているマシンで以下のコマンドを実行します。以下のコマンドでは、電卓を起動する機能を持ったDLLの名前をupcalc.dllとして出力しています。

msfvenom -p windows/exec CMD=calc.exe -a x86 --platform windows -f dll > upcalc.dll

実行例を以下の図に示します。

f:id:binary-pulsar:20181104223939p:plain

DLLを作成したら、Windowsマシンに作成したDLLを配置します。msfvenomにより作成されたDLLは、エントリポイントに機能が実装されているため、以下の書式でrundll32.exeを実行することで電卓を起動することが可能です。

rundll32.exe C:\Users\testuser\Desktop\upcalc.dll, EntryPoint

実行例を以下の図に示します。

f:id:binary-pulsar:20181104224016p:plain

shell32.dllを経由した呼び出し

DLLを直接呼び出すほかにも、Windowsに標準実装されているDLLに実装されている関数を経由して、攻撃者が作成したDLLを呼び出す手法があります。例えば、shell32.dllというWindows標準のDLLには、Control_RunDLLという関数が実装されており、この関数の引数に攻撃者が作成したDLLを設定することで、対象のDLLをエントリポイントから実行させることが可能です。先ほどの例に挙げたupcalc.dllを用いると、以下のようにrundll32.exeを実行することで電卓を起動することが可能です。

rundll32.exe shell32.dll,Control_RunDLL C:\Users\testuser\Desktop\upcalc.dll

実行例を以下の図に示します。

f:id:binary-pulsar:20181104224038p:plain

JavaScriptを経由した呼び出し

rundll32.exeでは、Internet ExplorerのDLLの一つであるmshtml.dllを経由してJavaScriptを実行することが可能です。mshtml.dllにはInternet Explorerの中心となる機能が実装されており、HTMLとCSS構文解析や表示に用いられます。攻撃者はmshtml.dllのRunHTMLApplicationを用いることで、任意のJavaScriptを実行することでプログラムの実行を試みます。

例えば、Windowsマシンでcmd.exeを起動して以下のコマンドを実行します。

rundll32.exe javascript:"\..\mshtml,RunHTMLApplication ";alert('Hack!');

JavaScriptのalert関数が実行され、ポップアップが上がるでしょう。実行例を以下の図に示します。

f:id:binary-pulsar:20181104224054p:plain

mshtml.dllはInternet ExplorerのDLLであるため、こうして実行されたJavaScriptからInternet Explorerで利用可能なオブジェクトを呼び出すことが可能です。よって、ActiveXObjectでWscript.shellのRunメソッドを呼び出せば、任意のファイルを実行することが可能です。例えば、以下のようにrundll32.exe実行することで、電卓を起動することが可能です。

rundll32.exe javascript:"\..\mshtml,RunHTMLApplication ";document.write();new%20ActiveXObject("WScript.Shell").Run("calc.exe")

実行例を以下の図に示します。

f:id:binary-pulsar:20181104224116p:plain

まとめ

本記事では、実行可能なファイルが制限された環境下で、攻撃者が実行制限を回避してファイルを実行する手法の一部を解説しました。AppLockerなどにより実行制限をかけた環境でも、何かしらの手法で制限を突破して悪意のある命令が実行されてしまうと考えて、セキュリティ対策したほうが良いでしょう。

DDE機能を悪用したMicrosoft Officeによる遠隔コード実行の手法とその対策

概要

近年のサイバー攻撃において、組織のネットワークに侵入する手法として代表的な手法の一つは、Microsoft Officeによる悪意のあるプログラムの実行であるといえるでしょう。Microsoft Officeによる悪意のあるプログラムの実行と言えば、マクロ機能を悪用した手法を思い浮かべる読者が多いかもしれません。添付ファイルを開いても「マクロを有効にしなければ大丈夫」という認識の人も少なくないでしょう。しかし近年では、マクロ機能を用いなくても悪意のあるプログラムを実行させることができる手法がいくつか存在します。本記事では、マクロ機能を使わずに悪意のあるプログラムを実行させる手法の一つである、Dynamic Data Exchange (DDE)機能を悪用した手法を取り上げます。

Dynamic Data Exchangeとは

DDEは動的なデータ交換を実現するプロトコルです。Microsoft Office製品では、DDEプロトコルを用いることにより、あるMicrosoft Officeファイルから別のMicrosoft Officeファイルのデータを、動的に取り込むことを可能とする機能が備わっています。DDE機能を活用することにより、複数のMicrosoft Officeファイルを連携させることが可能となります。大きなネットワーク上では特に、複数のMicrosoft Officeファイルを管理する上ではDDE機能は有用ですが、2017年10月にSensePost社の研究者により「DDE機能を悪用して任意のコードを実行させる手法」が公開されました。

sensepost.com

本記事ではその手法の概要と対策について取り扱います。

Microsoft Excelの場合

それではDDEによるプログラム実行の手順を解説します。Microsoft WordやMicrosoft PowerPointでも可能ですが、本記事ではMicrosoft Excelを取り上げます。Microsoft Excelを悪用した手法では、以下の性質を悪用します。

  • セルの値が等号(=)、加算記号(+)、減算記号(-)で始まる場合は、セルの値は数式として解釈
  • セルの値がアットマーク(@)で始まる場合は、内部関数を探索して数式の引数として解釈

DDE機能が有効な環境下では、以下の式をセルに挿入することにより、DDEによるデータの更新の際に式に埋め込まれたコマンドが実行されてしまいます。

<コマンド>|'<コマンドライン引数>'!<セル名>

例えば以下の値をMicrosoft Excelの適当なセルに値として設定します。

=cmd|'/k calc.exe'!A1

値を入力し終えると、以下のようにポップアップが起動します。

f:id:binary-pulsar:20181011192604p:plain

ここで「No (いいえ)」を選択すると何も起きませんが、「Yes (はい)」を選択するとcalc.exeが起動します。

f:id:binary-pulsar:20181011192651p:plain

このファイルを保存すれば、手法の検証用ファイルの作成は完了です。このファイルを開くと、以下のように自動アップデートを有効化するかどうかを確認するメッセージが表示されるため、「Enable Content (コンテンツの有効化)」をクリックします。

f:id:binary-pulsar:20181011192721p:plain

すると以下のようにアップデートの許可を求めるポップアップが起動します。

f:id:binary-pulsar:20181011192744p:plain

「Update (更新する)」を選択すると、さらにプログラムの実行の許可を求めるポップアップが表示されます。

f:id:binary-pulsar:20181011192800p:plain

ここで「Yes (はい)」を選択すると、DDE機能により以下のようにcalc.exeが起動します。

f:id:binary-pulsar:20181011192816p:plain

プログラム実行許可のポップアップの表示を偽装

次にポップアップの表示を偽装する手法を紹介します。前節の手法では、最後の「プログラムの実行許可を求めるポップアップ」にて「CMD.EXEの実行を許可するか?」という内容のメッセージが表示されます。攻撃者の観点で言えば、CMD.EXEとそのまま表示される状態では、攻撃対象から気付かれてしまうことが懸念事項となります。そこで、先ほどの値の代わりに、例えば以下の値をセルに設定します。

=MSEXCEL|'\..\..\..\..\..\Windows\System32\cmd.exe /k calc.exe'!A1

すると「プログラムの実行許可を求めるポップアップ」は、以下の図のように、「CMD.EXE」が「MSEXCEL.EXE」に変わっていることがわかります。

f:id:binary-pulsar:20181011192836p:plain

攻撃者はこうしてポップアップのメッセージを変更することにより、攻撃対象の警戒心を和らげます。その他にも、以下のようにrundll32.exeを用いたペイロードを埋め込む手法が考えられます。

=rundll32|'URL.dll,OpenURL calc.exe'!A

rundll32.exeは、DLLから関数を取り出して実行する機能を持つ、Windows OS標準の実行ファイルです。攻撃者が制御を得ることに成功したWindows OSのホストで、アンチウイルスソフトを回避するために利用されることがある実行ファイルでもあります。このように、cmd.exeを用いらずとも任意のコマンドを実行可能できる手法が存在することも、攻撃への対策として認知しておくとよいでしょう。

対策

ポップアップが表示された際に内容をよく確認し不用意な選択しないことが望ましいですが、組織に所属する全職員にそのような習慣を徹底させることは難しいでしょう。可能であればMicrosoft OfficeのDDE機能を無効化することにより、根本的な対策を講じることが良いでしょう。Microsoft OfficeのDDE機能を無効化する手順は、Microsoft社により以下のWebサイトにて公開されています。

マイクロソフト セキュリティ アドバイザリ 4053440

DDE機能の無効化機能は、本手法の公開に伴い2017年12月にアップデートプログラムとして公開されました。よって、DDE機能の無効化による対策を講じる場合は、以下のアップデートを適用する必要があります。

https://portal.msrc.microsoft.com/ja-jp/security-guidance/advisory/ADV170021

まとめ

今回の記事では、DDE機能を悪用してマクロ機能を使うことなく任意のコードを実行する手法を取り上げました。今回はMicrosoft Excelの場合を取り上げましたが、Microsoft WordやMicrosoft PowerPointでも同様の手法が可能です。対策として、ポップアップの内容をよく読み不用意な選択肢を選ばないように習慣づけることが考えられますが、組織のネットワークを守ろうという場合は全職員にそのような習慣をつけることは難しいと考えられるため、完全な対策とはいえません。可能であればDDE機能の無効化により根本的に対策することが望ましいでしょう。

ReflectionによりPowerShellでWindows APIを呼び出す手法

概要

近年盛んであるPowerShellを悪用した攻撃の根幹を成す技術の一つが、PowerShellによるWindows APIプログラミングであることは間違いないでしょう。PowerShellではその豊富な機能により、Windows APIを複数の手法で呼び出すことが可能であるため、カーネルエクスプロイトやメモリ上の機密情報の取得などが可能です。本記事では、Windows APIの呼び出しを可能とする技法のひとつである、Reflectionという機能を用いたWindows APIの呼び出し手法を取り上げます。

PowerShellとReflection

Reflectionは情報工学における技術の一つであり、プログラミングにおいては「自分自身の構造を書き換える機能」を指します。PowerShellにもReflectionが機能として実装されており、Reflectionにより新たな型を定義したりプログラム内部の情報を参照することが可能です。

PSReflect

Reflectionを活用してWindows APIを呼び出すためのPowerShellスクリプトが、Matt Graeber氏によって公開されています。

github.com

スクリプトの詳細についてブログの一記事としてまとめるにはなかなか骨が折れるため、詳細は割愛します。

PSReflectの機能は以上に公開されているスクリプトのうち、PSReflect.psm1に実装されています。スクリプトには様々な関数が実装されていますが、明示的に使う関数はNew-InMemoryModule関数とAdd-Win32Type関数の2つのみです。New-InMemoryModule関数はメモリ空間にモジュールを新たに定義する関数です。Add-Win32Type関数は、New-InMemoryModule関数により定義されたモジュールを用いて、ReflectionによりWindows APIPowerShellに追加する機能を持つ関数です。

PSReflectを利用してWindows APIを呼び出す

それではPSReflectを用いてWindows APIを呼び出す手順を示します。本記事ではuser32.dllに実装されているMessageBox関数を取り上げて、Windows APIを呼び出す手順を示します。

実践に移る前に、MessageBox関数というWindows APIの実装を調べましょう。Windows APIの多くはMicrosoft公式Webサイトに、公式文書として実装を参照することが可能です。(公式文書として公開されていないUndocumented APIと呼ばれているWindows APIが存在しますが、本記事の内容を超えるため触れません。)Microsoftの公式文書は様々な国の言語で公開されています。本記事では英語に馴染みがない読者を想定して、日本語版がある公式文書に関しては日本語版の公式文書のリンクを掲載しますが、言語である英語が最も情報の更新が早く情報が充実しているため、可能であれば英語版を読むべきでしょう。MessageBox関数の公式文書は以下のWebサイトに公開されています。

MessageBox 関数

MessageBox関数の実装は以下の通りです。

int MessageBox(
  HWND    hWnd,
  LPCTSTR lpText,
  LPCTSTR lpCaption,
  UINT    uType
);

Windows APIの関数を利用するには、それぞれの引数の意味とその型をどの型として定義すればよいかを理解する必要があります。以上に記載のWindows API関数の公式文書の内容では、引数の型がC#PowerShellでのプログラミングとは異なるため、それぞれ対応する方に置き換える必要があります。Windows API関数の公式文書に記載の型と、C#PowerShellでのプログラミングにおける型との対応に関しては、以下のMicrosoft公式文書に記載されています。

プラットフォーム呼び出しによるデータのマーシャリング | Microsoft Docs

公式文書によると、HWND型はハンドルを指定する引数の型であるためSystem.IntPtr型に対応します。LPCTSTR型はSystem.String型またはSystem.Text.StringBuilder型であるため、本記事ではSystem.String型を採用します。UINT型はSystem.UInt32型に対応します。 それではMessageBox関数の引数について解説しましょう。まず、第一引数のhWndですが、メッセージボックスを立ち上げるプロセスのハンドルを整数の数値で指定する引数です。親プロセスとして立ち上げる場合は0を指定します。次に、第二引数のlpTextですが、この引数にはメッセージボックスに表示する文言を文字列型の引数として指定する引数です。第三引数のlpCaptionはメッセージボックスのキャプションの文言を指定する引数であり、第二引数と同じく文字列型の値をしてします。最後に、第四引数のuTypeですが、この引数には「メッセージボックスの書式を指定する整数」を指定します。メッセージボックスの書式については、先述のMessageBox関数の公式文書に記載されています。例えばuTypeを「2」と指定すると「YesとNoとIgnoreが選択肢として表示されるメッセージボックス」が、「4」と指定すると「YesとNoが選択肢として表示されるメッセージボックス」が表示されます。

まずはPSReflect.psm1から、スクリプトに定義されている関数をインポートします。

PS C:\> Import-Module .\PSReflect.psm1
PS C:\>

続けて、PSReflect.psm1からインポートしたNew-InMemoryModule関数により、PowerShellのメモリ空間にモジュールを定義します。ModuleNameオプションに任意の名前を値として与えてNew-InMemoryModule関数を実行することにより、任意の名前のモジュールを定義することが可能です。本記事ではモジュール名をWinApiとして、変数Moduleに定義します。

PS C:\> $Module = New-InMemoryModule -ModuleName WinApi
PS C:\>

次に型情報を配列型の変数として定義します。関数毎に配列が多変数の一要素として、以下の書式で定義します。

(func <DLL名> <Windows API関数名> (<返り値の型>) @(<第一引数の型>, <第二引数の型>, ...))

MessageBox関数の場合は、例として以下のように変数Funcdefに定義します。

PS C:\> $Fundef = @( (func user32 MessageBox ([int]) @([IntPtr], [String], [String], [int]) ) )
PS C:\>

関数の型情報を定義したら、Add-Win32Type関数によりWindows APIを読み込みます。Add-Win32Type関数のModuleオプションに先ほどNew-InMemoryModule関数で定義したモジュールを、Namespaceオプションには任意の名前で名前空間を設定します。本記事の例では、名前空間の名前をWinDLLとして、Windows APIの読み込みを変数Typesに定義します。

PS C:\> $Types = $Fundef | Add-Win32Type -Module $Module -Namespace 'WinDLL'
PS C:\>

続けて、変数Typesでの定義で読み込んだWindows APIから、利用したDLLの名前を指定します。今回の例として取り上げているMessageBox関数というWindows APIは、user32.dllに実装されているため、以下のようにして変数User32に定義します。

PS C:\> $User32 = $Types['user32']
PS C:\>

最後に、変数User32に定義したuser32.dllを読み込んだ空間からMessageBox関数を呼び出すことにより、メッセージボックスを起動することが可能です。

PS C:\> $User32::MessageBox(0, 'Hello, world!', 'PopUp', 2) | Out-Null
PS C:\>

以下の図に例を示します。

f:id:binary-pulsar:20181003120256p:plain

まとめ

本記事では、近年のPowerShellの攻撃で用いられている根幹をなす技術である、Windows APIの呼び出しの手法の一つを取り上げました。Windows APIの呼び出しについてはその他にも複数の手法が存在し、いずれの手法も攻撃スクリプトに活用されています。その他の手法によるWindows APIの呼び出しについては、またの機会に取り上げます。