Ghidraで始めるリバースエンジニアリング(環境構築編) - 土日の勉強ノート

土日の勉強ノート

AI、機械学習、最適化、Pythonなどについて、技術調査、技術書の理解した内容、ソフトウェア/ツール作成について書いていきます

Ghidraで始めるリバースエンジニアリング(環境構築編)

今回から、リバースエンジニアリングツールである Ghidra を使っていきます。

書籍「リバースエンジニアリングツールGhidra実践ガイド (Compass Booksシリーズ)」を読みながら進めていきます。

それでは、やっていきます。

参考文献

はじめに

「セキュリティ」の記事一覧です。良かったら参考にしてください。

セキュリティの記事一覧
・第1回:Ghidraで始めるリバースエンジニアリング(環境構築編) ← 今回
・第2回:Ghidraで始めるリバースエンジニアリング(使い方編)
・第3回:VirtualBoxにParrotOS(OVA)をインストールする
・第4回:HTTPを題材にtcpdumpの出力を理解する
・第5回:nginx(エンジンエックス)を理解する
・第6回:Python+Flask(WSGI+Werkzeug+Jinja2)を動かしてみる
・第7回:Python+FlaskのファイルをCython化してみる
・第8回:shadowファイルを理解してパスワードを解読してみる
・第9回:安全なWebアプリケーションの作り方(徳丸本)の環境構築
・第10回:Vue.jsの2.xと3.xをVue CLIを使って動かしてみる(ビルドも行う)
・第11回:Vue.jsのソースコードを確認する(ビルド後のソースも見てみる)
・第12回:徳丸本:OWASP ZAPの自動脆弱性スキャンをやってみる
・第13回:徳丸本:セッション管理を理解してセッションID漏洩で成りすましを試す
・第14回:OWASP ZAPの自動スキャン結果の分析と対策:パストラバーサル
・第15回:OWASP ZAPの自動スキャン結果の分析と対策:クロスサイトスクリプティング(XSS)
・第16回:OWASP ZAPの自動スキャン結果の分析と対策:SQLインジェクション
・第17回:OWASP ZAPの自動スキャン結果の分析と対策:オープンリダイレクト
・第18回:OWASP ZAPの自動スキャン結果の分析と対策:リスク中すべて
・第19回:CTF初心者向けのCpawCTFをやってみた
・第20回:hashcatの使い方とGPUで実行したときの時間を見積もってみる
・第21回:Scapyの環境構築とネットワークプログラミング
・第22回:CpawCTF2にチャレンジします(この記事はクリア状況を随時更新します)
・第23回:K&Rのmalloc関数とfree関数を理解する
・第24回:C言語、アセンブラでシェルを起動するプログラムを作る(ARM64)
・第25回:機械語でシェルを起動するプログラムを作る(ARM64)
・第26回:入門セキュリティコンテスト(CTFを解きながら学ぶ実践技術)を読んだ

まず、書籍「リバースエンジニアリングツールGhidra実践ガイド (Compass Booksシリーズ)」のサポートサイトは以下です。

ここからサンプルプログラムがダウンロードできます。

book.mynavi.jp

今回は、Ghidra の環境を構築していきます。

Ghidraのインストール

Ghidra とは、アメリカ国家安全保障局(NSA:National Security Agency)によって開発されたソフトウェアリバースエンジニアリングのツールです。

どんなことが出来るかは、書籍「リバースエンジニアリングツールGhidra実践ガイド (Compass Booksシリーズ)」のサンプルプログラムを動かしながら理解したいと思います。

今回は、VirtualBox の Ubuntu 22.04 に Ghidra をインストールしていきます。

まず、以下は、Ghidra の GitHub です。

github.com

インストール方法が書かれています。

まず、JDK 17 64bit をインストールします。

私は既にインストール済みですが、以下で簡単にインストールできます。

$ sudo apt install openjdk-17-jdk

続いて、Ghidra の GitHub の releases から zipファイルをダウンロードします。

github.com

ファイル名は、ghidra_11.0.3_PUBLIC_20240410.zip です。

※2024/8/30:追記

新しい gcc、g++ ビルドしたプログラムは、DWARF v5 が使われていて、Ghidra は、v11.1 から、この DWARF v5 に対応しています。ダウンロードするときは、v11.1 以降を選んだ方がいいです。

