論文メモ: Visualizing Compiled Executables for Malware Analysis

はじめに

絵画や陶芸などは目で見ることで良し悪しがわかるものですが、ソフトウェアは良し悪しが目で見えづらいです。

目では見えないため、ソフトウェアにバグがあったり、さらにはアドウェアが入っていても気づきづらいです。

マルウェア解析の分野においては、悪意あるソフトウェアに難読化処理が施されていることも多いため、どのような処理が行われるのか推測が難しいです。

もしソフトウェアがもっと見えたなら、様々な問題が緩和されるのではないかでしょうか。

私は、日頃、3D CGによる可視化技術の調査や実装を行っているのですが、これをセキュリティの分野に適応できないかと模索しています。

既存研究を探してみたところ、今回取り上げる「Visualizing Compiled Executables for Malware Analysis」[Quist+09]という論文を発見しました。

ieeexplore.ieee.org

この論文では、ソフトウェアの挙動を3Dで可視化し、特にそれをマルウェア分析に役立てようという内容です。

2009年の「6th International Workshop on Visualization for Cyber Security」で発表された論文なので、かなり古い論文です。

古い論文なので、一般的なPC環境として「Windows XP」、仮想化システムとして「Xen」が登場してきて、時代を感じさせます。

それでも、ソフトウェアの挙動を可視化する手法について学べることもあるはずなので、ここにまとめていきます。

本論文の貢献

本論文では、リバースエンジニアリングの作業を助けるための、ソフトウェアの挙動を可視化するツールを提案しています。

仮想マシンにEtherというハイパーバイザーフレームワークを適用し、動的解析によってプログラム全体のフローを可視化します。

プログラムの挙動を可視化したサンプル画像をここに引用します。

f:id:toyamaguchi:20190601111930p:plain
[Quist+09] Figure 1

可視化することで、パックや圧縮処理が施されたプログラムの、本来のエントリーポイントを発見しやすくします。

また、プログラム全体の構成の理解を促すようにします。

こうして、リバースエンジニアリングにかかる時間を短縮できるようにします。

リバースエンジニアリングのワークフロー

まず、リバースエンジニアリングはとても難しいです。

あるときは様々なツールを使って、あるときはアセンブリ言語を読んで、プログラムの目的が何なのかを探ります。

様々なスキルをマスターするのにも時間がかかりますし、一回一回の解析にも忍耐が必要です。

一方で、マルウェア側も常に進化しており、デバッガーを検知したり、プログラムの圧縮や難読化を施したりして、解析を妨害してきます。

そんな困難なマルウェア解析ですが、この論文では最初に効率的な解析のワークフローを提案しています。

  1. 隔離環境を用意する。
  2. ターゲットのプログラムを起動し、そのプログラムが行う出力 (プログラムが与えた影響)を探す。ツールを使ってOSへの変更をモニターする。
  3. IDA Proのようなツールでプログラムをロードして、リバースエンジニアリング作業を始め、必要なら難読化解除を行う。
  4. 似たような処理を行う部分や、興味深い部分を特定し、分析する。

ここで著者は、特に隔離環境の重要性を説明していました。

VMWareVirtual PCのような仮想化システムは、システムの現在の状態のスクリーンショットを撮れます。

分析する前にスクリーンショットを取っておくことで、実行後のシステムの状態を比較できます。

また、実行プロセスの理解のために、感染前の状態に素早くリストアすることもできます。

マルウェアの感染被害を仮想化環境内に閉じ込めることで、安全に解析ができます。

提案ツールの構成

f:id:toyamaguchi:20190601134643p:plain
[Quist+09] Figure 2

Etherを使った仮想マシンでのモニタリング

Etherは、Xenの仮想化フレームワークに追加する一連のパッチと、アプリケーションで構成されています。

このパッチにより、Xenは実行中のプログラムにアタッチして、マルウェアに検出されることなく監視できるようになります。

