WEBVTT

00:02.750 --> 00:04.220
Hi everyone.

00:04.500 --> 00:11.760
Today I'd like to welcome you guys to Car Hacking Village of DEF CON 2020, Safe Mode.

00:11.960 --> 00:18.780
Today's presentation is going to be a throwback to the times before J1939.

00:18.920 --> 00:30.600
If you don't know what that is, that is a protocol that runs on top of CAN and is primarily used in heavy vehicle component communications.

00:30.600 --> 00:42.520
So we will be talking about how we came about the creation of a decoder slash parser for J1708 and J1587.

00:45.180 --> 00:49.680
So just a quick breakdown of how this presentation is going to pan out.

00:49.680 --> 00:53.440
First, we will let you know who we are.

00:53.740 --> 00:57.880
We're going to let you know how this project came about.

00:57.880 --> 01:04.280
And then we're going to give a brief recap of the protocols that are interesting to us.

01:05.900 --> 01:11.400
And you will then see how we came across these protocols.

01:12.660 --> 01:18.780
Afterward, we're going to talk about the decoder slash parser and we'll give you a quick demo.

01:19.560 --> 01:26.280
Last, we'll conclude this talk with the info you'll need to pick up where we are leaving off.

01:28.980 --> 01:32.280
Okay, so my name is Daniel Saloom.

01:32.760 --> 01:36.880
I'm a reverse engineer at Assured Information Security.

01:36.880 --> 01:39.200
We're based out of Rome, New York.

01:39.280 --> 01:44.600
I've been with them for a little over a year and a half at this point.

01:44.600 --> 01:55.160
And I spend my days analyzing the security of things, digging into protocols, and developing anything to support these efforts.

01:55.880 --> 02:00.800
You can see in the images, I'm on the right-hand side.

02:01.260 --> 02:04.240
And there's an image of Thomas on the left-hand side.

02:04.540 --> 02:08.040
So now you have proof that we actually work.

02:11.140 --> 02:13.960
Hi, so my name is Thomas Hayes.

02:13.960 --> 02:19.580
I'm a hardware engineer at Bendix Commercial Vehicle Systems based out of Elyria, Ohio.

02:19.580 --> 02:27.600
I spend most of my days designing hardware, so PCBs and digital and analog interfaces for brake control systems.

02:27.600 --> 02:30.620
And I've been there for almost five years now.

02:35.200 --> 02:38.980
Okay, so what are we doing here?

02:38.980 --> 02:50.040
Well, we discovered that there are more than just J1939 messages that cross the networks in heavy trucks.

02:50.040 --> 02:54.700
And within this traffic, there's some very interesting data.

02:54.940 --> 03:00.860
So we're here to show you how it came about, as we needed a simple way to see it.

03:00.900 --> 03:05.320
And I can imagine you guys want to see how the decoder works as well.

03:09.720 --> 03:11.520
So is there a backstory?

03:11.680 --> 03:12.920
We know trucks.

03:12.920 --> 03:14.520
I've been playing them for a while.

03:14.520 --> 03:23.760
This project started off in mid-2019, when we started to do some exploratory testing on heavy vehicle systems.

03:23.760 --> 03:28.980
We noticed multiple networks and interconnection between all of these modules.

03:29.000 --> 03:35.580
We started to explore some tools and decoders that are already out there, available for use for people in industry.

03:36.480 --> 03:49.960
These legacy protocols of J1708 and J1587 are still being sent across the bus, even though now the CAN J1939 is much more prevalent in newer vehicles.

03:50.140 --> 04:01.360
It looks like it could be very interesting, as it is a very important bus that happens on the vehicle, with a lot of useful information that we were interested in looking at.

04:03.720 --> 04:07.170
Okay, so how do we...

04:08.960 --> 04:13.040
I'm sorry, what do we need in order to get things rolling?

04:14.040 --> 04:17.440
First is an understanding of the protocols involved.

