start	end	text
1860	7800	Robert does not need an introduction, but he wants me to give you one because he loves to hear other people talk about him.
9040	17480	So, Robert taught me how to hack a Cadillac CTS back in the day. I think, what was it?
17820	24940	Or you showed me how to allow the DVD to show video while you're driving.
24940	26900	Yeah, while in motion. You need to.
26900	34280	Yes, that is very important. And that was a very big learning curve for me.
34300	38960	Of course, I was a big dummy, so I forgot the termination and on and on. Everything.
39440	43880	So, Robert is going to give his wonderful talk.
44120	44920	CMAP.
45080	48940	Yes, that's right. CMAP on your... and you've got a repo for this, which we'll put...
49560	51520	I know you've already posted it, but I will...
51520	52420	We'll link it to things.
52420	57200	Yeah, we'll put it into the... and this is track one, correct?
57200	57660	Yes.
57880	72440	So, any Q&A, normally we've been answering that in the track in text, but this one, we'll try to monitor track one text and we will get those questions to Robert at the end, okay?
73200	74180	It's all you, man.
74180	75120	Thank you.
130290	132290	There we go. Welcome back.
132370	133630	Do you want to kill that music?
133630	135350	In the stream?
136430	138870	It's coming from the Discord channel.
140210	141770	Thank you, Discord.
142490	143890	Thank you.
149560	151820	There. There it goes.
151820	153100	We got this.
154420	157460	You can see why we didn't do any of the live talks.
158080	160080	For this exact reason.
160080	163760	All right. Hello, everyone. My name is Robert Leally, also known as Carfucker.
163760	175660	And I would like to talk a little bit about a tool that will help you analyze or check what services are available on a particular vehicle.
175660	178920	So, I'm currently connected to a vehicle.
179260	182700	Specifically, we have a truck over here.
183220	192680	It's the same truck that we're using for the challenges inside of the DEF CON CHV truck.
192680	197540	So, after I'm done with this, you guys can go get the repo right from GitHub.
197540	206420	So, just go to GitHub.com canbushack and you'll find CMAP there.
206740	210580	Canbushack is one word. C-A-N-B-U-S-H-A-C-K.
210580	213880	And you'll find the CMAP repo that lives there.
214120	218720	The concept is pretty simple, but kind of basic as well.
218720	224760	So, I'm going to take you through sort of a very deep dive into CMAP, how it works.
224760	227820	Again, this is live. So, if it fails, sorry.
228180	230000	I'll sort of talk about the concepts.
230000	232520	I don't have any slides. Like I said, pretty lazy.
232520	234740	But the concepts are really simple.
234740	237420	So, you're just going to go in. You run this thing.
237420	242280	Connect it to a CAN bus. Right now, I'm currently using a Raspberry Pi.
243320	247380	Maybe I'll take a second to break out and show you what the Raspberry Pi looks like.
247380	249140	Do like a live feed over there.
250360	255740	It's connected to a Raspberry Pi, which has got a device that essentially enumerates a CAN0 network.
256080	258020	So, CAN0 is socket CAN.
258020	262440	On this one, actually, we are on CAN2.
262440	264500	We're going to be on CAN2, not CAN0.
264720	267520	So, let me just break this real quick.
268100	269240	If I can.
270040	273300	If not, I'll get another terminal window open.
274220	276660	I might just have to grab another terminal window.
278040	279340	Because, you know.
280520	281740	Bad idea.
281760	282360	Okay.
283500	285420	Now my whole screen is frozen.
285480	286600	Nothing wrong with that.
288260	289680	Sorry, guys.
290000	291740	This is why we do it.
295470	298870	So, my computer is not happy with this scenario.
298870	299770	Real quick.
305130	306350	Oh, my goodness.
307650	310330	This is why we didn't do any live talks, by the way.
311510	312950	I apologize.
313030	316550	I cannot get my computer to close this window.
325800	328400	It's completely frozen, my computer.
328400	329460	So, just one second.
330600	333420	Now you guys are missing the real DEF CON experience.
340620	343100	It was working great, just two seconds ago.
345080	347160	So, how's your guys' day so far?
347160	348680	Everything's going well?
348680	349780	Alright, good.
350660	356340	I'm going to take a picture of these screens so everybody can kind of see what's happening over here.
356340	358180	I don't know if you guys got a chance to see this.
358400	359820	But it's pretty crazy.
359880	360640	I'll show you.
360640	362840	Wow, my computer is totally stuck.
364960	365920	This is awesome.
366160	372420	This is what's happening over there.
372420	373580	It's pretty exciting.
373580	375740	Right now, my computer is totally frozen.
375960	378400	So, I've got nothing.
378400	379800	Quite literally.
380140	381800	It's done.
382000	384900	I can't even terminate a window right now.
384900	385960	This is insane.
386560	388580	I've never seen this before.
389100	391060	This is the first time.
392860	396480	I just posted a link to your repo on this holiday.
396480	398220	Yeah, no.
398660	399100	You know what?
399100	401320	We might just try it again in a second.
402860	403980	Because everybody...
403980	407940	It's quite literally just absolutely frozen.
408320	412400	Even my task manager is locked out.
414460	416600	This is why we didn't do any logins.
416600	419880	So, anybody have any questions about how this works?
421720	426780	I'll give it another couple minutes before we bomb out completely.
427060	427940	Are you done?
428440	435430	I'm better.
435430	437890	I need to plug that in anyways.
438590	439910	Oh, in the office.
440570	443070	It's just next to where I was sitting. It's just a battery charger.
443070	444070	Battery charger, okay.
444070	446670	I'll be back.
446970	449530	Alright, looks like we're back.
451050	455950	And I will just close these windows down.
456170	457090	I apologize for that.
457090	459250	And it's locked.
459250	460210	Okay, so.
461170	463190	Alright, so I'm going to restart.
464910	467150	So, hello everyone. My name is Robert Ali.
468550	471410	We're going to edit that out, I'm sure, later.
471410	475350	So, if you guys are just joining us, I just had some computer problems.
475690	480670	I'm going to go ahead and talk about CMAP, my new car mapping tool.
480870	484870	And I'm just going to kind of give you a deep dive of how it works.
484870	486790	What we're doing with it.
486790	488690	What the goal of it is, as well.
488690	490710	So, I guess this is PyCharm.
490710	491970	I have PyCharm loaded.
491970	494130	And actually, I have the actual code itself.
494130	498830	So, if you're going to use this for the first time, there's some configurations that need to happen.
498990	501710	I've documented it a little bit on how it works.
501710	505630	But ultimately, the concept is pretty simple.
505630	512870	We're just going to send CAN bus messages out to different controllers to see if they're there.
512870	514290	Just kind of like a ping.
514870	516090	So, this is like a ping.
516470	519530	Also, with a service mapping tool, as well.
519530	521550	So, the first thing that we're going to do.
521550	523310	So, I'm going to go ahead and go online.
523570	525230	And in debug mode.
525870	529030	And you'll notice, as soon as it does that, it kind of goes into debug mode.
529030	530310	I'll show you the console.
530570	531450	And here we are.
531450	535990	The first thing we're going to do is we're going to create a CAN bus object.
535990	541890	So, this CAN bus object essentially tells me what CAN bus I want to connect to.
541890	545350	So, I can give it different object instantiations.
545370	548110	Maybe I'm not going to be working with CAN0.
548390	549950	But maybe I'm going to be working with other ones.
549950	552110	Sorry, I've got to plug my laptop in.
552110	553030	I can plug it in for you while you're talking.
553030	555090	I appreciate that. Thank you.
555090	565270	So, after you connect to CAN bus and it gets onto the network using CAN0 or whatever CAN interface you are going to want to search.
565270	567450	Maybe you can enumerate through multiple searches.
567850	569030	That's kind of up to you.
569030	576350	So, this first program here is called scan with class.
576350	580510	So, we're going to scan the network.
580510	590030	But this particular file is meant as an example for you to sort of create your own applications in Python using this program.
590030	592850	So, first thing we do, we create a CAN0.
592850	595430	And now CAN0 can do a lot of things.
595430	600530	So, CAN0 is essentially a network using the network CAN bus class.
600530	603830	And that particular class has a method called scan for IDs.
603990	606630	So, scan for IDs takes a few arguments.
606630	609010	And so, we'll go through those different arguments here.
609370	614210	One is the actual service identifier that we want to use to do our scan.
614570	619210	On a lot of different vehicles, you might have more success with different service IDs.
619210	623510	I have defaulted it to service 3E, which is something called tester present.
623510	626610	In theory, tester present shouldn't do any effects.
626610	628710	It shouldn't have any effects on the vehicle.
628710	630090	It shouldn't start the vehicle.
630090	630990	It shouldn't turn on lights.
630990	634230	It shouldn't do anything weird on the particular vehicle itself.
634230	636890	But sometimes certain controllers don't respond to it.
636890	639190	So, you might want to use a different service ID.
639250	643010	Maybe service 10 for initiate diagnostics or something like that.
643010	644950	So, there's a lot of different services you could use.
644950	646350	You could just use 0.
646510	647470	Whatever you like.
647470	652590	Maybe try different services to see what service IDs work better.
652590	654230	It's a single byte identifier.
654510	659190	If you put something larger than a single byte, it'll just bring it back down to a single byte.
659190	661250	So, just put in a single byte.
661510	664630	The next thing we have is the arbitration ID.
664750	668410	So, this is the actual identifier, 11-bit identifier that we're going to start at.
669050	673430	Since it's 11 bits, we can put any number between 0 and 7FF here.
674870	678110	Since this is a start one, we probably want to start it with a low number.
678110	680770	But you can start it with a high number and put a low number before.
680770	681770	It doesn't matter.
681910	684170	It'll just go in the order that you decide to.
684170	689050	So, if you put a number like 7FF and you put 0 as the end address,
689050	691310	then it'll just decrement as opposed to increment.
691310	692490	And I'll show you that later.
692490	694830	So, you can go in whatever order you like.
695330	702750	Sometimes, when I do my scans, I often do decrement because you'll find more things in the top area,
702750	705650	like 700s, 600s, as opposed to the bottom area.
705650	708410	So, you're probably going to have more success decrementing.
708410	710870	But it's up to you, whatever order you want to go in.
710870	714490	So, there's the start arbitration ID and the end arbitration ID.
714730	716370	I just accidentally skipped over one.
716370	717310	It's called try twice.
717310	719850	I'm going to get into what try twice is in a little bit.
720130	722770	And then, we'll also prompt wait time.
722770	726270	I'll get into some of these other parameters in a little bit when we hit them.
727210	728490	So, let's go ahead.
728490	733230	So, now we're in that particular method, specifically scan for IDs.
733510	736550	So, we just passed it a bunch of variables.
736550	740010	There are some others that we didn't pass that are just leaving as the default.
740030	741930	And I'll talk about those when we hit them.
741930	747270	So, as we go through, we're going to import the CAN bus Python.
747350	750390	So, these are some of the prerequisites you'll see when you get to the GitHub.
750510	751770	One is CAN.
752410	754150	Logging is something that's usually included.
754150	755610	And time is something that's usually included.
755610	760430	But you do need something called Python-CAN in order for you to...
760430	762690	you do a pip install in order for you to run this.
762690	764450	So, that's important as well.
765030	767250	Oops, what just happened?
767990	770450	You know, always something.
770450	771230	Isn't it?
772270	774150	Frozen bootstrap, I'm not sure.
774150	776010	Oops, I hit the wrong button.
776010	776750	Hopefully.
777670	778630	Of course.
779010	781910	Let me just restart the debugger real quick.
783430	785070	Sitting too long on something.
785070	786710	I think it probably crashed.
789690	790710	Okay.
790750	791550	So, here we are.
791550	796850	So, now here's our input timeout that we're going to use a little bit later.
796850	798970	I'm going to initialize something called common pairs.
798970	799950	I won't get into too much.
799950	804350	I'm just going to go through the more interesting things such as this.
804350	808850	So, the first thing I'll do with CMAP is I'll listen to the bus.
808850	810850	The reason why I do that, there's two reasons.
810850	818050	One, if you have a non-active bus that maybe you have a misconfiguration with how you connect it to the vehicle network,
818050	819970	I want you to at least be aware of it.
819970	821790	Maybe there's no traffic on it.
821790	827770	In fact, that's what we're going to see here on our particular vehicle is there's no traffic on that particular bus.
827770	830970	But it's not because the vehicle's off or there's no traffic.
831370	833190	There's just no traffic normally.
833370	835350	The reason why is we have a gateway.
835350	839650	A lot of these vehicles nowadays, especially if we're connecting to the OBD2 port, have a gateway.
839650	840970	And this particular vehicle does.
840970	842970	But don't let that discourage you.
842970	846950	We're using diagnostics and these diagnostic ports are intended for that.
846950	851590	So all of this stuff will still pass quite nicely through a diagnostic connector.
851590	854510	So even if there is a gateway, it shouldn't matter.
854510	856250	Now, it might matter a little bit.
856250	860950	Some gateways do filter some information as it's going across the back.
861510	864530	So you might want to try it on the other side of a gateway too.
864530	872070	But I just want to give you guys an example of, yeah, you can actually do this on what's called the dirty side of a gateway if you want to.
872070	874430	So I'm going to initiate a time thing.
874430	878710	And then essentially what this will do is it'll sit there and listen to the bus.
878710	884810	And if there is no traffic, it'll just warn you, hey, do you really want to continue or not?
885630	892930	And if there is traffic, it'll create a list of IDs for later.
892930	904410	The reason why we want to know those IDs of what is on the bus is because we want to essentially avoid those identifiers later when we're actually transmitting requests.
905170	910090	To scan the bus because those identifiers are not the identifiers we want.
910090	915530	You can almost say that any traffic that's normally on the bus is not something you want to transmit on.
915530	919350	In fact, if we do transmit on it, that can cause problems.
919350	921670	You get lights and other things coming up on your dash.
921670	923550	That's something we're going to try to avoid.
923550	929270	So just be aware that we do intentionally filter out normal traffic.
929270	936190	If you don't want to do that, you can modify this particular class to skip this step if you'd like to.
936190	937790	You don't have to do this particular thing.
937790	946450	But I think it saves a lot of time and it avoids a lot of accidentally overriding messages that we know are not part of our scan.
946450	948370	So that's what I'm going to do here.
948970	953410	And after about two seconds or so, I have this sort of timeout after two seconds.
953410	960730	It says, hey, I wasn't able to... you'll see that my normal message length is actually going to be at zero.
960990	966830	So this is going to say, okay, for sure we need to just sort of warn the user.
966830	969330	And that's what we're going to see here, that there was a problem.
969330	971550	I'm going to go ahead and just jump past that.
972290	974510	So to warn the user, would you like to continue?
974510	977650	I gave a little command prompt and I have a timeout in there.
977650	979150	It's about two seconds or so.
979290	981370	Okay, cool. Let's move on.
981530	983150	So what's our message length?
983150	989610	Here we have a message length and just some other initialization that's happening of our payload that we're going to send out, etc.
989610	993230	I won't get in too much, but here we'll go down to the pairs list.
993530	995150	And we initialize everything.
995150	1008690	And then, of course, if the bus is quiet, one of the challenges with the Python CAN interface is if we're going to listen to the bus and it was quiet, it doesn't let us just sort of timeout.
1008690	1009930	It's got a kind of a weird bug.
1009930	1015650	So in order to get around that bug, I actually do create some noise on the network just to...
1015650	1022130	I have to create some CAN messages just to allow me to receive CAN messages.
1022130	1024950	It's kind of a weird bug that I found. I haven't found a way around.
1024950	1027670	So if anybody knows a way around it, I'd like to hear it.
1027670	1032010	I create some noise here on the CAN bus just so we can get around that.
1032750	1035490	Let's just take a look at the CAN bus real quick here.
1036470	1040170	Go into the device.
1040570	1044390	And so we should be able to do a CAN dump on CAN 0.
1045350	1048730	And there's our noise that's going across real quick.
1049370	1056130	Essentially I'm sending 7FF with a very specific payload that I've initialized earlier.
1056150	1059050	So there's our noise. I just want you to know it's there.
1059570	1063830	I'm actually going to get rid of the noise when we do monitor this CAN bus later.
1063830	1068710	I don't want to see it, so I'll actually just tell it to remove the noise.
1068710	1071650	And you can do that by just creating a negative filter or a not filter.
1072210	1075670	Just a comma 7FF tilde 7FF.
1075670	1079910	And now anything that has the identifier 7FF will be gone.
1079910	1080650	So there we have...
1081610	1085330	Now if I was monitoring the CAN bus, we shouldn't see anything.
1085330	1087170	Now it looks like some people are doing some scans.
1087170	1089530	Again, this is a live network right now.
1089530	1094450	So if anybody's on the network, they will actually be able to see it
1094450	1098270	because people are currently hacking this bus as we speak.
1098270	1102570	So it's kind of cool to see other people working on it as we are as well.
1102650	1105090	And they're going to love us in a little bit.
1105610	1111210	So what I'm going to do is I'm going to send a bunch of CAN IDs.
1111210	1116090	So I have essentially our low range, our low number, our high number,
1116090	1117970	and the direction that we're going to scan.
1117970	1119490	So plus 1, negative 1.
1119490	1124770	Essentially I can skip over IDs if I would like to here, but it's kind of up to me.
1124790	1127550	So here we're going to go and we're going to set this up.
1128270	1131790	All right, here's our arbitration ID.
1131790	1134530	Is it part of our normal messages that we had before?
1134530	1137310	In other words, do I need to skip this ID or not?
1137890	1140790	Because if we were monitoring the CAN bus earlier and we noticed,
1140790	1145810	hey, ID 222 is on the bus and I'm about to send 222, I'll skip over that one.
1145810	1149550	That way we don't have to collide with those particular messages.
1149550	1152470	So it's sort of an anti-collision way of doing it.
1152470	1154850	Now since we didn't have any normal messages on the bus,
1154850	1157490	our normal mode message is gone.
1157490	1159470	It's empty, which is cool.
1159830	1164490	So we'll move on to the next step.
1164650	1168590	In this case, we're going to set up our CAN frame, initialize some things,
1168590	1172550	and then we'll do this thing where we check how many tries
1172550	1176470	or set the amount of tries that we want each time to run.
1176470	1179690	So I'll take a look. Let's take a look real quick at what that means.
1179750	1184610	One of the challenges, especially if we're doing this on a busy and active bus,
1185450	1188330	we're going to send out a command and then we're going to listen
1188330	1191830	for some period of time for responses.
1191830	1194230	Now what is a response? It's just another message.
1194850	1198750	So all of these messages that might be going on on the bus at that particular time
1199130	1202650	could all be replies. So how do we differentiate them?
1203050	1206670	Well, number one, we have this normal message list that we listen to
1206670	1209230	and we can say, hey, is this in the message list or not?
1209230	1211970	The other thing we can do is we can try it multiple times.
1211970	1217310	And if we get the same ID two times, the probability is much greater
1217310	1219430	that this is actually a reply to our message.
1219430	1223170	So I have this ability. I built in this thing so you can actually have it either
1223790	1227130	send it one time or two times. Since this is a quiet bus,
1227130	1230670	we really don't need to do that. Send multiple tries.
1230670	1234950	And again, if you send multiple tries, you're going to send it twice,
1234950	1237950	which means it's going to take twice as long to do a scan.
1237950	1240690	So if you can limit the amount of tries, that's good.
1240690	1245510	So here we are. We set our tries to one, so it's only going to try it one time.
1245510	1249630	I have some logging here. Here we are recreating our CAN bus.
1250670	1253370	And I have a time here. So I want to sort of stop here
1253370	1257370	because this is super time dependent and just go over what I'm about to do.
1257430	1261090	What I'm going to do here at this particular step is I'm going to send
1261090	1264230	this message that I created earlier. If you want to take a look,
1264230	1269550	this message is pretty simple. It's got the identifier 442,
1269550	1275090	so that's where we start. It's got the data bytes 023E,
1275090	1278290	and then the rest are zero. The reason why we're sending zeros
1278290	1280150	is because we need to make sure we pad this data.
1280150	1284750	So essentially, remember I said service 3E is the thing that I'm going to send out?
1284750	1289590	That's in the data bytes themselves. You see it's the second data byte there.
1289590	1293510	So there we are. We're going to send 023E out onto the bus.
1293510	1296870	And if I bring this over, eventually we'll see that come across.
1296870	1298830	So I'm going to do that in just a second.
1299210	1301550	And then what we're going to do is we're going to say,
1301550	1306030	all right, I sent out a request. Then we're going to wait on that particular bus.
1306030	1307830	We're going to wait for a receive message.
1307830	1310350	And that's the reason why I have some noise there,
1310350	1313610	because we have to generate some messages so that our clock
1313610	1315490	or our timing essentially works.
1316150	1318630	So we're going to wait for a receive message,
1318630	1323490	and then we're going to take a look and inspect that receive message.
1324210	1325670	We're going to filter it out.
1325670	1329810	A few things. Is that a receive message that we've already seen before?
1329950	1331970	All right. Well, I don't want to see that anymore.
1332010	1333910	That's not the message that I was looking for.
1333910	1337130	I'm looking for new identifiers, not old identifiers.
1337130	1339550	So in other words, I'm sending out a request.
1339830	1344230	I should not see this identifier or should not have seen it in the past before.
1344230	1346310	So I'm looking for new IDs.
1346550	1349650	Is this ID the same ID that I just sent out?
1349650	1351850	Maybe I just was listening to my own data bus,
1351850	1353930	and I saw an ID that I just sent out.
1353930	1355430	So I don't know. That's not what I want.
1355630	1360050	If I'm sending noise, is this the noise identifier payload that I just sent out?
1360050	1362250	If it is, ignore that as well.
1363050	1365930	Or is this ID got a DLC that's...
1366630	1373110	One of the challenges with SocketCAN is that the way it displays error frames
1373110	1376870	is using ID 000 with a DLC of 4,
1376870	1379830	which is just kind of a dead giveaway that this is an error frame.
1379830	1382030	It's really the only way to know if it's an error frame.
1382030	1383410	So is this also an error frame?
1383930	1385390	Is this an error noise on the bus as well?
1385390	1387310	So I'm filtering out all those other things.
1387310	1389910	And then what we're left with should be,
1389910	1393730	if it passes all of those because they're not true,
1393730	1398470	then we should say, OK, that is indeed a successful arbitration ID.
1398470	1401470	And so we will append our list right here.
1401470	1403570	So let me go ahead and just run this real quick.
1403610	1409090	And then I'll show you what it kind of looks like on the bus as we're going across.
1409430	1411050	So there it is running. Oops.
1411050	1413390	We caught our first one. That's not a coincidence.
1413930	1414650	It started there.
1414690	1417310	So we caught our first identifier right there.
1418030	1419510	Just a second. Oops.
1419510	1420770	Try a second.
1421050	1422110	How do I get rid of that one?
1422110	1424510	No, we haven't caught one yet, but we'll catch one real soon.
1424510	1428210	Let me get rid of some of these breakpoints so we can just see it run.
1428310	1430510	And there it goes. It's running. It's running. It's running.
1430510	1436010	And then pretty soon we're going to get a message.
1436010	1438670	Cool. So we got our first message.
1438670	1439970	Actually, here, let me...
1439970	1441730	Oops. Messed up over here.
1443110	1443830	Let me...
1447990	1449210	Zoom in here.
1449230	1451830	So let me just sort of emphasize what just happened here.
1451830	1457010	So here I sent out this CAN message, 47D.
1457010	1458670	Didn't see anything come across.
1458670	1460650	And the same for all these other ones before.
1460670	1463410	But then I sent out CAN message 47E.
1463710	1464930	Sent out the same message.
1464930	1467810	And then what happened was I got a response.
1467930	1469390	How do I know it was a response?
1469390	1471910	Well, first of all, I've never seen this ID before.
1472150	1473870	That was one reason.
1474430	1475750	I didn't transmit this ID.
1475870	1477250	This wasn't something that I transmitted.
1477250	1480030	I know it's the next number here in this list.
1480030	1482270	But also it's interesting to look at the data bytes.
1482270	1483250	It's a little bit different.
1483250	1485990	It's not a 3E here. It's a 7E.
1485990	1487870	Now, I don't really care what the data bytes are.
1487870	1489830	I could do some more data byte inspection.
1489950	1492070	But for the most part, you don't really have to.
1492070	1495910	You just need to see an identifier that you didn't send on the bus.
1495910	1497730	If you did send it, then, well, you can ignore it.
1497730	1500070	But if you didn't send it, in this case, I didn't send this.
1500070	1501450	It's just something that I received.
1501750	1502530	Oh, good.
1504350	1505390	This is called a pair.
1505490	1507670	So we add this to our pairs list.
1507670	1508890	Now, I have two pairs lists.
1508890	1512310	If I'm trying twice, I'll compare the two pairs lists.
1512310	1513890	In this case, we're not trying twice.
1513890	1515750	We just get the one pair list.
1515750	1518390	So a pair is essentially these two identifiers.
1518510	1522090	A pair is the identifier 47E and 47F.
1522390	1526590	Those pairs are essentially how we can communicate directly with the controller.
1526590	1531250	If we send the ID 47E, we'll get a response back on 47F.
1531250	1534330	So this is kind of the channel, if you will.
1534330	1535370	This is an RF thing.
1535370	1537130	I kind of think about these as the same thing.
1537130	1540850	This is the channel that we send out on, and it's a different channel that we receive on.
1540850	1542330	It's the best way to look at that.
1542330	1543770	And then the data bytes are right here.
1543770	1548150	So anytime I send out a message on 47E, 47F will respond to me.
1548310	1549850	So let's keep going.
1549890	1550870	Let's keep going.
1550870	1552430	Let's just do this.
1553170	1556450	And I don't really care about hitting more pairs.
1556450	1559210	I'm just going to let it go until we get a response.
1566520	1567340	It should be going.
1567340	1567880	Sorry.
1567880	1569040	Okay.
1569240	1571700	So it's going, and it's going to catch a few more.
1572620	1573860	As you'll see.
1574420	1576800	I just realized I need to open up another window.
1577620	1578560	One second.
1601750	1603270	So I'm just going to let it keep running.
1603270	1604990	It'll eventually catch a few more.
1605050	1607750	It's loading up our list, and I'm just letting it run.
1607750	1615040	So just give me one second while I find something.
1615040	1616200	Yeah.
1617280	1622700	One part of debugging is there's no way to hit the escape or whatever.
1622700	1625280	So I've got to do it kind of programmatically.
1625280	1627500	It's an interesting problem that I have to do.
1628220	1628660	So...
1628660	1629840	Boo, boo, boo.
1649760	1650640	Okay.
1651520	1651960	All right.
1651960	1653480	So we finished our scan.
1655100	1657020	And what do we got here?
1657720	1659520	So let's take a look at what happened.
1659520	1661620	So what returns is our pairs list.
1661620	1663120	So let me just open up our debugger.
1663120	1664820	And we'll actually take a look at...
1664820	1666520	We'll watch some of this data.
1666520	1669880	So just one second while I scroll over.
1669880	1671240	Take a look at my watch list.
1671240	1672440	I'll have it open.
1685930	1688190	Just one second while I move this around.
1692710	1694670	Where are you variables?
1708460	1710760	I had them open just two seconds ago.
1711780	1713140	And I lost them.
1733270	1734050	All right.
1734050	1736190	Well, anyways, here's the pairs list.
1736210	1738050	I was going to just open it up for you.
1738050	1739790	But the easiest way to just...
1740930	1742530	So here's the pairs list.
1742610	1744950	Now, what we'll see here is actually...
1744950	1745930	It's hard to tell.
1745930	1747890	But these are all in decimal right now.
1747890	1750810	But if we wanted to, we could see in hex.
1752450	1753030	Sort of.
1753030	1753810	Here's a pair.
1754250	1755850	That's our first one that we grabbed.
1756290	1757610	47E, 47F.
1757610	1758690	So there we have a pair.
1758690	1760330	And then we have a few more here as well.
1760330	1763510	And then you have one that actually has a bunch of different pairs in it.
1763510	1772790	And the reason why we see something like this is you'll look that all of the different IDs are the same values across all of them.
1772790	1774830	And the reason why is this is called...
1775470	1776690	This particular identifier...
1777910	1779350	So I'll show you here.
1779750	1782990	7DF has multiple different controllers that respond to it.
1782990	1786270	It's called a functional request.
1786270	1791330	So every time we send that particular type of request out, we get multiple responses back.
1791330	1793810	So that's good to know about the functional request.
1793810	1795450	So the functional request will have...
1795450	1799090	The pair itself will be just a list of pairs, essentially.
1799090	1802250	So that's why you'll notice that these lists are actually lists of lists.
1802430	1805230	And most of the time, there's just a single pair inside of there.
1805230	1807470	But in this case, there's multiple pairs.
1807470	1809150	So now we've got a list of pairs.
1809150	1809990	That's great.
1810050	1811870	Now we can do something with that.
1811870	1813210	We have a list.
1813210	1814390	Basically, you do a ping.
1814390	1820790	You check out and see all the different IP addresses that you've got on the network.
1820790	1822690	Same thing. That's exactly what we just did.
1822690	1824290	A scan is kind of a ping.
1824370	1828010	We get a ping for all the different identifiers.
1828010	1830470	And now we've got a list that we can do something with.
1830650	1834470	So inside of this CAN0 has nodes.
1834470	1837810	And those nodes are essentially the pair list that we had before.
1838110	1842250	So now what we can do is just pull out the pairs inside of the pair node.
1843210	1846490	So here we're going to go ahead and take apart that particular one.
1846490	1848610	We're just going to grab the first pair.
1848770	1853790	If it's a list of multiple pairs like we had that I just showed you, I'm just going to kind of ignore that.
1853950	1858030	If you have a script and you want to do a little bit more with that, feel free to do that.
1858030	1860810	And then I'll just go ahead and print it out so we can kind of see.
1860810	1863070	Here it is, our 47E, 47F.
1863130	1868410	Just let us know, hey, we're going to do some work with that particular pair.
1868550	1871730	So let's take a look and see what we're doing next.
1871730	1876650	So we're going to do another thing.
1876650	1879490	Actually, I'm going to skip over the initiation of that particular one.
1879490	1883030	And then go right to the actual method that is interesting for me.
1883030	1885070	And that's the findServices method.
1885110	1886710	Now we have the identifiers.
1886710	1889010	Now what services can we do?
1889010	1890850	So we've done the ping.
1890850	1892710	Now let's do a port scan.
1892710	1894570	That's kind of the best way to describe this.
1894570	1896530	So findServices is going to do a port scan.
1896530	1900570	It's going to see what services or functions the particular controller supports.
1900570	1902330	So let's go ahead and run into that.
1903210	1910390	And the first thing we're going to do is initialize a list of known services in case we want to filter on just known services.
1910430	1912850	And that's kind of what I want to do in a little bit.
1912850	1915930	So we have a few different options here.
1915930	1924010	We can actually filter our list just to try to do a sweep of every single possible service identifier.
1924010	1928310	Which is only 256 possible service identifiers.
1928310	1934370	Or we can just skip service identifiers that are potentially valid.
1934370	1940330	So half of the service identifiers are reserved for response only, not for transmit.
1940330	1946310	So if you're going to get data back from the controller, half of them are reserved for that function as well.
1946310	1949750	So we can say, hey, I just want to work on ones that are valid.
1949750	1952610	Essentially skip the response-only service identifiers.
1952610	1956730	Or we can skip and just scan the ones that are known.
1956730	1961330	So we're just scanning known service identifiers as opposed to unknown ones.
1961330	1964010	And so that's what I've initialized as true here.
1964010	1967630	So we're going to use this list that we have right here.
1967630	1970090	And that's the list of identifiers that we want to go over.
1970090	1974710	Now depending on what type of service scan you want to do, maybe you want to do a more inclusive one.
1974710	1975750	So you'll scan everything.
1975750	1981270	Maybe you want to do a non-inclusive one like this where we just scan the UDS ID.
1981270	1983030	So I give you like three different options.
1983030	1987930	You can scan everything, a little bit of everything, or like half of everything, or just a small amount of everything.
1987950	1992950	So it's just the amount of time you want to spend on doing that.
1992950	1994230	It's kind of the trade-off.
1996650	2000870	So if we've already done the scan once, hey, let's not do it again.
2001330	2006970	Let's just return the container that we store all of the services that that particular node supports.
2007110	2010250	In this case, we haven't done it yet, so that's good.
2010250	2014370	So the other thing that we require is something called ISOTP.
2014830	2020050	I think it's called CAN-ISOTP, if that's the module name.
2020050	2022370	So we're going to have to use that one as well.
2022370	2029630	So go ahead and take a look, try to find CAN-ISOTP on the internets so that you can use this as well.
2030030	2031810	And I'll just keep going.
2031810	2033430	ISOTP is great.
2033430	2045210	ISOTP is essentially the diagnostic layer 2, if you will, the transport layer for CAN bus diagnostics.
2045210	2048250	And it's awesome because there's already a thing for it.
2048250	2055990	So let's go ahead and create the socket, set the padding options so that we can fill in the data bytes,
2055990	2062050	bind that socket, and then we can say, all right, if the service ID is sort of like limit the service ID,
2062050	2064810	so I'm going to skip over some of this stuff. It's pretty self-explanatory.
2064810	2068930	Let's go right into the meat of the actual script. What is it actually doing?
2069490	2070910	So we're going to create a range.
2070910	2073970	So inside of this range, we have two service IDs that we set.
2073970	2076610	One is the start service ID. Where do you want to begin?
2076610	2079110	One is the end service ID. Where do you want to end?
2079110	2083010	Again, if we apply some filters, it's going to skip over that.
2083010	2089370	So typically what I'll say is if you want to grab a small amount, turn on a filter.
2089370	2093430	But if you know there's just a service ID, maybe you want to target one or two service IDs,
2093430	2097550	then you can limit your range to what service IDs you're going to go after.
2097550	2102830	Again, service IDs are only one byte, so really there's only going to be 256 options here.
2102830	2105590	So let's go ahead and see what we want to do.
2105590	2110210	We just grabbed an identifier and a range.
2110570	2114670	And we want to... so I'll look at zero.
2114670	2117630	Hey, do I want to scan this zero ID or not?
2117630	2123790	Since I have a filter turned on, scan only service IDs, I say yes.
2123790	2128150	It's only going to scan a service ID that's in my list.
2128150	2129950	In this case, zero isn't in my list.
2129950	2131950	So it's just going to skip right over it.
2131950	2134190	It's going to continue saying, no, I don't want to do that.
2134190	2138410	So let's go to one where there actually is a service ID I'm interested in.
2138410	2145430	So in this case, the service ID, the first one is going to be ID 16 decimal or 10 in hexadecimal.
2145430	2154030	So service ID 10 is the first service of UDS, which is the session control service.
2154450	2157970	So let's take a look and go through here.
2157970	2164930	And we're going to add to it payload length, do some fun math here.
2164930	2169750	And then we're going to go down to the actual loop.
2169750	2172690	So we send our ID out.
2172690	2174730	Let's see if I already sent it. I did.
2174950	2178030	So here we go. We sent out a request.
2178430	2181590	10-0-0-0-3-10-0-0.
2181590	2184010	And look, we got a response back.
2184010	2187350	0-3-7-F-10-12.
2187970	2189910	So don't worry about what that means.
2189910	2191970	I'll do all the parsing for you.
2192650	2194190	Well, displaying for you.
2194190	2199110	And I'll just sort of say, all right, since this is a 10-12,
2199110	2201510	12 is what's called the negative response code.
2201790	2203570	This is an error frame.
2203570	2206910	This is like error. Hey, you have a problem with your request.
2207470	2210010	And here's the response.
2210010	2212170	And 12 is the negative response code.
2212310	2217070	And what it's trying to tell you is, hey, we have an issue with that request.
2217070	2224210	And the particular issue in this case, 12, means that the sub-function, 0-0 in this case, is not supported.
2224650	2228750	What we're trying to do with the service scan is not see if the sub-function is supported or not.
2228750	2230590	We want to see if the service is supported.
2230590	2232970	Because we're going to probe to see if the service is supported.
2233070	2235830	So ultimately, 12 is a good thing.
2235830	2237950	So we're going to go down here.
2237950	2239450	And I'm going to go run.
2239490	2242090	And we're going to take a look at how that logic works.
2242090	2243810	Hey, we received something.
2243830	2245030	We got an ID.
2245030	2249850	We got a negative response code, which is 7F, which we saw here.
2249850	2252610	And the service identifier here, 7F.
2253690	2255910	I see negative response code.
2255910	2262950	We're going to pull that out and say, hey, negative response code came back as 12 hex or 18 decimal.
2262950	2264570	Is that equal to 11?
2264570	2265670	Why 11?
2265670	2271390	Well, 11 is actually the negative response code for a service not supported.
2271390	2273070	That's specifically what it means.
2273070	2278070	So since this is a service that is supported, I don't really want to have that in my supported...
2278690	2280850	I don't want to have this in my not supported list.
2280850	2282390	I want to have that in my supported list.
2282390	2284810	So I'm going to create two lists here.
2285630	2287370	Or two sets, I should say.
2287370	2293350	Two sets that we can sort of just...
2293350	2294410	Hey, there's our service ID.
2294410	2296470	I'm going to add this supported one to it.
2296470	2299050	Even though I got a negative response, that's not terminal.
2299050	2301790	It just means that the sub-function that I request isn't supported.
2301790	2303910	But the service itself is actually supported.
2303910	2304970	So there we go.
2304970	2306330	Our service is supported.
2306810	2308390	And I added that to my list.
2308390	2311090	I'm just going to go through all of them real quick.
2311090	2312590	It doesn't take very long.
2312690	2317430	And we're going to take a look and see what that kind of looks like here.
2319990	2323910	So I'm going to get rid of some of these breakpoints.
2324950	2325850	And there we go.
2325850	2327190	We kind of got the entire list.
2327190	2327990	That was really fast.
2327990	2330770	So it doesn't take very long to go through that list.
2332030	2333590	Maybe we already did it.
2333590	2334790	Yeah, it went really fast.
2334790	2336310	Sorry, you guys might not have caught it.
2336310	2337650	But it didn't take very long.
2337650	2339970	It went through the entire list really quickly.
2340290	2347590	And we got a list of all of the services that were particularly supported on that particular one controller.
2347590	2349270	Now we just went through one controller.
2349270	2350890	And that's what we're going to do at a time.
2350890	2352010	Single controller.
2352770	2354670	And we're going to try...
2354670	2356490	Now that we have that list,
2357990	2359510	we're going to print it out and see what happens.
2359510	2361270	So what are we going to do?
2361270	2365270	We're going to print out a list of all of the different services that are supported.
2365270	2374630	In this case, 22, 85, 27, 28, 2E, 10, 11, 14, 36, 34, 37, 19, 3E.
2374630	2376730	Those are all the services that are supported.
2376730	2380030	Now if you want a good list of what these functions mean,
2380030	2383010	I actually have that as a enumerated...
2383010	2386650	I have created an enumerated list for all the particular services
2386650	2388230	and what they mean inside of this.
2388230	2390030	So you can actually reference it.
2390090	2391670	I forgot where I put it.
2391670	2394250	So give me a second here while I dig it up.
2394250	2395650	I think I called it...
2396250	2398310	Yeah, it's under service. Makes sense.
2398310	2399490	Good spot for it.
2399690	2402790	And I collapsed it here.
2402790	2408030	But yeah, I have a service description that you can run.
2408310	2410970	And there's a method called update service description.
2410970	2414850	And there's a property of every service.
2414850	2416630	So if you want to, you can enumerate a list.
2416650	2423510	And just read out the service description from each of these services as well.
2423510	2427330	There's also a list inside of here which I've collapsed because it's so big.
2427530	2429150	I don't know where I put it.
2429150	2430770	But I won't go into too much detail.
2430770	2432750	But it's in there in the code itself.
2432750	2436190	Feel free to take a look if you want to see what those service identifiers mean.
2436190	2437250	But we can take a look.
2437250	2440970	And there's just a handful that are really unique and interesting
2441890	2444710	that we'll probably want to scan later.
2444710	2447290	So we'll go ahead and take one of the services.
2447290	2450170	I think the first one we're going to take is actually service 22.
2450170	2451730	Because that's our first on the list.
2451750	2456190	Which is kind of a bummer because that's the biggest of all the services.
2456210	2459510	But let's go ahead and take a look at what it is we're actually doing here.
2459510	2463070	So I'm going to create a little report for you after it's done.
2463190	2467750	A list of all of the different service functions that are there.
2467750	2472190	And I just want to kind of send out the service and see what's happening.
2472190	2473990	So give me a second while I run it.
2474930	2479390	So the next method we're going to do is now we have a list of all the services that are supported.
2479450	2484250	Let's enumerate all of the particular service sub-functions that are also in there.
2484250	2486590	So the first thing we did was ping all of them.
2486590	2490970	Next we did was check the services that are supported.
2490970	2495270	Now we're going to actually ask it to say, hey, what sub-functions are actually supported?
2495790	2497990	I'm going to run that real quick here.
2500050	2501310	Just one second.
2501310	2505230	I don't want to get in too much right now because we're running out of time.
2505390	2507070	But this one's pretty cool.
2507090	2510430	So let's take a look and see what it is it's doing here.
2510430	2513950	So what it's doing is it's sending out a request.
2516630	2520750	0322 0091 0092 0093.
2520750	2526830	You get the idea. It's just enumerating all possible identifiers or sub-functions for this particular service.
2526830	2530830	In this case, this is a two bytes service, so it does it for you automatically.
2530830	2532070	You don't have to tell it.
2532190	2536210	That's part of the specification, how many bytes each particular service supports.
2536210	2541250	So we're just going to enumerate through a list of all possible sub-functions that are supported.
2541970	2547790	And eventually, when we're done, we're going to get a good list of all of the IDs that come through.
2547790	2555450	Now, I did have a plan here on canceling this scan midway through
2555450	2560710	so that we could get a list, but unfortunately, this particular service doesn't allow us to do that.
2560710	2564290	So what I'm going to do is I'm going to go to a diff.
2564290	2567170	I'm going to figure out how to exclude.
2567470	2570690	Let me just think about how I can exclude a particular service ID.
2571690	2572910	Maybe I can't.
2572910	2577130	What I really want to do is, let me just look it up real quick while we hang it out.
2577130	2579190	I'm going to check out the scan real quick.
2579190	2590210	And I'm going to see what this particular... I need to issue a keyboard halt error.
2590210	2592510	And that will break out of it.
2630800	2634120	So, just one second, I'm going to...
2634880	2637120	So there's a really cool utility called...
2638460	2640300	Oops, sorry.
2643920	2645540	Called psutil.
2645540	2648520	So I opened up another Python window.
2648520	2655340	We use psutil, which allows me to send a SIGINT to a process.
2655640	2659440	So we need to do a SIGINT and then it's called process.
2659560	2674280	And then the process ID, which is pit equals 9971.signal.signal.
2674280	2675240	I think it's two.
2677740	2678620	Network.
2679260	2680140	Oops.
2681340	2682700	Send signal, sorry.
2687330	2690730	And what that did is, it did a keyboard halt.
2690730	2693030	So it's a good way to do debugging.
2693030	2699410	It's just essentially, I'd have a try, catch, try, not catch, but try command.
2699410	2701670	So here it is. It tried to...
2701670	2704490	It actually ended that particular scan.
2704490	2709650	So that, just for demonstration purposes, I wanted to show you what kind of report we were able to get out of that.
2709650	2713910	And there you can kind of see, here's a list of all the identifiers.
2714810	2718850	This is service 22 on this particular node, 747F.
2718850	2721250	I don't know what node that is in the vehicle yet.
2721290	2724070	Maybe I can get that from doing my service scan.
2724690	2728870	But here it is. We have a list of parameter IDs.
2728870	2733050	So this is sort of a matrix of 00, 010, etc.
2733070	2739630	And so as we scroll down, you can kind of see, hey, this is a service that has a negative response code of 31.
2739650	2745650	So 31 means that the request that I sent is out of range.
2745650	2751630	So I sent an ID 0000 to it, and it says it doesn't support that.
2751630	2754930	But where it shines is we can actually see what is supported.
2754930	2759810	In this case, 0108 is supported.
2759810	2766350	So if I scroll down and keep scrolling, you'll eventually see that some of these services are indeed supported.
2766350	2770470	So we create a cool map of the services that are actually supported.
2770530	2774370	And here we have a longer list. We can kind of get an idea.
2774370	2779650	And not only that, we see the services that are supported, but I also, after I'm done printing the report,
2779650	2784410	I'll also print the actual data bytes that I received from the service itself.
2784410	2790590	So in the case of 0001, I got these data bytes.
2790590	2794410	This is a byte string that returned back to me.
2794410	2797090	So I can get a byte string of the actual data itself.
2797090	2800790	Maybe there's some interesting information that's stored inside of the byte string.
2801290	2804990	What I can do later with this list is I can say, OK, now that I have a list,
2804990	2809690	I can go back and just kind of recapture the data over and over and over again.
2809930	2812370	And so that's the idea. That's what CMAV does.
2812370	2816010	It gives you kind of a cool list. I'm going to keep it running.
2816950	2817910	Oops.
2821190	2826990	Keep it running so we can actually get some other sub-functions or services that might come up.
2826990	2831370	Some of the other services are much faster, so I'll let them run real quick.
2831510	2832770	Here's another one.
2833070	2837210	And pretty quickly get rid of all our debug information.
2837310	2843410	And I'll scroll down. Here's service 85 and all the different sub-functions it responded back to.
2843410	2849290	So it might not be that interesting. Maybe we'll get a 12, which means sub-function not supported.
2849350	2853930	But in some cases, we don't get a 12. We get a 7F, which is incorrect.
2854070	2860430	We can do this function or the sub-function, but not in this particular service or session.
2860430	2862070	So we have to change our session.
2863210	2865250	And what sessions are available?
2865250	2869150	Well, there's another report that's going to come up later on what sessions are supported.
2869150	2870710	So we can keep scrolling through.
2870710	2878230	And as we're running through all of these things, we can kind of say, hey, look, service 28, what's unique about all of them?
2878250	2880330	Or what's not unique about them?
2880330	2885910	So here we are. We're continuing to run. We're on service 2E right now.
2886010	2894010	Same with service 22. 2E is a very long one, so I'll issue another reset command as well.
2894390	2898770	So we'll kind of speed this up a little bit, but you don't have to reset every time.
2898770	2900370	Here we are.
2900630	2907370	Oh, sometimes it'll get a little stopped up here. This is kind of a bug that I know I'm going to try to fix in the next revision.
2907790	2914350	But if I don't get a response back from a particular controller, it sits there and waits for this 5 or 10 second timeout.
2914350	2918290	And I really should just limit the timeout. I thought I was doing it, but it's not working right now.
2918290	2922950	So this is something that is a known bug, but sometimes we'll get these no responses.
2923210	2926670	And this is actually a correct no response. It shouldn't respond back to us.
2926670	2932090	That particular one doesn't. So we'll wait for it. There it is. There's our service 10.
2932110	2936010	It responds back that it supports these particular sub-functions.
2936010	2940350	So I was just talking about modes before. There are actually three modes that it supports.
2941250	2945850	10.01, 10.02, and 10.03. It supports all three of them.
2945850	2949410	You'll notice that this is negative response code 12, which means it doesn't support it.
2949410	2953930	But in this case, it does support. Service 10.01 is supported.
2953930	2958610	10.02 is also supported, but it has a negative response code of 33,
2958610	2962050	which means that you need security access first in order to do this one.
2962050	2966790	So as a security researcher, you may be really interested, why do I need security access to do a 10.02?
2966790	2972150	If you do a little bit more digging on this particular service or sub-function,
2972150	2979630	this is the reprogramming mode. So it wants you to do security access in order to reflash the controller.
2979630	2982970	This is actually very unusual. Most cars don't require this.
2982970	2986150	But it's something that's new for these particular vehicles.
2986550	2993550	Service 11 is an ECU reset service. If this had succeeded, we would have had some issues probably through here.
2993550	2996070	The controller would have reset and taken a very long time.
2996070	3000950	Don't know why these all fail. Maybe it doesn't have a sub-function, and that might be why.
3001130	3007450	Service 14, similarly, quite interesting. Service 34, all of these need to be in a different sub-function.
3007450	3016010	So we get a lot of really cool information just from the get-go of what may or may not be supported on these particular controllers.
3016150	3021050	Including what is supported and what gives us a little bit of an empty spot.
3021050	3024930	It means I didn't get a response back, so I don't know what to tell you. It's empty.
3024970	3026910	So you get a lot of really cool information.
3026910	3031230	If you run these for a very long time across all the different controllers,
3031230	3034330	you're going to get a ton of information from the particular vehicle.
3034490	3036370	And then maybe you can save it and do something.
3036370	3040970	So I finished with one controller, and now I would move to the next one.
3040970	3045910	So that's essentially what this is telling me it wants to do, is go to the next controller, etc., etc.,
3045910	3049470	and find all the services and sub-functions on that.
3049490	3051370	So I'm going to do that real quick.
3051410	3056070	We're kind of running out of time, but I'd like to try to see what else we can get out of it.
3056130	3061010	There it is, trying to get data from these controllers.
3061010	3063390	Scroll down... it's really quite interesting.
3063390	3068690	Now it's scanning this ID 620, and it has a response of 504.
3068730	3071730	19, 22, and 3E are all supported.
3071730	3075190	So this one only has three functions that are supported.
3075190	3077070	Again, I'm running through a gateway.
3077310	3080750	My thought process here is maybe if I get past the gateway,
3080750	3087310	I'll actually have some more information that's available on the other side of the gateway,
3087310	3089690	which I do have this connected, I just haven't done that yet.
3089690	3093670	We have five minutes left, or ten minutes left, because I can't count.
3094110	3095550	I think this is a good time to stop.
3095550	3100070	I think I am giving you guys the information, but hopefully it's enough for you guys to go.
3100070	3105050	Again, let me just type in the web page right here.
3105510	3108950	www.github.com
3108950	3110170	I'm typing in something else.
3110450	3111690	Canvas at...
3113430	3114730	There it is.
3114730	3117010	It opened an edge. You're welcome.
3117570	3119090	I'll fix it.
3120050	3121590	You get the idea.
3121810	3123890	It's awesome. Thanks, Microsoft.
3125190	3126350	That's what I want.
3126350	3128630	And then CMAP is right here.
3130030	3134210	So CMAP, essentially, you can go ahead and get this code that I just showed you guys today.
3134210	3136190	I'm sure I'll be pushing some updates.
3136870	3139530	Give me my first pull request.
3139770	3144470	Somebody, right now, first pull request gets free CMAP.
3145350	3149310	And if you guys have any other questions, I'll be around all day.
3149690	3154450	Just hit me up on the Twitter at C-A-R-F-U-C-A-R.
3155150	3163810	If you want to do your own Canvas hacking or anything like that, I highly encourage you to get to the virtual.carhackingvillage.com.
3164050	3168670	This car that I just showed you, it is on there. Everything I've just shown you is on there.
3169090	3175370	You can put CMAP on there if you'd like to right now and run these right now on the same vehicle that I just ran this on.
3175370	3180670	And if you have some questions, regardless of that, we'll be available to give you some hands.
3180670	3183750	Alright, if there's anything else, any questions from the field?
3184190	3185550	I've not seen anything.
3186190	3189650	Maybe there wasn't anybody because of the initial start that we had.
3189650	3190650	Yeah, this is horrible.
3190650	3192430	For some reason, I was...
3192430	3194690	A lot? Like two? Or three?
3195250	3196130	Thirty!
3196570	3200030	Hey, you over there. Yeah, you. How come you're not asking me a question?
3201050	3202690	No, that. Over there.
3203430	3204410	Yeah, you.
3205370	3207310	Alright, maybe they don't have any questions.
3207430	3209590	Yeah, I've seen no questions in the chat.
3209590	3213470	That's fine. I guess I'm just that good at presenting. Or the opposite.
3213470	3214530	Linted is telling me.
3214830	3219650	Hey, Linted. Oh no, not Linted. Linted wants to know. He's got a technical question.
3219750	3221850	Robert, what's wrong with the cars right now?
3222090	3222810	Talk about...
3222810	3227790	Talk about hardware checkout. Alright. I think you have to...
3227790	3231990	Is Discord stream muted or is that just me? That's his question.
3233590	3233990	So...
3233990	3236590	You gotta go on Twitch, man. That's all there is to it.
3237210	3239450	Alright, cool. Thank you.
