Berkner Tech

CAN Bus Security With can-utils

CAN bus security testing pipeline with can-utils, from tapping the bus to injecting frames

The CAN bus is the nervous system of cars, industrial machines, and a growing pile of connected equipment. It is also from an era when the only threat model was electrical noise, so it has no authentication and no encryption at all. With two wires and the open-source can-utils, you can read every message on the bus and send your own. Here is how that works and how systems defend against it.

Why CAN Trusts Everyone

CAN is a broadcast bus. Every node hears every message, messages carry an arbitration ID but no sender identity, and nothing is signed or encrypted. The design assumed every node on the wire was trustworthy because they were all bolted inside the same machine. Add one untrusted node, through a telematics unit, an OBD-II dongle, or a compromised ECU, and that assumption collapses.

Step 1: Bring Up the Interface

With a USB-to-CAN adapter wired to CAN High and CAN Low, configure the SocketCAN interface at the bus bitrate and bring it up:

sudo ip link set can0 type can bitrate 500000
sudo ip link set up can0
ip -details link show can0
Example output
3: can0: <NOARP,UP,LOWER_UP> mtu 16 qdisc pfifo_fast state UP
    link/can
    can state ERROR-ACTIVE (berr-counter tx 0 rx 0) bitrate 500000

Step 2: Sniff the Traffic

Now watch the bus. candump prints every frame as it arrives, with its ID, length, and payload:

candump can0
Example output
  can0  0C9   [8]  00 00 00 00 00 00 00 00
  can0  123   [8]  10 00 00 00 00 00 00 00
  can0  244   [3]  4D 50 48
  can0  123   [8]  00 00 00 00 00 00 00 00

The work here is correlation: trigger an action on the device, watch which ID changes, and you have found the frame that controls it. ID 123 changing as you press a button is the lead you follow.

Step 3: Identify and Inject

Once you know which ID does what, you can send that frame yourself. The bus cannot tell your frame from a real one:

Anatomy of a cansend injected CAN frame command with an arbitration ID and payload
cansend can0 123#1000000000000000
Example output
# candump on the bus shows your frame arrive like any other:
  can0  123   [8]  10 00 00 00 00 00 00 00

Replaying a captured frame, or crafting a new one with a known control ID, makes the target act on your command. Because nothing authenticates the sender, a replayed frame is as good as the original.

What CAN Was Not Built For

The vulnerabilities here are not bugs; they are the bus working as designed. The three properties that make CAN reliable are the same ones that make it open:

Three things the CAN bus was not built for: sender authentication, encryption, and limited broadcast

Defending a CAN-Based System

You cannot bolt authentication onto CAN itself, so defense happens around it. Segment the bus so a compromised infotainment unit cannot reach the powertrain, filter aggressively at gateways between segments, and add message authentication at the application layer, such as AUTOSAR SecOC, for safety-critical frames. An intrusion detection system watching for out-of-spec IDs and timing catches the injection that the bus never will.

Where This Fits

Mapping a CAN bus, identifying control frames, and proving an injected frame is accepted is a core part of an automotive or industrial penetration test. That hands-on bus work, and the defense-in-depth review around it, is the kind of work we do at Berkner Tech.


References and Further Reading