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

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

サポート情報

ホーム > サポート情報一覧 > メモリに展開されたプログラムはどこから来たのか?

メモリに展開されたプログラムはどこから来たのか?

目次へ

 メモリに展開されたプログラムを追いかけたいところですが、ここは少し立ち止まって、この「メモリに展開されたプログラム」は、どこから来たのかを探っておきたいところです。そもそも、仮にメモリ上に怪しいコードをコピーしたとはいえ、その元のコードはどこかにあるはずで、それが実行プログラムの中にあるのなら、アンチウィルスソフトがCryptoWallの既存のシグニチャで検知するのでは?という疑問があります。

 【図31】のコードをみなおしてみると、直前に行われている「call sub_401490」が怪しそうです。なぜなら、関数の呼び出しの引数は通常スタックにpushされますが、sub_401490を呼び出す直前に設定されているeaxは、dword_71B6D0の示す値だからです。これは、retnを用いてメモリのアドレスへ制御を移すときに参照している値と一致します。

 つまり、sub_401490の第1引数は今回で言うところの0x001D0000を指しているのです。これは、関数として、第1引数に受け取り先のアドレスを指定するように作られていることを伺わせます。また、その前のpushから、第2引数が0x004026E0、第3引数が0x00002ECB、第4引数が0x66ADEE2Eであると考えられます。ここで、勘を働かせると、第1引数が受け取り先ということは、第2引数はデータ元、第3引数はサイズなんじゃないか、と想像できます。0x004026E0は、.textセグメント内なので、実行中のプログラムの領域であり、参照は可能であることも理由に挙げられます。そこで、この領域を表示してみました(【図34】参照)。

CryptoWall_IDA_Step001

【図31】メモリ内のプログラムへ制御を移す個所(再掲)

 

CryptoWall_IDA_Step005

【図34】0x004026E0のデータ内容

 

 先ほどの【図32】のメモリと比べると・・・全然違いました。勘が外れましたかね?仕方ないので、もう少し追ってみましょう。0x00406EC5(call sub_401490)にブレークポイントを設定して、一旦デバッグを終了し、再度そこまで一気に進めます。Call直前のパラメータを確認すると、スタックの中身に、先ほどのとおりの引数が格納されています。なお、メモリが0x00160000に変わっているのは、メモリ取得処理でOSが返す値がまちまちだからです。内容を確認すると、まだ0クリアされたままであることがわかります(【図35】参照)。そして、「Step into」で処理の中に入っていきます。

CryptoWall_IDA_Step006

【図35】0x00406EC5(call sub_401490)でブレークしている状況

 

 処理の中に入っていき、「Graph View」で参照すると、非常に縦に長いコードであることがわかります。「Graph Overview」でみると、どうも大きな2つのループブロックで構成されているようです。細かく見ていくと時間がかかるので、0x00160000に値が設定される点を見極めようと思います(【図36】参照)。すると、0x004015F0で1バイトの値をblレジスタから渡していることが判明しました。また、blレジスタには0x004015A6でパラメータを渡していることがわかりました。それ以外に色々処理をしているようですが、ここは省略してループブレークしたところにブレークポイントを設定し、そこまで一気に実行させてみました(【図37】参照)。

CryptoWall_IDA_Step007

【図36】0x00160000に値が設定されている様子

 

CryptoWall_IDA_Step008

【図37】0x00160000に値を設定するループが終わった直後

 

 ここで、2点気づくことがあります。1点目は、この展開されたデータは、【図34】の0x004026E0のデータ内容と一致するという点です。もう1点は、その後このメモリ上のコードが実行されるのですが、【図32】のコードと全く異なるという点です。

 なお、ループ処理は長いのですが、結果としては0x004026E0のデータが0x00160000にコピーされた値が格納された、というものが得られています。間にある様々な処理は、解析を遅らせるためのダミーのコードではないか?という疑念が湧きます。そのため、ここのループの処理は、あくまで0x004026E0のデータを0x00160000にコピーする処理である、と判断しておくにとどめておいて、それではうまく説明がつかなくなったときに洗いなおす、という考えのほうがよさそうです。

 次に問題になるのが、0x0040172A~0x00401B48のループです。最終的には、0x00401847で格納されたclを一時スタックに格納し、0x0040196Dで格納するという、メモリ上でのデータの入れ替えが行われているのが主な処理と思われます。これも、処理の途中経過が煩雑なため、その判断にとどめておき、問題があれば見直すことにしましょう。ループブレークまで進めてみます(【図38】参照)。

CryptoWall_IDA_Step009

【図38】0x00160000移行の内容の入れ替え処理終了時

 

 最初にメモリに展開された内容が入れ替わり、【図32】と同じ内容になったことが分かります。このプログラムは、本当に実行したいプログラムを変換した状態で格納しておき、実行時にメモリ上に展開、変換し、メモリ上の処理を実行させる、というのが主な目的となっているのです。つまり、これは自作によるプログラムのパッカーの一種と見ることができます。その目的しかないため、最初の表層解析であまり使用しているAPIが見当たらないのも頷けます。

 また、自作であるため、変換ルールも適宜変更できる点も注意すべきです。本当に危険なコードは展開された後のコードであり、展開後のコードならアンチウィルスによる検知も可能と思われます。しかし、変換プログラムを使われると、その変換後のバイナリパターンで検知するしか方法がなくなります。これは、全く同じコードであっても、変換ルールを変えられたらバイナリ値も変わってしまい、検知できなくなってしまうことを意味します。現在の標的型攻撃や多数の亜種が存在するマルウェアの根本原因はこの点であり、サンドボックスや振る舞い検知型の対策が行われる理由は、ここにあると言えると思います。

 

< CryptoWallの「メモリの怪しい使い方」の発見目 次 仮想メモリ取得した方法の正体 >