04:17.440 --> 04:21.720
In this case, we mentioned J1708 and J1587.

04:21.720 --> 04:23.600
They kind of work together.

04:23.640 --> 04:29.300
We also need a hassle-free way of analyzing the traffic that we see.

04:29.300 --> 04:34.300
And at that point, we can decide what may or may not be done with this data.

04:38.870 --> 04:43.310
So what are J1708 and J1587?

04:43.310 --> 04:50.790
So they are SAE, the Society for Automotive Engineers, standards for medium and heavy-duty vehicles post-1985.

04:51.350 --> 04:56.990
J1708 describes a physical layer and data links layer and defines a bidirectional serial vehicle network.

04:57.090 --> 05:01.910
J1708 defines how the messages are structured and how they're distributed over the network.

05:01.910 --> 05:07.410
And J1587 makes up a transport application layer and describes messages format and parameters.

05:07.410 --> 05:13.310
So that's almost a big dictionary for all the possible messages that can be sent over this communication protocol.

05:16.600 --> 05:22.360
So J1708 is almost always used in conjunction with the application layer protocol, J1587.

05:22.360 --> 05:25.000
It's based on an RS-45 bus.

05:25.180 --> 05:30.000
We can have a max of 20 nodes on a vehicle and it runs at 9600 baud.

05:30.000 --> 05:40.400
A message contains a 1-byte long MID, a message identifier, followed by some data related to that MID and a 1-byte checksum.

05:40.400 --> 05:42.900
The message can be up to 21 bytes long.

05:42.900 --> 05:49.720
However, if the vehicle is stopped and no movement is detected, the messages can be longer if required.

05:53.340 --> 06:01.300
So J1708 MIDs, we go up to 0 to 127, defined by J1708.

06:01.300 --> 06:04.720
And these are defined by SAE for important vehicle systems.

06:04.720 --> 06:10.840
And then from 128 to 255 are defined by J1587.

06:10.840 --> 06:16.260
And these are used a little bit more for maintenance and information on the vehicle, more for a diagnostic side.

06:16.680 --> 06:17.720
It's very cool.

06:17.720 --> 06:21.960
The MIDs also serve as an arbitration method for the communication.

06:21.960 --> 06:35.180
So the lower your MID number is, let's say 0 to 7 for engine, that means it's a very high important message and will be passed before perhaps the trip recorder message with MID at 56 and 61.

06:35.460 --> 06:37.500
The checksum is quite simple.

06:37.500 --> 06:39.880
It's a two's complement of the sum of the message.

06:39.920 --> 06:43.540
And the data content is defined by the application document given by the supplier.

06:43.540 --> 06:57.000
So you can send the messages defined by SAE or possibly something defined by you as a manufacturer if you need to send something specific or proprietary across the bus.

06:59.760 --> 07:04.360
So J1587 defines the PID, the parameter identifier.

07:04.360 --> 07:07.480
So that's a little bit of a complement to the MID.

07:07.660 --> 07:17.200
So if you have an MID for the engine, a PID can be related to your engine oil or a knock sensor or something in your camshaft.

07:17.200 --> 07:24.360
So it's a little bit more information for the PID for the system to recognize if there's a fault and direct where that fault can be.

07:24.980 --> 07:29.800
So it consists of one MID, one or more PIDs, and a checksum.

07:29.800 --> 07:35.160
The data length of 1587 messages is mostly limited to 21 bytes according to J1708.

07:35.280 --> 07:46.100
And if a message needs to be longer than 21 bytes, we can use the C-C-O-T-S, the TP4.

07:46.100 --> 07:50.000
So that can be used to segment and reassemble large messages if needed.

07:50.000 --> 07:52.380
And a lot of the PIDs are standard.

07:54.350 --> 08:02.810
The PIDs range from 0 to 4 bytes, and the units for elucidating the range will be defined in the spec or by whoever is sending them out.

