車をハックする方法—簡単なクラッシュコース

この記事の目的は、車のハッキングをすばやく、安く、簡単に始められるようにすることです。これを行うために、例としてRPMゲージをスプーフィングします。

以下は、完全なチュートリアルではありません。代わりに、起動して実行するのに十分な情報を提供することを目的としています。もっと深く掘り下げたい場合は、最後に必読の記事をチェックアウトできます。

このチュートリアルを実際に実行する場合は、Linuxコンピューター(または仮想Linuxマシン)とCAN-to-USBデバイス(後で説明します)が必要になります。

車はネットワークです

車は、エンジン、トランスミッション、窓、ロック、ライトなどを制御するための複数のコンピューターで構成されています。これらのコンピューターは電子制御ユニット(ECU)と呼ばれ、ネットワークを介して相互に通信します。

たとえば、ステアリングホイールのボタンを押してラジオの音量を上げると、ステアリングホイールECUはネットワークに音量を上げるコマンドを送信し、ラジオECUはこのコマンドを認識してそれに応じて動作します。

車には複数のネットワークがあり、通常は少なくとも2つあります。

  • エンジンやパワートレインメッセージなどの重要なデータ用に1つ
  • そして、ラジオやドアロックなどのそれほど重要ではないデータ用のもの

重要なネットワークは高速で信頼性の高いプロトコルを使用しますが、重要でないネットワークは低速で信頼性は低くなりますが安価なプロトコルを使用します。ネットワークの数とどのECUがネットワーク化されているかは、車のメーカー、モデル、および年式によって異なります。ECUは複数のネットワークに接続することもできます。

ネットワークへの接続

一部のネットワークには、OBD-IIポートを介してアクセスできます。OBD-IIは、1996年以降に米国で、2004年以降にヨーロッパで製造されたすべての自動車と小型トラックに義務付けられています。

コネクタは運転席の腕の届く範囲にあります。プラスチック製のカバーを持ち上げる必要があるかもしれませんが、工具がなくてもいつでもアクセスできます。

OBD-II規格では、5つのシグナリングプロトコルが許可されています。どちらを使用するかはメーカー次第です。CANは最も人気のあるものであり、これから説明します。OBD-IIコネクタのピン6と14を介してアクセスできます。車にCANバスがある場合は、上の画像のようにピンに金属製のリード線があります。

CANバスは、重要なデータを送信するために使用される信頼性の高い高速バスです。残念ながら、バス上のデータパケットは標準化されていないため、それらの意味を知るためにそれらを逆にする必要があります。OBD-II規格には、ベンダー固有のプロトコルに使用できるベンダー固有のピンの余地もあります。これにより、ディーラーは問題を簡単に診断できます。

私の車(GM)には、ピン6と14に標準CANバスがあり、ピン1にベンダー固有の単線CANバスがあります。標準CANバスは、信頼性の高い高速(500 kbps)プロトコルであり、高速CAN(HS-CAN)。重要なデータに使用されます。単線CANバス(SW-CAN)またはGMLANは、低速(33.3 kbps)で信頼性は低くなりますが、1本の線しか使用しないため安価です。このバスは、重要ではないデータに使用されます。

ベンダー固有のピンが表示され、使用されているプロトコルがわからない場合は、Googleの「OBDピン配置」。低速CAN(LS-CAN)と中速CAN(MS-CAN)もあります。MS-CANは通常ピン3と11にあり、フォードとボルボの車では125kbpsで動作します。

ツール

CANデータを解釈できるデバイスと、データを分析するためのソフトウェアの両方が必要になります

ハードウェア

CANパケットを送受信するには、これが可能なデバイスが必要です。ELM327ベースのデバイスに出くわすことがよくあります。これらには用途がありますが、ハッキングにはひどいものです。それらはCANバスを監視するには遅すぎます。

Kvaser、Peak、EMSWünscheなどのハイエンドデバイスもあります。これらは仕事を成し遂げますが、やり過ぎでかなり高価です。

一部のハイエンドデバイスでは、ソフトウェアを一緒に購入する必要があります。USB2CANは、Linux用のネイティブCANインターフェースであり、コストパフォーマンスに優れています。

CantactまたはCANUSBを使用することもできます。ただし、これらはLinuxのネイティブCANデバイスではなく、ASCIIベースのプロトコルを使用します。これは、セットアップが少し複雑になり、パフォーマンスが低下することを意味します。一方、これらは複数のオペレーティングシステムで十分にサポートされています。

私は自分のニーズに合わせて設計したCANalyzeを使用しています。手頃な価格のネイティブCANインターフェイスであるという点でUSB2CANに似ていますが、新しいマイクロコントローラーを使用し、オープンソースであり、オープンソースツールを使用して構築できます。このチュートリアルの残りの部分では、ネイティブCANインターフェースを使用していることを前提としています。

ソフトウェア

デバイスと通信するには、Linuxマシンにcan-utilsパッケージをインストールする必要があります。Linuxプロンプトに次のように入力することで、これを行うことができます。

sudo apt-get install can-utils

Can-utilsを使用すると、CANパケットの送信、受信、分析が非常に簡単になります。これらは、使用するコマンドです。

  • cansnifferは、変化しているパケットのみを表示します
  • candumpは受信したすべてのパケットをダンプします
  • cansendはパケットを送信します

Linuxには、SocketCANを介してカーネルに組み込まれたCANサポートがあります。これにより、独自の追加プログラムを簡単に作成できます。他のネットワークと対話するのと同じ方法で、つまりソケットを介してCANバスと対話できます。

CANバス

リバースを開始する前に、CANバスがどのように機能するかをある程度理解しておく必要があります。 2本のワイヤーで構成され、差動信号を使用します。バスなので、この2本の線に複数の機器を接続できます。 CANフレームがバス上で送信されると、すべてのECUで受信されますが、ECUで役立つ場合にのみ処理されます。複数のCANフレームが同時に送信される場合、優先度が最も高いフレームが優先されます。 CANフレームには、私たちに関連する3つの部分があります。

  • アービトレーション識別子メッセージの識別子。ECUはそれを使用して、受信したフレームを処理するか無視するかを決定します。また、メッセージの優先度も表します。数値が小さいほど優先度が高くなります。したがって、たとえば、ネットワークを設計するエンジニアである場合、エアバッグの展開のフレームに非常に高い優先度または低いアービトレーションIDを与えることになります。一方、ドアロック用のデータには、優先度を低くしたり、アービトレーションIDを高くしたりします。
  • データ長コード(DLC)データフィールドの長さをバイト単位で示します。CANフレームには、最大8バイトのデータを含めることができます。
  • データフィールド最大8バイトのデータが含まれます。

CANバスを逆にする

CANバスを逆にする一般的なアプローチは、模倣したい動作を生成し、その動作を引き起こすメッセージを見つけることです。たとえば、あなたの車の車線維持支援システム(LKAS)ががらくたで、自分で作ったとしましょう。

ステアリングを制御するには、送信するメッセージを知る必要があります。これを理解する方法は、元のLKASをオンにし、CANバスを監視し、ステアリングホイールの回転に関与するパケットを特定することです。これらのパケットを特定したら、独自のLKASでこれらのパケットをCANバスに送信して、ステアリングホイールを制御できます。

私たちの場合、タコメーターをスプーフィングしたいので、車をニュートラルにした状態でガスを踏んでRPMを変更し、RPMの変更に関与するパケットを見つけようとする必要があります。

セットアップ

CANデバイスを車のOBD-IIポートとコンピューターのUSBポートに接続します。Linuxプロンプトで以下を実行して、CANインターフェースを起動します。

sudo ip link set can0 up type can bitrate 500000

これは、標準である500 kbpsのビットレートでcan0インターフェイスを起動します(常にcan01つのデバイスしか接続されていない場合)。

識別する

車がオフのとき、ECUは通常スリープしているので、車の電源を入れるか、アクセサリモードにする必要があります。Linuxプロンプトでこれを実行すると、生のCANデータを確認できます。

candump can0

これにより、CANデータが受信されるとすぐに画面に出力されます。ただし、これは非常に組織化されておらず、特定のイベントに対応するパケットを確認することは非常に困難です。Ctrl + Cキーを押すと、プログラムを停止できます。データを読みやすくするために、アービトレーションIDでパケットをグループ化し、変化しているパケットのみを表示するcansnifferを使用します。それを開始するには、Linuxプロンプトでコマンドを実行します。

cansniffer -c can0

ここで-c、変化するバイトを色付けし、can0スニッフィングするためのインターフェイスです。一定のパケットを削除するには数秒かかります。

数字はおそらく完全に異なりますが、下の画像のようなものが表示されるはずです。

最初の列(デルタ)は、そのアービトレーションIDを持つパケットが受信される速度を秒単位で示します。2番目の列(ID)には、アービトレーションIDが含まれています。残りの英数字列(データ…)にはデータバイトが含まれています。データがASCII表現である場合は、右側に表示されます。それ以外の場合は、ドットです。

RPMを上げるためにエンジンをかけたままスロットルを踏むと、画面に新しいCANメッセージが表示されたり、既存のメッセージが変更されたりする場合があります。

バイトの変化がRPMの変化に相関するCANメッセージを見つける必要があります。RPMが増加/減少するにつれて、値が増加/減少することがおそらく予想できます。

RPMによって変化するように見えるcansnifferの最初のCANフレームは、アービトレーションIDのフレームC9です。RPMによって異なる潜在的なパケットが複数ある可能性がありますが、これは最初のパケットにすぎません。

