setodaNote

忘れる用のメモ書き

CAPE 環境を構築して Emotet を解析する

CAPE

CAPE (Malware Configuration And Payload Extraction) は 2016年9月頃に github に公開されたマルウェアサンドボックスです。Cuckoo (より正確には spender-sandbox)をベースに開発されており、多くのマルウェアからペイロードや設定情報を自動的に抽出することができます。

f:id:soji256:20190526111907p:plain
CAPE: Malware Configuration And Payload Extraction

対応しているマルウェアは以下の通りです。

  • 種別を指定することでペイロードや設定情報の抽出が可能

    • PlugX
    • EvilGrab
    • Sedreco
    • Cerber
    • TrickBot
    • Hancitor
    • Ursnif
    • QakBot
  • Yara による自動判定によりペイロードの抽出が可能

    • Emotet
    • RedLeaf
    • ChChes
    • HttpBrowser
    • Enfal
    • PoisonIvy
    • Screech
    • TSCookie
    • Dridex
    • SmokeLoader
  • その他、以下のマルウェアについても Yara による自動判定とペイロードの抽出が可能(対象マルウェアは現在も増え続けているそうです)

    • Azorult, Formbook, Ryuk, Hermes, Shade, Remcos, Ramnit, Gootkit, QtBot, ZeroT, WanaCry, NetTraveler, Locky, BadRabbit, Magniber, Redsip, Kronos, PetrWrap, Kovter, Azer, Petya, Dreambot, Atlas, NanoLocker, Mole, Codoso, Cryptoshield, Loki, Jaff, IcedID, Scarab, Cutlet, RokRat, OlympicDestroyer, Gandcrab, Fareit, ZeusPanda, AgentTesla, Imminent, Arkei, Sorgu, tRat, T5000, TClient, TreasureHunter.

オンライン版もありますがローカルでも構築できるようだったので、Emotet を解析できるところまで試してみました。

CAPE 環境の構築

Ubuntu 18.04.2 を準備する

CAPE のホストとして Ubuntu 18.04.2 LTS を VMware 上に準備します。Ubuntu 上に CAPE 用の Python 環境(venv-cape)、 Sandbox 用の Windows 7 環境(VirtualBox) をそれぞれ構築します。専用の Python 環境を利用するのは Cuckoo の公式が推奨していたのでそれに従いました。

f:id:soji256:20190526142702p:plain:w380
CAPE Sandbox

Ubuntu の環境前提

以下の環境となっていることを前提として説明を進めます。

  • Ubuntu18.04.2 (Cuckoo ホスト)

    • VMware 上に構築(VMware Workstation 15 Pro)
    • メモリサイズ: 8GB
    • プロセッサ:
      • コア数: 4
      • 「Intel VT-x/EPT または AMD-V/RVI を仮想化」を有効にする
    • ハードディスクサイズ:80GB
    • ネットワークアダプタ: NAT
    • ユーザ名: infected
  • Ubuntu 18.04.2 LTS の iso イメージのダウンロードリンク
    Download Ubuntu Desktop | Download | Ubuntu

「Intel VT-x/EPT または AMD-V/RVI を仮想化」はあとで仮想マシン内の VirtualBox で CPU コア数を変更するための設定です。コア数を変更しない場合には設定変更は不要です。

Ubuntu のアップデート

Ubuntu を最新の状態にアップデートします。ここでは接続先を国内のミラーサイト(理研)に変更しています。日本から接続する場合はファイルの取得先を国内のものに変更したほうが早く進む感じがします。

sudo sed -i.bak -e "s%http://us.archive.ubuntu.com/ubuntu/%http://ftp.riken.go.jp/Linux/ubuntu/%g" /etc/apt/sources.list
sudo apt update
sudo apt upgrade -y

CAPE のための下準備

# essential
sudo apt install -y git make automake vim