08:02.810 --> 08:12.270
So if you're a one-engine manufacturer, you could say the PID for oil pressure is 1 psi per bit, or another one could say it's 5.

08:12.270 --> 08:14.990
So it just depends on the manufacturer for that PID.

08:15.470 --> 08:16.970
There's also SIDs.

08:16.970 --> 08:29.650
These are related to the MID, but these are more related to anything that can be used to identify a section that is not necessarily covered under a PID, but covered under a diagnostic MID.

08:29.670 --> 08:35.070
So the MIDs for using SIDs will begin at 128.

08:35.070 --> 08:37.370
That's defined by 1587.

08:37.370 --> 08:42.550
And these are really used for something that can be troubleshooted or replaced by a field technician if needed.

08:45.720 --> 08:47.380
So what's in the data?

08:47.380 --> 08:52.600
Now, a lot of our testing was in the communication between trucks and trailers.

08:52.600 --> 09:00.840
So the trailer has an ABS ECU, and the trailer also has an ABS ECU, and those two will talk to each other using this protocol.

09:01.640 --> 09:05.520
The trailer ABS can have all kinds of diagnostic messages.

09:05.520 --> 09:07.620
A trough test is a test of the system.

09:07.620 --> 09:12.860
It will modulate the air solenoids a little bit and dispense a bit of air.

09:12.860 --> 09:19.440
Like when you hear a truck brake, you hear a large air release sound, and that's kind of just making sure that your system is working properly.

09:19.440 --> 09:26.360
You can restart the ECU, you can check the status of the ECU, and most importantly, demonstrate an ABS fault.

09:26.460 --> 09:46.240
So as per SAE standard, the ABS fault, if the trailer has an issue, the trailer ECU has to communicate to the truck ECU and illuminate a light on the dash, as well as a light on the trailer itself, indicating that there is an issue with the ABS and it needs to be resolved.

09:47.340 --> 10:04.160
Diving a little bit deeper, there's also configuration options on the ECU, so wheel size, which then relates to the speed of the vehicle, as there's a tone ring that counts the amount of rotations done, and driver info, so where the trailer is going and what truck it is connected to at the lot,

10:04.160 --> 10:13.800
and sensor data, so the speed, mileage, odometer stored on the ABS, location, temperature, and many proprietary vendor messages.

10:15.600 --> 10:18.420
So who uses J1708 and J1587?

10:18.420 --> 10:28.220
So any kind of heavy vehicles that we all know, but also school buses with all that same platform, military vehicles, and we even found that yachts will be using the same communication platform.

10:29.900 --> 10:33.740
So our use case, we were observing exchanges between a tractor and a trailer.

10:33.740 --> 10:42.120
As we said, the brake controllers communicate over J1708 and J1587, and these messages actually pass over a power line, which is very cool.

10:42.120 --> 10:59.640
Trailer manufacturers did not want to add another wire or two needed for an ABS communication, so they superimposed a sinusoidal wave on the power line going from the trailer, which then gets filtered out on the trailer side and on the truck side, depending if it's using that communication.

10:59.640 --> 11:03.360
It's very cool, but Dan and I did not focus our time on this.

11:03.360 --> 11:07.540
We were working on the J1708 and J1587 protocol.

11:10.700 --> 11:17.520
Okay, so the question comes up now, how do we look at these messages?

11:17.940 --> 11:19.620
There's a couple of options.

11:19.620 --> 11:39.660
We can use tools that were developed for J1939 and are backward compatible with the other two protocols we mentioned, or we can get our hands on an RS-485 transceiver, some bubble gum, a paper clip, maybe a tinfoil hat and see what we can hack up.

11:40.940 --> 11:44.380
But what happens when our bus is a power line?

11:44.640 --> 11:48.380
In this case, you need a specialty diagnostic tool.

11:49.360 --> 11:54.760
Some of the larger companies like Nexic, Halidex, Digitech, they provide these.