このメッセージには4バイトが変化しています(赤色)が、これらのすべてが必ずしもRPMを示しているわけではありません。3番目のバイトの変動は、07RPMの変動とは相関していないようです。最後のバイト1Bはそうです。

ただし、スロットルから足を離すとすぐにになります00。これは、RPMではなくスロットル位置を表していることを示しています。

最後に21 C0、RPMの変更に対応しているように見える2バイトがあります。さらに、16バイト整数として変化します。つまり、2番目のバイトC0がオーバーフローすると、最初のバイト21が1つ増えます。また21、およそ2000RPMに相当するようです。これは、メッセージをいつ再生するかをメモしておくとよいでしょう。

リプレイ

候補ができたら、Linuxプロンプトで次のコマンドを使用してCANバスに送信します。

cansend can0 0C9#8021C0071B101000

ここで、フレームの形式は#{data}であり、独自のCANメッセージに置き換える必要があります。

あなたの車はこれのために走っている、またはアクセサリーモードであることができます。エンジンがアイドル状態でないときに取得したパケットを使用してください。そうしないと、エンジンがアイドル状態のときにパケットを再生しても何も変化しません。

パケットを1回送信するだけでは、インストルメントクラスターに何の変化も見られない可能性があります。これは、元のメッセージがECUによって0.2秒間隔でバス上で継続的に送信されているため、メッセージが無視されるためです。

レートはcansnifferの最初の列に示されていることを思い出してください。これらのメッセージを生成しているECUを切断する以外に、これを回避する2つの方法があります。1つのオプションは、現在送信されているものよりもはるかに高い頻度でパケットを送信することです。Linuxプロンプトで以下を実行することにより、これを行うことができます。

while true; do cansend can0 0C9#8021C0071B101000; sleep 0.002; done

CANメッセージを特定したメッセージに置き換えます。ctrl + cを押して停止します。

もう1つのオプションは、バスを監視することです。スプーフィングするパケットを検出するたびに、直後に独自のパケットを送信します。これは、Linuxプロンプトで実行することで実行できます。

candump can0 | grep " 0C9 " | while read line; do cansend can0 0C9#8021C0071B101000; done

ここで、CANメッセージと0C9識別したCANメッセージおよびそのアービトレーションIDをそれぞれ置き換える必要があります。両方のアプローチを試して、どちらがより効果的かを確認できます。

タコメーターが変わったら、お疲れ様でした!そうでない場合は、RPMに関連する次のメッセージを特定して再生します。

ファジング

インストルメントクラスターにRPMを設定するCANフレームができたので、送信したデータを試して何が起こるかを確認できます。RPMに対応する2バイトは16ビット整数として動作するため、タコメータを8k RPMに設定するために、Linuxプロンプトで次の手順を実行します。

while true; do cansend can0 0C9#0080000000101000; sleep 0.002; done

結果は…

それでおしまい!これで、同じアプローチを使用して、スピードメーター、ラジオ、ライト、ドアロックなどを制御してみることができます。

考えられる問題

  • CANバスは最も人気のあるネットワークですが、それだけではありません。CANバスで探しているメッセージが見つからない場合は、別のネットワークを試してください。特に、ラジオ、ライト、ドアロックなどの重要ではないメッセージは、おそらく別のネットワーク上にあります。
  • 前述のように、CANを介して送信される正確なデータは、車のメーカー、モデル、および年式によって異なります。一部の車は、CANメッセージでカウンターを使用して、同じメッセージが複数回処理されないようにします。これは少し難しいですが、提供された情報でそれを行うことができるはずです。一部の車は、データの整合性を確保するためにチェックサムも使用します。このチェックサムの計算は難しい場合があります。トヨタをお持ちの場合は、自動車ネットワークとコントロールユニットの冒険、p10、チェックサム-トヨタをチェックしてください。誰もが本当に論文全体を読むべきです。
  • 識別されたパケットをバスで再生すると、CAN toUSBデバイスが「バスオフ」状態になる場合があります。これはCAN標準の一部であり、デバイスで発生したエラーが多すぎる場合に発生します。これは通常、バスに大量のトラフィックがある場合に発生します。これを回避するには、遅延とタイミングで遊ぶことができます。車をアクセサリモードにした直後にメッセージを再生してみたり、少し待ったり、車をつけたまま試してみたりしてください。ECUが何であるかを特定した場合バスに接続されている場合は、ヒューズを引いてメッセージの送信を停止し、バスのトラフィックを減らすこともできます。

必読

  • カーハッカーズハンドブック
  • チャーリーミラーとクリスバラセクの研究、はいすべて
  • カリフォルニア大学サンディエゴ校とワシントン大学の研究。

オープンガレージとそのビデオもチェックしてください。