みなさんこんにちは(&はじめまして)、ねこざめです。
先日、隣の席の先輩に誘われ、立川の方に荒野をかの隼で飛び回る作品の上映会&トークショーを見てきました。
隼のカッコよさにしびれたついでに、
例のサメを買って帰ったので、最近はリプレイをサメと一緒に見ながら、隼に乗って飛び回りたいとか考えていたりいなかったりします。このオタクはちょろいのでは?
やっぱり、かっこいいというのは人生でもセキュリティでも大事な要素だと思いますね。
さて今回は、かっこいいものつながりで、プロジェクトページが黒基調の画面にドラゴンの組み合わせという、オタクの中二心を最高にくすぐる感じの、リバースエンジニアリングツール「Ghidra」のお話です。
実は、以前のブログ(「難読化の話(超!?入門編)その3 中編」)の中で名前自体は出ていたりします。
が、もう少し私なりに踏み込んだお話をしてみますということと、何気に今回は通算50回目の弊社ブログ、かっこいい感じに行きたい!ということでお付き合いいただけたら幸いです。
Ghidraとは何ぞ
Ghidra
https://www.ghidra-sre.org/
ドラゴンがかっこいい黒基調の画面。目に優しい。
Ghidra(※)とは、NSA(アメリカ国家安全保障局)が開発したソフトウェアリバースエンジニアリングスイートのことで、2019年3月にバイナリが、4月にはソースコードもGitHubで公開されています。
ギドラ、と読むらしいです(公式FAQ)。
読みって何気に難しいポイントだったりする(そして恥をかく)のでうれしいですね。
特徴は
- Javaベースで、マルチプラットフォーム対応(=Linux派も)
- GUIベース
- ELF, PE等の実行可能ファイル(いわゆるバイナリ)の逆アセンブル・逆コンパイルが可能
- アーキテクチャはx86, Power PC, ARM(Thumb命令も含む)をはじめRISC, MIPSなど幅広く対応
があげられます。
また機能・拡張面においても、
- 解析対象に加えた変更をundoできる
- stringsコマンドに相当する機能を持ったScriptをはじめ多くの解析支援スクリプト(Java/Python)が用意されている
- Scriptはもちろん、対応アーキテクチャも追加可能
- eclipse向けの開発プラグインが用意されている
- CLI(Batch処理)用のAPI(Headless API)・Server機能も用意されている
という具合に、これ一つで静的解析が完結できる、と言っても過言ではない非常に充実したツールスイートとなっています。
なぜ静的解析と絞った言い方をしたのかというあたりはもう少し後でお話しましょう。
とりあえず触ってみるのが一番です
プロジェクトページで、現在最新版のv9.0.4が公開されています。 (2019年5月27日 現在)
ダウンロードは真ん中のボタンからできます。
※実行にあたってはJava 11 Runtime and Development Kit (JDK11)以上が必要で、実行前にあらかじめPATHを通しておく必要があります。
※本記事においては、Installation Guideに準拠する形でjdk.java.netで配布されている OpenJDK 11.0.2(現在はアーカイブページからダウンロード)・OpenJDK 12.0.1 を用いて動作を確認しています。
この最新バージョン(v9.0.4)では、
- mac上で動作した際、スクロールが通常と逆になる現象
- dexファイルが読み込めないことがある不具合
が解消されているほか、当初問題となった
- XXE (XML eXternal Entity)を利用した攻撃が可能な脆弱性
- いわゆる「DLL読み込み」の脆弱性
等が対処済みとなっていますので、最新版を利用しましょう。
これらの脆弱性は、どちらをとってもそれだけでこのブログ記事がかけてしまう内容ではあるのですが......
ファーストインプレッションの形で、細かい使い方などが日本語・英語で書かれている記事や、Ghidraに付属したスライドもありますが、
今回は紹介記事ということで、一度Ghidraを起動し、逆アセンブル・逆コンパイルの画面を出すまでの流れを一通り見ていきます。
スライドは/{Ghidraの解凍先}/docs/GhidraClass/Beginner/の下にあります。が、スクショ付ではないんですよね。
Bigginer(初心者)とは何なのか
-
Ghidra自体は、ダウンロードしたzipを適当なディレクトリに展開の上、展開されたディレクトリの直下にあるバッチファイル/シェルスクリプトを実行することで開くことができます。
Windowsの場合は"GhidraRun.bat"を、
Linux/macOSの場合は"ghidrarun"を実行。 -
右上の"File"->"NewProject"を選び、"New Project"のダイアログを出します。
-
ここでは"Non-Shared Project"を選びます。
-
適当なプロジェクトの保存先を選び、いい感じの名前をつけて"Finish"を押します。
-
プロジェクトが作成され、バイナリを読み込むことができる状態になります。
-
左上の"File"->"Inport File..."からダイアログを開き、中身を見たいバイナリを指定します。
※もちろんダイナミックにドラッグアンドドロップでもOKです!
-
ファイルフォーマットやアーキテクチャ("Language")などを指定するダイアログが表示されます。(例はMIPSのバイナリを指定し、"Options"を展開した状態)
"Options"を押すと
・ベースアドレス
・ロードしているライブラリ(のパス)
等も指定できます。 -
OKを押すといわゆる"取り込み処理"が走り、完了するとプログラムの情報(ELFヘッダやPEのヘッダ情報等)などが表示されます。
※うまくいかない or 7. のところでオプション指定を間違った場合でも、いったんこのダイアログを閉じ、次の操作で5. の状態に戻しやり直すことができます。
- やり直したいバイナリを選び、右クリック
- "Delete" -> "yes"
- 指定したバイナリがプロジェクトから除外されて(=5. の状態に戻ります)、もう一度読み込むことができます。
なお、同時に読み込まれたライブラリについては除外されません。
※"Delete"とありますがファイルの本体は消えませんのでご安心を。
-
逆アセンブル・逆コンパイルしたい場合は、ターゲットのファイルを選んだ状態でツールバーにある緑のドラゴンっぽいアイコンを押すと、"CordAnalyzer"の画面が開きます。
バイナリと戯れるたのしい時間の始まりです!
-
その初めてバイナリを開いた時には「自動解析を行うか」といった旨のダイアログが表示されます。"yes"を押して実行しましょう。解析が行われ、逆アセンブル・逆コンパイル結果が見られるようになります。
※プログラムサイズが大きい場合、すべてが表示されるまで時間がかかる場合があります。また、解析途中では操作中でも一部の画面は勝手に更新されますが、正常です。
ARMについて、Thumbモードで逆アセンブルをするかどうかは、この直後に選択できます。
ある関数を表示した例です。画面中央が逆コンパイル結果、右側は逆アセンブル結果となっています。
変数名が気に入らない・注目したいから変えたい場合は変数名を選んで右クリック->"Rename Valiable"で変更できます。
また、各種ツール(グラフ表示など)は"Window"タブ、文字列やアドレスの検索は"Search"タブから実行できます。
今見てきたのはごくごく基本的なもので、このほかにも多くの機能があります。ちょっと覗いてみましょう。
CLIとかチーム機能とか
さてこういうツールでは「CLIで叩けるとうれしい」という声も聞こえてきそうですが、そんなコアな(?)皆様にも朗報です。
CLI・バッチベースの処理を想定したAPI、実はちゃんと用意されています。(公開当初のポートフルオープンの設定のバッチやXXEのお話もあってなかなか触っている方が少ない印象ですが...)
HeadlessAPIと称されており、GUIでできる基本的な機能はサポートされていますし、もちろんドキュメントもあります。
本来ならここで例の一つでも示せるといいのですが、割と一杯いっぱいでしたすみません。
ドキュメントについては、/{Ghidraの解凍先}/support/analyzeHeadlessREADME.html がそれにあたります。
また、Ghidraにはプロジェクトを共有する機能があり、serverを立てて共有し、CLIからアクセスということも可能です。
(プロジェクトを作成するためのダイアログに"Shared Project"が並んでいるのはそういうことです。)
つまり、あらかじめサーバークラスタを用意しておいて、別途集めた怪しいものをまずはバッチ処理的に解析して、怪しいやつを手元で解析・チーム共有ということもできるわけです。GhidraがNSA内部プロジェクトだったころの運用が想像できたりしますね。
ところで大規模クラスタってなんかこうロマンを感じませんか?響きがかっこいいですよね
実際、GitHubなどを見渡すとkubernates(k8s)に対応したDockerfile等を有志で作った方が公開されているようです。(https://github.com/bskaggs/ghidra-docker など)
現実問題、私たちが使う上で、大規模クラスタを構築する使い方をするかはともかく、こうした機能も充実しているところを見ると、ツールではなく「スイート」とNSAが書いているのも頷けるというものです。
次のパートでは、ほかのインターネット上でみられる記事でも扱われる「ぶっちゃけIDA Proと比べてどうなの?」という疑問にも答える形で進めていこうと思います。
ここからようやく本題...? ~IDA Pro
今までC++や.NETなど個別の言語ならともかく、こうしたマルチプラットフォーム・マルチアーキテクチャ対応のツールといえば商用のIDA Pro、というイメージが強かったかと思います。そこに来た今回のGhidra。
NSA版IDA Proと表現してもいいとも思いますが、やはり違いはあるものです。
むしろ私個人としては、GhidraとIDA Pro、この二者は似て非なるもの、別物と考えています。
別物という考えにつながる根拠としては、次の2つの違いがあげられます。
- デバッガの有無
- Processor用の独自言語の存在
順番に見ていきましょう。
Ghidraにデバッガは(まだ)ない
これについてはまず少し補足を。お高いほうのIDA Proには高性能なデバッガが付属しており、無料版であるfreewareには長らく付属してきませんでした。が、この春ごろfreeware版にも付属するようになりました(本記事執筆時にfreeware版のダウンロードページを確認したところ、できないことの中から"Debugger"の文字が消えていました)。
一方Ghidraにはデバッガは付属していません。これはIDA Proとの大きな違いとして、今までの紹介記事等でも扱われている点です。
もちろんソースコードが公開されていますし、モジュールという形で追加することも可能ではないかと思います(本当か~~?)。
ですが、そもそも今までGhidraにデバッガが付属してこなかったのはある意味自然なことではないかと思います。
というのも、NSAのホームページ上には
"It helps analyze malicious code and malware like viruses, and can give cybersecurity professionals a better understanding of potential vulnerabilities in their networks and systems."
NSA (2019) "Ghidra", https://www.nsa.gov/resources/everyone/ghidra/ より引用
といった記述があり、マルウェア解析を主眼とした形で開発・運用されてきたことがうかがえます。マルウェアの解析ですから、リスクは小さく、できれば動かさずに解析したい、つまり静的解析でケリをつけたいというのは十分に理解できます。量的な問題もあるでしょうし。
これらのことから、「デバッガが付属していない」という点は、Ghidraが実際にオペレーションの中に位置づけられて開発されてきたということを表す、大きな特徴の一つであると言えます。
Processor用の独自言語の存在
Processorとは、IDA Pro/Ghidraでは逆アセンブル(・逆コンパイル)を担うモジュールのことを指し、IDA Pro・Ghidra共に追加することもできます。
IDA Proの場合、機械語(バイトコード)とアセンブラ命令の対応なども含め、C++やPythonで書かれています。
一方、Ghidraは
Sleighと呼ばれる、機械語とアセンブラの対応を定義することに特化した専用の言語が用意されています。
詳細は長く複雑になるため省きますが、このSleighと中間言語P-Codeの組み合わせにより、アーキテクチャに依存していない逆アセンブラが実現されています。
Sleighのドキュメントについては
/{解凍先}/docs/languages/index.html のSleigh Manualにあります。
普段Ghidraを使う上では意識しない部分ではありますが、バックグラウンドにある独自言語の存在というのは関心の分離、というソフトウェア設計的な面でも興味深いもので、大きな特徴と考えられます。
終わりに
無理やりすぎる書き出しに始まり、スクショも少なく駆け足になってしまいましたが、Ghidraについて私なりの見解を交えつつ、紹介してまいりました。
最初ブログを振られたときはどうしようかと思ってましたが、まだ日本語情報の少ないGhidraについて少しでも情報が提供できていれば、と思います。
なんか動いてるバイナリがある、職場・研究室etc.で先輩が作ったらしいけどソースがない!とお困りのあなた、ちょっと覗いてみたいと思ったあなたも、Ghidra、試してみてはどうでしょう?
実はこの「引き継いじゃった謎のものに対する防御になるかも?」ということが書きたかっただけという説もなくはないです。
※あくまで自己責任にてお願いします。
なにはともあれ、何事もtry and errorが大事です。
あ、あと
ソースコードの管理も大事ですね!
ともかく、
- 画面に書かれているものを読んでみる
- わからないことがあったらググってみる!
というスタンスで気楽に&思い切って使ってみましょう!
それでは、良きバイナリライフを!