(この論文は古いので、現在のマルウェアに効果があるかは定かではありません。)

ちなみに、このようなEtherによるプログラム実行のモニタリングは、[Dinaburg+08]にて発表されたものです。

このEtherによって、いくつかの利点が得られるそうです。

  1. マルウェアによる検証やデバッグ回避などを起動させず、正常動作をさせることができる。
  2. デバッガーやトレースシステムを破ることを目的とした難読化は、仮想化フレームワーク側からプロセスを監視してしまうEtherシステムには効果がない。
  3. 仮想化システムの全体の構造は安全に維持される。

さらに、プログラムの分析・視覚化のためにEther自体を拡張して、プログラム内での書き込み処理、読み込み処理、別プログラムの実行処理を記録できるようにしました。

これによって、プログラムのフローグラフを作成するために必要なデータが得られます。

さらに、追加された機能によって、プログラム内のパッカーや難読化を回避するために、実行中のプログラムの現在の状態をダンプする適切な時期が決定されます。

DLLの分析をするための新しいインポートツールも実装されました。

最終的に、Etherからすべてのステートメント実行、メモリの読み書き、実行された命令の逆アセンブリを含むトレースファイルが出力されます。

VERAによる可視化

基本ブロックと実行遷移

Etherはトレースファイルを生成し、それをVERAに渡します。

処理の流れを制御文(ジャンプ命令など)で区切ると、処理のまとまりがいくつもできあがりますが、この処理のまとまりのことを「基本ブロック」と呼びます。

VERAは、トレースファイルを元にして、一連の処理を基本ブロックに分け、基本ブロック間の遷移関係を調べます。

これらの結果をもとに可視化が行われ、基本ブロックがグラフ中のノードに、基本ブロック間の遷移がグラフ中のエッジになります。

実行回数の多いエッジは、より太く描かれます。

Open Graph Drawing Framework (OGDF)

ノードとエッジのデータが揃ったら、Open Graph Drawing Framework (OGDF)を使用してグラフのレイアウトを決定します。

他のライブラリではうまくできなかったことも、このライブラリを使用したことで、大きなグラフを素早く効率的にレンダリングすることができたそうです。

ここでweighted symmetric layoutのオプションを選択しました。

circular layoutなどの他のグラフ作成方法では、適切な情報が効果的に伝達されないことがわかりました。

レイアウトが解決すると、そのデータは再びVERA側に渡されます。

グラフの色

  • 黄色: ディスク上のプログラムとメモリ内のプログラムの両方に存在するコードの実行
    • 2つの領域のコードが同じであることを示している。
  • 赤色: エントロピーの高いセクション
    • ほとんどのパッカーと難読化ツールは、プログラムを圧縮して、データが均等に分散されるようにする。
  • 緑色: 存在しないコードセクションへの実行
    • 実行された命令がディスク上のプログラムに存在しない場合、これはコードが動的に生成せれたか、自己修正型であることを示す。
  • 薄紫: セクションがディスク上に存在するが、ランタイム実行ファイルには存在しない場合の実行
    • データがPEセクションヘッダに割り当てられているが、実行時までしようされていない場合に最もよく見られる。
  • ネオングリーン: メモリ内およびディスク上のプログラムとは異なる命令
    • 自己改変型コードの実行を示す。

プログラムの機能の特定

この可視化ツールを使うことで、プログラムの処理段階を特定できるようになります。

特に、アンパックコードの特定、初期化部分の特定、メインループの特定は、マルウェア解析でよく確認されます。

アンパックコードの特定

アンパックコードを特定することは、比較的簡単です。

プログラムのエントリーポイントの直後にある、いくつかのループが結合された部分です。

Figure 3では、MEWパッカーのアンパックループが示されています。 (Figure 1の右側部分を拡大したものが、Figure 3です。)

f:id:toyamaguchi:20190601192735p:plain
[Quist+09] Figure 3

