2 ポイント 投稿者 GN⁺ 2024-05-26 | 1件のコメント | WhatsAppで共有
  • Samsung WB850FはDRIMeIII SoCとWi-Fiを組み合わせた最初のモデルで、ファームウェアZIPに含まれる partialImage.o.map のおかげで、メインSoCファームウェアの解析とホットスポット検出の回避が可能になった
  • WB850F_FW_210086.zip には、6つのパーティションを含む WB850-FW-SR-210086.bin と、30万行を超える リンカダンプ が入っており、Main_Image が実際のARMファームウェアであることを確認できた
  • Ghidraでの解析では、文字列アドレスの差分を使って Main_Imageベースアドレス 0xc0004000 を見つけ、.text の関数名を変換してシンボルとして取り込む過程が鍵だった
  • ホットスポット判定関数 DevHTTPResponseStart は、HTTP 200のYahooドメインCookie、または301/302/307リダイレクトURL先頭付近の yahoo. 文字列によってAP認証の有無を判定する
  • YahooがHTTPSへリダイレクトするようになったことで yahoo. の位置がコードの許容範囲を外れ、samsung-nx-emailservice パッチ適用後にWB850Fの写真アップロードが成功した

WB850FファームウェアZIPの構造

  • Samsung WB850Fは、iLauncherアプリケーションの終了後もSamsungが依然として ファームウェアとサポートファイル を公開している数少ないモデルの1つである
  • WB850F_FW_210086.zip には次のファイルが含まれている
    • GPS_FW/BASEBAND_FW_Flash.mbin
    • GPS_FW/BASEBAND_FW_Ram.mbin
    • GPS_FW/Config.BIN
    • GPS_FW/flashBurner.mbin
    • FWUP
    • partialImage.o.map
    • WB850-FW-SR-210086.bin
    • wb850f_adj.txt
  • FWUP は、ファームウェアのテスト/自動化モジュール用スクリプトと思われ、upgrade all という文字列だけを含む
  • wb850f_adj.txt は、GPSファームウェアを更新し、関連ファイルを削除する、より複雑なスクリプトである
  • GPS関連スクリプトと GPS_FW フォルダは今回の解析対象から除外する

partialImage.o.map: リンカダンプという地図

  • partialImage.o.map は30万行を超えるテキストファイルで、partialImage.o に対する リンカ出力 と、リンクされたファイルの完全なメモリマップを含んでいる
  • .text セクションには、sysInitarchPwrDownDevHTTPResponseStartDevHTTPResponseDataDevHTTPResponseEnd のような関数名が入っている
  • .data セクションには、sysBussysCpusysBootLine のようなデータシンボルが含まれる
  • このファイルは、ファームウェア内のコードと関数名を突き合わせるための シンボルマップ として活用される

WB850-FW-SR-210086.binヘッダとパーティションテーブル

  • binwalkWB850-FW-SR-210086.bin を見ると、HTML、PNG、JPEGヘッダ、VxWorksヘッダ、複数のUnixパスが見えるが、明確なパーティションやファイルシステムは現れない
  • 先頭1KBをヘクスダンプすると、ファームウェアバージョン 210086 の後に 0x00 0x06 が現れ、その後に FW_UP/ONBL1.bin のようなファイル名が見える
  • 各レコードは60バイト構造に見え、32バイトの0パディング文字列、2つのリトルエンディアン整数、20バイトの0パディングされたパーティション名から成ると分析された
  • 2つの整数はそれぞれ 長さファイル内オフセット と解釈される
  • 合計6レコードあるため、0x00 0x06 はファームウェアバージョン文字列の終端またはパディングバイトと、1バイトのパーティション数として解釈される
  • 再構成したパーティション

    • FW_UP/ONBL1.bin
      • サイズ: 196バイト、オフセット: 0x0000800、パーティション名: ONBL1
    • FW_UP/ONBL2.bin
      • サイズ: 46KB、オフセット: 0x00008c4、パーティション名: ONBL2
    • [WB850]DSC_5KEY_WB850
      • サイズ: 30MB、オフセット: 0x000bef4、パーティション名: Main_Image
    • RomFS/SPID.Rom
      • サイズ: 48MB、オフセット: 0x1d2b32c、パーティション名: Resource
    • FW_UP/WB850.HEX
      • サイズ: 19KB、オフセット: 0x4c75f2c、パーティション名: OIS
    • FW_UP/skin.bin
      • サイズ: 36MB、オフセット: 0x4c7acb2、パーティション名: SKIN
    • パーティション抽出には DRIMeIIIファームウェアパーティション抽出ツール を作成して使用した

コードパーティションとデータパーティションの区別

  • 抽出ツールは、パーティション名を基準にファイルを取り出し、.bin を付ける
  • file の結果だけでは、Main_Image.bin がOpenPGP Secret Keyと誤認されるなど、有用性には限界がある
  • ONBL1ONBL2 は、Main_Image 内の "BootLoader(ONBL1, ONBL2) Update Done" という文字列から、ブートローダー第1段階と第2段階だと推定される
  • Main_Image は実際のファームウェアであり、binwalk -A はこのファイル内で多数の ARM関数プロローグ を報告する
  • ResourceSKIN は大きなコンテナであり、カメラUIスキンに関連するSoCメーカー提供の構成である可能性がある
  • OIS はファイル名と違って実際にはHEXではなく、専用の光学式手ぶれ補正装置のファームウェアかもしれない
  • 解析の中心は Main_Image である

GhidraでMain_Imageをマッピングする

  • ONBL1ONBL2Main_Image の3パーティションには実際のARMコードが入っている
  • 一般的なARMファームウェアはアドレス 0x0000000 にリセットベクタテーブルを置くが、3つのバイナリはいずれも先頭部分に線形コードがあり、まだ不明なアドレスへ再マッピングする必要があった
  • ホットスポット誤検出を解析するには、次の作業が必要だった
    • Main_Image をマッピングする正しいメモリアドレスを見つける
    • partialImage.o.map のシンボル名をGhidraに読み込む
    • ホットスポットログイン判定を誤ってトリガーする関数を解析する
  • GhidraのDefined Stringsタブで "yahoo" を検索すると、DevHTTPResponseStart() のデバッグ文字列と思われる項目が出てくる
    • DevHTTPResponseStart: url=%s, handle=%x, status=%d
    • DevHTTPResponseStart: This is YAHOO check !!!
    • DevHTTPResponseStart: THIS IS GOOGLE/YAHOO/SAMSUNG PAGE!!!! 111
    • 301/302/307! cannot find yahoo!
  • partialImage.o.mapDevHTTPResponseStart0x321a84 にあり、Ghidraも同じオフセットで関数を見つけた
  • デバッグ文字列ポインタ値と実際の文字列オフセットの差が 0xc0004000 と一致したため、Main_Imageベースアドレス0xc0004000 だと結論づけた
  • Ghidraでは後からベースアドレスを変更できないため、バイナリをプロジェクトから削除して再インポートし、その際にベースアドレスを設定する必要があった

関数名の取り込みとDevHTTPResponseStartの解析

  • Ghidraの ImportSymbolScript.py は、テキスト表からシンボルを一括取り込みできる
  • スクリプトは各行に、シンボル名、16進アドレス、関数であることを示す f、またはラベルであることを示す l を期待する
  • partialImage.o.map では、現時点では .text セクションの関数だけが必要だったため、次の項目を除外する必要があった
    • 空行
    • オブジェクトファイルオフセット
    • .text のようなセクションラベル
    • L$_ 接頭ラベル
    • $ 接頭のローカルシンボル
  • アドレスには、Ghidraのベースアドレスと合わせるため 0xc0004000 を加える
  • 変換結果は sysInit c0004000 farchPwrDown c0004094 f のような形式にして、GhidraのScript Managerから読み込む
  • 関数名を取り込んだ後は、複数の DAT_ フィールドをポインタとして指定し、デバッグ文字列に合わせて引数名を変更すると、DevHTTPResponseStart のデコンパイル結果を読めるようになる

