サポート情報 | フォーカスシステムズ サイバーフォレンジックセンター

お問い合わせはこちら
東京証券取引所 プライバシーマーク ISMS JUSE

サポート情報

ホーム > サポート情報一覧 > CryptoWallの通信(1回目)

CryptoWallの通信(1回目)

目次へ

 通信先のURLを得たため、いよいよ通信を行います。通信の内容は、暗号化開始までに大きく2回に分けて行われていることが判明しています。まずは、1回目の通信の流れを追跡し、「通信の手順」を明らかにしていきたいと思います。

 今回調査した検体では、まず通信のために必要なパラメータを算出しています。パラメータは、phpのアドレスの後ろの「?」以降のパラメータと、POSTパラメータの2種類があります。これらのパラメータのうち、ランダムに生成されるものと、利用しているPCの環境固有となるものが混在していました。

 処理の流れとしては、まずPCの固有の情報を収集します(【図99】参照)。データの内容をみると、数値の部分、CryptoWall固有の情報文字列(crypt13001)、PCの利用環境固有のハッシュ値(「PC毎固有の「ハッシュ値」の計算」で1回目に求めたハッシュ値)が含まれていることが確認できます。この情報のうち、数値の根拠は今回の調査では調べ切れていません。恐らく、何らかの環境情報ではないか、と考えています。

 この内容から考えると、「暗号化されたPCを個別に識別する情報と必要な環境情報」なのではないかと推測されます。

IDA_Cryptowall_Comm1_SendData1

【図99】通信のために収集する固有の情報

 

 次に、通信に使われるランダムな文字列を2つ生成します。この文字列は、最初に英小文字のみで生成し、さらにランダムな位置と数値を取得し、一部を数字に置き換えて生成します。また、2つ目のランダムな文字列は、生成されたバイナリ値をアスキー文字に変換しています(【図100】参照)。

IDA_Cryptowall_Comm1_SendData2

【図100-1】ランダムな英小文字を取得し、さらに一部をランダムな数値に置き換え(1つ目)

 

IDA_Cryptowall_Comm1_SendData3

【図100-2】ランダムな英小文字を取得し、さらに一部をランダムな数値に置き換え(2つ目)

 

 この後、【図99】の文字列に対し変換テーブルを用いて変換しています(【図101】参照)。この変換テーブルの生成方法までは解析しきれていませんが、生成の度に異なるため、何らかの生成ルーチンがあると考えられます。このテーブルのインデックスから得られた値とxorをとることで、【図101】のようなデータを生成しています。さらに、このバイナリ値を文字列化しています。

IDA_Cryptowall_Comm1_SendData4

【図101】PC固有の情報を変換した値

 

 これらのパラメータを用意したところで、URLとPOSTに設定するパラメータを生成します。

 まず、最初に作成したランダムな文字列の2つ目(【図100-2】)と、PC固有情報を変換し文字列化した値(【図101】)を用いてPOSTに用いる文字列を作成しています。ランダムな1文字 + 「=」 の後ろにこれらを結合してパラメータとしています(【図102】参照)。なお、この時何故かランダムな文字列の末尾1文字が欠けるようになっています。

IDA_Cryptowall_Comm1_SendData6

【図102】POSTのために編集されたパラメータ

 

 次に、URLの末尾に結合する文字列を生成しています。「通信先URLの展開」されたURLのマップの先頭にあるURLを取得し、そこから「/」以降の文字列を抽出します。さらに、その後ろにランダムな1文字 + 「=」を付与し、その後ろに最初に作成したランダムな文字列の1つ目(【図100-1】)を結合しています(【図103】参照)。

IDA_Cryptowall_Comm1_SendData7

【図103】URLのために編集されたパラメータ

 

 通信でCryptoWallが渡したいパラメータの生成が終わると、HTTP通信で必要となるユーザエージェント情報を、ObtainUserAgentString関数を用いて取得します(【図104】参照)。

IDA_Cryptowall_Comm1_SendData8

【図104】ユーザエージェント情報

 

 これらのパラメータの準備ができたところで、実際に通信を行います。以下のWindowsAPIを用いています。

 

