
ファームウェアハッキングへの初心者のアプローチ
このドキュメントは、ファームウェアのリバースエンジニアリングとエクスプロイトの初心者である私の個人的な経験を記録したものです。

デモンストレーションとして、CVE-2023-27216 を解析・再現します。
ファームウェアをエクスプロイトするには、以下の手順があります:
gdbserver をスタティックにビルドする。通常、ファームウェアのバイナリファイルには、ブートローダー(uBoot)、カーネルファイル、ブートローダー用のカーネルヘッダー(uImage)、圧縮ファイルシステム(一般的に SquashFS 形式)、CRC/MD5テーブル(ファイルの整合性を検証するため)、その他の雑多なファイルが含まれています。
まずファームウェアを解析する方法を調べ、調査を行い、いくつかのリソースを入手しました:

binwalkを使用してファームウェアを抽出する: binwalk -Me DSL-3782_A1_EU_1.01_07282016.bin

抽出された squashfs-root フォルダといくつかの奇妙なファイルが得られました。

ボーナス: squashfs-root フォルダが見当たらない場合は、表示されている ".squashfs" ファイルに対して unsquashfs を使用してください。それらはZIPファイルのようなものです 😅。
ファームウェアのアーキテクチャとエンディアンを確認します。これは、ファームウェアから抽出したバイナリを確認することでチェックできます。アーキテクチャとファームウェアを確認するには: file <binary>

ここで、ファームウェアがMIPS 32ビットMSBアーキテクチャで動作することをほぼ確認できます。「ほぼ」の理由は、一部のファームウェアが Lexra のような MIPS互換 の異なるアーキテクチャで動作する可能性があるためです。
squashfs-root フォルダを確認すると、いくつかの興味深いファイルが見つかりました:
usr/etc/init.d/rcS => これはファームウェアの起動時に実行されるスクリプトですusr/etc/passwd => これはユーザー情報を含むファイルですuserfs/romfile.cfg => 認証情報 admin:admin がありますrcS ファイルを確認すると、いくつかの興味深いコードが見つかりました:
echo "admin:$1$$iC.dUsGpxNNJGeOm1dFio/:0:0:root:/:/bin/sh" > /usr/etc/passwd
passwd ファイルに書き込むために使用されますBoa は古いWebサーバーで、主に2000年代のルーターなどの組み込みデバイスで使用されていました。しかし、boaサーバーの開発は2005年にすでに停止しています!Boaサーバーは約20年前に開発が終了しましたが、ベンダーのおかげで今日でも生き続けています。

エミュレーションプロセスには、Ubuntu や Kali などのDebianベースのOSを使用することをお勧めします。ファームウェアハッキングに特化した別のOSとして AttifyOS もあります。このドキュメントでは、Kali Linuxを使用しました。エミュレーションプロセスを始めるにあたり、2つのツールがあります:

FAT を使用してファームウェアを完全にエミュレートする方法を見ていきましょう。まず、githubからリポジトリをKaliマシンにクローンします。そしてセットアッププロセスを進めます。fat.config ファイルも変更する必要があります。そうしないと機能しません。
git clone https://github.com/attify/firmware-analysis-toolkit.git
cd firmware-analysis-toolkit
./setup.sh
vi fat.config # Modify to your sudo password.
次に、メーカーからダウンロードしたファームウェアバイナリをKaliマシンの FAT のフォルダにコピーして実行します。
./fat.py DSL-3782_A1_EU_1.01_07282016.bin
注: FAT のセットアッププロセス中にエラーが発生する可能性があります。libmagicがないと表示されるかもしれません。

単純に次のコマンドを実行してください
pip unistall python-magic
pip install python-magic
これで問題が解決するはずです。その後、ビルドコマンドを再度実行します。今度は完璧に動作するはずです。

Enter を押して実行します。エミュレーションプロセスが正常に動作し、http://192.168.1.1(Kaliマシン上)にブラウザでアクセスして動作を確認できます。

認証情報があればコンソールにログインすることもできます。ここでは admin:admin です。

エミュレートされたファームウェアを停止する場合は、Ctrl+A X を押してください。再度実行する必要がある場合、ファームウェアはすでにイメージにビルドされているため、fat.py を再度実行しないでください。生成済みのスクリプトを実行するだけでOKです。
cd firmadyne/scratch/<Image-ID>
./run.sh

デバッグ目的で gdbserver をビルドします。gdbserver をビルドする方法はいくつかあります。静的にビルドされたサーバーをダウンロードすることもできます。静的にビルドされたものを保存しているリポジトリがあります。しかし、githubリポジトリのものはかなり古く、互換性の問題が発生する可能性があるため、私は自分で gdbserver をビルドする方を好みます。
参考としてこちらのブログ記事を参照してください https://sheran.sg/blog/cross-compile-gdb-for-mips/。ブログは2024年7月30日にアップロードされました。このプロジェクトの直前なので、完璧に動作します。
注: ブログは MIPS x32 LSB 用にビルドされていますが、私たちには MIPS x32 MSB が必要です。mipsel-linux-gnu を mips-linux-gnu に変更する必要があります。
MIPS 用のツールチェーンをインストールする必要があります。幸い、Debianパッケージにすでに含まれています。
**apt update && apt upgrade -y
apt install -y build-essential m4 gcc-mips-linux-gnu g++-mips-linux-gnu**
MIPS 用の gdbserver をビルドするには、ビルドしてインストールする必要があるパッケージがいくつかあります。ソースの入手先は以下の通りです。
ソースの入手
wget https://sourceware.org/pub/gdb/releases/gdb-15.1.tar.xz
wget https://gmplib.org/download/gmp/gmp-6.3.0.tar.xz
wget https://www.mpfr.org/mpfr-current/mpfr-4.2.1.tar.xz
ツールチェーンでライブラリをビルドする これらのライブラリをビルドする際にroot権限を持つことが重要です。MPFRをビルドするための要件であるため、最初にGMPをビルドする必要があります。
tar xvf gmp-6.3.0.tar.xz && cd gmp-6.3.0
./configure --host=mips-linux-gnu
make -j$((`nproc`+1))
make install
cd ..
次にMPFRをビルドします:
tar xvf mpfr-4.2.1.tar.xz && cd mpfr-4.2.1
./configure --host=mipsel-linux-gnu --with-gmp-build=<YOUR-FOLDER>/gmp-6.3.0
make -j$((`nproc`+1))
make install
cd ..
これでようやくgdbserverをビルドできます:
tar xvf gdb-15.1.tar.xz && cd gdb-15.1
./configure --host=mipsel-linux-gnu --with-gmp-lib=/usr/local/lib --with-mpfr-lib=/usr/local/lib --with-gmp-include=<YOUR-FOLDER>/gmp-6.3.0 --with-mpfr-include=<YOUR-FOLDER>/mpfr-4.2.1/src
make -j$((`nproc`+1)) LDFLAGS=-static
ビルドされたバイナリ gdbserver は gdb-15.1/gdbserver フォルダにあります。
エミュレートされたファームウェアには wget、nc、curl、/dev/tcp などがありません。ファイル転送用のPython HTTPサーバーをホストすることはできません。ssh もありません。しかし、イメージをマウントすることで gdbserver をエミュレートされたマシンに配置できます。
sudo ./scripts/mount.sh 1gdbserver をマウントされたフォルダ内の任意の場所にコピーします。sudo ./scripts/umount.sh 1./run.sh を再度実行)。