ランサムウェアを作ってみた(シェルスクリプトで)

ランサムウェアの暗号化部分についての実証コードを書いてみた。暗号の計算にはOpenSSLのコマンドが使えるので、シェルスクリプトを使って書いた。

github.com

注意

  • このコードを試して起こった損害について作者は責任を追わない。基本的にdocuments/以下にあるテストファイルのみが操作対象だが、シェルスクリプトがザルなので空白を含むファイルなどが混ざっていると少し危いかもしれない。
  • このコードはランサムウェアの暗号化の動作を実証することを目的としたものであり、実際にランサムウェアなどのマルウェアに「応用」することを意図したものではない。もちろん、実際に身代金目的のランサムウェアを作って配布することは違法である可能性が高い。そもそも、このコードは暗号化部分の最低限の実装しかしていないので、実際にランサムウェアを作るにあたって役に立つことはほとんどないだろう。

はじめに

ランサムウェアは起動するとコンピューター内のファイルを暗号化し、復号を見返りに身代金を要求するマルウェアである。支払い後に実際に復号するものとそうではないものがあるらしいが、ここでは実際に復号能力があるものを考える。

ランサムウェアが作者の意図通りに動作するには、以下の条件を満たしてほしいだろう。

  • ランサムウェアの存在が発覚したあとは、そのランサムウェアは解析の対象となるが、それによって身代金なしにファイルを復号されてしまっては困る。
  • ランサムウェアの被害者ごとに、それぞれ身代金を支払ってほしい。
  • 復号時のクライアントとサーバーの通信は最小限に留めたい。

複数の暗号を組み合わせることでこれを実現できる。今回はそれを実証するコードを書いてみた。

仕組み

まず、ランサムウェアの作者は秘密鍵と公開鍵の鍵ペアを作成し、ランサムウェアには公開鍵のみを同梱する。この方法であれば、ランサムウェアが解析されても秘密鍵は復元できない。

この公開鍵を作ってファイルを暗号化することも可能だが、これには次の問題がある。

  • そもそも、公開鍵を使って大きなファイルを暗号化するのはコストが高くつく。
  • また、身代金が支払われたあとの復号の方法が問題になる。仮に秘密鍵を送るとすると、このランサムウェアは被害者1人が身代金を支払うだけで終わってしまう。
  • かといって、サーバー側でファイルを復号すると大量の通信が必要になる。

そこで、次のようにする。

  • ランサムウェアは起動したらまず新規に共通鍵を生成する。
  • 共通鍵を公開鍵で暗号化し、保存する。
  • メモリ上にある共通鍵を使って、ファイルを暗号化する。全ての暗号化が終わったら、共通鍵は捨てる。

被害者は身代金を支払う際に暗号化された共通鍵を添付する。ランサムウェアの作者はこれを手元の秘密鍵で復号して送り返す。ファイルの復号は手元で行うことができる。

使い方

RSAやAES-CBCなどの暗号はOpenSSLのコマンドとして用意されているため、このデモはシェルとOpenSSLがあれば動かすことができる。

まず、デモコードを取得する。

~$ git clone https://github.com/qnighy/ransomware-demo.git
~$ cd ransomware-demo
マスター鍵対を作成する
~/ransomware-demo$ ./genmaster.sh

これによってRSA鍵対が作成される。秘密鍵ランサムウェアの作者が保有し、公開鍵はランサムウェアに埋め込まれる。

ランサムウェアを実行する

ランサムウェアが配布され、被害者のコンピューター上で実行されたとする。

~/ransomware-demo$ cd client
~/ransomware-demo/client$ find documents
documents
documents/lipsum.txt
documents/hello.txt
~/ransomware-demo/client$ cat documents/hello.txt
Hello, world!
~/ransomware-demo/client$ ./encrypt.sh
~/ransomware-demo/client$ find documents
documents
documents/hello.txt.enc
documents/hello.txt.iv
documents/hello.txt.sha256
documents/lipsum.txt.enc
documents/lipsum.txt.iv
documents/lipsum.txt.sha256

この ./encrypt.shランサムウェアによる暗号化である。ここでは3つのことが起こっている。

  • バイスごとの共通鍵が作成される。
  • この共通鍵を使ってファイルが暗号化される。
  • 共通鍵はマスター鍵を使って暗号化される。
支払いとデバイス鍵の復元

ファイルを復号するためには、まずランサムウェアの作者に身代金を払ってデバイス鍵を復元する必要がある。

~/ransomware-demo/client$ ./decrypt.sh
device_key.dat not found. First pay for us!
~/ransomware-demo/client$ cp device_key_encrypted.dat ../server/
~/ransomware-demo/client$ mv ../server/
~/ransomware-demo/server$ ./decrypt-key.sh
~/ransomware-demo/server$ cp device_key.dat ../client/
~/ransomware-demo/server$ mv ../client/
復号

バイス鍵を復号したら、これを使ってファイルを復号できる。

~/ransomware-demo/client$ ./decrypt.sh
~/ransomware-demo/client$ find documents
documents
documents/lipsum.txt
documents/hello.txt
~/ransomware-demo/client$ cat documents/hello.txt
Hello, world!

まとめ

ランサムウェアにおけるファイルの暗号化は決して複雑ではないが、複数の暗号を組み合わせて実現されている。この記事では暗号化のOpenSSLのコマンドを使って、ランサムウェアがどのように暗号を組み合わせているかを示すデモを作成した。