11:55.200 --> 11:59.240
But the problem with this approach is it's going to cost you some moolah.

11:59.240 --> 12:12.100
And flow between programs is not really there, as software is kind of tied with the hardware and it's all proprietary, which means minimal flexibility.

12:13.940 --> 12:18.500
So our solution is pretty J1587.

12:18.800 --> 12:24.080
This is a decoder that helps with at least part of the problem.

12:25.260 --> 12:29.220
By default, this takes in hexadecimal bytes.

12:29.220 --> 12:35.420
Which are comma delimited, but really it can take in a stream of any bytes.

12:35.600 --> 12:44.620
And a user can define how to manipulate that data to be parsed correctly by the decoder.

12:45.220 --> 12:53.540
It also supports reading from standard in files or sockets, UDP or TCP.

12:53.660 --> 13:03.160
And what it does is it takes this information, these messages, and it will break them down into a human tolerable format.

13:03.160 --> 13:07.220
So they can be easily analyzed by an end user.

13:08.080 --> 13:19.980
So to start off, what happens is the parser will read the SAE documentation PDFs.

13:19.980 --> 13:28.950
Okay, and it will do this to set up a primary database, which is used for interpreting the data that's coming in.

13:29.410 --> 13:36.670
And this is needed because there's no simple database holding the data that we need in a convenient format.

13:36.670 --> 13:42.430
Okay, it's all in the specifications or proprietary by vendors.

13:42.830 --> 13:49.430
So there is an option for an end user to create custom messages with this tool.

13:49.430 --> 13:52.790
And this will be handy for working with proprietary data.

13:54.350 --> 14:05.870
The benefit of this, using this tool, is that it can be piped from or to other programs, as it's just a command line utility.

14:08.150 --> 14:10.710
So there are some requirements.

14:10.750 --> 14:12.690
What do we need to get this off the ground?

14:12.690 --> 14:19.750
Well, the first part is on you guys, you're going to need an interface to some bus to get the traffic.

14:20.750 --> 14:33.690
The next part is, it uses the program PDF2Text, which is contained within the popular udos package standard on most Linux distributions.

14:33.710 --> 14:48.050
Okay, and what happens with this is we use this tool to convert the SAE portable document format specifications into formatted text files.

14:48.050 --> 14:52.670
Okay, then you need Python 2.

14:52.670 --> 15:00.090
We are hoping to port this to Python 3, but it started as a spaghetti code project that we just needed up and running.

15:00.150 --> 15:02.390
And Python 2 was default here.

15:02.390 --> 15:07.950
And that's what we stuck with until now when we realized it's actually useful.

15:09.030 --> 15:11.950
There's still some minor issues with it.

15:11.950 --> 15:16.830
The spec obviously was not written with being parsed in mind.

15:16.830 --> 15:25.470
Okay , so there's a lot of regular expressions and things that parse this information out of these files.

15:27.650 --> 15:37.470
Okay, so I think at this point, I'm going to give you guys a quick demo about how this thing works.

15:38.650 --> 15:43.710
It's a repository, which will be made public after this talk.

15:43.710 --> 15:45.430
And you can just clone it.

15:45.430 --> 16:03.050
And at that point, you will set up the configuration file to point at the text files that you've created from using PDF2Text on the SAE J1587 and 1708 specifications.

16:03.050 --> 16:03.670
Okay.

16:03.670 --> 16:08.010
So the first thing that I'll mention is this repository.

16:08.130 --> 16:13.090
Within it, we have a tool called Fuzzy Messages, which I'll be using for the demo.

16:13.090 --> 16:21.530
All right, this program just creates random bytes, I believe 1 to 19 bytes in length.

16:21.590 --> 16:28.530
And this winds up working out as a nice test environment to create a robust program.

16:28.530 --> 16:32.830
That way, it's not just failing on any sort of messages.

