The Janus Attack
The Janus Attack is a low-level CAN protocol attack where a single CAN frame contains two different payloads, so that a targeted device sees a different payload to other devices. This attack could be used to transmit a frame to evade an Intrusion Detection System (IDS), or it could put two different actuators into inconsistent states (e.g. moving a pair of motors in a different directions). It breaks the atomic multicast feature of CAN (where every device sees the same frame) - an important property that lots of systems rely on (often implicitly).
The attack works by exploiting the CAN protocol synchronisation rules and targets devices that have different sample points.
The attack can be mounted purely in software that takes control of the GPIO port connected to the CAN TX pin of a CAN transceiver, so a hijacked device using a remote code execution vulnerability could be used to mount the attack.
Below is a demonstration video of the attack, using two CANPico boards (that contain the Microchip MCP2517/18FD CAN controller) are attacked by a CANHack board (a cut-down version of the CANPico that doesn’t have a CAN controller, neatly proving that the attack can be mounted in pure software). The logic analyzer is running our can2 protocol decoder to show how the Janus signal is decoded into a CAN frame. There are two CANPico boards plus a CANHack board (the CANPico board can also run CANHack, but it’s also easy to make a CANHack board out of breadboard).
How does the Janus Attack work? It forces CAN controllers to sync at the same time and then changes the CAN bus level after one controller has sampled the bus but before another. The bit sequences are set so that each device sees a valid frame, but the frames can have different payloads. The logic analyzer trace below shows how a Janus frame is made up of many more transitions than CAN bits but that are a valid CAN frame.
There are some restrictions on the bit sequences: both the first and second CAN frame have to have the same length, so there must be the same number of stuff bits. The CANHack toolkit has a function to show the bit patterns of both halves of a Janus frame.
There is a further restriction: if the Janus bit is
10 (i.e. the first sampled value in a CAN bit is
is a 1 but the second sampled value a 0) then all controllers
have to see the same subsequent bits (
11) until they
are brought back into sync (which happens after a
There is a Janus bitstream test function
is_janus() included in the latest
version of the Python CAN frame tool
in the CANHack repository,
plus a very simple brute force algorithm to look for Janus
payloads (other smarter algorithms no doubt exist). This can
be used to create CAN frames to show how the attack works. It would
also be possible to attack devices with sample points that were more
similar if the CANHack toolkit used output compare timer hardware
present in most microcontrollers to make the CAN TX transitions
more accurately. But the goal with the CANHack toolkit is not to
make it easy to attack a CAN bus but to prove that there is
vulnerability that must be defended against.
So how to defend against this attack? Firstly, an IDS with dedicated hardware should be used to detect these transitions: an IDS that uses a conventional CAN controller cannot detect this (it also can’t detect many other CAN protocol attacks). Secondly, devices should have sample points set as close to each other as possible (ideally, this would be part of an acceptance test when integrating devices together on to a CAN bus). There are other protections too: using CAN-HG Bus Guardian hardware prevents a Janus frame from being sent (and allows an IDPS to shut down an attack), and protecting a payload with a cryptographic Message Authentication Code (MAC) makes it much harder for an attacker to find a valid Janus payload (even if the attacker has the ability to sign messages with the necessary shared cryptographic key).