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

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

サポート情報

ホーム > サポート情報一覧 > 「攻撃する側の論理」からのプログラムの推察

「攻撃する側の論理」からのプログラムの推察

目次へ

 このページでは、解析で得られた情報から、攻撃者がどのようなことを企図し、現在のCryptoWallの姿になったかを推察してみたいと思います。あくまで、「こういう内容から、こういう意図が考えられる」という推測の域から出ないものであることはご了承ください。ただ、プログラムは「目的を達成」するために書かれていることから、推察から得られる「攻撃者像」は「人の行動原理」に基づいた対策のヒントになるのではないか、と思います。

 

1.複数人による作成

 今回解析したCryptoWallは、作成に関わった人間は複数人いるものと考えられます。プログラムの作りは、開始直後からプログラム本体の書き換え部分(「マルウェアの内部を解析する」~「展開されたプログラムの行き先」の処理)と、書き換えられたプログラムのスレッド起動以降の処理(「新しいスレッドの追跡」以降)の処理で大きく2つに分かれています。これは、前半部分がプログラム本体の解析を困難にするための「パッカー」で、後半部分が「ランサムウェア本体」と言えます。

 この区別は、機能を考えても推測できますが、解析時の「プログラムの作りの違い」からも見て取れます。

 まず、APIの呼び出し方法が違います。「パッカー」部分では、VirtualAllocを実行するためにretnを使用した呼び出し方をしており、それ以外のAPIを呼び出す場合にもGetProcAddressを用いてアドレスを取得してcallで実行しています。一方、「ランサムウェア本体」部分では、ImportTableを自作し、そのアドレスを基点としたオフセットからAPIのアドレスを取得してcallで実行しています。

 APIの使用にも特徴があります。「パッカー」部分では、仮想メモリの利用はVirtualAllocとVirtualFreeを使用していますが、「ランサムウェア本体」部分では、NtAllocateVirtualMemoryとNtFreeVirtualMemoryを用いています。また、メモリ内部をゼロクリアする際にも、「パッカー」部分ではRtlZeroMemoryを使用し、「ランサムウェア本体」部分ではmemsetを使用しています。

 プログラムの作りも違います。

 「パッカー」部分ではメモリ開放時にRtlZeroMemoryによるゼロクリアを行っていますが、「ランサムウェア本体」部分では行っていません。また、「パッカー」部分ではプログラム自身も難読化していたり、アンチデバッグと思われる仕組みを組み込んだりしています。

 「仮想メモリ内のWindows API使用フロー」の中ではあまり詳しく触れませんでしたが、【表1】の[01F3B]~[02087]で、GetTickCount、Sleep、GetTickCountを行っています。実は、2回目のGetTickCountの後、1回目のGetTickCountの結果との差分を比較し、15秒以上差があれば正常のルートに行くようになっています。Sleepの時間が16秒に設定されており、一見すると正常ルート以外にいくはずがないと思います。これは推測ですが、サンドボックスの中に、検査速度を上げることを目的として、Sleepがある場合はスキップするような製品があるのではないでしょうか?もしSleepをスキップするならば、2回のGetTickCountの間隔は15秒に満たなくなり、検知されないように処理を終了してしまうのではないかと思われます。また、サンドボックスでSleepが有効な場合、検査期間が16秒未満であれば、やはり以降の処理の判定が行われず、すり抜けてしまいます。難読化も含め、「検知逃れ」に留意していることが見て取れます。

 一方で、「ランサムウェア本体」部分では「検知逃れ」を意図的に行っている様子はありませんでした。新たなプロセスやスレッド起動はありますが、あくまで機能的に必要に駆られて行っているだけで、「検知逃れ」を企図しているようでは無さそうです。

 これらのことから、「パッカー」部分と「ランサムウェア本体」部分は別の人間が作ったと見るのが妥当だと思います。もちろん、それぞれについて複数人で開発している可能性もありえます。「ランサムウェア本体」開発者が、検知逃れのためにアンチセキュリティに長けた開発者が作成した「パッカー」を、何らかの方法で入手して利用している、と考えるべきでしょう。

 

2.既存リソース利用による省力化

 「CryptoWallによる暗号化処理(前編)」と「CryptoWallによる暗号化処理(後編)」で述べたとおり、CryptoWallではCryptoAPIを用いて暗号化を行っています。これは、独自に強度の高い暗号化処理を自作するより、現在暗号強度が十分とされている利用可能な機能を利用するほうが、はるかに開発が楽であることが理由として考えられます。また、オリジナルコードの場合、特徴的な部分が検知の対象になりえますが、OS標準のAPIの利用は正規の利用との判別が難しく、検知しづらいことも見逃せません。

 API以外にも、既存のロジックを利用している形跡があります。「CryptoWallの通信(1回目)」や「CryptoWallの通信(2回目)」で、独自の変換テーブルを用いた変換を行っている、ということを書きました。これは、0x00~0xFFまでの値が順に入った256バイトのマップをシャッフルし、マップ参照した結果とxorを取り、マップの一部分をまたシャッフルするという、1バイト単位のストリーム暗号のように見られました。そのため、公開されているストリーム暗号のアルゴリズムを調べたところ、「Arcfour」のサンプルコードの挙動と酷似していることが分かりました。「Arcfour」は、非公開とされるRC4アルゴリズムと相互運用可能といわれており、実質RC4の暗号文作成や復号に利用できるものと思われます。そのため、このソースコードを流用したか、ライブラリをスタティックリンクしたことにより、実際の処理が埋め込まれていたのではないかと思われます。

 この仮定が正しいとすると、サーバ側でも同じアルゴリズムの利用が考えられます。また、RC4であれば、既存のサービスやライブラリの利用での省力化の可能性もあります。同様の省力化として、PNG部分の復号も、Base64のソースコードを利用したのではないか、と考えられます。

 このように、APIやフリーのライブラリ等を使うことで省力化し、短期間での開発、改修を行っているものと考えられます。

 

3.複数人使用の想定

 「CryptoWallの通信(2回目)」では、受信した結果の中に、torやURLのアドレス情報が含まれていたことが判明しています。また、脅迫文のPNGも含まれています。これは、CryptoWall本体内にある脅迫文のtorやURLのアドレス部分を、実行時に編集できるための仕組みと言えます。また、PNGはそのような編集ができないため、予め編集されたPNGを添付するようにしているものと思われます。

 「CryptoWallによる暗号化処理(前編)」では、拡張子の判定を2回行っています。1回目の判定は暗号化対象外の拡張子を判定し、1回目の判定にかからなかった場合に2回目の暗号化対象の拡張子を判定しています。普通に考えると、暗号化対象の拡張子をしっかり管理しておけば、1回目の判定は要らないように思えますが、なぜ2回にわけているのでしょうか?

 この答えを推測するのに、実は特徴的な部分がコード内にあるのです。1回目の判定は【図147-1】、2回目の判定は【図147-2】のとおりです。このとき、1回目の判定では、判定対象の拡張子のコードはスタックメモリ上にあります。そして、これは関数の最初の部分で直接値を設定しています。つまり、1回目の判定のための暗号化対象外の拡張子は、オンコードされているのです。一方、2回目の判定は【図147-3】の[2E8C8]以降のデータを参照しています。これは、通常のプログラムのデータセグメントに当たる部分だと考えられます。通常の開発でのリソースエリアであることが予想されることから、「2回目の判定対象は、任意で追加、削除ができるように作ってあるのではないか」、と考えられるのです。

 この2点を見ると、このランサムウェアの開発者は「不特定多数の攻撃者によって使用される」ことを企図しているのでは、と考えることができるわけです。

 1点目のtorやURLのアドレスやPNGデータを通信で受信し、脅迫文を生成するのは、それぞれの攻撃者個別の情報を埋められるようにしているからに他ならないと思います。このことから、「通信先URLの展開」で展開されるデータもまた、それぞれの攻撃者が「URL文字列長」+「URL」・・・のデータをRtlCompressBufferで圧縮し、RC4で暗号化して格納しているものと思われます。

 2点目の拡張子判定の2重化についても考えて見ます。1回目の暗号化対象外拡張子では開発者が「OSが起動しなくなるような不具合を発生させないために」ハードコードしてでも暗号化を回避していると考えられます。確認まではしていませんが、恐らく、exe、dll、bat、sys、iniなどがヒットするのではないかと思われます。もちろん、これらを2回目の暗号化対象拡張子に含めなければ良いですし、「作った本人」は重々承知しているはずです。その上で行っているということは、2回目の暗号化対象拡張子は、「作った本人」以外が任意に変更して利用した場合に、不用意な拡張子の追加をしてもOSの動作に影響を与えないための安全対策、とみることができるのです。

 こうして、個々の攻撃者が任意にC&CになるWebサーバを用意してURLリストを作り、暗号化する拡張子を設定してランサムウェアをカスタマイズして、ドライブバイダウンロードを行うためのキットに組み込む、という構図ができあがるのでは、と推測できるのです。

 