# There are other optional dependencies that are mostly used by modules and utilities. 
sudo apt install -y python-dpkt python-jinja2 python-magic python-pymongo python-libvirt python-bottle python-pefile python-chardet swig libssl-dev clamav-daemon python-geoip geoip-database mono-utils

# for MongoDB
sudo apt install -y mongodb

# for Virtualenv
sudo apt install -y python python-pip python-setuptools python-virtualenv virtualenv

# for tcpdump (https://cuckoo.readthedocs.io/en/latest/faq/#tcpdump-permission-denied)
sudo apt install -y apparmor-utils
sudo aa-disable /usr/sbin/tcpdump

# for users who are not root (in this case, user name is "infected")
sudo usermod -a -G vboxusers infected
sudo groupadd pcap
sudo usermod -a -G pcap infected
sudo chgrp pcap /usr/sbin/tcpdump
sudo setcap cap_net_raw,cap_net_admin=eip /usr/sbin/tcpdump

# for VirtualBox
sudo apt install -y virtualbox
sudo vboxmanage hostonlyif create
sudo vboxmanage hostonlyif ipconfig vboxnet0 --ip 192.168.56.1 --netmask 255.255.255.0

Cuckoo ではデフォルトの DB として SQLite3 が採用されています。主に性能面から MySQL や PostgreSQL に変更することが推奨されていますが、小規模の利用であれば問題なさそうだったので CAPE でも標準の SQLite3 のまま進めます。

サンドボックス用の仮想マシンの準備

ここでサンドボック用の Windows 7 の準備をします。後述する読み替えが必要な箇所がありますが、以下のリンク先にある構築手順がベースとなっていますので手順詳細についてはそちらを参照してください。

CAPE のコンフィグファイルにも記載がありますが、いくつかの設定変更やパッケージをインストールしておくことで Powershell の解析などもできるようです。今回は単純に Emotet の通信先一覧が解析できるところまでを目的としているのでそこまで詳細な設定はせずに進めます。

CAPE のセットアップ

virtualenv venv-cape
. venv-cape/bin/activate

このコマンドを入力することで隔離された Python 環境に移行します。画面上ではプロンプトの先頭に (venv-cape) と表示されます。

f:id:soji256:20190526115553p:plain
Vitrualenv (venv-cape)

手順通りに進められれば適宜この隔離環境で操作するように記載をしていますが、予期せぬ操作などで手順から外れた場合には基本的には「. venv-cape/bin/activate」と入力して隔離環境にしてから操作を進めてください。以下では特段プロンプト表示は再現しませんが、この隔離環境にいることを前提として進めます。

# In order to properly function, Cuckoo requires SQLAlchemy and Python BSON to be installed.
pip install sqlalchemy bson

# To have MAEC support, you need to first install the Cybox and then the MAEC libraries:
pip install cybox==2.1.0.9
pip install maec==4.1.0.11

# for yara
sudo apt install -y libtool libjansson-dev libmagic-dev
pip install yara-python
wget https://github.com/VirusTotal/yara/archive/v3.10.0.tar.gz
tar -zxf v3.10.0.tar.gz
cd yara-3.10.0
./bootstrap.sh
./configure --enable-cuckoo --enable-magic
make
sudo make install
cd ../

# for Volatility
git clone https://github.com/volatilityfoundation/volatility.git
cd volatility
python setup.py install
cd ../
pip install distorm3 pefile

# for CAPE
sudo apt install -y pkg-config libvirt-dev libfuzzy-dev libgeoip-dev
git clone https://github.com/ctxis/CAPE
cd CAPE/utils/
python ./community.py --force --rewrite --all
cd ../
pip install -r requirements.txt
cd ../

# run services
sudo service clamav-daemon start
sudo systemctl enable clamav-daemon
sudo service mongodb start
sudo systemctl enable mongodb

CAPE の設定ファイルを修正する

ルーティングの設定はサンドボックス環境をインターネットに接続するための設定です。接続しない場合は修正不要です。

vi CAPE/conf/cuckoo.conf
[cuckoo]
#machinery = vmwareserver
machinery = virtualbox

