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

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

サポート情報

ホーム > サポート情報一覧 > CryptoWallによる暗号化処理(後編)

CryptoWallによる暗号化処理(後編)

目次へ

 CryptoWallによるファイルの暗号化処理では、やはりCryptoAPIが用いられています。理論上、暗号化されたファイルは、それ自体を解読するのは困難だと思われます。

 しかし、仕組みや内容を知ることで、別の簡単な解決策が見つかる可能性もあります。また、挙動から検知のする方法が見つかるかもしれません。中身を知った上で、知恵をだしていきたいところです。

 ファイルの準備ができると、暗号化のためにCryptAquireContext関数で暗号化サービスプロバイダ(CSP)のキーコンテナへのハンドルを取得します(【図152】参照)。サービスプロバイダには、「Microsoft Enhanced RSA and AES Cryptographic Provider」を指定しています。

IDA_Cryptowall_CryptAcquireContext_AES

【図152】キーコンテナへのハンドル取得

 

 次に、CryptAquireContextで得たハンドルを使用し、CryptGenKeyによって鍵の生成を行っています(【図153】参照)。解析では、この時に得られるハンドル値に特に注意が必要です。

 この時のパラメータを注目すると、アルゴリズムIDにCALG_AES_256(0x00006610)、フラグにCRYPT_EXPORTABLE(0x00000001)が指定されています。このことから、AES 256bitでの暗号化を目的としていることが分かります。

 この後、鍵ハンドルを用いてCryptGetKeyParam APIでキー情報を得ています。

IDA_Cryptowall_CryptGenKey_AES1

【図153-1】暗号鍵の生成処理

 

IDA_Cryptowall_CryptGenKey_AES3

【図153-2】暗号鍵生成によって得られた鍵ハンドル

 

 引き続き、暗号化のためのパラメータの設定が行われます(【図154】参照)。

・パディングのモードをPKCS5_PADDINGに設定

・暗号化のモードをCRYPT_MODE_CBCに設定

初期化ベクトルを0に設定

 IDA_Cryptowall_CryptSetKeyParam_AES1

【図154-1】暗号化時のパディングのモードをPKCS5_PADDINGに設定

 

IDA_Cryptowall_CryptSetKeyParam_AES2

【図154-2】暗号化時のモードをCBCに設定

 

IDA_Cryptowall_CryptSetKeyParam_AES3

【図154-3】暗号化時の初期化ベクトルをオール0に設定

 

 こうして暗号化の準備ができた鍵ハンドルから、BLOB形式で鍵をExportしています(【図155】参照)。

 IDA_Cryptowall_CryptExportKey_AES1

【図155-1】鍵のExport処理

 

IDA_Cryptowall_CryptExportKey_AES2

【図155-2】Exportされた鍵

 

 AES 256の鍵が作成、抽出できたところで、CryptDuplicateKeyで鍵の複製が行われます(【図156】参照)。

 この時に注意が必要なのは、複製元の鍵ハンドルが、スレッドの呼び出し時に引数で渡された、公開鍵のハンドルであることです。

 直前の処理までAESの鍵ハンドルを使用していたため、うっかり見落としがちですので注意が必要です。

 そして、この複製された鍵を用いて、先ほど抽出したAES 256の鍵を暗号化しています(【図157】参照)。つまり、このExportされたAES256のBLOBデータは、受信した公開鍵のペアの秘密鍵がないと復号できないことを意味します。

 暗号化が終わると、複製された鍵をCryptDestroyKeyで開放しています。

IDA_Cryptowall_CryptDuplicateKey_Public1 IDA_Cryptowall_CryptDuplicateKey_Public2

【図156】公開鍵の複製

 

IDA_Cryptowall_CryptEncrypt_Public1

IDA_Cryptowall_CryptEncrypt_Public2

【図157】AES256の鍵を公開鍵で暗号化

 

 AES256の鍵を暗号化したところで、最初のファイルの書き込みが行われます(【図158】参照)。

 最初に、公開鍵のハッシュ値をファイルに出力しています。これは様々な目的が考えられます。既に、「CryptoWallによる暗号化処理(前編)」でも触れていますが、既にファイルが暗号化されているかの判定に用いられています。それ以外の目的についても、後に考察してみたいと思います。

 次に、暗号化されたAES256の鍵をファイルに出力しています。この鍵はファイル本体の暗号化に用いられることが予想されますが、このことからそのファイルの暗号化に用いた鍵は、暗号化されたファイルの17バイト目以降の256バイトのデータとして格納されていることが分かります。

 3番目に、バイナリ値を4バイトファイルに出力しています。この値の意味は残念ながら追跡できていません。

IDA_Cryptowall_EncriptedWriteFile1

【図158-1】公開鍵ハッシュ値のファイル出力

 

IDA_Cryptowall_EncriptedWriteFile2

【図158-2】暗号化されたAES256鍵のファイル出力

 

IDA_Cryptowall_EncriptedWriteFile3

【図158-3】4バイトバイナリ値のファイル出力

 

 以上のファイル出力が終わったところで、今度はAES256鍵をCryptDuplicateKeyで複製します(【図159】参照)。

 複製された鍵を用いて、暗号化が行われます(【図160】参照)。この時対象になるのは、暗号化されるファイルの名前です。CryptWallでは、ファイルをランダムな名前に置き換えてしまうので、元に戻すためのファイル名をAES256で暗号化している、というわけです。

 暗号化が終わると、使用された鍵はCryptDestroyKeyで破棄されます。

IDA_Cryptowall_CryptDuplicateKey_AES1

【図159】AES256鍵の複製

 

IDA_Cryptowall_CryptEncrypt_AES1

IDA_Cryptowall_CryptEncrypt_AES2

