Skip to content

Instantly share code, notes, and snippets.

@sprout42
Last active August 12, 2021 16:00
Show Gist options
  • Save sprout42/5e10a0afb90fbe1f7653a72747704695 to your computer and use it in GitHub Desktop.
Save sprout42/5e10a0afb90fbe1f7653a72747704695 to your computer and use it in GitHub Desktop.
GRIMM's 3PO Challenge 1

CAN Bus Reverse Engineering Challenge #1: Send the “Brake Fluid Low” Message

Prove it! Send the “brake fluid low” message to cause a spurious driver alert.

Background:

Automated embedded software is integrated from multiple sources, using a variety of code languages and practices - even in a single ECU. This creates major security risks where content comes together.

Setup:

These setup steps are only necessary if you are doing this on your own computer with your own vehicle and hardware.

NOTE: The CAN message shown in this challenge that brings up the "Brake Fluid Low" warning message works on GRIMM's 3PO test bench, but won't work on your vehicle unless it is a similar era and type of vehicle (2012 Ford Focus).

  1. Clone the CanCat repo
$ git clone https://github.com/atlas0fd00m/CanCat ~/CanCat
  1. Install the necessary python dependencies (CanCat is currently only python2 compatible)
$ pip2 install ipython pyserial
  1. Connect a CanCat capable device, such as the Macchina M2, to your computer

  2. Update the CanCat device with the CanCat Arduino sketch. This can be done using the Arduino IDE, or if you have arduino-cli installed it can be done with the provided makefile:

$ cd ~/CanCat/sketches
$ make m2
  1. Connect the CanCat device to the MS-CAN bus. On GRIMM's 3PO test bench MS-CAN is clearly labeled. On your own vehicle you will need to identify the wires to connect to.

Step-by-step Instructions:

  1. move to the CanCat directory
$ cd ~/CanCat
  1. Start CanCat, this will start an ipython session that already has a CanCat object called c.
$ ./CanCat.py -p /dev/ttyACM0 -S 125K

The -p option specifies the port that the CanCat is connected to and the -S option specifies the CAN bus speed (in this particular example 3PO's MS-CAN bus runs at 125Kbps).

  1. Get a count of the CAN messages received, this helps to ensure that you are correctly connected to the CAN bus. If you run this command a few times you should see the number of received messages increasing fairly quickly.
In [1]: c.getCanMsgCount()
  1. Display the CAN messages that have been received with a CAN arbitration ID of 0x290. This is a status message broadcast by the Body Control Module (BCM). One piece of information in this message indicates if the brake fluid is low.
In [2]: c.printCanMsgs(arbids=[0x290])
  1. On 3PO you will see that there are 8 bytes of message data and the first byte of this message is 0x98. This changes to 0x88 when the brake fluid is low. Run the following command to inject our own message with that bit flipped:
In [3]: c.CANxmit(0x290, “\x88\x00\x01\x06\x00\x00\x00\x00”)
  1. Watch the instrument panel for the “Brake Fluid Low” error message.

Result:

You’ll notice that the error message appears briefly on the screen, then disappear. Why is this? The Body Control Module (BCM) is responsible for sending the message with the arbitration ID of 0x290. If you look back where you printed all the messages with that arbitration ID in step 5, you’ll notice that the BCM actually sends that message about 3-4 times per second. Shortly after you inject your fake message, the BCM sends the correct message which clears the error. This is fairly typical behavior as most messages on a CAN bus are periodic messages. This often requires an attacker to take some steps to avoid their attack being nullified in this manner. These steps may be as simple as flooding the CAN bus with your messages, or may require reverse engineering and re-flashing the offending module.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment