gdbserverのクロスコンパイル手順のメモ | reverse-eg-mal-memoのブログ

reverse-eg-mal-memoのブログ

サイバーセキュリティに関して、あれこれとメモするという、チラシの裏的存在。
medium(英語):https://sachiel-archangel.medium.com/

最近はLinuxベースのIoT機器のマルウェアも増えてきて、それを解析したいってことあるよね?(普通は無ぇよ)

でも、IoT機器はWindows用PCなどでよく使われるx86、x64のCPUでないことも多いです。

お手軽なことで有名な Raspberry Pi は Arm だったりしますよね。

 

Linuxのマルウェア解析では、gdbserver を使ったリモートデバッグが一つの方法として利用できると思います。

でも、IoT機器は容量の制限もキビシイので、余計なアプリケーションを入れていないことも多く、gdb や gdbserver が入っていないことが多いです。

被害に遭ったIoT機器と調査対象のマルウェアはあるものの、対象のCPUで動作する gdbserver が無くてデバッガによる解析ができない・・・というとき、「gdb はオープンソースなんだから、gdbが無いなら自分でビルドすればいいじゃない」(アントワっぽい発言)ということになりますね。(普通はならねぇよ)

 

自分の手元にはx86、x64のPCしかないけど、どうやって Arm や MIPS の実行ファイルをビルドするの?ということになりますが、これは開発手法でいうところのクロスコンパイルを使うことになります。

今回は、buildroot を使ってお手軽に色々な CPU アーキテクチャの gdbserver を構築する手順をメモしておきます。

 

 

忙しい人のために結論から

 

そもそも詳しい人なら知ってるしこんなブログ見ないとは思うけど、要約した手順を書いておきます。

