• JP
  • magnifying glass search icon to open search field
  • お問い合わせ
  • リソースセンター
  • サポートを受ける
  • 現在、攻撃を受けていますか?
Palo Alto Networks logo
  • 製品
  • ソリューション
  • サービス
  • 業種
  • パートナー
  • パロアルトネットワークスをお勧めする理由
  • 会社案内
  • その他
  • JP
    Language
  • お問い合わせ
  • リソースセンター
  • サポートを受ける
  • 現在、攻撃を受けていますか?
  • スタート ガイド

LockCrypt ランサムウェアの復号

Tomer Harpaz 8 02, 2018 at 12:00 午後

※ 本記事は2018年7月27日に米国で掲載されたブログ記事の抄訳版となります。

概要

LockCryptはEncryptServer2018という別名でも知られるランサムウェアファミリで、2017年の半ばからインターネット上に出回りはじめて以降依然として活発です。このマルウェアはリバースエンジニアリングによる完全な分析を Malwarebytes Labsが2018年4月に行っていますが、利用されている自家製の暗号はお粗末なもので、解読は可能と正しく結論づけています。

ただし、Malwarebytesのリサーチャーは本マルウェア用の復号ツールは公開しておらず、ほかにオンライン上で公開済みの復号ツールも確認できませんでした。また、これ以外にあげられている支援は同ラボの新しいブログエントリしかなく、そこでも同ランサムウェアの被害にあった人はMichael Gillespie (@demonslay335)に復号について相談するよう勧めているのみでした。

そこで私たちはGillepsie氏に連絡を取り、@hasherezade、@FraMauronzの両氏と復号ツールの作成をしましたが、この復号ツールは完全とはいえませんでした。既知の平文ファイル(1MB)が大量に必要でしたし、復元できないファイル名があったり、ファイルの末尾1-2バイト分が復号できずに残る場合があったのです。

これを受け、本稿では、本マルウェアの自家製暗号について分析した結果とその解読方法、また25KB程度のごく小さい平文のみで暗号キーを復元する方法について説明します。このシナリオであれば現実的といえるでしょう。というのも、LockCryptは手当たり次第すべてのファイルを暗号化しますが、DLL のようなアプリケーションファイルもその例外ではないため、同じバージョンのソフトウェアを別のコンピュータにインストールすれば容易に復元可能だからです。復元用スクリプトや手順などは本稿の末尾に記載します。

ただし最近、別の暗号方式を利用する新しい亜種が見つかっている点はご注意ください。私たちはこの新しいバージョンの解析は行っていませんが、こちらはずっと堅牢な暗号が利用されているようです。

初期の分析

このマルウェアの暗号を逆アセンブルしてみてわかったことは、このマルウェアの作成者は、ファイルを暗号化するにあたり、カスタムメイドの非常に弱い暗号を選んだということでした。私たちは、2018年にもなってカスタムメイドの暗号モデルを利用したランサムウェアと遭遇することがあるなどとは思ってもいませんでした。というのも、Windows API を利用すれば、今現在ないし近い将来に利用可能なハードウェアでは復号に数十億年かかるような方式で、簡単にデータを暗号化できるからです(たとえば、十分に暗号強度の高いメソッドを使って生成されたキーを持つ128ビットAES暗号方式など)。

以下に示すのは、本マルウェアの暗号関数を逆アセンブルした結果を同等のPythonコードで示したものです。なお当該encrypt()関数のC言語版はMalwarebyteによる分析に掲載されています。ポインタ操作がある分、こちらの方が分かりやすいかもしれません。

コード1

この関数からは以下の結論が導き出せます:

  1. フェーズ1が定義する変換は周期的で、1サイクルの長さは12500バイト
  2. フェーズ2が定義する変換は周期的で、1サイクルの長さは25000バイト
  3. エッジケース(後述)を除き、各平文ビットは3つのキービットとXOR演算される(2つのキーはフェーズ1、残り1つはフェーズ2で)
  4. つまり、フェーズ2で行われたビット シフトを「取り消す」(バイト順を入れ替え戻した上で5ビット分ROR演算を行う)ことで、両フェーズをひとまとめとし、長さ25000バイトの周期的キーをもつストリーム暗号として扱うことができる(また、それがオリジナルのキーの機能でもある)。

最後の2つの結論について次の図で説明します。この図はデータの4バイト目から8バイト目を変換する様子を、各暗号関数のそれぞれのステップの流れを追って可視化したものです。各行の間にある⊕という記号は、それらのビットが互いにXOR演算されているということを意味しています。

変換が行われる前の4バイト目から8バイト目の各ビットは以下のような状態です:

XOR1

フェーズ1ループの2回目の繰り返しが終わった後は次のようになります:

XOR2

フェーズ1ループの3回目の繰り返しが終わった後は次のようになります:

XOR3

フェーズ1ループの4回目の繰り返しが終わった後は次のようになります(フェーズ1のループはすべて同じことの繰り返し):

XOR4

フェーズ2ループの2回目の繰り返し中、ROL演算が終わった後は次のようになります:

XOR5

フェーズ2ループの2回目の繰り返し中、XOR演算が終わった後は次のようになります:

XOR6

バイト順を入れ替えてこれらのバイトの暗号化は終了です。

「ストリーム キー」を復元する

先の図で暗号化された4バイト目から8バイト目を使い、バイト順の入れ替えを元に戻して5ビット分ROR演算をすると次の結果が得られます:

XOR7

要するに、この演算(バイト順の入れ替えを元に戻して5ビット分ROR演算する)により、この暗号を典型的なストリーム暗号に「正規化」したわけです。この後、これらのバイトと既知の平文とのXOR演算を行えば、先の結論4で述べたキー ビットの機能が得られます:

XOR8

このストリーム(実際には各ビットがキー ビットと3回XOR演算されている)を「ストリーム キー」と呼ぶことにしましょう。このストリームキーは25000バイト長のサイクルで周期性があるので、25000(25k)バイトの長さの平文と暗号文があれば、キーを復元してファイルを復号するのに十分といえそうです。

なにか既知の平文と暗号データのペアを次のPythonの関数で処理すればストリーム キーを復元できます。ここでインデックス パラメータは、与えられた文字列中の25000バイト分の既知の平文バイトに対するインデックスを示しています。ただし、先頭4バイト分は暗号化されることがないため、ここから 4 を引いています。つまり、平文の文字列のインデックスidx+4からidx+4+25000の範囲が使用されます。このため、既知の平文ファイルのサイズが50000バイトなら0 <= idx < 24998の範囲が利用されます。

コード2

それではいよいよ(まだ不完全ですが)次の関数を使ってファイルを復号していきましょう:

コード3

残念ながら、上記のソリューションにはいくつかのエッジケースは扱えていません:

  1. 暗号化された最初の2バイト(元のファイルの4バイト目から6バイト目)は、2つのキー ビットとしかXOR演算されていないので:
    1. 残りのバイトを復号するには、idx >= 2 のストリーム キーを使う必要がある
    2. 最初の2バイトを復号するには、idx == 0 のストリーム キーを使う必要がある
  2. 元ファイルのサイズが2 (mod 4)に等しくなければ、encrypt()関数にlen(plain) != 0 (mod 4)があることから、ファイルの末尾1-2バイトはフェーズ1の最終の繰り返し回によってしか暗号化されていないことになる。これら末尾1-2バイトの各平文ビットは1つのキービット(得られていないキー ビット)としかXOR演算が行われていないため、復号できない。

さらにMalwarebytesが示したように、ファイル名はオリジナルのキーのサブセットと直接XOR演算して暗号化されているため、ファイル名も復号できません。ただし、@demonslay335 氏が復号ツールの中で使っているように、暗号化されたファイル名の長さをmとした場合、n >= m の長さをもつ既知のファイル名があれば復号は可能です。

つまるところ、任意の長さのファイルとファイル名を復元したければ、本稿で述べたストリーム キーだけでなく、実際のオリジナル暗号キーが必要そうだ、ということです。

オリジナル暗号キーを復元する

実は、これまでの分析から(XORを加算演算とするガロア体(2)上の)連立一次方程式が得られ、ストリーム キーとオリジナル キーをこの方程式で結びつけることができるようになります。この分析を一般化するなら、次のPythonの関数によって、オリジナル キーをそのビット インデックス間でXOR演算した結果が得られ、それが各ストリーム キーのビット(i をインデックスとして使用)が生成されます:

コード4

つまり、stream_key[i] == reduce(xor, (key[k] for k in k_for_i(i))) ということです。

この関数により、ガロア体(2)上に、オリジナル キーとストリーム キー間の変換を表す200000x200000の非常に疎な行列が生成されます:

コード5

この行列Aは、A_i_j_s[i]列だけが1で、残りの行iはすべて0となります。

またこの行列は各行に3つしか値がないという「非常に」疎な行列なので、普通のコンピュータ上で線形代数モデルを使って解くことも可能です。たとえば数学ソフトウェアのSageMathで次のコードを実行させます:

コード6

検証してみたところ 16GB の RAM を搭載した Intel Core i7-4790 CPU と SageMath 上でこの方程式を数十分から数百分程度で解くことができました。重要なファイルを完全に復元したいなら、これは十分実用的といえるでしょう。なお、idxが25000の倍数であれば、処理が速くなるようです。これは、行列が行階段形に近くなるためかもしれません。したがって、十分に大きい(50KB以上など)既知の平文ファイルがあるならidx = 25000とすることを推奨します。

ファイルを復号する