解凍します。

$ unzip ghidra_11.0.3_PUBLIC_20240410.zip

解凍したディレクトリの ghidraRun を起動します。

cd ghidra_11.0.3_PUBLIC/
./ghidraRun

起動すると、使用許諾が出るので、問題なければ、I Agree をクリックします。

使用許諾の画面
使用許諾の画面

Ghidra が起動しました。

Ghidraが起動した
Ghidraが起動した

インストールは以上で完了です。

プロジェクトの作成からプログラムの解析まで

プロジェクトの作成

Tip of the Day は閉じておきます。

プロジェクトを作成していきます。

File → New Project... をクリックします。

プロジェクトを作成する
プロジェクトを作成する

Non-Shared Project と Shared Project が選択として現れます。Shared Project は、共同で作業するためのプロジェクトで、Ghidra Server というのが必要らしく、通常は、Non-Shared Project を選びます。Nextをクリックします。

Non-Shared Projectを選ぶ
Non-Shared Projectを選ぶ

次に、プロジェクトの場所と、プロジェクト名を決めます。どちらも任意ですが、プロジェクトの場所とは、複数のプロジェクトが格納される場所なので、新しいディレクトリを作って、そこを指定してください。その下に、今回指定したプロジェクト名のディレクトリが出来ます。指定できたら、Finish をクリックします。

プロジェクトの場所とプロジェクト名を決める
プロジェクトの場所とプロジェクト名を決める

プロジェクトが作られました。

プロジェクト作成完了
プロジェクト作成完了

これからプログラムをロードするのですが、構造の分からないプログラムより、以前に作った STM32 のサンプルプログラムを使います。

daisuke20240310.hatenablog.com

プログラムのインポート

STM32 のプログラム(ELFファイル)をインポートします。

File → Import File... をクリックします。

プログラムのインポート
プログラムのインポート

STM32 の ELFファイルを指定すると、確認画面が出ます。

ELFファイルで、32bit の ARM と正しく認識していますので、OKをクリックします。

ELFファイルのインポート確認画面
ELFファイルのインポート確認画面

インポート結果のサマリが出ます。OKをクリックします。

インポート結果のサマリ
インポート結果のサマリ

プログラムの解析

続いて、プログラムを解析させます。

Active Project のテキストのアイコンをダブルクリックします。

テキストアイコンをダブルクリックする
テキストアイコンをダブルクリックする

すると、Code Browser が開き、解析するかどうか聞かれるので、Yes をクリックします。

解析するかを確認される
解析するかを確認される

解析オプションを聞かれるので、デフォルトのままでいいと思います。もしくは、Select All を選択して、Analyze をクリックします。

解析オプションの選択
解析オプションの選択

右下に解析状況が表示されています。解析が完了すると、ソースコードが表示されます。試しに main をクリックすると、デコンパイルされた結果が右のウィンドウに表示されます。

解析結果が表示される
解析結果が表示される

ちなみに、もとの main関数のソースコードは以下になります。

int main(void)
{
  initialise_monitor_handles(); // セミホスティング機能の初期化

  led_init();     // LEDの初期化
  button_init();  // Buttonの初期化
  systick_init(); // SysTickの初期化

  // メインループ
  while (1) {
    time = g_system_time - lap_time;

    switch (state) {
    case WAINTING:
      waiting(); // 開始待ち
      break;
    case RUNNING:
      running(); // ルーレット回転中
      break;
    case STOP_OK:
      stop_ok(); // 停止(成功)
      break;
    case STOP_NG:
    default:
      stop_ng(); // 停止(失敗)
      break;
    }
  }

  // ここには到達しない
  return 0;
}

デバッグ情報が含まれている ELFファイルですが、ほぼ、Cソースコードを復元できています。

今回はここまでにします。

おわりに

今回から、Ghidra を使ったリバースエンジニアリングを始めました。

次回は、Ghidra の使い方を理解していきたいと思います。

最後になりましたが、エンジニアグループのランキングに参加中です。

気楽にポチッとよろしくお願いいたします🙇

今回は以上です!

最後までお読みいただき、ありがとうございました。