4.「身代金」を支払わせるための方策

 被害者側からすればたまったものではないですが、解析したCryptoWallでは様々な「身代金」を支払わせるための細工が施されています。

 第1に、「CryptoWallの脅迫文の生成とファイル出力」で触れたとおり、5ヶ国語による脅迫文の生成が行われます。これは、脅迫を受けた被害者が、なるべく母国語で脅迫文を読めるようにすることで、状況を正確に理解できるようにしています(そんなやさしさがあるなら、最初から攻撃して欲しくないのですが)。

 第2に、ユーザ自身ではデータを復元できない工夫がされています。ファイルの暗号化のために、現代では「暗号強度が十分」で容易に復号化できない方式を使っています。また、VSSのデータを削除することで、データの復元の可能性を減らそうと試みます。この結果、データを戻すためには「暗号鍵と復号ツール」を購入しなければならないようにしています。

 第3に、復号に関しては、割と真剣に作っているフシがあることです。「CryptoWallの暗号化レイアウト」でも触れたとおり、ファイルの先頭には公開鍵のバイナリ値をMD5でハッシュ化した値が16バイト格納されています。そこでも述べたとおり、ファイルの先頭のチェックをこのハッシュ値かどうかを比較することで、既に暗号化されたファイルかを判定しています。しかし、「それだけ」が目的であれば、何もわざわざ公開鍵のハッシュ値を計算しなくても、端末固有のハッシュ値を用いても良いはずです。それどころか、「WellcomeToCryptoWall!!」のような文字列でもかまわないはずです。その上であえて公開鍵のハッシュ値をヘッダに設定しているのは、やはり単独のファイルでも「暗号鍵と公開鍵のペア」情報と紐付けられるようにしてある、と考えるほうが合理的ではないでしょうか。こうしておけば、「何らかの理由」でユーザ自身の情報が失われても、「暗号鍵と公開鍵のペア」さえ残っていれば、暗号化されたファイルのサンプルを1つ送ってもらえれば「暗号鍵と公開鍵のペア」が特定できるわけです。

 こう言えばもっともそうですが、「そもそも犯罪者である攻撃者がそこまで頑張って保障してくれるか?」という疑問が沸くかと思います。私は、「攻撃者は頑張って保証するのに十分な動機がある。」と考えます。理由は、彼らの目的は、「感染者から身代金をもらう事」が最大の目的だからです。

 考え方はこうです。もし仮に、CryptoWallによって暗号化されたファイルが、身代金を払っても上手く復号化できなかったとしたらどうなるでしょう?最初のうちのいくらかの被害者は、脅迫に応じて身代金を払うこともあろうかと思います。しかし、その結果受け取ったツールで復号化できなかったとしたら、今の時代その話がすぐにネットで拡散されてしまいます。「CryptoWallで暗号化されたら最後、身代金を払ってツールを受け取ってもファイルは復元できない」なんて話が広まったら、誰が身代金を払うというのでしょうか?つまり、攻撃者は、確実に復号化できるようにすることで、「身代金を払えば、データは確実に戻せる」という被害者との「奇妙な信頼関係」が必要なのです。

 プログラムの作りから、攻撃者のこういった一面も感じ取ることができます。

 

