CANHack MicroPython SDK reference manual
CANHack MicroPython SDK reference manual
AUTOMOTIVE L ABS
Security Products for the Automotive Industry
CAN-HG
CANHack MicroPython SDK
TECHNOLOGY
Reference Manual
BRIEFING
DR. KEN TINDELL
2018-07-18
TX CAN L
With carefully written software it is possible to drive the TX pin quickly enough to
emulate parts of the CAN protocol and mount protocol attacks. The CANHack toolkit is
designed to prove that this is a viable attack mechanism.
The CANHack software is provided as generic C that ‘bit bangs’ the TX pin using spin
loops. It has been ported to the RP2040 microcontroller in the Raspberry Pi Pico and been
wrapped with a Python API in custom MicroPython firmware for the Raspberry Pi Pico,
and firmware is provided for three different boards:
• The Canis Labs (canislabs.com) CANPico board1, that has a CAN transceiver
shared with a Microchip MCP2517FD CAN controller connected over SPI.
• The Canis Labs CANHack board.
• The Car Hacking Village DEF CON 30 badge from Intrepid Control Systems
(intrepidcs.com)
The generic C and the MicroPython API code are available in the Canis Labs repository:
https://github.com/kentindell/canhack
1
See https://kentindell.github.io/2021/05/24/canpico-intro/ for more about the CANPico
WARNING. Connecting the CAN hardware directly to a vehicle CAN bus comes with
risk and should not be undertaken without understanding this risk. Grounding a vehicle
chassis through the USB port of a Pico connected to a laptop, PC or USB hub powered
from the mains may cause permanent damage to the vehicle’s electronics and/or the
Raspberry Pi Pico and devices it is connected to. The CAN transceiver will tolerate a
ground potential difference (“ground offset”) of between -2V/+7V. Connecting pin 2 of
the screw terminal to the target system’s ground will establish a common
ground reference. The CAN bus must be properly terminated (with 120W resistors at
either end). If the CAN bus is already terminated at both ends then the termination on
the board should not be engaged. In addition, causing disruption to a vehicle’s CAN bus
traffic may be interpreted by the vehicle fault management systems as a hardware fault
and cause the vehicle to permanently shut down CAN communications with consequent
loss of functionality.
2
See: https://kentindell.github.io/2021/07/15/janus-attack/
3
See: https://kentindell.github.io/2020/07/11/can-atomic-multicast/
4
See: https://kentindell.github.io/2020/01/20/new-can-hacks/
5
By default, these would be /dev/ttyACM0 and /dev/ttyACM1 on a machine running Linux
6
See https://github.com/min-protocol/min
If running on a CANPico, this constructor must be called after the CAN controller TX
output is put into open drain mode (by setting the CAN controller tx_open_drain
parameter to True).
Raises
• ValueError – if bit_rate is not one of 500, 250, or 125
Methods
set_frame([can_id=0x7ff] [, remote=False] [, extended=False] [, data=None] [, set_dlc=False] [,
dlc=0] [, second=False] )
Set the specified frame buffer.
The frame buffer is an internal buffer in RAM in the toolkit that pre-defines the bit
sequence for a CAN frame (pre-calculating where the stuff bits go, etc.)
This function pre-computes the layout of a CAN frame into a frame buffer inside
the toolkit (it will set the shadow frame buffer is second is True because the Janus
Attack7 requires two separate CAN frames).
This method must be called prior to mounting an attack: the pre-computed bit
pattern in the frame buffer is used to synchronize the attack on a targeted frame.
Parameters
• can_id (int) – An 11-bit or 29-bit integer representing the CAN ID of the frame
• remote (bool) – True if the frame is a remote frame
• extended (bool) – True if can_id is a 29-bit CAN identifier
• data (bytes) – The payload of the CAN frame
• set_dlc (bool) – True if the DLC should be set to a specific value
• dlc (int) – the value of DLC if set_dlc is True
• second (bool) – True if this call is setting the shadow frame in preparation for
the Janus Attack
Raises
• ValueError – if the dlc value is > 15 or if the payload is more than 8 bytes or
remote is True and data is set
7
For more details on the Janus Attack see: https://kentindell.github.io/2020/01/20/new-can-hacks/
This transmits a ‘hello world’ CAN frame on the bus. You can see this on the bus with a
bus analyzer, logic analyzer8 or other receiver. Here’s a CANPico receiving the frame:
>>> frames = c.recv()
>>> frames[0]
CANFrame(CANID(id=S123), dlc=5, data=68656c6c6f, timestamp=130795841)
>>> fames[0].get_data()
b'hello'
Note that a real CAN controller on an empty bus will transmit a frame forever in a loop
because no receiver asserts a dominant in the ACK bit. The CANHack toolkit is not a
CAN controller and doesn’t bother following all the rules of CAN (attackers don’t have
to follow the rules..) so doesn’t check its own ACK field reads back as dominant (it does
check to see if its own bits are overwritten by an error frame or it loses arbitration – some
rules are important enough to follow).
If the frame is received then everything is connected up OK. If not then possible causes
of failure are:
• The bit rate is wrong (CANHack defaults to 500Kbit/sec but can run at
250Kbit/sec and 125Kbit/sec)
• The CAN H/L bus connections are bad: either loose or crossed
• The bus isn’t properly terminated (if the board is one end of the bus then its on-
board termination should be activated, but not if the ends of the bus are already
terminated)
8
See https://kentindell.github.io/2021/06/28/pulseview-raspberry-pi/ for how to build the Pulseview logic
analyzer on a Raspberry Pi and installing the Canis Labs can2 CAN protocol decoder