analyzing-firmware-images について
ファームウェアの更新イメージや、組み込み機器のファイルシステム、サービス、バイナリを調べるセキュリティ分析スキルです。IoT機器やルーターなどを評価する研究者向けで、抽出からエミュレーション、暗号の検証まで扱います。
主な機能
- 01イメージ形式とエントロピーの特定
- 02組み込みファイルシステムの抽出
- 03認証情報とシークレットの検索
- 04Webインターフェースとサービスの検証
- 05異なるアーキテクチャのバイナリ分析
- 06更新署名と暗号の評価
活用シーン
- 01ファームウェアイメージによるIoT機器の評価
- 02ファームウェア内の認証情報や鍵の検索
- 03機器の更新検証方式の評価
- 04組み込みWebインターフェースとネットワークサービスの調査
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ trilwu/ secskills --skill analyzing-firmware-imagesインストール後、Claude Code で/analyzing-firmware-imagesを入力して読み込まれたか確認します。
詳細
ファームウェアイメージの分析
ファームウェアは凍結された Linux(または RTOS)イメージであり、そのセキュリティも同時に凍結されています。 CGI スクリプトにハードコードされた認証情報やコマンドインジェクション、署名されていない更新パッケージ、有効なまま放置されたデバッグインターフェースは、例外ではなく標準的なものです。作業の手順は、抽出、全体像の把握、そしてこのシステムが出荷以来一度もパッチを適用されていないことを念頭に、あらゆるシステムに対して行うのと同じ質問をすることです。
使用する場面
- ファームウェアの更新ファイル(.bin、.img、.chk、.trx)を抽出して分析する場合
- ファームウェアイメージから IoT デバイスのセキュリティ状況を確認する場合
- デバイスのファームウェアにハードコードされた認証情報、鍵、シークレットがないか探す場合
- 組み込みデバイスやルーターの攻撃対象領域を評価する場合
- 更新メカニズムと署名検証を評価する場合
- マイクロコントローラーのベアメタルまたは RTOS イメージを分析する場合
使用しない場面
- 標準的な x86/x64 バイナリーのリバースエンジニアリング --
analyzing-binariesを使用してください - マルウェアサンプルの分析 --
analyzing-malwareを使用してください - ソースコードが利用できる場合 --
auditing-code-for-vulnerabilitiesを使用してください
ファームウェアの取得
分析の前に取得が必要です。取得方法によって、得られるものが決まります。
| 方法 | 得られるもの | 備考 |
|---|---|---|
| ベンダーからのダウンロード | 多くの場合、圧縮または暗号化された更新パッケージ | サポートポータル、FTP サーバー、FCC の提出書類を確認します |
| OTA のスニッフィング | 転送中の更新ペイロード | デバイスの更新チャネルで mitmproxy または tcpdump を使用します。多くのデバイスは平文 HTTP を使用しています |
| UART/シリアルコンソール | シェルアクセス、ブートローダーとのやり取り | 3 本の配線(TX、RX、GND)が必要です。マルチメーターまたはロジックアナライザーで特定します |
| JTAG/SWD | メモリー全体の読み出し、デバッグアクセス | ピンの特定が必要です。JTAGulator、OpenOCD を使用します |
| チップオフ | フラッシュの生データ(NAND/NOR) | フラッシュチップを取り外し、プログラマー(CH341A、FlashcatUSB)で読み取ります。最終手段です |
| ブートローダーからの抽出 | U-Boot の md または sf read コマンドによるダンプ | UART 経由でブートローダーのシェルにアクセスできる場合に使用します |
OTA を傍受するには、デバイスが mitmproxy を経由するように設定します。多くのデバイスはプロキシ設定を無視するため、ARP スプーフィングまたは透過ブリッジが必要になる場合があります。更新に HTTPS が使われている場合は、デバイスが証明書を検証しているか確認してください。実際には、検証していないデバイスが驚くほど多くあります。
初期分析
抽出する前に、フォーマットの特定とエントロピー分析から始めます。
file firmware.bin
binwalk firmware.bin # identify embedded filesystems and compression
binwalk -E firmware.bin # entropy analysis -- high entropy = compressed or encrypted
hexdump -C firmware.bin | head -64 # header bytes reveal container format
strings -n 10 firmware.bin | head -100 # quick orientation
エントロピープロットから分かること:
- イメージ全体でエントロピーが高く、ほぼ一定(1.0 に近い) -- 全体が暗号化または圧縮されています。先に進むには、復号鍵または展開方法が必要です。
- エントロピーの高い領域が、エントロピーの低いヘッダーで区切られている -- メタデータを挟んで圧縮されたファイルシステムパーティションがあります。これは一般的な状態です。パーティションを抽出してください。
- 全体的にエントロピーが低い -- ファイルシステムが圧縮されていないか、フラッシュの生データです。直接抽出できるはずです。
一般的なコンテナーフォーマット:
| ヘッダーマジック | フォーマット |
|---|---|
hsqs / sqsh | SquashFS |
UBI# | UBI/UBIFS |
0x1985 | JFFS2 |
0x28cd3d45 | cramfs |
HDR0 | TRX(Broadcom ルーター) |
\x27\x05\x19\x56 | uImage(U-Boot) |
抽出
ファイルシステムに適したツールを使用してください。汎用的な抽出では、メタデータや権限が失われます。
# General recursive extraction -- good starting point
binwalk -Me firmware.bin
# SquashFS -- the most common embedded filesystem
unsquashfs -d rootfs squashfs-root.img
# Non-standard SquashFS (vendor-modified): use sasquatch
sasquatch -d rootfs squashfs-root.img
# JFFS2
jefferson firmware.jffs2 -d rootfs
# UBI/UBIFS
ubireader_extract_images firmware.ubi
ubireader_extract_files firmware.ubi
# cramfs
cramfsck -x rootfs cramfs.img
# Raw NAND dumps may need OOB data stripped first
nandextract firmware.nand
binwalk で何も見つからず、エントロピーが高い場合は、イメージが暗号化されている可能性が高いです。復号ルーチンを含むブートローダー、または以前のバージョンのファームウェアを探してください。ベンダーによっては、復号鍵をブートローダーや付属のパーティションに格納しています。
ファイルシステムの分析
抽出したら、rootfs を初めて監査する Linux システムとして扱います。
認証情報とシークレット
# Password files
cat rootfs/etc/passwd
cat rootfs/etc/shadow
# Hardcoded credentials -- these are endemic
rg -rn 'password|passwd|admin|root|default' rootfs/etc/ --include='*.conf'
rg -rn 'BEGIN (RSA|EC|OPENSSH|DSA) PRIVATE KEY' rootfs/
rg -rn 'api[_-]?key|secret[_-]?key|token' -i rootfs/
# Certificates and keys
find rootfs -name '*.pem' -o -name '*.key' -o -name '*.crt' -o -name '*.p12'
# WiFi and VPN credentials
find rootfs -name 'wpa_supplicant*' -o -name '*.ovpn' -o -name 'ipsec.*'
/etc/shadow にあるデフォルトの認証情報は、ファームウェアで最もよく見つかる問題です。root にパスワードハッシュが設定されているか、またそのハッシュを解読できるか確認してください。たいてい解読できます。ハッシュの扱いについては cracking-passwords を参照してください。
設定とサービス
# Startup scripts reveal what runs and how
ls rootfs/etc/init.d/ rootfs/etc/rc.d/
cat rootfs/etc/inittab
# Systemd units if present
find rootfs -name '*.service' -path '*/systemd/*'
# Installed packages and versions
cat rootfs/etc/opkg/status 2>/dev/null # OpenWrt-based
ls rootfs/usr/lib/ipkg/info/ 2>/dev/null # older ipkg
# Network configuration
cat rootfs/etc/network/interfaces 2>/dev/null
rg -rn 'iptables|ip6tables|nftables' rootfs/etc/
Web インターフェース
悪用可能なバグが潜んでいるのは Web インターフェースです。組み込み Web サーバーは通常、BusyBox httpd、lighttpd、uhttpd、または GoAhead で、シェル、Lua、C で書かれた CGI スクリプトを配信します。
# Find the web root
find rootfs -name 'httpd*' -o -name 'lighttpd*' -o -name 'uhttpd*'
ls rootfs/www/ rootfs/usr/www/ rootfs/usr/share/www/ 2>/dev/null
# CGI scripts -- these are the attack surface
find rootfs -name '*.cgi' -o -name '*.sh' -path '*/cgi-bin/*'
find rootfs -name '*.lua' -path '*/luci/*' -o -name '*.lua' -path '*/www/*'
# Command injection patterns in CGI
rg -rn 'system\(|popen\(|exec\(|os\.execute|io\.popen|\`.*\$' rootfs/www/
rg -rn '\$QUERY_STRING|\$REQUEST_URI|\$HTTP_' rootfs/www/
CGI パラメーターを介したコマンドインジェクションは、組み込み Web インターフェースで常態化しています。 よくあるパターンは、クエリパラメーターからユーザー入力を受け取り、サニタイズせずにシェルコマンドへ渡す CGI スクリプトです。すべての CGI スクリプトを確認し、このパターンがないか調べてください。ユーザーが制御できる入力を使った system()、popen()、バッククォート実行、os.execute()、io.popen() を確認します。
以下も確認してください。
- 認証バイパス(ログインせずにアクセスできるページ)
- 診断ページ(ping、traceroute、DNS ルックアップ)におけるクロスサイトスクリプティング
- ファイル配信ハンドラーにおけるパストラバーサル
- ハードコードされたセッショントークン、または予測可能なセッション生成
バイナリー解析
ファームウェアのバイナリーは、x86 以外のアーキテクチャを対象としています。逆アセンブルする前にアーキテクチャを特定してください。
# Identify architecture from ELF headers
file rootfs/usr/sbin/*
readelf -h rootfs/usr/sbin/httpd # Machine field: ARM, MIPS, PowerPC
# Common architectures in firmware
# ARM (little-endian) -- modern IoT, cameras, some routers
# MIPS (big-endian) -- routers (Broadcom, Atheros, MediaTek)
# MIPS (little-endian) -- some Realtek-based devices
# PowerPC -- older enterprise networking gear
クロスアーキテクチャの逆アセンブル
Ghidra は、一般的なファームウェアのアーキテクチャをすべてネイティブで処理できます。バイナリーを読み込み、正しいプロセッサとエンディアンを選択して、自動解析を実行します。
# Ghidra headless analysis
analyzeHeadless /proj FirmwareProj -import rootfs/usr/sbin/httpd \
-processor ARM:LE:32:v7 -postScript DecompileAll.java
# radare2 with architecture specification
r2 -a arm -b 32 rootfs/usr/sbin/httpd
# For MIPS big-endian:
r2 -a mips -b 32 -e cfg.bigendian=true rootfs/usr/bin/target
逆アセンブルでは、以下に重点を置いてください。
- Web サーバーと CGI ハンドラーのバイナリー
- カスタムデーモン(BusyBox や標準パッケージ由来ではないもの)
- デバイス固有の機能を実装する共有ライブラリー
- root 権限で実行され、ネットワーク入力を受け付けるバイナリー
QEMU によるエミュレーション
# User-mode emulation for individual binaries
qemu-arm -L rootfs/ rootfs/usr/sbin/httpd
qemu-mipsel -L rootfs/ rootfs/usr/bin/target
# Use -strace to trace syscalls
qemu-arm -strace -L rootfs/ rootfs/usr/sbin/httpd
# If the binary needs specific /dev nodes or /proc, use chroot
sudo chroot rootfs/ /usr/sbin/httpd
# Or mount necessary filesystems
sudo mount -t proc proc rootfs/proc
sudo mount -t sysfs sysfs rootfs/sys
ネットワークサービス
稼働中のデバイスをスキャンするのではなく、初期化スクリプトとバイナリー設定を調べて、デバイスがネットワーク上に公開しているものを列挙してください。
# Services started at boot
rg -rn 'start\(\)|start_service' rootfs/etc/init.d/
# Listening ports from configuration
rg -rn 'listen|bind|port' rootfs/etc/ --include='*.conf'
# Common embedded services to look for
find rootfs -name 'telnetd' -o -name 'dropbear' -o -name 'sshd'
find rootfs -name 'upnpd' -o -name 'miniupnpd' -o -name 'minissdpd'
find rootfs -name 'mosquitto*' -o -name 'mqtt*'
find rootfs -name 'snmpd' -o -name 'snmp.conf'
よくある問題:
- デフォルトの認証情報、または認証情報なしで有効になっている Telnet
- 内部サービスの説明を WAN に公開している UPnP/SSDP
- 認証のない MQTT ブローカー
- デフォルトのコミュニティ文字列(
public、private)を使用する SNMP - 認証のない、標準外ポートで稼働するカスタム管理プロトコル
- ISP 管理 VLAN の外部に公開された TR-069(CWMP)インターフェース
- 本番環境でも有効なままのデバッグポート(GDB サーバー、ネットワーク経由のシリアル接続)
システム全体のエミュレーション
個々のバイナリーのエミュレーションでは不十分な場合は、ファームウェア全体をエミュレートします。
# FirmAE -- automated full-system emulation
sudo python3 firmae.py -r <brand> firmware.bin
# EMBA -- comprehensive firmware analysis framework
sudo ./emba -f firmware.bin -l ./logs
# firmwalker -- static analysis without emulation
./firmwalker.sh rootfs/
FirmAE と EMBA は、適切な QEMU マシンタイプの推定、ネットワークの設定、/dev/ ノードへのパッチ適用といった難しい部分に対応します。これらが失敗した場合、QEMU によるシステム全体の手動エミュレーションでは、対象プラットフォームに適したデバイスツリーとカーネルを構築する必要があります。
システム全体が起動したら、ネットワークサービスと同じようにテストします。nmap でスキャンし、Web インターフェースをテストし、カスタムプロトコルをファジングします。違いは、ファイルシステムを利用でき、テストしながらコードを読めることです。
暗号解析
ファームウェアイメージには、暗号素材が含まれていたり、独自の暗号方式が実装されていたりすることがよくあります。
# Find encryption keys and certificates
find rootfs -name '*.pem' -o -name '*.der' -o -name '*.key' -o -name '*.pub'
rg -rn 'AES|DES|RSA|SHA256|MD5|encrypt|decrypt' rootfs/usr/lib/ --include='*.so'
# Check update signature verification
# Look for signature checks in the update handler
rg -rn 'verify|signature|sign|openssl|gpg' rootfs/usr/sbin/ rootfs/etc/init.d/
確認する項目:
- 署名されていないファームウェア更新 — 更新メカニズムが暗号署名を検証しない場合、ネットワーク上で攻撃者の位置を得た者が任意のファームウェアを送り込めます。これは重大な問題です。
- 対称鍵のみを使った更新署名 — ファームウェア自体に埋め込まれた共有鍵が使われている場合、ファームウェアを入手した者なら誰でも更新に署名できます。鍵を抽出して実証してください。
- ハードコードされた TLS 証明書と秘密鍵 — すべてのデバイスに同じ鍵ペアが搭載されています。鍵を抽出し、あるデバイスの鍵で別のデバイスの通信を復号できることを実証してください。
- 脆弱な暗号化、または独自の暗号化 — 設定ファイルに対する XOR による「暗号化」、パスワードの「暗号化」に使われるハードコードされた鍵、暗号化とは呼べない独自の難読化ルーチンなどです。
- エントロピー源 — 組み込みデバイスは起動時のエントロピーが不足していることがよくあります。
/dev/urandomが適切にシードされているか、鍵生成前に RNG が初期化されているか、デバイスにハードウェア RNG が搭載され、実際に使用されているかを確認してください。
詳細な暗号レビューの方法については、reviewing-cryptography を参照してください。
防御レビューのチェックリスト
分析を終えたら、以下の項目に照らして評価してください。いずれかの項目が欠けている場合は、指摘事項となります。
| 管理項目 | 確認事項 | よくある不備 |
|---|---|---|
| 署名付き更新 | 更新パッケージは非対称鍵で暗号学的に署名されていますか?フラッシュ書き込みの前に署名が検証されていますか? | 署名がない、または対称鍵のみを使用 |
| セキュアブート | ブートローダーはカーネルとルートファイルシステムの整合性を検証しますか? | 署名検証を行わないU-Boot |
| デフォルト認証情報なし | 初回使用時に、デバイスはパスワードの変更を強制しますか? | root:root、admin:admin、または空のパスワード |
| 最小限のサービス | 必要なサービスだけが有効になっていますか? | Telnet、UPnP、SNMPがデフォルトで有効 |
| デバッグインターフェース | 本番環境でUART、JTAG、SSHは無効化されているか、アクセスが制限されていますか? | root権限で認証なしのUARTシェルにアクセス可能 |
| ストレージの暗号化 | 認証情報と鍵は保存時に暗号化されていますか? | 設定ファイル内の平文パスワード |
| あらゆる通信でTLSを使用 | すべてのネットワークサービスが、有効な証明書を使ってTLSを使用していますか? | Web管理画面での平文HTTP、平文MQTT |
| 入力検証 | CGIおよびAPIハンドラーは入力を検証し、サニタイズしていますか? | Webパラメーターを介した直接的なシェルインジェクション |
| 最小権限 | 可能な場合、サービスはroot以外のユーザーで実行されていますか? | すべてがrootで実行 |
| ロギングと監査 | セキュリティイベントは記録されていますか? | ログがない、または揮発性メモリにしかログが保存されない |
受け入れてはいけない言い訳
- 「隔離されたネットワーク上にあります。」 組み込みデバイスは、UPnP、ファイアウォールの設定ミス、ホームに通信するクラウド管理ポータルなどを通じて、外部に露出します。到達可能であると想定してください。
- 「ファームウェアは暗号化されているので、分析できません。」 復号鍵はブートローダー、または以前の暗号化されていないバージョンにあります。セキュアブートを伴わない暗号化は保護ではなく、難読化です。
- 「単なる一般消費者向けデバイスです。」 一般消費者向けデバイスはボットネットを形成します。同じ種類の脆弱性が当てはまります。
- 「パッチを適用できないので、報告しても意味がありません。」 リスクを理解し、補完的な対策を講じられるように、内容を記録してください。
- 「ベンダーが安全だと言っています。」 ベンダーの保証は証拠ではありません。証拠となるのはファイルシステムです。
- 「これはLinuxではなく、カスタムRTOSなので、標準ツールは使えません。」 アーキテクチャーレベルのツール(Ghidra、QEMU、binwalkのエントロピー解析)は、あらゆるバイナリで使えます。手法を適応させ、分析を省略しないでください。
- 「このデバイスをわざわざ攻撃する人はいません。」 Miraiは、デフォルト認証情報を探すためにIPv4空間全体をスキャンしました。「わざわざ攻撃する」ために必要なのは、たった1つのスクリプトです。
参考資料
analyzing-binaries-- 逆アセンブルとリバースエンジニアリングの手法auditing-code-for-vulnerabilities-- ソースコードが入手可能な場合のコードレベルのレビューenumerating-network-services-- サービスの検出と評価reviewing-cryptography-- 暗号実装のレビュー