ホットスポット検出条件

  • DevHTTPResponseStart はHTTP応答ステータス、URL、ヘッダを見て、Wi-Fi APが認証済みかどうかを判定する
  • HTTP 200 OK応答では、応答ヘッダにYahooドメインCookieがある場合に認証成功として扱う
    • 検査対象は domain=.yahooDomain=.yahoodomain=kr.yahooDomain=kr.yahoo である
    • 条件を満たすと p_request_ongoing を0に変更し、ブラウザが未認証状態なら safnotify_auth_ap(0) を呼び出す
  • HTTP 301/302/307リダイレクトでは、URL内の yahoo. 文字列を検査する
    • yahoo. が存在しない、または url + 11 より後ろにある場合は、Yahooを見つけられなかったものとして処理される
    • ブラウザフレームバッファが有効でなく、かつ未認証なら safnotify_auth_ap(1) を呼び出す
    • yahoo. が先頭付近にあれば、safnotify_auth_ap(0) で認証成功として扱う
  • 負のステータスは中断されたリクエストのように false を返す
  • 200でもリダイレクトでもない正のステータスでは、ブラウザフレームバッファ状態に応じて結果が変わる

TLS後に壊れたYahooチェックと回避

  • カメラが問い合わせるURLは http://www.yahoo.co.kr/ である
  • 直接リクエストすると、サーバは HTTP/1.1 301 Moved Permanently とともに Location: https://www.yahoo.com/ へリダイレクトする
  • https://www.yahoo.com/ では、yahoo. 部分文字列は位置12にある
  • コードは yahoo. が最初の11文字以内にあることを要求するため、このチェックは HTTPS移行 後に壊れてしまった
  • ホットスポットチェックを通過するには、DNSレコードを別サーバへ向け、そのサーバがよりYahooらしい名前へのHTTPリダイレクトを返すか、YahooドメインCookieを設定する必要がある
  • samsung-nx-emailserviceパッチ 適用後、カメラは実際に接続して写真をアップロードした

同じ回避が適用された他のカメラ

  • 今回の解析では、リバースエンジニアリングした1つの関数をもとに、Samsung WB850F Wi-Fiカメラのホットスポット検出を理解し、回避することに成功した
  • 最終パッチ自体は小さかったが、Samsungエンジニアが実装した検出方法のため、パケット追跡だけで回避方法を推測するのは難しかった
  • 何を探すべきか分かった後は、MSN.comを問い合わせるカメラにも同じ回避を適用した
  • その結果、EX2F、ST200F、WB3xF、WB1100Fが対応カメラ一覧に追加された
  • Main_Image には7万7千個を超える関数があり、デジタルカメラの動作をさらに理解するための解析対象がまだ多く残っている

1件のコメント

 
GN⁺ 2024-05-26
Hacker News のコメント
  • https://op-co.de/blog/posts/samsung_nx_cryptofail/#index3h3 のほうが気に入った
    本当に驚くべきファームウェア暗号化の失敗事例

  • すごい作業だ。リバースエンジニアリングの方法をチュートリアルにしてみるつもりはあるのか気になる

    • 実のところ、この記事がチュートリアルの役割を果たすのに十分な情報を提供できていればと思っていた
      ググりやすい部分だけ省略しただけ
  • 欲しいのは、カメラのボタンでdSLR写真を撮ったら、少ししてその画像が Apple Photos に入っている、ただそれだけ

    • 以前は写真を自動同期できるWi-Fi内蔵SDカードがあったが、その分野の主要企業だった Eye-Fi は廃業し、現代的なクラウドサービスで動作する新製品を作ったところはないようだ
      スマートフォンがコンシューマー向けカメラ市場をほぼ消し去ってしまい、需要が足りないのだろう。プロジェクトのアイデアとしては、ESP32 を SD カードの中に押し込む方法を探ること
    • Wi-Fi 搭載のCanon dSLRなら FTP が使えそう
      携帯電話、タブレット、Webサイトにも接続できるが、アプリやサービスが必要。カメラから直接 FTP で送るドキュメント: https://gdlp01.c-wss.com/gds/5/0300024975/01/eos5d-mk4-wff-i... 113ページ。リンクは EOS 5D Mark IV (WG) Wi-Fi (Wireless Communication) Function Instruction Manual
    • Linux が載ったSamsung NX1 と NX500なら、Wi-Fi ネットワークさえあれば JPEG や RAW を任意のオンラインサービスへアップロードするよう、かなり簡単にスクリプト化できる
      残念ながら10年前の機種で、中古市場でも珍しい
    • Snapbridge 搭載の Nikon Z シリーズが、その方面ではほぼ最善
      Wi-Fi や Bluetooth でペアリングでき、望めば iPad からカメラをリモート操作して画面も見られる
    • すでに Google Photos 向けには可能なので、これも可能なはず: https://www.stg-uploader.xyz/