以上をまとめますと、マルウェアが利用する暗号キーを復元する手順は以下のようになります:

  1. 暗号化済ファイルについて、暗号化される前の平文ファイルを用意します。この元ファイルは、少なくとも 25006 バイト以上のものが必要です。
    1. 暗号化前の元ファイルを用意するには、ランサムウェアによって暗号化されたソフトウェアと同じバージョンのソフトウェアを別のコンピュータ上にインストールしてから、ファイルサイズをヒントとして、暗号化された DLL ファイルと対応する平文DLLファイルを探すとよいでしょう。
  2. まだインストールされていない場合はPython 2.7をインストールします。
  3. recover_stream_key.pyスクリプトを使い、暗号化されたファイルとそうでないファイルのペアから特定のidx用のストリーム キーを復元します。
    1. 先に説明したとおり、十分に大きな平文ファイルがあるならidx = 25000にすることをお勧めします。
  4. SageMathをインストールします。
  5. SageMath Jupyter Notebookを開き、「オリジナル暗号キーを復元する」セクションに記載されている 3 つのコード スニペットを上から順にペーストしてから実行します(訳注: 日本語版ではコード部分を画像として記載しておりますので、ここでは英語ブログの「Recovering the original key」セクションからコピーすることをおすすめします)。これによりオリジナルの暗号キーを復元します。
    1. 重要: コード実行前に必ずスニペット上部に記載されている3つのパラメータをご自身のものに書き換えてください。
    2. 検証によれば、この段階に20分から数時間かかることがあります。
  6. 本稿末尾のリンクからダウンロードしたdecryptor.pyスクリプトで、暗号化されたファイルを復号します。

本稿の分析とスクリプトファイルが、当該ランサムウェアの被害に遭われた方々の失われたファイルを復元するお役に立てば幸いです。

両スクリプトはこちら のUnit 42チームのGitHubからダウンロードできます。

 

ニュース

Wireshark によるパケット解析講座 1

Wireshark は無料で利用できるプロトコル アナライザです。 Wireshark を使うとネットワーク トラフィックをキャプチャしたり、キャプチャしたパケットを表示させることができます。そこでパロアルトネットワークスの脅威インテリジェンス調査チーム Unit42 に所属するアナリストが、Wireshark を使ってマルウェア検体が生成したトラフィックをレビューするさいに利用している便利な使いかたをご紹介していきます。
January 17, 2019

ニュース

Wireshark によるパケット解析講座 3

前回までではWiresharkの列表示のカスタマイズ方法と表示フィルタの式について見ていきました。本稿ではトラフィックから感染ないし侵害を受けたホスト名やユーザーを特定する方法について説明します。
March 31, 2019

ニュース

Wireshark によるパケット解析講座 2

前回は Wiresharkの列表示のカスタマイズ方法について見ていきました。本稿では脅威インテリジェンスの調査上便利なフィルタリングの設定方法について説明します。
January 20, 2019

ニュース

DNSトンネリング: 攻撃者はDNSをどう悪用するのか

悪意のある攻撃者は、ドメインネームサービス(DNS)をコマンド&コントロール(C2)用通信チャネルとして悪用してきました。またこのプロトコルはこのほかに、データを漏出させる目的でも悪用されてきました。DNS の悪用はC2に「ハートビート」接続のために通信するという用途からさらに広がっており、攻撃者はここ数年、悪意のあるデータやペイロードをDNS経由で被害者のシステムに侵入させる用途にもDNSを使っています。本稿では、DNSを悪用したデータ侵入・漏出の種類、方法、使用方法を紹介し、その防御メカニズムへの指針を示します。
March 18, 2019

ニュース

Wireshark によるパケット解析講座 4

セキュリティ専門家は、不審なアクティビティのパケット キャプチャ(pcap)をレビューする際、より詳しく調べるために、オブジェクトをpcapからエクスポートしなければならない場合があります。
July 12, 2019

データシート

PA-400シリーズ

パロアルトネットワークスの機械学習を活用したNGFW「PA-400 Series (PA-460、PA-450、PA-440)」なら、分散した大企業の支社、小売店、中規模企業にも次世代ファイアウォール機能を導入できます。
August 3, 2022

最新ニュース、イベント情報、脅威アラートを配信

このフォームを送信すると、お客様は弊社の利用規約とプライバシー ポリシーに同意したものとみなされます。

black youtube icon black twitter icon black facebook icon black linkedin icon
  • USA (ENGLISH)
  • AUSTRALIA (ENGLISH)
  • BRAZIL (PORTUGUÉS)
  • CANADA (ENGLISH)
  • CHINA (简体中文)
  • FRANCE (FRANÇAIS)
  • GERMANY (DEUTSCH)
  • INDIA (ENGLISH)
  • ITALY (ITALIANO)
  • JAPAN (日本語)
  • KOREA (한국어)
  • LATIN AMERICA (ESPAÑOL)
  • MEXICO (ESPAÑOL)
  • SINGAPORE (ENGLISH)
  • SPAIN (ESPAÑOL)
  • TAIWAN (繁體中文)
  • UK (ENGLISH)

人気のあるリソース

  • 会社概要
  • イベント センター
  • イベント
  • リソースセンター
  • プレスリリース
  • Unit42 ブログ
  • 投資家の皆様へ
  • ブログ
  • Japan Live Community
  • Tech Docs
  • キャリア
  • お問い合わせ
  • サイトマップ

法定通知

  • プライバシー
  • 個人情報保護基本方針
  • 利用規約
  • トラスト センター
  • ドキュメント
  • 一般事業主行動計画

アカウント

  • 購読の管理
  • パートナーログイン
  • パートナーになる
脆弱性の報告

Copyright © 2023 Palo Alto Networks. All rights reserved