●InternetOpenAWinInet関数の使用のための初期化処理。
●InternetSetOptionWinInet関数のオプションを設定する。Write(送信)およびRead(受信)のタイムアウトを設定するために用いている。
●InternetConnectInternet通信のためのセッションを確立する。
●HttpOpenRequestHTTP通信の要求ハンドルを作成する。
●HttpAddRequestHeadersHTTPリクエストヘッダに値を追加する。Content-Type、Connection、Content-Lengthを設定するために用いている。
●HttpSendRequestExHTTPサーバに指定された要求を送信する。
●InternetWriteFileHTTPサーバへ送信処理を行う。
●InternetReadFileHTTPサーバからの受信処理を行う。
●HttpEndRequestHttpSendRequestExで行ったリクエストを終了する。
●InternetCloseHandleInternetOpenA、InternetConnect、HttpOpenRequestで得た通信用ハンドルを閉じる。

 

 各処理の詳しい解説は、プログラムの仕組みの解説になってしまうので、細部は開発系の専門書を参照してください。各処理実行時の画面ショットは【図105】のとおりです(ページ下部にまとめて掲載)。

 解析に関するトピックとしては、「InternetSetOption」について今回細工を行っています。この関数を用いて送信、受信のタイムアウトをそれぞれ120秒に設定しています。しかし、解析中にブレークポイントで停止しながら作業をしていると、120秒ではタイムアウトが発生してしまうことがあります。そのため、実行時にスタックの値を「0x006DDD00」(2時間)に変更して解析を進めました。このパラメータが100%適用されているかは不明ですが、このようにパラメータの意味を理解した上で、解析のために一部パラメータを変更することも一つの重要なテクニックといえるでしょう。

 さて、この処理で問題なのは、受信時の処理です。受信データをどのように処理しているのでしょうか?

 リストにあるC&Cサーバが全て利用可能であれば、CryptoWall側としては問題ないのですが、場合によってはサービスがダウンしたり、見つかってphpファイルを削除されて閉鎖されたりしている可能性があります。そのため、通信では、まず所定のリターンが得られているかチェックし、失敗していれば「通信先URLの展開」で作成されたURLマップから、次のURLを抽出してリトライしています。これを、通信が成功するまで続けています。

 例えば、サーバは存在するものの、phpがない場合、【図106-1】のようなレスポンスが帰ってくることがありました。

IDA_Cryptowall_Comm1_Recieve1

【図106-1】受信データ例(C&Cサーバが無効化されている場合)

 

 これは、Webサーバが当該URLのファイルがないことを返してきています。この受信データを受け取った場合、チェック処理でエラーとしています。

 CryptoWallの受信データ解析プログラムは、バイナリ値を文字列化したデータを受け取ることを前提に作られています。そのため、受信データに対して「sscanf(data, “%02x”, buf)」を行いますが、【図106-1】のようなリターンの場合、正しく変換されません。そして、受信データ解析処理でエラー(このURLは無効)と判定されるのです。

 そのため、通信が成功するまで繰り返したところ、以下のようなデータを受信することができました(【図106-2】参照)。

IDA_Cryptowall_Comm1_Recieve2

【図106-2】受信データ例(C&Cサーバが有効な場合)

 

 受信データをみると、16進数を文字列化したような内容で、sscanfで復元できそうです。HTTP通信であることから、通常はHTML形式のテキストデータを受信すべきところであることを考えても、明らかに怪しいデータです。

 この情報をsscanfでバイナリ値に変換した後、再びテーブルとxorを用いた変換処理を行っていました。すると、数字のパラメータが格納されていることが分かりました(【図107】参照)。

IDA_Cryptowall_Comm1_Recieve3

【図107-1】sscanfでバイナリに変換した結果

 

IDA_Cryptowall_Comm1_Recieve4

【図107-2】変換テーブルで変換し、前後の「{」「}」を除いた結果

 

 この数値パラメータの意味するところは詳しくは分かっていませんが、前半の値「186」を16進数に換算して「0x000000BA」とし、これに「0x000003E8」を掛けた値を格納していることが分かっています(【図108】参照)。また、後半の値もそのまま格納されています。この通信では、この値を受信することが目的だったと言えるでしょう。ということは、この段階では、まだ暗号に使われる鍵に関する情報のやりとりは行っていない、ということがわかります。

IDA_Cryptowall_Comm1_Recieve5

【図108】受信で得たパラメータから算出された値を格納している

 

 通信が成功すると、新たなスレッドを生成する処理を行います。暗号化に関する重要な通信や準備は、このスレッドで行われることになります(【図109】参照)。

IDA_Cryptowall_CreateThread

【図109】新たなスレッドの生成

 

< 通信先URLの展開 目 次CryptoWallの通信(2回目) >

 

 

 

(以下、【図105】の画面ショットを掲載)

 

IDA_Cryptowall_Comm1_proc1

【図105-1】通信APIの状況(InternetOpenA)

 

IDA_Cryptowall_Comm1_proc2

【図105-2】通信APIの状況(InternetSetOption)

 

IDA_Cryptowall_Comm1_proc3

【図105-3】通信APIの状況(InternetSetOption)

 

IDA_Cryptowall_Comm1_proc4

【図105-4】通信APIの状況(InternetConnectA)

 

IDA_Cryptowall_Comm1_proc5

【図105-5】通信APIの状況(HttpOpenRequestA)

 

IDA_Cryptowall_Comm1_proc6

【図105-6】通信APIの状況(HttpAddRequestHeaders)

 

IDA_Cryptowall_Comm1_proc7

【図105-7】通信APIの状況(HttpAddRequestHeaders)

 

IDA_Cryptowall_Comm1_proc8

【図105-8】通信APIの状況(HttpAddRequestHeaders)

 

IDA_Cryptowall_Comm1_proc9

【図105-9】通信APIの状況(HttpSendRequestExA)

 

IDA_Cryptowall_Comm1_proc10

【図105-10】通信APIの状況(InternetWriteFile)

 

(※受信の通信はInternetReadFileを繰り返し行っている。画面ショットなし。)

 

IDA_Cryptowall_Comm1_proc11

【図105-11】通信APIの状況(HttpEndRequestA)

 

IDA_Cryptowall_Comm1_proc12

【図105-12】通信APIの状況(InternetCloseHandle)

(※InternetOpenA、InternetConnectA、HttpOpenRequestAで取得したハンドルに対して行う)