Binary Analysis 15 · Linux 組み込みイメージ — U-Boot・カーネル・ルートファイルシステム

Chapter 15

Linux 組み込みイメージ — U-Boot・カーネル・ルートファイルシステム

この章のゴール.

Linux ベースの機器(ルータ、IP カメラ、ゲートウェイ)のフラッシュを、 ブートローダ・カーネル・デバイスツリー・ルートファイルシステムの 4 層に分解し、 binwalk / unblob で展開してファイルを取り出せるようになること。

この章で使う既出の用語(定義は各リンク先). メモリマップ(01 章 3 節)、binwalk(02 章 3 節)、unblob(02 章 3 節)、CRC(03 章 8 節)、オフセット(03 章 1 節)、ビッグエンディアン(03 章 2 節)、サイズ(04 章 7 節)、ブートローダ(04 章 5 節)、ELF(05 章 1 節)、ロードアドレス(07 章 10 節)、ファイルシステム(09 章 1 節)、ページ(10 章 4 節)、エントリ(11 章 2 節)、バイナリ(12 章 3 節)、引数(12 章 3 節)、秘密鍵(13 章 2 節)、圧縮(14 章 4 節)

1. マイコンとの違い

これまでの章は「ベアメタル / RTOS のマイコン」だった。 Linux が動く組み込み機器(Cortex-A、MIPS、一部の RISC-V)は、PC の Linux に近い層構造を持ち、道具も Linux 寄りになる。フラッシュは NOR / NAND / eMMC で、容量は数 MB〜数 GB と大きい。

典型的な層:

層役割形式
1 次 / 2 次ブートローダチップ ROM → U-Boot生バイナリ、SPL(Secondary Program Loader、U-Boot 本体を読み込む小さな前段)
U-Bootカーネルを読み込んで起動uImage、環境変数領域
カーネルLinux 本体zImage / Image(多くは圧縮)
デバイスツリー(DTB)ハードウェア構成の記述0xd00dfeed
ルートファイルシステム/bin /etc /lib…squashfs / JFFS2 / UBIFS / ext4
オーバーレイ / データ設定・ログJFFS2 / UBIFS / ext4
Linux 組み込みイメージの層構造1次/2次ブートローダ(SPL)生バイナリ0x0U-Boot環境変数(bootargs・mtdparts)カーネル(zImage/uImage)多くは圧縮デバイスツリー(DTB)0xd00dfeedルートファイルシステムsquashfs/JFFS2/UBIFS/ext4オーバーレイ・データ設定・ログまず binwalk -e / unblob既知形式の塊なので自動で割れる。メモリマップがほぼ完成U-Boot の mtdparts と DTB(dtc で DTS に)がパーティション構成の決定版
ブートローダ・カーネル・DTB・ルートFSの層。binwalk -e / unblob でまず割る

2. まず binwalk / unblob で全体を割る

Linux イメージは既知形式の塊なので、binwalk の独壇場である。

binwalk fullflash.bin            # 各層のオフセットと種類を一覧
binwalk -e fullflash.bin         # 抽出(_fullflash.bin.extracted/ に展開)
unblob fullflash.bin             # より堅牢な抽出(推奨)

出力例:

DECIMAL    HEX        DESCRIPTION
0          0x0        U-Boot SPL
131072     0x20000    uImage header, ... Linux kernel, lzma compressed
1310720    0x140000   Squashfs filesystem, little endian, ...
6291456    0x600000   JFFS2 filesystem

これで 01 章のメモリマップがほぼ完成する。以降は各層を個別に開く。

3. U-Boot と環境変数

U-Boot は Linux 組み込みで最も普及したブートローダである。解析で有用なのは環境変数領域で、bootcmd(起動コマンド)、bootargs(カーネルに渡す引数)、ネットワーク設定などが平文のテキストで入っている。

strings uboot_env.bin | grep -E "bootcmd|bootargs|mtdparts"
# mtdparts=... はフラッシュのパーティション分割(オフセットと名前)を教える貴重な情報

mtdparts はフラッシュのパーティション表そのもので、「どのオフセットが kernel / rootfs / config か」が名前付きで書いてある。メモリマップの決定版になる。

4. カーネルとデバイスツリー

dtc -I dtb -O dts board.dtb -o board.dts     # デバイスツリーを人が読める形に
grep -A3 partition board.dts                 # フラッシュ分割の定義

5. ルートファイルシステムを開く

ここに実行ファイル・設定・スクリプト・鍵が全部ある。形式ごとに展開ツールが違う。

形式特徴展開
squashfs読み取り専用・圧縮。最も一般的unsquashfs rootfs.squashfs
JFFS2書き込み可・NOR 向けjefferson rootfs.jffs2
UBIFSNAND 向け(UBI の上)ubireader_extract_files、ubidump
ext2/3/4eMMC / 大容量マウント、debugfs、7z
cramfs古い読み取り専用cramfsck -x
unsquashfs -d rootfs rootfs.squashfs         # ./rootfs/ に全ファイル
ls rootfs/etc/                                # 設定ファイル
cat rootfs/etc/passwd rootfs/etc/shadow       # ユーザとパスワードハッシュ
ルートファイルシステムから何を読むか/etc/passwd /etc/shadowユーザとパスワードハッシュ。弱いハッシュ・共通PW/etc/init.d rc* systemd起動時に何が動くか。裏口・telnet/etc/ssl /etc/*/keys証明書と秘密鍵(13 章)/etc/config *.confネットワーク・資格情報/bin /sbin /usr/bin独自バイナリ → 16 章の対象/etc/os-release bannerバージョン → 既知の CVE と照合展開: squashfs → unsquashfs、JFFS2 → jefferson、UBIFS → ubireader、ext4 → マウント/7z。NAND は OOB/ECC が混じることがある
shadow・鍵・独自バイナリ・バージョンを監査。squashfs は unsquashfs

6. ルートファイルシステムから何を読むか

取り出した / は、機器のソフト構成そのものである。監査で見る場所:

7. NAND 特有の面倒

NAND フラッシュのダンプには、OOB(Out-Of-Band)領域(各ページの後ろに付く ECC / バッドブロック情報)が混じることがある。生の NAND ダンプは、データとOOBが交互に並んで見え、そのままでは展開できない。

8. 手を動かす

Linux イメージを層に分ける


この章のポイント