この図から、もとのプログラムの難読化解除には複数のループが関係していることがわかります。

アンパックコードの終わりは、ループが終わり、直線的に薄紫のノードが伸びているところを探すことでわかります。 (Figure 1の中央部分あたり。)

この領域の最初の基本ブロックは、プログラムのオリジナルのエントリーポイントである可能性が高いです。

初期化部分の特定

初期化コードは、入口と実行が1つしかない基本ブロックの長い連鎖として見ることができます。

Figure 1では、これは元の入り口点から始まり、3つの分岐が発生する左側で終わる中央部分です。

プログラムの初期化では、メモリの割当、使用するファイルとリソースのオープン、およびネットワークリソースへのアクセスを処理します。

ただし、初期化はこの領域だけに限定されるものではないので、注意が必要です。

初期化処理を特定することで、この後に使われるリソースを特定し、プログラムの意図を絞りこめるため、大きなステップとなります。

メインループの特定

Figure 1で、メインループは左半分のうちの、中央に位置しています。

頻繁に実行されるループは、より太いエッジで描かれます。

この部分を特に分析することで、このシステムで利用されるバックドアを見つけることができたりします。

Figure 1の場合、自分自身をアクティブにしてから、最初のコールバックを実行し、着信接続を待ちます。

Applicatoin of Analysis: Mebroot

実際のデータセットでVERAを使用することで実用性を示します。

トロイの木馬であるMebroot (MD5:1f7fed180237ed352d274c69012a4717)の初期ロードポイントを分析するために、VERAを使用しました。

Mebrootは、マスターブートレコードに感染し、(当時の)最新のOS上で実行されます。

その主な目的は、被害者からクレジットカード番号やその他の財務情報を盗むことです。

感染したマシン上で、他の悪質なコードを起動するためのダウンロードエージェントとしても使用されます。

悪意のある機能のほとんどはカーネルモードで実装されています。

ユーザーモードのロード機能を分析するためにVERAを使用します。

最初の実行分析

Mebrootを約5分間実行して実行しました。

結果はFigure 5に示されており、挙動は非常に限定されたものでした。

f:id:toyamaguchi:20190601192938p:plain
[Quist+09] Figure 5

表示される情報は非常に少ないため、プログラムのこの部分は、迅速な分析を妨げるためのビジーなループである可能性が高いです。多くの場合、アナリストを誤った道へと導きます。

分析を12時間継続

実行を12時間継続することで、トロイの木馬の実行について、より広い視野を得ることができました。

f:id:toyamaguchi:20190601193000p:plain
[Quist+09] Figure 6

Figure 5は、このFigure 6の左上の部分になります。

Mebrootの困難な分析

Mebrootは最初に約45分間のビジーループに入ることによって、自分自身が分析されるのを防ぎます。

この間、興味のあることは何も起こりません。

このループが完了すると、Mebrootはホストのマスターブートレコードに感染します。

マスターブートレコードには、ブートプロセスが発生した後に実行中のWindowsカーネルに、後で挿入される初期化コードが含まれています。

また、Mebrootには、mid-instruction point jumpとして知られるテクニックが使われていました。

この難読化手法は、Intel命令セットのデータ密度に依存しています。

IDA Proなどの静的逆アセンブラがコードを分析するとき、命令は実行されるものと同じではありません。

Nick Harbourはこの問題を[Harbour08]で論じており、これがまさにMebrootの内部に存在しているのです。

Mebrootに関するこの事実を知ることで、IDAに逆アセンブルされたコードの見方を修正させることができます。

Mebrootの残りの部分は権限を与えられたカーネル空間の内部で実行され、今回の分析では明らかにすることはできません。

このトロイの木馬は、ネットワークログと、Mebrootの感染を識別するIDSシグネチャーに基づいて、正常に実行されたことがわかりました。

ユーザー調査

