前回の記事で、「32ビットプロセスから far call すると、64ビットに動作が変わるみたいだけど、そのギミックがわからないよ。ぴえん。」と泣きを入れたところ、TwitterでYuu Arai氏が情報を提供してくださいました。
https://twitter.com/yarai1978/status/1277450218758221825
https://twitter.com/yarai1978/status/1277463691475087366
うーん、色々ググったり、IntelのCPUマニュアルを見てみたりはしていたのですが。
リサーチの能力不足を露呈していまいましたね。 orz
ツィートにも出ていますが、関連する情報が詳しく書かれています。
Knockin’ on Heaven’s Gate – Dynamic Processor Mode Switchin
http://rce.co/knockin-on-heavens-gate-dynamic-processor-mode-switching/
Heaven's Gate: 64-bit code in 32-bit file
http://vxheaven.0l.wtf/lib/vrg16.html
Switch from 32bit mode to 64 bit (long mode) on 64bit linux (Linuxのケース)
記事の年月日が割と古く、少なくとも2011年には知られていた技術だったんですねー。
ただ、自分でアプリを書く場合に32ビットから64ビットの処理を意図的に呼び出したい、という用事は今まで無く。OS内でしれっとやっていることもあったのかもしれませんが、開発者側はAPIを呼び出してリターンが得られればそれでOKだったりするので、単に気づいてなかっただけなのかもしれませんね。
提示したリンクに詳しい仕組みは書いてあるので、本人の覚書程度の概要と、マルウェアで使われた場合のポイントでもメモしておこうかと思います。
・・・まあ、自分の知識不足の反省文みたいな記事ですね。またしてもマゾい記事を・・・。
32ビットと64ビットのプロセスモードを変更する"Heaven's Gate"
32ビットと64ビットのプロセスモードを変更するこのテクニックを、以上のリンクの記事では"Heaven's Gate"と呼ぶそうです。
なんかネーミングがカッコいいぞ。
元々は、32ビットアプリケーションを実行時に syscall などで64ビットの ntdll.dll を実行する時に、そのプロセスモードを切り替えるといったようなことを目的としていたようです。
端的にテクニックのポイントを書きだすと以下になります。
- 32ビットから64ビットへプロセスモードを変更する場合、セレクタ "0x0033"を指定してfar call または far jumpを行う。
- 64ビットから32ビットへプロセスモードを変更する場合、セレクタ "0x0023"を指定してfar call または far jumpを行う。
解説には、これらの発見の経緯も書いてあります。
読んでいて難しかったですが、彼らは32ビットから64ビットの処理を呼んでいることは知っていて、その処理をリバースエンジニアリングで解析したようです。
その結果、その場合には常にFセグメントの fs:[0x0C0h] にアクセスしているのを見つけ、それが「WOW32Reserved」と呼ばれていることを突き止めています。その先の処理を分析すると、固定のセレクタを指定してコールまたはジャンプしている、ということが判明したようです。
なお、この場合の64ビットの処理には色々制限があることも解説されていますが、今回はコードを作ることは目的としていないので省略します。
マルウェア解析における"Heaven's Gate"
今回、この"Heaven's Gate"を調べることになったそもそもの原因は、マルウェアで使われていたためです。
では、マルウェアは、「なぜ、この"Heaven's Gate"を使ってきたのか?」という点に注意を向けたほうが良いと思いました。
作成者も、理由もなくこのテクニックを使ってきたわけではない、と考えると、その行動の原因は今後のマルウェア対策や解析をするにあたり、注意すべき点を示すかもしれないからです。
特に、このEmotetとみられる検体は、メモリフォレンジック対策の暗号化やAPI名を不可逆な符号化(ハッシュ化のような処理)など、いくつかのアンチフォレンジック技術を使っており、これもその一環かと思われるためです。
個人的には、やはり「解析回避」が目的なのだと思います。
私の場合、IDAで解析していましたが、今回の far call 以降は、64bit版のIDAを使ってもそのままでは上手く解析できませんでした。
理由として、セレクタ"0x0033"を使ったプロセスモード変更についてはIDAには実装されていなかったためです。
また、デバッグ開始時に32ビットで開始した場合、途中からプロセスモードを64ビットへ切り替える方法が分かりませんでした。機能としてそもそも無いのかもしれません。
こういった「知識不足で何が起きているか分からない」や「デバッガの機能で対応できない」といった理由で解析を諦めさせるための手段として用いられているのではないか、という懸念があります。
私も、素読みで64ビットのコード呼んでるって分からなかったら振り落とされてたぜ・・・
また、マルウェアの自動解析の技術にサンドボックスがありますが、サンドボックスの機能がこの"Heaven's Gate"の先のコードまで分析できるかは確認していません。
製品版なんて高いもの私個人が持ってるワケないじゃない。cuckoo sandboxも組みなおさなきゃ・・・。
恐らく、仮想環境上で実際に実行させてモニタするような機能であれば解析できる可能性がありますが、プログラムの実行をエミュレートしているようなものはセレクタ"0x0033"からの far call から先が上手く動かないものもあるんじゃないでしょうか。
こうした理由から、サンドボックス解析回避も狙っていたかもしれません。
これは確認できないので、あくまで推測ですが。
もし、こういった理由でマルウェアの解析が上手くいっていない場合、攻撃者は今後もこのテクニックを使ってくるでしょう。
そのためにも、マルウェア解析者はこのテクニックを知っておく必要があると思います。そして、 "0x0033" や "0x0023" セレクタを指定した far call や far jump が見つかった場合は、プロセスモードを変更したと気づき、対応した調査をする必要があると思います。
実際の解析は?
様々なツールが"Heaven's Gate"に対応できて解析できるようになるのが一番良いのですが。
当面のところ、これらの呼び出しが見つかった場合、呼ばれた先のコード部分をダンプし、ファイルに保存しなおして別途再解析するのが当面の方法になるかと思います。
攻撃の仕組み上、シェルコードを実行するのと同じような状態になるので、バイナリのシェルコードの分析ができるのであれば、同じ方法で分析できると思います。
謝 辞
今回は、冒頭に述べたとおりTwitterにてYuu Arai氏 (@yarai1978) にお知恵をいただきました。
感謝いたします。
読者へのアフターケアがパねぇっす!