Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Analyze AutoMotive ECU

shutingrz
December 14, 2019

Analyze AutoMotive ECU

IoTSecJP Version.6.0 #IoTSecJP で発表したカーハッキングの資料 (公開用)

Please contact me at Twitter mention or DM (@shutingrz) for any questions or comments.

shutingrz

December 14, 2019
Tweet

More Decks by shutingrz

Other Decks in Technology

Transcript

  1. • 必要なもの • 12V電源(ACアダプタでOK) • ジャンパワイヤ • ブレッドボード • CAN-USBアダプタ

    • CANableがおすすめ • テスター • これだけなら7000円程度 • メータ合わせて1万かからない! 参考:解析環境について
  2. • トヨタアクア(2013年製) 搭載のコンビネーションメーター • クルマのあらゆる情報を集約し、スピードや警告を表示する • 現代の車載コンピュータ(=ECU)はCANバスを通して情報を やりとりしている • ECU

    : Electric Control Unit もともとはエンジン制御用のため開発された経緯から Engine Control Unit の略だったのこと • さらに近年ではCAN FD/車載 Ethernet が普及の兆し? 基本情報
  3. CAN (Control Area Network) • バス型ネットワークでノイズに強い通信方式 •L1 および L2 のレイヤーの仕様

    • 各ECUで2本の線をつなぎ合わせコリジョンを避けつつ通信 • CAN ID が小さい方が優先される / IDが大きい方は少し待って再送信 ノード ノード ノード ノード 送信 受信 受信 受信 バス ID: 123 Data: 00FF00...
  4. • Linuxでは canX という形式のインターフェイス名で認識 • IDは 11bit CANの場合 0x000 ~

    0x7FF • データは最大 8 バイト • CAN FDという非互換のプロトコルでは 最大 32、64バイトなど CANデータの例
  5. 挙動に対応するデータ構造の特定 000~7FF →反応 000~4FF →反応 000~2FF →無反応 300~4FF →反応 3B7

    →反応 500~7FF →無反応 • どのIDで目的の挙動を示すかを二分探索 • ID特定時のデータは8バイトで全て「FF」 • 目的の ID が判明したら次はどのデータ部に反応するかをひたすら試行 FF FF FF FF FF FF FF FF →反応 00 00 00 00 FF FF FF FF →反応 … 04 … →無反応 … 08 … →反応 (5Byte目 の 4bit目) FF FF FF FF 00 00 00 00 →無反応 (略) ビットレベルで定義 されることも多い ID Data (略)
  6. • candump (スニファ) / cangen (トラフィックジェネレータ) • ファジングデータの生成に使用 • cangen

    で ID: 000 ~ 7FF , Data:「全てFF」のデータを生成 • candumpでそれをテキストデータに落とし込む • canplayer & grep , head , tail • ファジングに使用 • テキストデータをもとにトラフィックを生成 • データ絞り込みのために一般的なLinuxコマンドが使える 特定のために使用するソフトウェア
  7. • ゲートウェイの設置 • 機能に合わせてネットワーク を分離化 • ホワイトリストフィルタ • ただし診断通信は運用上 通さざるを得ない

    • MAC(メッセージ認証) • AUTOSARで文書化 • リアルタイム性との兼ね合い CANセキュリティの今 CGW パワートレイン系 ボディ系 マルチメディア系 OTA系
  8. • トヨタアクア(2013年製) 搭載のECM (Engine Control Module) • かつては ECU (Engine

    Control Unit) という名称 • 様々なセンサー情報をもとにスロッ トル等を調整 • クルマを動かすのに一番大事な所 基本情報 ※ヤフオクで500円
  9. • 一般車ではECUにてエンジンリミッ ターがかけられている • モータースポーツ界隈ではそのリ ミッターを外しパフォーマンスを得 る試みがある • ROMチューン •

    リプログラミング • ファームウェア・テーブル書き換え • クルマ業界では「リプロ」という ECUのリバースエンジニアリング
  10. • Uconnectという車載ナビに脆弱性 • 携帯電話網を使ってナビやWifi AP機能 などを提供する • リモートでファームウェアをリプロし、 任意のCANメッセージを出せるように •

    運転アシスト用ECUのCANメッセージを 偽造しアクセルやハンドル操作 参考: リモートから攻撃されたジープ http://illmatics.com/Remote%20Car%20Hacking.pdf https://www.wired.com/2015/07/hackers-remotely-kill-jeep-highway/
  11. • クルマはIoT機器の一種 • 一般的なハードウェアハックのアプローチが有効 1. ROMに直接アクセス 2. デバッグ機能でアクセス 3. 車両診断機能でアクセス

    番外: 脆弱性を悪用(Jeepのような) • リッチなECUならまだしも単機能ECUではほぼ見つからない リプロの手法
  12. • 昔はよく使われていた手法 • 微細化が激しいがMSOPサイズな ら素人でもできる • 近年ではフラッシュ内蔵のSoCが 普及しており本手法は困難に • 外付けでEEPROMにファームウェ

    アが存在するのは稀 1. ROMに直接アクセス ・メーターの走行距離が保存されるROM ホットエアーで外しSOP8変換基板に再実装
  13. • NECのMCUをカスタマイズした 「76F00XX」シリーズが搭載され ている • “プログラミングポート”が存在 • これらを利用した ECU Tuning

    製 品が出ている • NECのマイコンにある機能: NBD (Non-Break Debug)を利用する 参考: 2013年頃のレクサスのエンジンECU
  14. • LEXUSと同じDenso MCU • 76F0085が搭載 • プログラミングポートは未搭載 • パターンが外に出ていない •

    俗称"Toyota Denso Gen1 ECU"シ リーズ以降は全てこの仕様らしい • レクサスのECUを入手してピンア サインを比較・特定すれば行ける かも?(今回は断念) アクアのエンジンECUの場合
  15. • "MCU NEC 76F0085を搭載した Toyota Denso Gen1 ECUの最新バー ジョンは小さな金属ケースに入っ ており、NBD

    / JTAGポートはあ りません。(略) したがって、このECUタイプは一 般的な方法では読み取ることがで きません。" • "ファームウェアはBGAを外すか、 トヨタから入手する必要がありま す" (要約) 参考: リプロツール業者の記事 http://bitbox.ru/en/news/68
  16. • リプロ最後の砦 • ECUはOBDポートを用いて診断を行う • 近年はCANバス上で診断(DoCAN) • ファームウェア更新のときにも診断機 能を用いる •

    メーカー・車種・生産年代によって仕 組みが異なり、最近ではセキュリティ も強固 3. 車両診断機能でアクセス ©Saitobesho
  17. • ピンアサインの特定 • ピンは合計195pinある • 整備書を使って特定 • メータと同じく気合でもいける • LED等はないので正常に起動し

    たか調べるにはCAN通信を見る 必要がある • しかし起動しても能動的に CAN通信は流れてこない 1. 起動
  18. • OBD2 • 故障診断のために作られ、古くから用いられている • 仕様策定の段階でコネクタ形状まで統一され以後使い続けられる • KWP2000 • より高度な診断、更新のために作成された

    • メーカーにより実装がバラバラ • UDS • KWP2000の実装依存の部分をちゃんと仕様化 • それでもメーカーが従うかは別・・・ • 現在はUDSが標準になってきている 参考: 車両診断機能の一覧
  19. • OBD2 • 故障診断のために作られ、古くから用いられている • 仕様策定の段階でコネクタ形状まで統一され以後使い続けられる • KWP2000 • より高度な診断、更新のために作成された

    • メーカーにより実装がバラバラ • UDS • KWP2000の実装依存の部分をちゃんと仕様化 • それでもメーカーが従うかは別・・・ • 現在はUDSが標準になってきている 参考: 車両診断機能の一覧
  20. • OBD2は仕様としてエンジンに関する様々な項目を取得できる • エンジン回転数や燃料・温度... • 世界的に搭載を義務付けられているため、ECMが動いているかの 確認にも使える • リクエストペイロードは2バイト •

    1バイト目: サービスID • 2バイト目: パラメータ • サービスIDが「何をするか」、パラメータは「何に対して」 • KWP2000・UDSではパラメータはSubFunctionという OBD2を用いた生存確認
  21. • リクエスト •CAN IDは 7DF (CAN上の診断でのブロードキャストのようなもの) •ペイロードは "01 00"「対応している項目を教えて」 •

    レスポンス ※返ってきているのでECUはちゃんと動いている! •CAN IDは7E8 (本来のリクエストCAN IDに+8したものがレスポンス) → つまりECMのOBD2のCAN IDは 7E0 ※先頭バイトに余計なものがついているのは ISO-TPのカプセル化による フレームを跨いだデータ通信を可能にする(詳細割愛) OBD2を用いた生存確認 can0 TX - - 7DF [8] 02 01 00 00 00 00 00 00 '........' can0 RX - - 7E8 [8] 06 41 00 BE 3F A8 13 00 '.A..?...'
  22. • Caring Caribouの uds discovery • CANID: 7DF, 7E0 に反応

    •7DFはCAN上診断のブロードキャスト を示す リクエスト用CANIDは7E0だろう • このECUはUDS亜種 •機能はUDS、SIDだけKWP2000 KWP2000・UDSの機能の確認 $ ./cc.py uds discovery ------------------- CARING CARIBOU v0.3 ------------------- Loaded module 'uds' (snip) Identified diagnostics: +------------+------------+ | CLIENT ID | SERVER ID | +------------+------------+ | 0x000007df | 0x000007e8 | | 0x000007e0 | 0x000007e8 | +------------+------------+
  23. • メモリ読み書き系 •ReadMemoryByAddress : •指定したメモリアドレスの読み込み •RequestUpload : •指定したメモリアドレス範囲の転送(ECU→Client) •WriteMemoryByAddress :

    •指定したメモリアドレスの書き込み •RequestDownload : •指定したメモリアドレス範囲の転送(Client→ECU) UDSで定義されている、リプロに有用なサービス
  24. • 要求が受け入れられる場合はサービスIDに+40したレスポンスIDが返る • Positive Resonse • 受け入れられない場合はレスポンスIDが「7F」でそのあとにエラーコード • Negative Response

    (ちなみにCode22はconditionsNotCorrect ) 参考: UDSのデータ形式 Client ECU 10 01 50 01 10 02 7F 10 22 通常セッションに切り替え要求 Positive Response リプロセッションに切り替え要求 Negative Response (ErrCode 22)
  25. • SID 0x00 ~ 0xFF 、 SubID: 00 でひたすらリクエストを送って 応答を確認

    •サービスが存在しない場合はCode11が返るためそれ以外を探す • Caring Caribou の uds services が使えるが、取りこぼしが多い •改良版をPull Request中 3. 対応サービスのスキャン
  26. • 診断用のサービスIDがあるがメモリ読み書き系は全く無い •別の診断セッションに切り替えられれば出てくるかもしれない • メーカ独自定義のサービスが割と多い(やめてほしい。。) • SIDの割り振り方はKWP2000 •しかし中身(SubFuncのIDなど)はUDSというちぐはぐな仕様 3. 対応サービスのスキャン(結果)

    SID Name Desc 10 DiagnosticSessionControl 診断セッション切り替え 21 ReadDataByIdentifier 各種情報の読み取り 27 SecurityAccess セキュリティ認証機構 30 InputOutputControlByIdentifier 各種入出力機能の制御 3B WriteDataByIdentifier 各種情報の書き込み A1 ~ A4 , A7, A8 *[Defined By Vehicle Manufacturer] メーカ独自定義 ↑スキャンの結果 ECUが反応したSID (一部抜粋)
  27. • セッションは複数種類ある •通常セッション、リプロセッション、 拡張セッション... • デフォルトは通常セッション • 通常セッションはできることは殆どない • メモリ読み書きしたいなら他セッション

    • 他セッションは原則SecurityAccessを 突破したうえで切り替える • 突破せずとも切り替えられるパターンも • メモリ読み書き系は実装により突破しな いと拒否されることもある 診断セッションについて ISO 14229より引用
  28. • SID: 10でSubIDを00~FFで試す →5つのセッションが見つかった • リプロセッションが存在 • ただSecurityAccessを突破しない と入れない模様 •

    他セッションはSecurityAccess突 破なしでも切り替えられた • 全てメーカ独自のセッションID • 独自なので何ができるか全く不 明 • メモリ読み書き系は見つからない 診断セッションの切り替え ID セッションの種類 Resp Code 意味 01 Default 50 Positive Response 02 Programming 22 conditionsNotCorrect 40 vehicleManufactur erSpecific 50 PositiveResponse 5f vehicleManufactur erSpecific 50 40 PositiveResponse 61 systemSupplierSpe cific 50 PositiveResponse
  29. • 最後の望みはリプロセッション • ファームを書き換えるので機能も きっとあるはず! • リプロセッションに切り替えるた めにSecurity Accessの突破が必須 診断セッションの切り替え

    ID セッションの種類 Resp Code 意味 01 Default 50 Positive Response 02 Programming 22 conditionsNotCorrect 40 vehicleManufactur erSpecific 50 PositiveResponse 5f vehicleManufactur erSpecific 50 40 PositiveResponse 61 systemSupplierSpe cific 50 PositiveResponse
  30. • チャレンジ&レスポンスの認証方式。SeedをもらってKeyを送る • 実装方法は自由なのでメーカ・車両・年代で変わる • 故障診断以外の機能は認証を突破しないと使えない Security Access Client ECU

    27 01 67 01 72 70 8D 9D 27 02 12 34 56 78 7F 27 35 Level 01 の Seed をください Seed: 72 70 8D 9D Seedに対応のKeyは12 34 56 78? ちがうわ!! ( Invalid Key)
  31. • Keyが何バイトかは実装依存 • UDSではエラーコードに "Incorrect message length or invalid format

    (0x13)"がある • これを利用してサイズを特定 • 0x13ではなく0x35(Invalid Key) になるバイト数を探す →4バイトであることが判明 STEP1: KEYサイズの特定 can0 7E0 [3] 27 02 00 can0 7E8 [3] 7F 27 13 can0 7E0 [4] 27 02 00 00 can0 7E8 [3] 7F 27 13 can0 7E0 [5] 27 02 00 00 00 can0 7E8 [3] 7F 27 13 can0 7E0 [6] 27 02 00 00 00 00 can0 7E8 [3] 7F 27 35 can0 7E0 [7] 27 02 00 00 00 00 00 can0 7E8 [3] 7F 27 13
  32. • 認証回数は9回まで • 10回目は回数超過としてコード 0x36 (Exceeded number of attempts) •

    認証回数が超過するまでは何度でも同じ Seedが返される • 再起動するとSeedがかわる • Seedの生成に偏りがある • 1バイト目はほぼ4通りしかない • 起動ごとにだいたい決まる • 4バイト目は時間ベースで増加 • 約1500回周期でSeedが被ることがある →リプレイアタックが有効 (今回は意味無し) STEP2: 認証仕様の特定 Seed: 41 a2 43 81 Seed: 01 7d 9f 82 Seed: 01 65 82 87 Seed: c1 89 60 89 Seed: 82 72 98 8a Seed: 41 af 40 8f Seed: 41 b6 46 90 Seed: 01 7c 89 95 Seed: c1 bb 4c 97 Seed: 82 72 8a 98 Seed: 41 a1 5c 9d
  33. • Seed関係なく特定のバイト • いわゆる「パスワード」=総当りで解ける • 初期のECUではよくあった • ビットシフト • 単純なXOR

    • この年代のECUでよくある模様? • 上記+バイトの足し引き • 長い鍵+AESによる暗号化 • これは鍵を手に入れないと突破は不可能 様々なECUでのKEYの生成パターン
  34. • この年代は単純な4Byte XORが流行ってる情報がある • 総当りして試してみよう → 0 ~ FFFFFFFF まで試行して最大213日かかる計算に

    (1auth / 0.004sec) • そもそも4byteXOR以外なら213日を無駄にすることに • すぐに諦めて別の方法を模索 試行1: 単純な総当り (失敗) Source code: https://github.com/shutingrz/aqua-engine-ecu-hack/blob/master/brute_key_xor.py
  35. • 以下の想定 1. 4byteXORとみなし、1バイトずつ のXOR比較をしていると仮定 2. 1バイト目が正解なら2バイト目の 比較に移行し、不正解ならreturn されるため命令数の差異が発生 →正しい組み合わせのときだけ平均レ

    スポンス時間が長くなるのでは? 試行2: タイミング攻撃⏱ 一致? エラー InputByte++ KeyByte++ 最終? 認証成功 初期化: InputByte KeyByte Yes Yes No No ↑1バイト目が正しかった場合、 1ループ分余計に時間がかかる?
  36. • 1つの組み合わせにつき50回試行 →全通りで有意な差はでなかった • 複数回試行で順位が何回も変わる • もし時間がかわるとしてもリモート 測定では様々な要因で正確な計測は できないかも 試行2:

    タイミング攻撃⏱ (失敗) Source code: https://github.com/shutingrz/aqua-engine-ecu-hack/blob/master/check_key_timing.py $ python3 ./check_key_timing.py endByte test: 12740 / 12750 (XORCand: 0x000000fe, ETA(s): 0:00:00) finish. sort: key: 0x25, time: 0.004235796928405761 key: 0x26, time: 0.004141133308410644 key: 0x76, time: 0.004133680820465088 (snip) topByte test: 12740 / 12750 (XORCand: 0xfe000000, ETA(s): 0:00:00) finish. sort: key: 0xea, time: 0.004177097320556641 key: 0x7c, time: 0.004164288997650147 key: 0xe7, time: 0.004154132843017578 (snip)
  37. • IOActiveが出した2車種のレポート • Ford Escape / TOYOTA Prius • 様々な手法で実車をハックしている

    • 診断機を解析することで SecurityAccessを突破 • 暗号化仕様も詳細に記載 • 著者はCODEBLUE2014で同レポー トに関連する発表をしている PRIUS HACKレポート https://ioactive.com/pdfs/IOActive_Adventures_in_Automotive_Networks_and_Control_Units.pdf https://www.slideshare.net/codeblue_jp/chris-valasek-japub
  38. アクアの認証仕様と比較してみる Aqua ECM Prius ECM 年代 2013年 2010年 ECMの診断用CANID 0x7E0

    0x7E0 SendKeyのLevel 0x02 0x02 Seedの長さ 4バイト 4バイト Keyの長さ 4バイト 4バイト 認証試行回数限度 9回 9回 Seedのライフタイム 試行超過するまで同じ値 試行超過するまで同じ値 • 同じ認証仕様と推察される • 他にもレポート記載のSeed例についても類似点がみられた
  39. アクアで試してみた can0 7E0 [2] 27 01 can0 7E8 [6] 67

    01 72 70 D3 C3 can0 7E0 [6] 27 02 72 10 B3 C3 can0 7E8 [2] 67 02 ~ can0 7E0 [2] 27 01 can0 7E8 [6] 67 01 00 00 00 00 Request Seed Response Seed (7270D3C3) Send Key (7210B3C3) Auth Success (Positive Response) Request Seed (認証済みか確認) Authenticated ( 00000000 ) • 成功した ※認証後にSeedを要求された場合は 00000000 を返す仕様なので、それで認証成功を確認できる
  40. • 認証突破前はエラー • コード22 「条件不足」 • 突破後に試したところ成功 • リプロセッションに入れた! •

    それでもメモリ読み書き系 のサービスは存在せず。。 • UDSの仕様は無視されてる リプロセッションへの切り替え can0 7E0 [2] 10 02 can0 7E8 [3] 7F 10 22 can0 7E0 [2] 27 01 can0 7E8 [6] 67 01 F1 76 2A 3C can0 7E0 [6] 27 02 F1 16 4A 3C can0 7E8 [2] 67 02 can0 7E0 [2] 10 02 can0 7E8 [1] 50 セッション切替 (失敗) セッション切替 (成功) 認証(成功)
  41. • レポートによるとリプロは以下の手順 1. リプロセッション切替 2. リプロ用CANIDの切替送信 3. ファームバージョンごとに設定された TargetData(パスワード)を送信 4.

    正しい場合、ECUから0x3Cが返る 5. ライタプログラムを送信 6. ファームウェアを送信 ※完全に独自実装 参考: 診断ソフトがリプロを行う際の手順 ファームウェアを含むキャリブレーションデータ (.cuwファイル)
  42. • レポートではリプロ時に下記の機能があるとの記載が • GetMemoryInfo(メモリレイアウトの要求) • CheckBlock (書き込み可能か確認) • EraseBlock (メモリのクリア)

    • WriteBlock / WriteBlockWithAddress(メモリの書き込み) • VerifyBlock(書き込まれたデータの読み出し) • ただしTargetDataを送信後に初めて使えるようになる 参考: リプロ手順中のコマンド
  43. • レポートではリプロ時に下記の機能があるとの記載が • GetMemoryInfo(メモリレイアウトの要求) • CheckBlock (書き込み可能か確認) • EraseBlock (メモリのクリア)

    • WriteBlock / WriteBlockWithAddress(メモリの書き込み) • VerifyBlock(書き込まれたデータの読み出し) • ただしTargetDataを送信後に初めて使えるようになる 参考: リプロ手順中のコマンド
  44. • リプロ用コマンドはTargetDataを 送信した後に使える • TargetDataはファームウェアの バージョンごとに異なり、更新 ファイルにのみそれが記載 • 法則性はなく推測は難しい •

    ファーム更新がなければ更新ファイル は存在せず、知ることは不可能 大きな壁: TargetData フォーラムで稀に投稿されることも (TOYOTA MR2の更新ファイル)
  45. • 総当りを試してみよう → 0 ~ FFFFFFFF まで試行して最大245日かかる計算に (1auth / 0.004sec)

    • パスワードなので全通りやれば必ず当たるとはいえ非現実的 • 諦めた(燃え尽きた) 試行: Target Dataの総当り (失敗) Source code: https://github.com/shutingrz/aqua-engine-ecu-hack/blob/master/brute_targetdata.py
  46. • スバル(2007~)・三菱の一部車種 は診断経由でファームウェアを 読み書き可能な模様 • SecurityAccess・リプロ手順が 解析されツール化している • 汎用的に利用できるので TargetDataなどの対策が存在し

    ないと思われる • お金持ちになったら試したい (ヤフオクで1万超えとか) まとめ 3/3 野良リプロソフト「ecuflash」のコード (Themidaでパッキングされてた)