このツールとアプローチがプログラムの分析にどれほど効果的かを評価するために、予備的なユーザー調査を行いました。

ユーザーは、前の週に行われたリバースエンジニアリングレーニングコースに参加しました。

リバースエンジニアリングのワークフローについて一通り学び、すべてのテストに合格しました。

ユーザーは今回のツールの使用方法をさらに学び、2つのマルウェアサンプルについて、VERAの可視化ツールの評価を実行するように求められました。

この2つのマルウェアサンプルは、UPXとMewの異なるパッカーで暗号化されています。

ここでユーザーはいくつかの質問を受けました。

  • 標準の評価プロセスの各ステップで、彼らの使っていたツールのどのような側面が役立つのか
  • プロセスの各段階で、ユーザーは各ステップの主なタスクをどのように達成したか、また、そのステップで何が発見されたのか
  • 分析段階の終わりに、ユーザーはVERAを使用することの利点と欠点、VERAを使用することで分析のスピードが上がるかどうか、そして従来の手法では見当たらないと思ったことや、伝統的な技術を使っていたら見つけたであろう物事を見逃していたことについて
  • 最後に、VERAを再び使用する可能性があるかどうか、および同僚にVERAを推奨するかどうか

コードの特定のセクションを見つけたユーザーの成功をFigure 7に示します。 (全員で6人)

f:id:toyamaguchi:20190601213530p:plain
[Quist+09] Figure 7

特定のセクションというのは、具体的にはオリジナルのエントリポイント (OEP: Original Entry Point)を見つけたユーザーの数、初期化コード、およびメインループのことです。

さらに、図に示されているように、すべてのユーザーは再びVERAを使う可能性があり、それを推奨するだろうと述べていました。

まとめと将来の研究

VERAフレームワークは、リバースエンジニアリングをスピードアップするためのツールです。

このツールによって、作業の合計時間を短縮することができました。

今後検討されている機能については、次のようなものが挙げられています。

  • プログラム内のループの強調表示
  • カーネルベースのプログラム分析方法
  • 3D可視化環境の強化

雑感

論文の内容に関する雑感。

  • 仮想化環境にのみ存在するライブラリを探索して、それが存在したら仮想化環境上で実行している、と判定するマルウェアもいます。そのため、この古い論文に紹介されているEtherも、マルウェアに検知されてしまうかもしれないです。
  • マルウェアに検知されない状態で動的解析をしないと、マルウェアが本来の処理をしてくれないため、良い可視化ができません。そのため、検知されずに動的解析する方法は、常に最新の手法に置き換える必要がありそうです。
  • 可視化したグラフの赤色の部分は、パッカーや難読化ツールなどによってプログラムを圧縮されているため、データが均等に分散されるようになります。圧縮されているか、否かを判断する材料として、エントロピーが役に立つらしいです。興味深いです。
  • Mebrootの解析のように、12時間プログラムを監視し続けなくても良い手法が欲しいですね。
  • 説明を読む限り、mid-instruction point jumpは静的解析ツールを誤らせるテクニックに読めるため、あとで調査したいです。
  • 可視化技術は見た目の良し悪しを判断する必要もあるためか、ユーザー調査が行われていた点が興味深かったです。(ただ、ユーザーの皆さんがたくさん褒めてて、逆に疑ってしまいますが。)

参考文献

  • [Quist+09] D. A. Quist and L. M. Liebrock: Visualizing Compiled Executables for Malware Analysis, 2009 6th International Workshop on Visualization for Cyber Security, pp.27–32 (2009).
  • [Dinaburg+08] A. Dinaburg, P. Royal, M. Sharif, and W. Lee: Ether: Malware Analysis via Hardware Virtualization Extensions, Proceedings of the ACM Conference on Computer and Communications Security, pp.51-62 (2008).
  • [Harbour08] N. Harbour: Advanced Software Armoring and Polymorphic Kung-Fu. Defcon 16. (2008).