セキュリティキャンプ講義「仮想化技術を用いたマルウェア解析」にチャレンジしてみた(準備編)
今年の八月中旬に行われたセキュリティキャンプ全国大会2015の解析トラック15・16-Dでの講義「仮想化技術を用いたマルウェア解析」にチャレンジして、一通りできた。
発表者の黒米さんの許可が戴けたのでその流れを書き残す。
発表で使われたスライドは黒米さんの技術ブログ"
一生あとで読んでろ
"に置いてある。
構成
プラグインを書くことよりも環境の準備に相当手間取ったので、準備編とプラグイン開発編の二段階で書いていく。
内容は以下の通り。
* 準備編
DECAFの導入と操作方法、注意点。
* プラグイン開発編
DECAF上で動かしているWindowsの仮想マシンで、仮想化検知を施されたプログラムblue.exe
の検知を回避するプラグインを開発していく。
DECAFの準備
DECAFとは
DECAFは"Dynamic Executable Code Analysis Framework)の略で、QEMUにテイント解析機能を追加したTEMUの後継として作成されたバイナリ解析フレームワークのこと。詳しくはBitBlazeプロジェクトを検索。
インストール
インストールした環境は以下の通り。
* Ubuntu 14.04 LTS 64bit
他にはUbuntu 14.04 LTS 32bit
とArch Linux 64bit
でインストールを試みたが、コンパイルが上手くいかず断念した。
まず、適当なディレクトリに移動してから以下のコマンドを実行していく。
$ sudo apt-get update $ git clone https://github.com/sycurelab/DECAF $ cd DECAF/decaf $ pwd /home/<user>/DECAF/decaf $ sudo apt-get install qemu $ sudo apt-get install build-dep qemu $ sudo apt-get install binutils-dev $ sudo apt-get install libboost-all-dev $ ./configure # スライドの方にはテイント解析などをオンにするオプションが載っているが、今回はなくても問題なかった。 $ make
もしもpython
関係のエラーが出たら、コマンドのpython
が3系にリンクが張られていないかを確認すること。DECAFのスクリプトは2系で書かれていて、例外処理関係でエラーが出る。
具体的にはconfig-host.mak
のPYTHON=python
をPYTHON=python2.7
とかに書き換える。
これ以外のエラーが出たら・・・頑張れ!
DECAF自体のインストールはmake
が上手くいけばおしまい。
次はWindowsの仮想マシンを用意する。
仮想マシンの準備
Developer Resources : Microsoft Edge Devで30日だけ動作するWindowsの仮想マシンを配布しているので、ダウンロードする。
トップページ下にある"Virtual Machine"をクリック。
Windowsタブで
* Virtual Machine => IE8 on XP
* Select Platform => VMWare
と設定し、"Download .zip"からダウンロード。
$ pwd /home/<user>/DECAF/decaf $ mkdir ../VMs $ mv $HOME/Downloads/IE8.XP.For.Windows.VMware.zip $HOME/DECAF/VMs $ cd ../VMs $ unzip IE8.XP.For.Windows.VMware.zip
VMWare用の仮想マシンからqemu用の仮想マシンを作成する.
作成には少々時間がかかる.容量も7GBほど食われた覚えがあるから注意.
$ qemu-img convert <name of VM>.vmdk -O qcow2 pre_ie8.qcow2 $ qemu-img convert -p -f qcow2 -O qcow2 -o compat=0.10 pre_ie8.qcow2 ie8.qcow2
qcow
に変換しても動作するが,スナップショットが使えない.
作成が終わったら,下のコマンドで起動してみる.
$ $HOME/DECAF/decaf/i386-softmmu/qemu-system-i386 $HOME/DECAF/decaf/VMs/ie8.qcow2 -m 2048 -monitor stdio
これでWindowsXPが立ち上がることを確認する。-m
オプションは割り当てるメモリの量を指定する.1GBでは動作が遅い。
また,今回は1つしかプロセッサを与えていないため,しばらくは処理が重いが時間を置くと落ち着く.
画面が引き延ばされるのを修正したいならCtrl+Alt+u
を押す。
マウスが暴走するようなら
$ export SDL_VIDEO_X11_DGAMOUSE=0
Windowsが立ち上がることを確認したらシャットダウンする。
次に問題のプログラムをWindnowsにコピーする。
$ git clone https://github.com/ntddk/blue.git $ sudo modprobe nbd $ sudo qemu-nbd -c /dev/nbd0 ie8.qcow2 $ sudo /sbin/fdisk -l /dev/nbd0 $ sudo mount -o loop,offset=$((63*512)) /dev/nbd0 /mnt $ sudo cp -r blue /mnt/Documents and Settings/All Users/Desktop $ sudo umount /mnt $ sudo qemu-nbd -d /dev/nbd0 $ sudo rmmod nbd
これで起動したときのデスクトップにblue
のフォルダが出るようになる。
また,プラグインもコンパイルしておく.
$ pwd /home/<user>/DECAF/VMs $ cd ../decaf/plugins $ git clone https://github.com/ntddk/geteip $ cd geteip $ ./configure --decaf-path=/home/<user>/DECAF/decaf $ make
このプラグインはIsDebuggerPresentをフックする.関数フックのテンプレートとして勉強になる.
今後の起動はDECAFの公式HPやスライドに載っている自動化スクリプトを使ってもできる.
下のスクリプトも同じ動作をするのでHaskell好きな人はどうぞ.
-- decaf_auto.hs import System.IO import System.Process -- createProcess import System.Posix.Directory -- changeWorkingDirectory import Control.Concurrent (forkIO, threadDelay) inputCmd p_in p_out cmd = do hPutStrLn p_in cmd threadDelay (1000 * 1000) -- Nonblocking forkIO $ putStrLn =<< hGetContents p_out rawInput msg = do putStr msg getLine main :: IO () main = do hSetBuffering stdout NoBuffering decaf_path <- rawInput "*** Enter the root directory of DECAF (i386-softmmu/qemu-system-i386 should be there): " image_path <- rawInput "*** Enter the image path: " changeWorkingDirectory decaf_path (Just p_stdin, Just p_stdout, _, _) <- createProcess (shell $ "i386-softmmu/qemu-system-i386 " ++ image_path ++ " -m 2048 -monitor stdio") { std_in = CreatePipe, std_out = CreatePipe } hSetBuffering p_stdin NoBuffering hSetBuffering p_stdout NoBuffering threadDelay (3 * 1000 * 1000) inputCmd p_stdin p_stdout "ps" inputCmd p_stdin p_stdout "help" return () -- E.O.F.
やっていることはqemu-system-i386
のプロセスを作成し,そのプロセスの標準入力・標準出力に対しての操作を行っている.
しかしこのスクリプト(Python版も含めて)は使わないほうがいいと感じた.
これは実行すると書いてある動作以外をせず,qemu
のプロンプトが出ないで入力・出力が閉じてしまう.
使うなら下のコマンドで普通に実行したほうがいい.
$ pwd /home/<user>/DECAF/VMs $ ../decaf/i386-softmmu/qemu-system-i386 ie8.qcow2 -m 2048 -monitor stdio
出力が一段落ついたあたりで一回Enter
を押すと,(qemu)
のプロンプトが出る.
プロンプトを表示させてプラグインを読みこませる.
(qemu) load_plugin ../decaf/plugins/geteip/geteip.so (qemu) geteip blue.exe
これでblue.exe
を実行した時にgeteip.c
の内容が実行される.blue.exe
はblue/Release/blue.exe
にある.
何もいじっていなければIsDebuggerPresent
の実行時と実行後にそれぞれフックしたメッセージが出るだけのはず.
この辺はどうにも不安定で,いじっていなくてもIsDebuggerPresent
を回避できたりした.
詳しいことはプラグイン開発編で書く.
最後に
ここまでがうまく行けば,準備は終わり.
誤字やうまく行かないところがあれば気軽に言ってくれると嬉しい.
ここまで長い記事を書いたことがないので,どこか間違いがありそうな気がする.
次は,blue.exe
のソースを参考にプラグインを書いていく.