利用した Buildroot のバージョンは 2022.08.1 です。

 

  • Linux 環境を構築する。
  • Buildroot をダウンロードする。(https://buildroot.org)
  • Buildroot に必要なアプリケーションをインストールする。必要なアプリケーションはマニュアルを参照。(https://buildroot.org/downloads/manual/manual.html#requiremen
  • Buildroot のディレクトリで 「make menuconfig」で以下を設定する(ターゲットの環境によっては、一部異なる)。
    • 「Target option」でCPUのターゲットアーキテクチャを選択。
    • 「Toolchain」で「Enable WCHAR Support」と「Thread library debugging」、「Build cross gdb for the host」をスペースキーで有効化(*を付ける)。
    • 「Target packages」で「Debugging, profiling and benchmark」を選択し、さらにサブメニュー内の「gdb」をスペースキーで有効化(*を付ける)。
    • 「Save」で設定を保存し(.configに保存される)、「Exit」で終了。
  • 「make」でビルドを実行する。
  • Buildroot のディレクトリ配下のサブディレクトリ「output/target/usr/bin」に出力された gdbserver を取得する。

 

 

詳しくない人のためのチュートリアル

 

分かる人には、以上があれば十分ビルドできると思います。

しかし!ここを読み始めたそこのアナタ、上の説明だけではできないのでしょう?

 

まあ、私もできなかったからメモ残すことにしたんだけどな。

しかも、数か月すると忘れるしな。

 

実際、マニュアルはしっかりしている方なのに、なかなか思い通りにいかなかったですね。

Buildroot のダウンロードと解凍、必要なツールのインストールとその後の make menuconfig でのコンフィグ画面表示までは割とすんなりいったんですが、そのあと中々 gdbserver を出力してくれませんでした。

 

「8.13.2. Using gdb in Buildroot」で「BR2_PACKAGE_HOST_GDB」、「BR2_PACKAGE_GDB」、「BR2_PACKAGE_GDB_SERVER」を有効化するように書いてありましたが、設定が保存された .config ファイルには、そもそも「BR2_PACKAGE_GDB」と「BR2_PACKAGE_GDB_SERVER」の項目が無かったんですよね。

(´・ω・`)

 

 

 

仕方ないので、「BR2_PACKAGE_HOST_GDB」の下に手動編集で「BR2_PACKAGE_GDB=y」と「BR2_PACKAGE_GDB_SERVER=y」を足してみましたが、それで make すると再編集されて消されてしまう・・・というので、その理由が分からなくて詰まりました。

というか、詰まるポイントってそこくらいだった、というくらい buildroot はお手軽なツールとなっています。

これが無料で使えるとかヤバすぎるだろ!

 

というわけで、実際のチュートリアルです。

 

 

1. Linux環境を構築する

これはもう、VMでサクッと準備することをおススメします。

VMのホストはなんでも構いません。私はVMwareを使っています。

念のためVMのスナップショットを取った方がいいと思うので、無料ならVirtual Box、有料でもいいならVMwareも選択肢ということになりますかね。

ゲストOSの Linux は Ubuntu にしました。以後の解説は、Ubuntu (20.04.5 LTS)を使っていることを前提にしています。

流石に、Ubuntu のインストール方法等はここでは省略します(多分、それらの記事をググればいくらでも出る)。

 

 

 

2. Buildroot をダウンロードする

これも、当該ページにアクセスしてダウンロードするだけです。

私は、自身が作業した当時で stable release となっていた 2022.08.1 をダウンロード使用しました。

バージョンによってメニュー等に変更が生じる可能性があることに注意してください。

 

 

 

ダウンロードしたら、ビルド環境を構築したいディレクトリにファイルを設置し、「tar xvfz (ダウンロードしたファイル).gz」で解凍してください。

 
tar.gz でダウンロードした場合:
tar xvfz buildroot-2022.08.1.tar.gz

 

 

3. Buildroot に必要なアプリケーションをインストールする

Buildroot も、全ての機能をパッケージしているわけではなく、いくつかの必須のアプリケーションがあります。

これらをインストールしないと、正常にビルドできず、エラーになってしまいます。(たぶん。私は素直に最初にインストールしちゃった)

 

必要なアプリケーションはマニュアルに書かれています。

将来のバージョンでは追加・変更されている可能性があるので、この記事の手順どおりやっても上手く行かない場合は、マニュアルの内容を確認してください。

 

 

 

ただし、モノによっては既にインストールされているものもあり、それはスキップしても問題ありません(アップグレードはしたほうがいいかも)。

今回のUbuntu環境で行ったのは以下のとおり。

 

sudo apt install make

sudo apt install gcc

sudo apt install g++
sudo apt-get install ncurses-dev

 

*ncurses-dev は、後の make menuconfig 実行時のUIに必要。nconfig, xconfig等を使うなら要らないかもしれない。

*構築時に余計なことをやってメモってなかったりすることもあるので、足りなければ他のパッケージも追加でインストールしてください。

 

 

4. 「make menuconfig」で設定

buildloot を解凍したディレクトリに移動し、コンフィグ画面を起動します。

 

make menuconfig

 

 

 

すると、以下のような画面が表示されます。

 

 

 

まず、Target options でターゲットとなるCPUアーキテクチャを選択します。

Target options → Target Architecture を選択します。

 

 

 

 

なお、選択できるCPUアーキテクチャは、Buildroot 2022.08.1 では以下となっていました。

 

ARC (little endian) 
ARC (big endian)
ARM (little endian)
ARM (big endian)
AArch64 (little endian)
AArch64 (big endian)
i386
m68k
Microblaze AXI (little endian) 
Microblaze non-AXI (big endian)
MIPS (big endian)
MIPS (little endian)
MIPS64 (big endian)
MIPS64 (little endian)
Nios II 
OpenRISC
PowerPC 
PowerPC64 (big endian)  
PowerPC64 (little endian)
RISCV
s390x
SuperH
SPARC
SPARC64
x86_64
Xtensa

 

ターゲットのCPUアーキテクチャを選択したら、さらに Target Architecture Variant を設定します。

これは、CPUのアーキテクチャの中でも細かいグレードやバージョンに対応したもののようです。

例として、MIPS Big-endian の場合の Target Architecture Variant 画面を提示します。

 

 

 

 

次に、Toolchain を編集します。

以下の3つにチェックを付ける必要があります。

チェックは、当該行にカーソルを移動してスペースキーで付けることができます。

 

Enable WHAR support

Thread library debugging

Build cross gdb for the host  

 

 

 

 

最後に、Target Packages を編集します。

Target Packages → Debugging, profiling and benchmark を選択します。

 

 

 

gdb にチェックを入れます。

チェックは、当該行にカーソルを移動してスペースキーで付けることができます。

 

 

 

ちなみに、今回のハマりポイントはここでした。

 

実は、Toolchain で「Build cross gdb for the host」を設定していても、「Enable WHAR support」、「Thread library debugging」が未チェックだと、下図のように選択自体ができなくなっていました。

「w/ threads」と「threads debug」が必要、と書いてはあるけど、流石にどの項目のことかは最初分からなかったよ・・・。

というか、チェック項目となる[ ]自体がなかったので、項目自体にしばらく気づいてなかったですね。

(表示されていなかった時の状況は以下の画像のとおり)

 

 

 

 

編集が終わったら、カーソルの→キーで Save へ移動し、編集結果を保存します。

.config というファイル名がデフォルトで入っているので、これは変更せず保存します。

 

 

 

保存したら、Exit で終了します。

 

 

 

5. 「make」でビルドを実行する

menuconfig による編集を保存して終了したら、make でビルドを実行します。

 

 

 

ここはこれだけですが、注意点として、インターネット上のリポジトリを参照していたりするので、そのダウンロードのためにインターネット接続が必要です。また、初回のビルドは結構時間がかかると思いますので、気長にお待ちください。

もう一つの注意点としては、menuconfig で設定を変えて何度もビルドしなおしていると、稀に構成・依存関係の問題でビルドエラーになることがあります。この場合、「make clean」で一度クリーンして再度 make を実行することで解決することがあります(私も数回それで解決した)。

 

エラーメッセージがない状態で終了すれば、ビルドは完了です。

 

 

 

 

6. 出力された gdbserver を取得

ビルドした結果は、make をしたディレクトリ配下にある output ディレクトリにあります。

今回欲しいのは gdbserver ですがそれは output/target/usr/bin に作成されていました。

 

 

 

当該ファイルを確認するため、file コマンドを実行してみると、

 

gdbserver: ELF 32-bit MSB executable, MIPS, MIPS32 version 1 (SYSV), statically linked, stripped

 

ということを確認できました。

32bitのMIPSアーキテクチャ、MSBということでBig-endianということも確認できます。

これで、MIPS 32bit Big-endian の gdbserver が入手できたことになります。\(^o^)/

 

あとは、それぞれの環境に合わせてこのファイルを転送し、gdbserver として実行させることができれば、リモートデバッグが可能になります。

私の場合、IDA Pro で gdb のリモートデバッグができるので、大変助かる、というわけです。

別のアーキテクチャの CPU の gdbserver が必要になっても、Target options で変更して作り直して入手できますね。

 

 

 

まとめ

 

今回、自身では技術的なことを何もやってないのでまとまらねぇ

ま、まあ、IoT機器をターゲットにしたマルウェアの調査機会も増えてきましたが、その準備に膨大な時間や手間暇をかけてたら本末転倒、ということで、既存のものでいいものがないか探していたらいいものがあったので、使い方をメモしてみた、という内容でした。

 

実際のところ、IoT機器で Embeded Linux はよく見かけます。

ただし、そういった環境では実運用で使わないプログラムは極力外すため、gdb や gdbserver を含むツール類は入っていません。

(開発環境なら別ですが。)

機器開発会社の協力が得られれば、そこに gdbserver 用意してもらったり、開発環境も借りれれば潤沢な調査環境にできるわけですが、そうはいかない場合もあると思います。

特に、開発・生産終了したような古い機器の場合、現物でどうにかする必要がでてきます。

また、海外のメーカーなどの場合は、メーカーの協力を得られるかも未知数です。

このため、目の前の機器を使って、足りないものは自分で用意して・・・という必要が生じたときに、今回のような方法を知っておくと役に立つかもしれませんね。

 

gdbserver を使ったリモートデバッグは、gdb を使った接続のほか、IDA pro のように gdb に対応したデバッガでも接続して調査することができるようです。

これにより、マルウェアを動作させながらの調査が可能になります。

リモートデバッグについては、必要がありそうなら書いてみますかね。