16:32.830 --> 16:42.570
As you might see, when running different types of hardware, you'll get funky bytes that aren't actually part of the message at times.

16:42.570 --> 16:50.030
So we've decided to make this program a little bit robust, and that it won't just error out on an incorrect message.

16:50.030 --> 16:55.910
It might print a warning to standard out, and it'll keep chugging.

16:55.910 --> 17:12.210
Okay, so the first thing I'm going to do is I'm going to create a file with, let's say, 100 messages, and I'm going to write that to temp.

17:12.830 --> 17:15.570
Okay, let me just make sure that that worked.

17:16.690 --> 17:18.910
Yep, seems like I got messages in there.

17:18.910 --> 17:27.470
All right, so now to run the tool, I just point it at that file that I created with all the messages.

17:27.770 --> 17:32.390
I'm also going to give it a flag to print the limiters between the messages.

17:33.470 --> 17:41.490
So you can see, when there are errors, it gets printed to standard error.

17:41.530 --> 17:45.150
So these can be piped to DevMill if you're not interested.

17:45.150 --> 17:53.970
But you can also see here the original message MID in hexadecimal, and these also are accompanied by decimal forms.

17:53.970 --> 18:01.490
And then the PIDs and the meanings of the PIDs, along with the accompanying bytes.

18:01.490 --> 18:04.050
Okay, so that's pretty good.

18:04.050 --> 18:13.270
But if you want more information, you can give this program a little bit more verbosity, like so.

18:13.270 --> 18:15.650
And you'll get details.

18:15.650 --> 18:18.730
This is the same message here that we saw previously.

18:18.950 --> 18:26.730
But now you can see it's giving details about the individual bytes related to a PID.

18:27.050 --> 18:32.970
So here we can see there's one byte and this has to do with the extended range barometric pressure.

18:32.970 --> 18:35.350
Okay, and here are the units right here.

18:35.350 --> 18:38.030
I just want to mention one thing.

18:38.030 --> 18:41.530
We are using random bytes for this data.

18:41.530 --> 18:46.130
So this MID says idle adjust system.

18:46.310 --> 18:55.390
And it's not necessarily in a real world scenario, this PID is probably not going to be matched with this MID.

18:55.430 --> 18:56.350
Okay.

18:56.590 --> 19:00.810
But we don't error out, we just want to parse the data as it comes.

19:02.770 --> 19:06.270
There's a couple of other options I wanted to mention.

19:06.410 --> 19:10.090
So some people prefer JSON.

19:10.970 --> 19:13.570
We added a flag for JSON.

19:13.570 --> 19:19.490
I will disable the output that you just saw, which can be easily grepped.

19:19.490 --> 19:23.390
And I will print these messages in JSON format.

19:23.390 --> 19:29.850
And I'm also going to pipe the standard out to dev null.

19:30.370 --> 19:39.810
Okay, so you can see in here, same messages, but these are output as JSON formatted messages.

19:39.810 --> 19:47.470
This could be convenient if you use the JQ tool, and you want to filter these messages the way you'd wish.

19:47.470 --> 19:50.350
But there's another option for you.

19:50.350 --> 19:53.590
And that is, we have a whitelist here.

19:57.110 --> 20:10.350
So what we can do is specify specific PIDs, like if we are interested in certain PIDs within a message, we only want to print those messages, we use the whitelist option.

20:10.350 --> 20:13.130
So I will just grab one from here.

20:18.960 --> 20:24.860
And so you can see I printed out one message with that PID, 48.

20:25.760 --> 20:30.540
And that is in actually decimal form for that.

20:31.540 --> 20:34.900
Okay, so there's a couple other things that this can do.

20:35.500 --> 20:40.220
If you just give it the dash H, it'll give you some help.

20:40.720 --> 20:45.780
One of the options is for a custom database.

20:45.780 --> 21:03.480
Now this means if you want to define your own messages, and overwrite those that are provided by the spec, or let's say you're working with some proprietary messages, and you have a good idea what it means, you can define that.

