CryptolockerのDGAを検証

Sousan Yazdi(ジュニア アンチウイルス アナリスト)
Margarette Joven(アンチウイルス マネージャー)
特別技術協力:Liang Huang(シニア アンチウイルス アナリスト)

CryptoLockerは昨年の終わりに登場したトロイの木馬型のランサムウェア ファミリーです。このマルウェアはマイクロソフトのWindowsシステムを標的とするよう設計されており、被害者のコンピュータ上のファイルを完全に暗号化し、それらのファイルを人質に取ります。被害者に対しては、暗号化されたファイルを回復する唯一の方法は身代金を支払うことだというメッセージが表示されます。たいてい、身代金として300米ドル、300ユーロ、あるいはその額とほぼ同等のデジタル通貨ビットコインが要求されます。多くの場合、ファイルを取り戻すために必要な復号鍵を入手するには72時間以内に支払いを行い、支払いを行わない場合は暗号鍵は削除され、ファイルを回復できないことが被害者に通知されます。

このトロイの木馬は、被害者のコンピュータで初めて実行された際にまず無作為の名前を使ってユーザーのApplication Dataフォルダに自身のコピーを作成します。それからautorunレジストリキーを作成し、感染したユーザーがログオンするたびに自動で先ほど作成したコピーを実行します。その後、標的とするファイルの暗号化に使用するRSA-2048鍵を生成するため、このマルウェアのコマンドアンドコントロール(C&C)サーバーの1つに接続を試みます。

このランサムウェアはC&Cサーバーへの接続が確立されてからのみ、ファイルの暗号化を開始しますので、このマルウェアがこうしたサイトと通信を行うのをブロックすることで、有害なペイロードが発生することを防ぐことが可能です。問題は、CryptoLockerがドメイン生成アルゴリズム(DGA)というものを使って潜在的なC&Cサーバーのリストを生成し、その中の1つをオンライン上で見つけて接続を試みようとすることです。

CryptoLockerにはさまざまな側面があり、そのすべてを分析し、検証することも可能ですが、このブログ記事ではこのマルウェアが使用するDGAの部分にのみ焦点を当てることとしましょう。

ドメイン生成アルゴリズム

ドメイン生成アルゴリズムは、感染したコンピュータとの通信を行うC&Cサーバがセキュリティ研究者や司法当局によって閉鎖されるのを困難にするため、数年前から使用されるようになりました。ハードコードされたドメイン名の固定リストをマルウェア本体内に入れると簡単に見つかってしまい、ブラックリストに載せられてしまうことが多いため、何千というドメイン名候補をすばやく生成できるDGAが用いられています。CryptoLockerで使用されているDGAは比較的シンプルなものですが、リバースエンジニアやマルウェアアナリストを混乱させるために長いループやジャンプで複雑化されています。

概略

まず、CryptoLockerは疑似乱数の鍵を生成し、それから0x3E8 (1000)のドメイン名を生成することが可能なループからDGAを呼び出します。ドメイン名が生成されると、生成された名前をパラメータとして使用してInternetConnectを呼び出します。接続がうまくいくと、ループ外へジャンプします。接続が失敗すると、1000ミリ秒という時間を置いた後に次のイテレーションが始まります。DGAに送られる鍵はイテレーションごとにインクリメントされます。


図1. 生成された鍵をパラメータとして使用してDGAを呼び出すループ

鍵の構築

上のスクリーンショットで示されるとおり、DGAを呼び出す前に鍵が必要となります。この鍵の構築は4段階で行われます。

第1段階:

その他多くの乱数生成器同様、CryptoLockerのDGAにはシードと鍵値が必要です。ループにおいてイテレーションごとに使用される鍵は、QueryPerformanceCounterとGetTickCountという2つのAPIのうち、どちらかから取り出される初期シードから生成されます。CryptoLockerはまずQueryPerformanceCounterを呼び出し、成功した場合には回収した値がシードとして保存されます。失敗した場合には、GetTickCountを呼び出します。このAPIの返り値、つまりシステムが起動してから経過したミリ秒の数字がシードとして保存されます。この初期シードがECXレジスタに格納されます。


図2. 初期シードの生成

この初期シードの値を使い、シード配列が生成されます。

第2段階:シード配列の生成

このシード配列には0x270(624)DWORDという決まったサイズあります。初期シード値はこの配列の冒頭部分に格納されています。これをAddress_Start_Arrayと呼ぶこととします。この配列に格納されることとなる次のシード値を得るため、SHR、 XOR、IMUL、ADD演算が適用されます。ループは0x270 DWORDを計算すると終了します。これが存在するアドレスをAddress_End_Arrayと呼ぶことにします。

下の図3はこの配列を構成する逆アセンブルコードです。


