株式会社Ninjastars 技術系ブログ

「本質的安全を提供し、デジタル社会を進化させる!!!」

ランサムウェアへの挑戦 -選ばれし者たちへ

株式会社Ninjastars
取締役:齊藤和輝

ランサムウェアについて

ランサムウェアとはマルウェアの一種であり、
感染すると攻撃対象のマシン(PC/スマートフォン)上でのユーザー操作が制限されてしまいます。
現在、ランサムウェアは暗号化タイプと非暗号化タイプの2種類に分類できます。
暗号化ランサムウェアでは攻撃対象の外部記憶装置のデータを暗号化し、ファイルへのアクセスを制限します。
それに対して、非暗号化ランサムウェアではポルノ画像やグロ画像を表示し続けることでシステムへのアクセスを制限してきます。

どちらのタイプであってもPCやファイルを人質にとり、制限を解除したければ金を払えという風に金銭を要求します。





今回の記事では「Reversing.Kr」のRansomwareを題材にランサムウェアについて解説していきます。
Reversing.Krとはリバースエンジニアリングの技術を学ぶための演習問題を公開しているサイトです。
問題によっては配布されるプログラムがマルウェアとして認識されてしまう場合もありますが、
あくまでソフトウェア解析技術の向上を目的としたプログラムなのでご安心ください。
Reversing.Krのリンクはこちら
reversing.kr

本記事は常設CTFの問題のネタバレを多く含みます。ご覧いただく際はご注意ください。

今回の演習問題では元々実行可能ファイルであったはずの「file」がランサムウェアに人質として捕らえられ、実行不能なファイルになっています。
問題回答までの流れとしては、ランサムウェア本体であるrun.exeを解析して、fileがどのように暗号化されているのかを明らかにしたあと、元に戻して実行可能な状態にまで持っていきます。

まずはrun.exeを解析していきましょう!

実際にrun.exeを実行してみると、文字化けしています。
元が韓国語なので私にとってはどちらも解読不可能な文字列ですが...

f:id:Ninjastars:20190524181324p:plain
Keyを要求しています
Keyを使ってどのように復号処理をしているのかをGhidraで見ていきましょう。
ここで注目すべきはProgram Trees内のUPXという文字です。
これはUPXと呼ばれるパッカーでパッキングされていることを表しています。
f:id:Ninjastars:20190524181837p:plain

マルウェアはお決まりのパッキング手法というものがなく、独自の手法でパッキングされていることが多いのでマニュアルアンパッキング技術が必要になります。
こちら⬇の記事でマニュアルアンパッキングの基礎と手法をご紹介しているので、こちらを参考にしながら実際にアンパッキングに挑戦してみましょう。
www.ninjastars-net.com
ここからはアンパッキングしたrun.exeを見ていきます。
このプログラムではKeyを要求する際に入力した文字列を取得している関数が必ず存在するので
Symbol Tree->Imports->MSVCR100.DLLから探してみましょう。
scanf関数があるのでXREF[1]から見ていくと、0x44A792で呼び出されていることがわかりますね。
次に動的解析ツールのOllyDbgを使って0x44A792にブレークポイントを設定していきます。
この処理の周囲(0x44A7E2)にfopen関数があるのでfileを操作しているのであろうことが予想できます。
f:id:Ninjastars:20190524183527p:plain
scanf関数とfopen関数
0x44A870にてgetc関数によりfileのバイナリ列をメモリに展開しています。
getc関数の戻り値はEAXに格納されているので、EAXをいじっている命令を探していきましょう。
すぐ近くの0x44A87Cでの
MOV BYTE PTR DS:[ECX+5415B8],AL
という命令でEAXのデータをECX+5415B8に展開していることがわかります。
f:id:Ninjastars:20190524190335p:plain
アドレス:0x5415B8
ステップ実行すると、fileのバイナリが順に展開されていることがわかると思います。
展開が終了する0x44A897にブレークポイントを設定し、中身をすべて展開してみましょう。
次にメモリ上に展開されているバイナリをいじっている命令を探しにいきます。
0x44A8CF付近にて入力した文字コードとバイナリのXORをとり、
さらに0xFFとXORをとっている命令群があります。
おそらくこの命令群が復号化ルーチンだと予想できます。
f:id:Ninjastars:20190527123415p:plain
復号化ルーチン
上記の処理を行った後にメモリ上のバイナリデータを上書きし、fileに書き込んでいます。
f:id:Ninjastars:20190527124135p:plain
fileへの書き込み
この処理が復号化ルーチンなのかを確かめましょう。
試しに「abcde」を入力してみます。
先ほどの式では以下のように変換されるはずです。
f:id:Ninjastars:20190527132745p:plain
復号化ルーチンの具体例
バイナリエディタであるStirlingでfileの中身を確認しましょう。
f:id:Ninjastars:20190527132544p:plain
file復号化の結果
1バイト目のバイナリが0x40になっているので先ほどの式が復号化ルーチンであることが確認できました。
また、入力した文字は5文字でしたがfileのバイナリ全体が変換されているので
5文字を循環させて復号化していることが想像できます。
5バイト目を計算してみると
「0x0D=0x93 xor 0x61 xor 0xFF」であることがわかります。
これで循環していることが確認できました。
次に何文字で復号できるのかを見つけていきましょう。
前提条件としてfileをPE形式の実行ファイルにしなければいけません。
そのために適当な実行ファイルをStirlingで確認しましょう。
f:id:Ninjastars:20190527135638p:plain
run.exeの中身
PE形式の実行ファイルには最初の一行は必要ですので、
そこを揃えることを考えます。
入力すべき文字は次の式で求めることができます。
f:id:Ninjastars:20190527140507p:plain
文字を求める式
これで16文字求めると
「letsplaychesslet」となりますが、「let」という文字列が2回登場しているので
「letsplaychess」だけでいいことがわかります。
これをKeyに入力しましょう。
f:id:Ninjastars:20190610160614p:plain
run.exeにKeyを入れてみましょう。
f:id:Ninjastars:20190527141619p:plain
成功です!
するとついにPE形式の実行ファイルにすることができました!
file.exeにリネームして実行してみましょう。

見事フラグを出すことに成功しましたね!お疲れ様でした!
本記事で学んだ技術、知識をさらなる学びの足がかりにしていただければ幸いです。
それではまた次回!

注意事項

本レポートに記載されている内容を許可されていないソフトウェアで行うと、場合によっては犯罪行為となる可能性があります。そのため、記事の内容を試す際には許可されたソフトウェアに対してのみ実施するようにしてください。

本レポートについて
お問い合せ
E-mail:saito@ninjastars-net.com

株式会社Ninjastars
取締役:齊藤和輝