[resultserver]
#ip = 10.152.152.128
ip = 192.168.56.1

[routing]
#route = none
route = internet
(snip)
#internet = none
internet = ens33

ネットワークパケットを取得するための設定です。

vi CAPE/conf/auxiliary.conf
[sniffer]
#interface = br0
interface = vboxnet0

メモリ解析のプロファイルを Windows7 にするための設定です。

vi CAPE/conf/memory.conf
[basic]
#guest_profile = WinXPSP2x86
guest_profile = Win7SP1x86

VirusTotal を利用しない場合の設定です。(ソースからはファイルそのものは送付せず、ハッシュ値とURLのみを送信しているように見えます。)

vi CAPE/conf/processing.conf
[virustotal]
#enabled = yes
enabled = no

VirtualBox 周りの設定です。

vi CAPE/conf/virtualbox.conf
[virtualbox]
#mode = gui
mode = headless

[cuckoo1]
#label = cuckoo1
label = Win7SP1x86
(snip)
# snapshot = Snapshot1
snapshot = cuckoo-cape
(snip)
# interface = vboxnet0
interface = vboxnet0

CAPE 用のネットワーク設定

ここでCAPE用のネットワーク設定をします。Cuckoo の設定と同様です。手順詳細については以下のリンク先の記事を参照ください。

cuckoo-rooter の準備

以下のコマンドで rooter.py をバックグラウンドで実行させます。その際 sudo をパスワード入力が求められる状態で打ち込んでしまうと失敗するので注意してください。もし失敗した場合は sudo pkill -f rooter.py と入力して失敗したプロセスを落としてから再度コマンドを入力します。

# for ifconfig
sudo apt install -y net-tools

# for cuckoo-rooter (stop/start)
#sudo pkill -f rooter.py
sudo python CAPE/utils/rooter.py /tmp/cuckoo-rooter -g infected &

CAPE を起動する

すべての準備が整ったので CAPE を起動します。

cd CAPE/
python cuckoo.py -d

以下のような表示が出れば正常に起動できています。

2019-05-25 18:37:23,512 [modules.machinery.virtualbox] DEBUG: Getting status for Win7SP1x86
2019-05-25 18:37:23,640 [modules.machinery.virtualbox] DEBUG: Machine Win7SP1x86 status saved
2019-05-25 18:37:23,660 [lib.cuckoo.core.scheduler] INFO: Loaded 1 machine/s
2019-05-25 18:37:23,678 [lib.cuckoo.core.scheduler] INFO: Waiting for analysis tasks.

別ターミナルを起動し、Web インターフェースを起動します。

# for venv-cape
. venv-cape/bin/activate

# for Cuckoo web
cd CAPE/web/
python manage.py migrate
python manage.py runserver

以下のような表示が出れば正常に起動できています。

Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
Performing system checks...

Web ブラウザから http://127.0.0.1:8000/ にアクセスすると CAPE の画面が表示されます。

f:id:soji256:20190526125925p:plain
CAPE WebUI - Top

画面上部にある「Submit」をクリックすることで解析設定画面に移ります。この画面から解析したいファイルや URL 等を設定します。マルウェアの種別が判明しているときには Analysis Package の項目から適切なパッケージを選択します。Yara による自動判定が優秀なので不明な場合はデフォルト設定のまま解析するので問題ないと思います。

f:id:soji256:20190526130051p:plain
CAPE WebUI - Submit

以下は Emotet を解析した場合の結果です。Emotet であると判定され、通信先一覧が抽出されていることが確認できます。

f:id:soji256:20190526125627p:plain
CAPE Report - Emotet (1/2)

f:id:soji256:20190526125803p:plain
CAPE Report - Emotet (2/2)

CAPE の挙動について

CAPE には Yara による自動判定機能を備えています。パッケージを指定せずに解析をした際に CAPE の自動判定の対象となるマルウェアであることが判明した場合には自動でパッケージを指定した状態での再解析が実行されます。この挙動は解析時のオプションとして No CAPE submissions (disable automatic job submission) を指定することで避けることができます。

再起動後に CAPEを使う場合

vboxnet0 と cuckoo-rooter の準備をしてやる必要があるみたいです。以下のコマンドを打ち込むとちゃんと起動してくれます。なお、WebUI の起動はカレントディレクトリの移動をしておかないとエラーになるのでご注意ください。

sudo vboxmanage hostonlyif ipconfig vboxnet0 --ip 192.168.56.1 --netmask 255.255.255.0
. venv-cape/bin/activate
sudo python CAPE/utils/rooter.py /tmp/cuckoo-rooter -g infected &

cd CAPE/
python cuckoo.py -d

# From another terminal
. venv-cape/bin/activate
cd CAPE/web/
python manage.py runserver

以上

参考文献

CAPE について

CAPE の導入手順について

yaraの導入手順について

エラー時に参考にしたサイトなど

付録

未解決:Failed to run signature RegBinary

解析中に以下のようなエラーが表示される場合がある。

2019-06-01 02:50:30,538 [lib.cuckoo.core.plugins] DEBUG: Analysis matched signature "antidebug_setunhandledexceptionfilter"
2019-06-01 02:52:33,021 [lib.cuckoo.core.plugins] ERROR: Failed to run signature RegBinary: unpack requires a string argument of length 2
Traceback (most recent call last):
  File "/** CAPE DIR **/lib/cuckoo/core/plugins.py", line 482, in run
    result = sig.on_call(call, proc)
  File "/** CAPE DIR **/modules/signatures/CAPE.py", line 124, in on_call
    self.reg_binary = IsPEImage(buf, size)
  File "/** CAPE DIR **/modules/signatures/CAPE.py", line 50, in IsPEImage
    machine_probe = struct.unpack("<H", buf[offset:offset+2])[0]
error: unpack requires a string argument of length 2

未解決:Failed to run signature critical_process & dep_disable

解析中に以下のようなエラーが表示される場合がある。検体とパッケージが合っていないときに出るようにも思う。

2019-06-01 02:42:08,360 [lib.cuckoo.core.plugins] DEBUG: Analysis matched signature "antidebug_setunhandledexceptionfilter"
2019-06-01 02:42:08,428 [lib.cuckoo.core.plugins] ERROR: Failed to run signature critical_process: int() argument must be a string or a number, not 'NoneType'
Traceback (most recent call last):
  File "/** CAPE DIR **/lib/cuckoo/core/plugins.py", line 482, in run
    result = sig.on_call(call, proc)
  File "/** CAPE DIR **/modules/signatures/critical_process.py", line 34, in on_call
    value = int(self.get_argument(call, "Value"))
TypeError: int() argument must be a string or a number, not 'NoneType'
2019-06-01 02:42:08,429 [lib.cuckoo.core.plugins] ERROR: Failed to run signature dep_disable: int() argument must be a string or a number, not 'NoneType'
Traceback (most recent call last):
  File "/** CAPE DIR **/lib/cuckoo/core/plugins.py", line 482, in run
    result = sig.on_call(call, proc)
  File "/** CAPE DIR **/modules/signatures/dep_disable.py", line 34, in on_call
    value = int(self.get_argument(call, "Value"))
TypeError: int() argument must be a string or a number, not 'NoneType'

未解決:何も表示されない Reports タブ

表示されそうで何も表示されないところがわたし、気になります。

f:id:soji256:20190602005951p:plain
Reports Tab

更新履歴

  • 2019/05/26 新規作成
  • 2019/05/29 再起動後にCAPEを起動する際のコマンドを修正
  • 2019/05/30 「Issue #251」 への対応手順を追記
  • 2019/06/01 「Issue #251」への対応手順の記載を削除(無関係の Issue であったため)。導入手順全体を再度検証して不要な手順を削除するなど整理。付録に未解決のエラーについての記載を追記。