図3. シード配列を構成する逆アセンブルコード

図4は同等の疑似コードです。


図4. シード配列を構成する疑似コード

DGAで使用されるKEY値を生成するため、このシード配列の値に別の関数がアクセスします。これを次で見ていきましょう。

第3段階:シード配列の処理

配列の処理は最初の要素から配列の227番目のDWORD要素であるインデックス0xE3まで行われます。図5に示すように、計算アルゴリズムではADD、XOR、AND、SHR演算が用いられています。


図5. シード配列を処理する疑似コード

上の図5に見られるオペランド(Const_1 + ((Temp_a & 1)* 4))は、常に2つのうちのどちらかの定数値まで計算します。

  • [Const_1] = 0
  • [Const_1 + 4] = 0x9908B0DF

図5にはオペランド[(Address_Start_Array + 0x630) + (index*4)]も見られます。これは配列のインデックス0x18Cから配列の最後の要素までのDWORDを指します。

0xE3要素からの配列の残りの部分に対しては、さらに多くの計算が行われており、マルウェアのその他の部分で使われていますが、このブログ記事ではDGAを取り上げていますので、それらの計算に関しては省略します。では、KEYを計算するコードへ話を移しましょう。

第4段階:DWORD値の計算

この最後の段階では、以下の一連の計算が配列の2つ目の要素に適用されます。


図6. KEYを計算するための疑似コード

上の図1に示されるように、ここで得られる値がDGAアルゴリズムへ送られるKEYです。

ドメイン名の生成

CryptoLockerのDGAはKEY、現在の日にち、現在の月、現在の年という4つの値を使用します。最初の値であるKEYは上で解説した計算で得られています。残りの3つの値はAPI関数GetSystemTimeへの呼び出しで取得します。

4つすべての値に対して数学演算が行われ、その結果がドメイン名を生成するループへ送られます。

KEY

KEY値はMUL、SHR、IMUL、ADD演算を使って修正されています。これをNewKeyと呼ぶこととします。図7はこの計算のアルゴリズムです。


図7. NewKeyの計算

現在日

現在日の値に対しても計算が行われています。これにはSHLとXOR演算のみが用いられており、この結果をDayKeyと呼ぶこととします。


図8. DayKeyの計算

現在月

現在月もSHLおよびXOR演算を使って修正されています。同様に、この新たな値をMonthKeyと呼ぶこととします。


図9. MonthKeyの計算

現在年

現在年も修正されています。この計算ではADD、SHL、XOR演算が用いられており、その結果得られた値をYearKeyと呼ぶこととします。


図10. YearKeyの計算

文字列の長さ

各サーバー名の文字列の長さは次の計算で決定されます。


図11. サーバー名の長さを決定

名前の生成

上で計算されたパラメータは下のループで使用されます。これがサーバー名を構成する文字を生成します。


図12. サーバー名を構成する文字の生成

TLDの取得

サーバー名に追加されるトップレベルドメイン(TLD)は7つの文字列から選定されます。図1で示されているように、DGAはループ内で呼び出されています。このループ内の各イテレーションに対し、CryptoLockerは同じ順番でTLDリストを見ていきます。しかし、最初にどの文字列がくるのかは、図7の計算から得られるNewKey値によります。

TLD文字列はユニコード形式になっており、暗号化された形でマルウェアの本体に格納されています。CryptoLockerはどの文字列を最初に使うかを決定すると、シンプルなADDおよびXOR演算を使って文字列を復号し、TLDリストを構築し始めます。


図13. TLDリストの構築

下はTLDに使用される文字列とCryptoLockerがたどる順序です。


図14. TLDリスト

復号されたTLD文字列はワイド文字形式になっているため、まず文字列をマルチバイト形式に変換するため、API関数WideCharToMultiByteへ送られます。生成済みのサーバー名に文字「.」が連結され、その後に変換されたTLD文字列が続きます。こうして完成したドメイン名はAPI関数InternetConnectへ送られ、図1に示されるようにサーバーがアクティブかどうかをテストします。

CryptoLockerが生成するドメイン名には次のようなものがあります。

	sljjjupfgagolpg.ru
	uftfesnodnjflwta.info
	vxagtvsyqxtrfcm.com
	wxphewjnfhlyyjj.net
	xckjffnjivafxen.biz

最後に

CryptoLockerは昨年、最も有害なマルウェアの1つとして話題となりました。このマルウェアはメールを介して広まることで知られていますので、メールの添付ファイルを開いたり、リンクをクリックしたりする際には常に気をつけましょう。アンチウイルスソフトを最新に保ち、システムのパッチを行ってください。そしてファイルの回復をスムーズに行えるよう、(取り外し可能なハードドライブなどの)オフライン機器に定期的にデータをバックアップしましょう。