ブログ

FFRI BLOG

2013-05-29 ご家庭でできる簡単マルウェア自動解析システム


先端技術研究部の本郷です。

今回は、マルウェア自動解析システムを作って、解析結果を集計してみたいと思います。

題して「ご家庭でも簡単にできるマルウェア自動解析システムの作り方」です。


はじめに

1日あたり10万もの新種マルウェアが発生していると言われています 。

膨大なマルウェアを手動で解析していくのは非現実的ですので、自動で解析する仕組みが必要になります。

システムの構築

まず、マルウェアを自動解析する部分では、Cuckoo SandboxというOSSの自動解析システムを使用します。

Cuckoo Sandbox
http://www.cuckoosandbox.org/

現在はバージョン0.6が最新版となっています。

インストールは少々癖がありますが、ここはがんばってドキュメントを参考にインストールしたことにします。

Cuckoo Sandboxはデフォルト設定では、レポートをHTML形式とJSON形式で出力します。MongoDBへのデータ転送をサポートしていますので、ここでは、この機能を使い、解析結果をMongoDBに蓄積したいと思います。

その前に、MongoDBサーバーを立てておく必要があります。こちらはCuckoo Sandboxに比べると簡単にインストールできます。

MongoDB
http://www.mongodb.org/

インストールできたら、

Cuckoo Sandboxの<Install Dir>/conf/reporting.confの設定を変更します。

<変更前>

[mongodb]
enabled = off

<変更後>

[mongodb]
enabled = on
host = <MongoDBのIP>
port = 27017(デフォルトの場合)

これだけです。簡単ですね。

使ってみる

・Cuckoo Sandbox

これで構築、設定が完了です。実際に使ってみたいと思います。

まず、以下のスクリプトを実行して、解析したいファイルを登録します。

$ python <Install Dir>/utils/submit.py <ファイルを配置したパス>

あとは、以下のスクリプトを実行して、解析を開始するだけです。

$ python <Install Dir>/cuckoo.py

これで、数分待てば、レポートが出力されます。

レポートは以下のパスに出力されます。

<Install Dir>/storage/analyses/<タスクID>/reports

Cuckoo SandboxにはWebUIも用意されています。WebUIを使用する場合は、以下のスクリプトを実行します。

$ python <Install Dir>/utils/web.py

ブラウザでアクセスすると次の画面が表示されます。

Cuckoo Sandbox

フォームに解析したいファイルを指定し、Submitボタンを押すと解析が始まります。

解析結果は以下のように出力されます。

Cuckoo Sandbox 解析結果

・MongoDB

ここで、MongoDBに保存されたデータを見てみましょう。

以下のコマンドを実行します。

$ mongo cuckoo
> db.analysis.find()

このままでは見づらいのでJSON形式で表示してみます。

> db.analysis.find().forEach(printjson)

デフォルトでは、cuckooデータベースのanalysisコレクションにデータが保存されます。

0.6からAPIトレースの部分はcallsコレクションに保存されるように変更されました。

MongoDBで集計してみる

せっかくMongoDBにデータを入れたので、MapReduce を使って集計をしてみます。

今回はマルウェアがコールしたAPIの数をカウントしてみます(もちろんマルウェアがアクセスしたドメイン名やIPアドレスをカウントして、ブラックURLを作ることもできます)。

まず、map関数を書きます。

var map = function() {
  var id = this._id;
  this.calls.forEach(function(call) {
    var key = {
      api: call.api
    };
    emit(key, {count: 1});
  })
}

map関数で、マルウェアごとの解析結果をKey-Valueで受け取り、APIごとに新しいKey-Valueを作成し、reduce関数に渡しています。

次にreduce関数を書きます。

var reduce = function(key, values) {
  var sum = 0;
  values.forEach(function(value) {
    sum += 1;
  });
  return {count: sum};
}

reduce関数で、map関数で作成したKey-Valueを受け取り、カウントを行います。

最後にmapreduceを起動するメインの部分を書きます。

var mongo = new Mongo('localhost');
var db = mongo.getDB('cuckoo');
 
var res = db.calls.mapReduce(map, reduce, {out: 'api_count'});
shellPrint(res);

localhostにあるcuckooというデータベースのcallsコレクションを対象にMapReduceを実行し、api_countというコレクションに結果を出力します。

これらをapi_count.jsという名前でひとつのファイルに保存します。

以下のコマンドを実行すると、集計処理が始まります。

$ mongo api_count.js

それでは、結果を見てみましょう。

MongoDBに保存した結果を見るため、以下のコマンドを実行します。

$ mongo cuckoo
> db.api._count.find().sort({“value.count”: -1})

次の結果が表示されます。

MongoDB結果

1000検体で呼び出されているAPIの数を降順で表示してみました。

RegOpenKeyExやRegQueryValueEx、NtReadFileやNtWriteFileが多く呼ばれているようです。もちろん蓄積した情報からアクセスしたレジストリキーやファイル名も特定することができます。

今回は、マルウェアによって呼び出されたAPIをカウントするだけの簡単な例でしたが、正常なアプリケーションの挙動情報も蓄積し、マルウェアの挙動情報と比較して、様々な分析に使えそうです。

いかがだったでしょうか。最近はビッグデータがバズワード的に使われ、どこもかしこもビッグデータですが、マルウェアの情報をネタに分析してみるのも面白いかもしれませんね。



関連記事

マルウェア自動解析ツール「FFR yarai analyzer」の導入事例紹介

マルウェア解析の実態

Adobe Reader のサンドボックス機構を迂回するゼロデイ脆弱性