CAN Bus Reverse Engineering – Finding the VIN

By | December 5, 2020

Last winter, I attended a presentation hosted by ASRG-D where the presenter gave his endorsement of the The Car Hacker’s Handbook. So I picked up a copy and read through it. It is an enjoyable read and an excellent compilation for vehicle penetration testing. My only complaint was that there are some minor issues with the sections pertaining to diagnostics – For example, OBD Protocol (SAE J1979) was referred to as UDS (ISO 14229) where they are actually distinct application layer protocols, but again just some minor issues. Full disclosure, I am Technical Lead at a company that specializes in developing diagnostic and flash reprogramming applications so as a reader I was a bit biased. While my day job focuses on the CAN bus and related protocols – It was interesting to see how a security professional who specializes in reverse engineering and penetration testing would go about figuring out CAN signals from thin air.

I decided to write a series of posts where I deploy some of the tools and techniques covered in the book on my own vehicle. I bought a USB2CAN device from 8devices based on the reviews from Open Garages and the book in order to do some of the CAN bus reverse engineering exercises from the book.

First, I had to install can-utils in Ubuntu:

sudo apt-get install can-utils

Next, I plugged the device into my laptop and I initialized the device in the terminal:

sudo ip link set can0 type can bitrate 500000
sudo ip link set up can0

So my device was now ready to read data off the High Speed CAN bus at 500Kbps on Pins 6 & 14 of J1962 Connector (OBD Port).

My first goal was to find my VIN on this CAN Bus. Each CAN Frame has an identifier and a payload of up to 8 data bytes. So I keyed on my vehicle and I fired up candump from can-utils.

candump -ta can0

Out came pouring a ton of CAN frames really fast. Good! So everything was working! I could listen on the network.

...
(1607194977.323530) can0 080#90007D000080C2F7
(1607194977.323795) can0 030#800021800000B205
(1607194977.324042) can0 090#0000C20060000000
(1607194977.324284) can0 0A0#017B29BB00008179
(1607194977.324533) can0 0F8#0000000000001100
(1607194977.324783) can0 120#01E0000080008000
(1607194977.325048) can0 130#51D23A58E0000000
(1607194977.325299) can0 138#00008400BA718271
(1607194977.325534) can0 1A0#1F40000080007B7A
(1607194977.325783) can0 270#5E08042100000000
(1607194977.326043) can0 280#462C00000200C000
(1607194977.326291) can0 2D8#0418008000000000
...

Next – I wanted to log this to disk so that I could analyze and search through it.

candump -ta -l can0

So I was looking for my VIN – A typical VIN in North America is broken down into three sections:

  1. World Manufacturer Identifier (WMI): The manufacturer of the vehicle. [Digits 1-3]
  2. Vehicle Descriptor Section (VDS): Characteristics of the vehicle (Engine Type, Vehicle Line, etc.) [Digits 4-9]
  3. Vehicle Information Section (VIS): Model Year, Plant Code, Sequence Number [Digits 10-17]

The WMI for my vehicle is 1FA (Ford Motor Company). The VIN string is likely to be ASCII encoded on the CAN bus so the value I was looking for in the data was “31 46 41” and sure enough when I searched for “314641” in the log file outputted by candump – I found the following message:

(1607194985.294562) can0 40A#C100314641445033

To add credit to the fact that this was the message I was hunting for – I could see the first three digits of the VDS section was in the data as well – “44 50 33” or “DP3”. Since we know this is a Ford vehicle based on the WMI, we know the 5th-6th digits “P3” mean this is a Ford Focus variant and since the Focus is a Passenger Car we know from “D” that this vehicle has Driver and Passenger Front and Side Airbags and Active Belts in all positions – Translation chart here. That is a lot of useful information in this single CAN Frame.

After that I could narrow down the search – I knew I was looking for CAN ID $40A on the bus. So I added a filter and enabled ASCII output (-a) and piped the output to VIN_Hunt.log.

candump -ta -a can0,40A:7FF > VIN_Hunt.log

The contents of VIN_Hunt.log look like this*:

... 
(1607195817.288159)  can0  40A   [8]  FF 05 11 02 20 40 80 82   '.... @..'
(1607195817.412602)  can0  40A   [8]  FF 06 31 11 11 10 14 11   '..1.....'
(1607195817.537854)  can0  40A   [8]  FF 07 11 09 11 08 91 10   '........'
(1607195817.662733)  can0  40A   [8]  FF 08 08 44 46 24 22 44   '...DF$"D'
(1607195817.788397)  can0  40A   [8]  FF 09 11 11 18 11 24 65   '......$e'
(1607195817.912846)  can0  40A   [8]  FF 0A 11 12 11 33 10 88   '.....3..'
(1607195818.037850)  can0  40A   [8]  C0 00 16 86 33 60 C2 30   '....3`.0'
(1607195818.162652)  can0  40A   [8]  FF 0B 11 04 4C 22 24 21   '....L"$!'
(1607195818.288021)  can0  40A   [8]  FF 0C 07 11 13 81 44 44   '......DD'
(1607195818.412719)  can0  40A   [8]  FF 0D 11 70 11 21 00 13   '...p.!..'
(1607195818.538343)  can0  40A   [8]  FF 0E 20 88 88 88 60 09   '.. ...`.'
(1607195818.662622)  can0  40A   [8]  FF 0F 11 11 21 12 65 57   '....!.eW'
(1607195818.787891)  can0  40A   [8]  FF 10 01 10 11 11 02 11   '........'
(1607195818.912712)  can0  40A   [8]  FF 11 31 13 10 10 00 00   '..1.....'
(1607195819.038084)  can0  40A   [8]  C0 00 16 86 33 60 CC 30   '....3`.0'
(1607195819.162957)  can0  40A   [8]  C0 01 00 01 02 87 AE 00   '........'
(1607195819.288079)  can0  40A   [8]  FF 12 26 11 10 01 10 01   '..&.....'
(1607195819.412582)  can0  40A   [8]  FF 13 10 11 11 21 21 11   '.....!!.'
(1607195819.538086)  can0  40A   [8]  FF 14 18 08 41 08 08 03   '....A...'
(1607195819.662968)  can0  40A   [8]  FF 15 00 00 00 00 80 00   '........'
(1607195819.787946)  can0  40A   [8]  FF 16 21 00 21 01 20 00   '..!.!. .'
(1607195819.912697)  can0  40A   [8]  FF 17 00 00 00 00 00 00   '........'
(1607195820.038070)  can0  40A   [8]  C0 00 16 86 33 60 D6 30   '....3`.0'
(1607195820.162749)  can0  40A   [8]  C0 01 00 01 02 87 AE 00   '........'
(1607195820.287997)  can0  40A   [8]  C1 00 31 46 41 44 50 33   '..1FADP3'
(1607195820.412818)  can0  40A   [8]  C1 01 4B 32 37 45 4C XX   '..K27ELX'
(1607195820.537861)  can0  40A   [8]  C1 02 XX XX XX XX XX 00   '..XXXXX.'
(1607195820.662742)  can0  40A   [8]  C1 03 4A 00 34 89 89 91   '..J.4...'
(1607195820.788366)  can0  40A   [8]  C1 04 FF FF 07 AD 00 00   '........'
(1607195820.912687)  can0  40A   [8]  C1 05 08 9C 09 00 0A 8D   '........'
(1607195821.038062)  can0  40A   [8]  C0 00 16 86 33 60 E0 30   '....3`.0'
(1607195821.162692)  can0  40A   [8]  FF 20 00 00 00 00 00 00   '. ......'
(1607195821.287859)  can0  40A   [8]  FF 21 00 00 00 00 00 00   '.!......'
(1607195821.412680)  can0  40A   [8]  FF 00 11 12 11 11 11 10   '........'
(1607195821.538302)  can0  40A   [8]  FF 01 31 04 4C 84 00 40   '..1.L..@'
(1607195821.662803)  can0  40A   [8]  FF 02 21 24 22 10 88 40   '..!$"..@'
(1607195821.787818)  can0  40A   [8]  FF 03 17 05 10 31 22 08   '.....1".'
(1607195821.912674)  can0  40A   [8]  FF 04 12 11 D0 00 C4 42   '.......B'
(1607195822.038101)  can0  40A   [8]  C0 00 16 86 33 60 EA 30   '....3`.0'
(1607195822.162724)  can0  40A   [8]  C0 01 00 01 02 87 AE 00   '........'
(1607195822.288290)  can0  40A   [8]  FF 05 11 02 20 40 80 82   '.... @..'
...

*Please note that I have redacted the Sequence Number [Digits 12-17] of the VIN with XX for the data bytes and in the ASCII column as a precaution. The Sequence Number information along with the rest of the VIN is uniquely identifying information and can be possibly be used for nefarious purposes. Even though I bet it is available somewhere else on the web I am not going to post it here myself.

And look at that! The rest of the VIN is contained in two other messages. It looks like the contents of CAN ID $40A is made up like this:

  • Data Byte 0 (Message Type): $C0, $C1, $FF
  • Data Byte 1 (Message Count): For Message Type $C0 – $00-01; For Message Type $C1 – $00-05; For Message Type $FF – $00-21
  • Data Byte 2-7 (Payload): Data, the meaning of which is determined via the Message Type and Counter

From here we can see that the VIN is housed in Message Type $C1 – Message Count $00, $01, $02.

(1607195820.287997)  can0  40A   [8]  C1 00 31 46 41 44 50 33   '..1FADP3'
(1607195820.412818)  can0  40A   [8]  C1 01 4B 32 37 45 4C XX   '..K27ELX'
(1607195820.537861)  can0  40A   [8]  C1 02 XX XX XX XX XX 00   '..XXXXX.'

So piecing it all together the VIN is: 1FADP3K27ELXXXXXX where XXXXXX is the redacted Sequence Number. From the VIN we know this is a 2014 Model Year Ford vehicle (See Model Year – E [Digit 10]). Ford has made guides available for decoding VINs for their vehicles – Here is the Ford 2014 VIN Guide.

So using the decoder guide we know from the VIN:

  • WMI [Digit 1-3]: 1FA – “Ford Motor Company”
  • Restraint Category [Digit 4]: D – “Category Code 8” (See guide for details)
  • Line, Series, Body Type [Digit 5-7]: P3K – “Focus SE Five Door Hatch”
  • Engine Type [Digit 8]: 2 – “2.0L GDI, I-4, Gasoline”
  • Check Digit [Digit 9]: 7 – Just used to validate integrity of digits 4-8
  • Model Year [Digit 10]: E – “2014”
  • Plant Code [Digit 11]: L – “Michigan Assembly Plant”
  • Sequence Number [Digits 12-17]: XXXXXX – Sequential Number assigned by the plant (Shhhh… It’s a secret)

As Craig Smith points out in The Car Hacker’s Handbook, this information could be used to determine which exploits an attacker could use on a target vehicle. An attacker could passively get this information from the CAN bus. I hope this guide was helpful in introducing the topic of reverse engineering CAN bus signals. Thanks for reading!

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.