Part 1 — CAN Bus Reverse Engineering With SocketCAN
Introduction
The objective of this series of articles is to introduce some practical examples and approaches for reverse engineering a vehicle CAN bus network, using low cost tools and open source software.
I have previously presented at ASRG (Automotive Security Research Group) on the topic of CAN bus reverse engineering and how low cost tools can be used to support reverse engineering activities. This included using a RaspberryPi to participate on, or pretend to be a module on a real vehicle CAN bus, by implementing software which replicates the behaviour of other vehicle modules based on the knowlredge learned during the reverse engineering activities. An example of this can be seen below, where the RaspberryPi interacts with an LCD screen module using CAN.
The first part of this series, will be introducing how to get setup with can-utils, creating and using a virtual CAN interface/network in a Linux enviornment. Carrying out activities in this article require a minimum of a Linux-based PC (or linux virtual machine), or ideally a RaspberryPi.
SocketCAN
Support for CAN is built into the Linux kernel with the development efforts of ‘SocketCAN’, which will be used to support these activities.
SocketCAN abstracts the CAN communication protocols and provides developers with a Berkleley Socket API for reading and writing to a CAN network. Perhaps you have previously implemented a simple UDP server/client before to send and receive data using sockets. If so, a lot of this (especially in Part 2 onwards) should be familiar.
Getting started
First step, install can-utils. can-utils is a package which contains user-space utilities and tools for the Linux SocketCAN subsystem. The can-utils git repsitory provides some useful references, such as the embedded linux wiki guide for CAN.
Install can-utils
$ sudo apt-get install can-utils
Assuming can-utils has been installed without any issues, it is possible to create an environment to generate, send and receive CAN frames without the need for other physical CAN devices or hardware.
SocketCAN — Virtual Interface
Similar to a network loopback device, support for a virtualised CAN device is supported. The virtual CAN interfaces allow for the reception and transmission of CAN frames without hardware.
Setup VirtualCAN
The following commnad will create an interface called vcan0.
$ sudo ip link add dev vcan0 type vcan
This will load the vcan kernel module, you can check if the vcan kernel module has been loaded by running the command lsmod.
The vcan module can be seen in the image below denoted as vcan. Linux Kernel modules are very interesting, and if you would like to learn more about them check out this link.
$ lsmod
Optionally, you can run the command dmesg, which prints the message output from the kernel (very useful for debugging if you start to develop your own kernel modules).
When we created our vcan interface vcan0, the vcan kernel module was loaded. In the dmesg output below, it can be seen that the Virtual CAN interface driver has been loaded.
$ dmesg | tail
Should you have any issues creating the interface, or vcan is not shown when running the lsmod command , you can manually load the vcan kernel module by running the following:
$ sudo modprobe vcan
If for some reason you want to remove the vcan kernel module, you can do so by running the following:
Please note, if you remove the vcan kernel module you will have to setup the vcan0 interface again.
sudo rmmod vcan
The interface vcan0 should now (hopefully) be visible as a network interface, you can confirm this by running:
$ ifconfig vcan0
Note the flags value <NOARP>, vcan0 is currently loaded, but not enabled (i.e. the interface has not been brought ‘up’). The next step is to bring hte interface up, by running:
$ sudo ip link set up vcan0
The interface vcan0 should now be a visible network interface, this can be verified by running:
$ ifconfig vcan0
Note that vcan0 now has the flags for ‘UP’ and ‘Running’ set.
Now we have can-utils set up, as well a virtual interface to use, let’s test it.
Using cansend and candump
We will use two tools here to send and display some CAN frames:
- cansend: A simple tool for creating and sending a CAN frame on a specificed interface. (source code)
- candump: A simple tool for displaying CAN frames on a specified interface in a variety of different formats. (source code)
I would suggest loading two terminals so you can see them side-by-side.
(Terminal 1) $ candump vcan0(Terminal 2) $ cansend vcan0 100#0123456789ABCDEF
Congratulations, you have just sent (and received) a virtual CAN frame. Here we are letting existing applications (cansend & candump) do the work for us, but maybe you want to do your own thing…