21:03.480 --> 21:08.320
We provide a sample file in the repo.

21:08.400 --> 21:14.980
And you can see here that basically, this is the format, it's just JSON.

21:14.980 --> 21:20.900
And you just give it your definitions, you can use this file as a guide.

21:20.900 --> 21:23.660
Okay, there are still some issues.

21:23.660 --> 21:30.380
There are a few PIDs that are a little bit more tricky to work with.

21:30.380 --> 21:37.720
And those might not have their individual byte definitions overwritten, but it's a work in progress there.

21:37.720 --> 22:02.640
I wanted to mention that, okay, if you want to read from standard input, the way that you do it is you just pipe hexadecimal delimited bytes, as I mentioned, to this, and you will use this usual format for reading from standard input.

22:02.640 --> 22:09.220
Okay, I'll also use the... I'll use packet delimiters here.

22:09.220 --> 22:11.440
And you can see what the meaning is.

22:11.480 --> 22:29.780
But one of my colleagues came to me and he said, well, you know what, you know, we have an issue because the output that I'm getting from my program is not set up like that, it doesn't have the comma delimited values, it's all just a string of hexadecimal bytes.

22:29.780 --> 22:45.920
So what we did was we added the option here, if you look in this file called canon functions, an end user can define a function to be called on the command line that will manipulate this format.

22:45.920 --> 22:55.960
And the only requirement is that the output would be a Python list of bytes, okay, or a Python list of integers.

22:55.960 --> 23:06.120
So in this case, we can use the dash j option and say canon no delims, I believe I called it.

23:06.220 --> 23:12.800
And you can see that it will just parse the message in that format.

23:12.800 --> 23:15.260
Okay, so it doesn't really matter.

23:15.260 --> 23:23.880
All you need to do is know what your input looks like, and figure out how to get that into a Python list of integers.

23:27.600 --> 23:31.140
Let me see if there's anything else I want to mention.

23:32.020 --> 23:33.380
I think that's it for now.

23:33.380 --> 23:38.760
I'll let you guys play with the rest of those options as you see fit.

23:43.830 --> 23:49.690
So getting back, what are the benefits of using this decoder?

23:49.690 --> 23:57.030
Well, there's no real software investment, other than getting your hands on the SAE specs.

23:57.030 --> 24:01.150
Okay, I'm sorry, we can't just provide them for free.

24:01.430 --> 24:05.630
But SSA, sorry, SAE would not be happy with us.

24:05.630 --> 24:09.410
And they take the intellectual property very seriously.

24:09.410 --> 24:11.090
So I'm sorry about that.

24:11.090 --> 24:12.990
You can handle it, I'm sure.

24:14.070 --> 24:21.610
The other benefit is that you can work with anything that outputs 1708, 1587 messages.

24:24.270 --> 24:26.030
So where can you get it?

24:26.030 --> 24:30.490
If you want to get your hands on this tool, you'll go to this URL.

24:30.790 --> 24:35.050
After the talk, we will make this a public repo.

24:35.270 --> 24:42.430
We're rolling with an MIT license, so don't forget where it came from, and feel free to make money on it.

24:42.430 --> 24:45.990
But remember that there are a few dependencies.

24:45.990 --> 24:52.330
So you need the specs, you need PDF to text tool, and Python 2 at the moment.

24:54.830 --> 25:07.150
We wanted to give a special thank you to NMFTA for giving us the opportunity to do this work, and our friendly motor freight carriers for allowing us to play with their trucks.

25:07.150 --> 25:17.690
Also the Hilton Executive Lounge for hosting a nice, hectic atmosphere by letting this group meet and set up mobile test benches.

25:18.350 --> 25:23.190
We only left a few solder burns under nice wood grain tables.

25:26.290 --> 25:31.390
We just want to thank you for joining us, and enjoy the rest of your DEF CON talks.