5.目的達成のために必ずしも難しい処理は必要ない 

 今回解析したCryptoWallは、感染したユーザの権限のままで動作し、目的を達成するように作られています。マルウェアによっては、User権限からAdministratorの権限への昇格のためにログインを辞書攻撃などで試行したり、Ring0(カーネルモード)の取得を試みようとしたりします。また、感染拡大のために、ネットワーク上の他のPCの捜索や接続を試みるケースがあります。

 CryptoWallは、解析した範囲ではこのような挙動は認められませんでした。無論、今回使用したPCは解析用にインターネット接続しているだけで、他のPCが同一セグメント上にありませんし、この後の処理で行っていないかまでは確認していません。しかし、攻撃者としてはそういったことをするまでもなく、目的を達成できるのです。そのため、そういった「無駄な」努力はしていないのです。むしろ、そのような挙動がかえって「検知」を招く恐れもあり、攻撃者にとってメリットが無いのではないでしょうか。このことから、シンプルに必要な機能を実装し、難しいことをしなくても目的を達成できるように作るようにしているのではないかと考えられます。

 

6.解析されることを前提としている可能性 

 今回解析したCryptoWallは、「パッカー」部分と「ランサムウェア本体」部分で大きく分かれていると考えられ、「ランサムウェア本体」は検知逃れを意図的に行っている様子が無いことは既に述べました。今回のような「デバッガによる解析」についても、同様の傾向があるように思われます。

 この理由は、「ランサムウェア本体」部分の開発者に「解析逃れ」の知識が無かった可能性もありますが、一方で、「仮に解析されても、暗号化されてしまえば、ファイルの復号はできない。」と考えて、「解析逃れ」の労力を省略したことが考えられます。この労力とは、開発時に「解析逃れ」のロジックを組み込むことの手間のほか、複雑になることで「バージョンアップ」のための改修でも労力が増えるほか、複雑な処理はバグの温床になりやすく、問題発生時の原因究明等の労力も含みます。

 「ランサムウェア本体」部分の開発者が「解析逃れ」に対するモチベーションが低い理由を考えて見ましょう。

 仮に今回のように、暗号化処理の流れがつまびらかになり、暗号化されたファイルの内容などが分かっても、「それでも、暗号化されたファイルは戻せない」と考えているためではないか、と思われます。今回、ファイルの暗号化に用いられた方式は、ファイルデータは「AES256」のブロック暗号、その鍵は「RSA公開鍵暗号」であることが分かりました。ともに、暗号強度を証明されているものです。そのため、「CryptoWallの暗号化レイアウト」で述べたとおり、差し押さえたC&Cサーバから暗号鍵と公開鍵のペアを差し押さえるなどの方法でしか、現在のところは被害者の救済の目処が立ちません。

 同様の姿勢は、通信データの送受信にもいえます。RC4を用いており、その鍵に乱数を使っている見込みであることから、そこをさらに重点的に調査すれば、正確にどのパラメータを鍵としているかを解析できるでしょう。そして、被害者のセキュリティ対策でpcapデータを保持していれば、送受信のデータから内容を復元できるでしょう。しかし、暗号化通信の復元ができ、内容を知ることができたとしても、被害の救済には繋がらず、結局「後の祭り」であることに変わりはありません。

 このことから、「ランサムウェア本体」部分の開発者は、「本体が解析されても、ファイルが復元できない以上、被害者は身代金を払うか、諦めるかの二択しかない。」と考えているのではないかと思います。そして、「ランサムウェア」としては、あくまで感染時や実行時に「検知」されなければいいのです。「ランサムウェア本体」部分の解析が容易だったことから、こういった攻撃者の思想が見えてくるのではと思います。

 

 今回の解析結果から、「攻撃する側の論理」を推察してみました。プログラムの作り、動き方、データの内容や編集方法から、攻撃者の「意図」や「思想」が垣間見えると考えています。これは、「マルウェアの検知」という喫緊の課題へ対応する一方で、マルウェアの開発者や攻撃者といった犯人像や今後の傾向を予測することに寄与できるのでは、と思います。

 

< CryptoWallの暗号化レイアウト目 次おわりに >