【図160】ファイル名を暗号化

 

 ファイル名の暗号化が終わると、暗号化されたファイル名をファイルに出力しています(【図161】参照)。この時、4バイトの暗号化されたファイル名のサイズ+暗号化されたファイル名となるように出力されています。

 ファイル出力が終わると、FlushFileBuffer APIで1度ディスクに出力が行われます。

IDA_Cryptowall_EncriptedWriteFile4

【図161-1】暗号化されたファイル名のサイズのファイル出力

 

IDA_Cryptowall_EncriptedWriteFile5

【図161-2】暗号化されたファイル名のファイル出力

 

 ファイル名の出力が終わると、ファイル本体を読み込み、暗号化する処理が行われます。

 既にオープンされているファイルをReadFile APIで読み込みます(【図162】参照)。

 続いて、ファイル名を暗号化したのと同様にAES256鍵を複製し、読み込んだファイルデータを暗号化します(【図163】参照)。

 暗号化が終わると、複製されたAES256鍵は破棄され、暗号化されたファイルがサイズ、暗号化データの順にファイル出力されます(【図164】参照)。

 ファイル出力が終わると、再びFlushFileBuffer APIでディスクに出力が行われます。

IDA_Cryptowall_EncriptedReadFile1

【図162】暗号化対象ファイルの読み込み

 

IDA_Cryptowall_CryptEncrypt_AES3

【図163】ファイルデータの暗号化

 

IDA_Cryptowall_EncriptedWriteFile6

【図164-1】暗号化されたファイルのサイズの出力

 

IDA_Cryptowall_EncriptedWriteFile7

【図164-2】暗号化されたファイルの出力

 

 暗号化対象のファイルの出力が終わると、最初に生成したAES256の鍵を破棄し、暗号化プロバイダを開放します。

 これについて、一つ重要な点に気づく必要があります。この処理の流れから、AES256鍵は、ファイルごとに作られる、ということです。そのため、ファイルの先頭のハッシュ値の後ろに暗号化されたAES256鍵を格納しているのです。

 このことから、仮にAES256の脆弱性が発見され、鍵をある程度の時間で復号できたとしても、復号にかかる時間はファイルの数だけ必要になってしまう、ということです。

 最後に、読み込み、書き込みで開いていたファイルハンドルをクローズします。この時、フォルダには暗号化前のファイルと暗号化後のファイルが存在します(【図165】参照)。

IDA_Cryptowall_EncriptedFile1

【図165】暗号化処理終了時のフォルダの状況

 

 ランサムウェアの目的から考えると、元のデータが残っていては意味がありません。そのため、元のファイルを消す処理を行います。

 処理は、Deleteではなく、MoveFileEx APIを用いて、暗号化されたファイルの名前を元のファイル名で上書きし、さらにランダムな名前に戻す、という方法で行われていました(【図166】参照)。

IDA_Cryptowall_MoveFile1

【図166-1】MoveFileExによるファイルの消去(ファイル名変更で上書き)

 

IDA_Cryptowall_FileMove2

【図166-2】MoveFileExによるファイルの消去(ファイル名変更で上書き結果)

 

IDA_Cryptowall_FileMove3

【図166-3】MoveFileExによるファイルの消去(ランダムな名前に再設定)

 

 これが、CryptWallによるファイル暗号化処理の全貌です。

 脅迫文の一部にRSAのことが書かれていたり、秘密鍵が必要であることをほのめかしているため、ファイルの暗号化もRSAだと思われている方もいたかもしれませんが、ファイル自体の暗号化はAESのブロック暗号であることが解析で分かりました。CryptoWall自体が出てから日が経っているため、情報をしっかり集めていれば、暗号化方式などは既知の話かもしれません。しかし、この解析手法は手間がかかる反面、実際の処理をパラメータを含めて解析できるため、得られる情報も多いのではないかと思います。

 今回の解析で判明した、CryptoWallの暗号化方式をまとめます。

 

 ○公開鍵情報はC&Cサーバへの2回目の通信でもたらされる。(エラーが返ってきた通信を除く)
 ○通信内容や通信結果のファイル出力のデータは、独自の変換ロジックを用いている。
 ○暗号化処理のスレッドは、ドライブ名毎にマルチプロセスで実行される。
 ○暗号化対象のファイルは、拡張子で判別している。
 ○ファイル本体およびファイル名の暗号化はAES256bitを使用している。
・パディングのモードをPKCS5_PADDINGに設定
・暗号化のモードをCRYPT_MODE_CBCに設定
初期化ベクトルを0に設定
 ○暗号化に用いられたAES256bitの鍵は、公開鍵によって暗号化され、ファイルの17バイト目以降に格納されている。
 ○ファイルの暗号化に用いるAES256bitの鍵は、ファイルごとにそれぞれ生成されている。

 

※今回の解析で使用した検体のハッシュ値:

MD5:679a7a6bcf6b0baba0c911ebf2c1e13d

SHA_1:49e12d15d3dc10c1a9e8445235e772ef4f761788

 

 CryptoWallのファイル暗号化処理という、ランサムウェアの本丸の処理の解析はこれで完了といってよいと思います。暗号化が終了した後、自動起動のために配置されたファイルの削除、レジストリの消去、一時ファイルの消去、脅迫文の表示などは未解析ですが、方法は容易に想像がつきますし、どうしても必要となったら、またそのときに解析する、ということにしておきます。

 「CryptoWallによる暗号化処理」では、処理の流れに重点を置いて説明しましたが、ファイルのレイアウトについて、少しおさらいをしてみたいと思います。

 

< CryptoWallによる暗号化処理(前編)目 次 CryptoWallによる暗号化レイアウト >