Hey everyone! Welcome to my talk, Car2Cloud Talk Using MQTT for Car Hacking. My name is Jamie Lightfoot. I used to work as an electrical engineer, and now I work at Grimm doing car hacking. Hey everyone! Welcome to my talk, Car2Cloud Talk Using MQTT for Car Hacking. My name is Jamie Lightfoot. I used to work as an electrical engineer, and now I work at Grimm doing car hacking. This is a Car Hacking Village 101 talk, which is meant to introduce people to foundational So, let's talk about how MQTT works and how you can use it. Let's talk about why we're talking about it in the first place. Automotive companies won't directly come out and say it, but if you've got a newer car or truck, then they're probably collecting a lot of data. They have information on you and your driving habits all the time. Some of this is still the safety features like OnStar or other ways of remote assistance where they need to know the location of your car. Some of this is still this convenience. For example, you've got remote unlock or lock functionality, remote start, remote alarm through like a phone app. There's also over there updates so you don't have to go into a dealership. Some of this connectivity is much more for the engineering company's benefit than for the consumer. In a past job, I worked on a project where we aggregated truck engine and transmission data and we would use that to predict future maintenance needs and ship the repair parts to where we knew the trucks were going to be weeks in advance. We would save the company tons of money on downtime and we'd also get them insight into what kind of warranty claims were going to be coming up. In all of these cases, the data somehow has to get to or from the car to somewhere else useful like your OEM branded mobile app, some kind of online engineering portal, a dealership tool, or whatever. And that's where MQTT comes in. Most of this talk is going to be about the protocol itself, but to give you an idea of how this ties into an actual car, For newer cars and trucks, we have a Telematics Control Unit, or TCU, which is the PCB in this diagram. The TCU is going to be likely on the CAN bus and accept other inputs from the car. For example, if there's a GPS antenna, so it has the ability to interface with the car and it also has an understanding of what is currently happening in the car. It'll be able to use its cellular connection to the cloud to send information in the form of MQTT messages. It can also do the same thing in reverse, where it is accepting MQTT messages from the cloud and then taking some kind of action within the car, for example, sending information out over the CAN bus. The TCU device has to have, at a minimum, the ability to connect to a cellular network or more likely networks, plural, as coverage is going to vary throughout a given area and you want to be able to switch between them. And then CAN transceivers are another way of interfacing with the other parts of what is happening in the car. But if you have a cellular connection from the car to the cloud, why would you choose MQTT over some other method of communication? Like maybe you're able to send a text to the TCU device and wake it up and then have it establish an HTTP connection. The reason is because cars are a bit of a difficult use case from a network and architecture standpoint. You've got unreliable connectivity or maybe varying connectivity quality because you're driving around and you might go through areas with poor signal. So you need to have some kind of protocol that has minimal overhead and size. You might want the ability to buffer messages if you're offline for a minute. And you also might want some kind of method to know if your message was received or not. You're probably dealing with high network latency, which means that you want to reduce overhead as much as possible. MQTT clients will remain connected and they don't need to reinitiate a connection with each message. Whatever architecture you use also needs to be able to scale up to millions of vehicles and handle millions and millions of messages per day. Hopefully you're also considering the security of the system, but we'll talk about that more later. MQTT stands for MQ Telemetry Transport or Message Queuing Telemetry Transport. It came from Andy Stanford Clark and Arla Nipper who are at IBM and Eurotech respectively. IBM had a MQ or Message Queuing product at the time. The OASIS standard for MQTT does not use queues to describe the message communication, but that's where the name came from. It was originally made to monitor oil pipelines over a satellite link. So that's where the emphasis on low bandwidth, very lightweight came from. MQTT.org describes it as a publish, subscribe, extremely simple and lightweight messaging protocol designed for constrained devices and low bandwidth, high latency or unreliable networks. The design principles are to minimize network bandwidth and device resource requirements while also attempting to ensure reliability and some degree of assurance of delivery. Given the network challenges that we talked about earlier, it seems like MQTT is a good fit. So let's talk about how it works. In MQTT systems, there are two types of network entities. There's an MQTT broker, now called a server, but I call it a broker out of force of habit. You also have one or more MQTT clients. An MQTT broker is a program that receives all the messages from the clients and then routes the messages to the appropriate destination client. It's pretty much like a post office. All messages have to travel through the broker in order to get to the other clients. A client can't send anything directly to another client. A client then is a device that is either interested in receiving certain information from the broker via other clients or publishing information to the broker, which will then be sent on to the interested clients or both. In an automotive environment, a client is going to be the car or specifically the TCU unit in the car. And the broker is going to be some kind of cloud service that the car company has set up. A mobile app might also be a client, a dashboard might be a client, but there's usually some more architecture going on. So they aren't all talking unfiltered to the same broker. Here are a few examples of cloud broker services that I have seen or worked with. There are others. These are just a couple options. To visualize brokers and clients, I made this diagram where we have a broker in the middle and a number of clients. Each client can either subscribe, publish, or both. What kind of behavior they do is contingent on how they try and connect to the broker. We'll see more about that in a minute. Earlier I said that it is a publish-subscribe method, or PubSub for short. Each client can designate what information it wants to publish to the broker. And each client can also specify what information it wants to receive back. And then the broker just doles out the messages as intended. Additionally, clients can provide forms of authentication to the broker, but they aren't directly addressable. So if you have a whole fleet of trucks or cars sending out messages, you probably want to be able to keep the messages separate or organized so you know which messages apply to which vehicle. And that's where topics come in. You can designate topics however you like. However, there are some patterns to follow. Here I've got some example topic names where maybe we have a DEFCON-wide broker and there's a topic called CarHackingVillage where if you subscribe to that, you get all the information being sent out related to CarHackingVillage. And then if you publish to it, then everyone who is subscribed will receive that information. But, because CarHackingVillage has a lot of different things going on, let's break it down into subtopics where you have CarHackingVillage slash talks or CarHackingVillage CTF, where if you're only interested in the talks or the CTF, you can subscribe just to that and narrow down the information that you receive. Likewise, if you're publishing, you are publishing to a more narrowed down audience. And then you can just keep nesting as far as you want. For example, maybe in the CTF we have different team IDs and you can subscribe to your team ID and see what score you have. So, if you've got people publishing to each of these individualized nested topics, if you still want to receive all of the information about CarHackingVillage, then you will want to subscribe to CarHackingVillage slash either pound sign or hashtag, depending on how old you are, and you'll receive all of the CarHackingVillage topics. If you were to subscribe to the pound sign by itself, that would function as a wildcard and give you all topics available on that broker. So, for our DEF CON example, it would give you information on all the villages, all the CTFs, all the things happening. But if you are a client, this is probably more information than you want or that you can handle. If you're a top-level component in the architecture, you're probably interfacing with the broker in a different way to get all the information out. A client can only publish to one topic at a time. You can't publish to a group of topics or a wildcard. For the publishing volume, it's up to the client, but think on the order of maybe once per second. So, in automotive, the topics might look like car data, and then the VIN number, and lock status or location, latitude, location, longitude, information about the engine, and so on. Where you would receive back, probably JSON. All of that is defined by your system. It's kind of however you want to set that up. You can also use the pound sign and plus sign to selectively handle levels. So, you could do car data and then a plus sign, location, latitude, and that would get you all of the latitudes for all vehicles if that level that you're using the plus sign for typically handles VIN data. You could also do car data, pound sign or hashtag to get all information. So, the lock information, location, engine, and so on for all vehicles on that broker. If you are securing a MQTT broker, you want to make sure that your clients don't have wildcard privileges. There's also a set of topics that all start with dollar sign SYS. These are all administrative type topics that give information on the clients, messages being sent, and so on. If you are securing a broker, you want to make sure that these are turned off for all non-admin users as well. Revisiting this diagram, receiving information isn't like the request response workflow that you're probably used to. You are not requesting data and then getting a response back containing that data. Instead, you are subscribing to topics you want data from, and then when data is published to those topics, you receive that information. After you're subscribed, you'll continue receiving information on those topics from other clients as it gets published until you either disconnect from the broker entirely or you unsubscribe from that topic. There's also an optional small set of delivery assurance messages. We'll talk about that a little bit later. If we revisit our earlier diagram of topics, if the first client publishes something to Topic 1, the broker is going to forward that on to Client B because Client B is subscribed to Topic 1. It will also send it to Client C because Client C is subscribed to the wildcard and wants information on all topics. If we talk about the MQTT packet structure briefly, all packets are going to have a fixed header that has information about the type of packet and then some flags relating to the packet type. There are a number of packet types as listed here. They come in pairs. For example, you have Connect, and then Connect Acknowledgement, Publish, and then different types of Publish Acknowledgement, Subscribed, Subac, Unsubscribed, Unsubac, and then you have Ping, Ping Response, and then Disconnect. The next part of the fixed header is for flags, but that pretty much only applies to the Publish message type because there are Quality of Service and other configurations that need to be set. Connect, Subscribe, and Publish messages provide more information than other types of messages and need to use a variable header in addition to the fixed header to include that info. For example, a Connect message is going to provide version information, keep-alive information, and so on. And then after the headers, you have any kind of payload information. Typically, you're going to see JSON, but you can do whatever you want, really. So, here are two examples of Wireshark captures of packets. The first one is a minimal packet where it's two bytes and it is a Disconnect message. And then we have a longer packet on the bottom where we are publishing hi to the CarHackingVillage topic. If we look at a Subscribe message connection in Wireshark, the client is sending a Connect command. The broker is going to respond with a Connect acknowledgment. Then the client sends a Subscribe request, and then if it's accepted, the broker will respond with a Subscribe acknowledgment. If you're doing security testing and you can't get a connection to work, I suggest two different things. One is to use a dash d in your subscription command, and then the other one is to set up a test server and get an idea of what a known good connection looks like. If a client has been able to successfully subscribe, after that you'll see a ping and ping response periodically between the client and the server as a keep alive signal. For a Publish command, we have a Connect, a Connect, a Publish, and then a Disconnect message. If we had a higher quality of service setting, then you might get an ACK or other message back. And then the final publish line is from the broker to the other connected client. So once again, you can use the dash d to get some more debug information. There are three quality of service settings that you can choose. 0 is the default, 0 is at least once, it's going to be fire and forget, there's no kind of checking or acknowledgement afterwards. Level 1 is at least once, it's going to keep sending that message until it gets acknowledgement back. Level 2, there's a little bit more going on, and as a result, you can ensure that only one copy is received. At this point, I think the best thing to do is to try out a MQTT broker on your own computer to see how it works. And to do that, I recommend that you download Mosquito, because you can do all of this on the command line. There's very minimal setup, and I think it helps cement the ideas. First of all, you need to go to their download page and get it set up on your computer. If you're on Mac, you can do brew install mosquito. Then you will need to start the service. I'm on a Mac, so I did the line shown here. And then you want to open up two more terminals. In the first one, you want to subscribe to a topic. For example, I had CarHackingVillage. And then the "-i client1 is my client ID". You don't have to provide this. It will make one for you if you don't, but just for completeness. And then in the other terminal window, you do a publish message to CarHackingVillage topic with whatever you want your message to be. And then in the first terminal window where you subscribe, you should see that data come through. Visually, that looks like starting the service. It will listen on port 1883 by default. You subscribe, you publish, and then back in the subscribe window, you see that you got Hello World. If localhost is too boring for you, then you're in luck. Mosquito.org has set up a test broker where you have ports for each type of broker service. You can subscribe to all topics using the hashtag or pound sign. And then use "-v to show topic names along with the data so you don't just get Hello World, you get CarHackingVillage topic Hello World. You can see this note on their website that says don't publish anything sensitive because anyone can be listening. You probably know where this is going. Here are some screenshots from the other day where I have subscribed to all topics on the unencrypted port 1883 test mosquito.org server. We have what seem to be plain text passwords. We've got the lighting and temperature controls for some office. Probably most concerningly an over-the-air update. And then this last person was just publishing basic C4 encoded images. A lot of the data being published here is probably junk. However, some of it does look important. A lot of times, IoT projects or other projects that use MQTT will use a default value of test.mosquito.org as their broker so that the whole project will just work right out of the box. There's usually a note to change it, but of course not everyone does that. I have seen a production TCU unit that had test.mosquito.org commented out in the configuration file, so it can happen. Since this is DEF CON, I should probably talk about security. You likely noticed that in the earlier examples, including test.mosquito.org, there is a pretty minimal set of information that we needed in order to subscribe to a topic or publish information to that topic. We would hope that MQTT offered some kind of security features so we aren't completely wide open to anyone who can guess our IP address of the broker and then sees port 1883 open on their nmap scan. As with the Mosquito test server listings, there are different levels of security that you can set on your broker. For the lowest level, which is the default, you only need to know the host name, port, which default is 1883, a topic, including wildcards, in order to subscribe. Technically, you also need a client ID, but the Mosquito command line tools will make one for you if you don't have one. By default, MQTT does not require authentication or encryption. You can set that up on your own. You can also set up authentication without encryption, but as shown in this screenshot, that means that plain text credentials are visible if you can sniff traffic. Hopefully, that isn't enough security for your connected car architecture and you want to do a little bit more. The next thing to do is to add encryption. We can do MQTT over TLS. We use a certificate to encrypt traffic between the client and the server, which means no more plain text credentials. Random people can't connect to your server. If you try and connect without a certificate, the server won't even respond with an acknowledgement. Your data is going to be encrypted in transit, which is a significant step up in security. I don't think you'll see many car networks with unencrypted traffic. I don't know that you can say the same for IoT. Let's say you have a car network set up with MQTT over TLS. You still need to use defense in depth. If you were to buy a TCU off of eBay, you get console access, you dump the firmware, and now you have the host name, the port number, what a valid client ID might look like, and then the certificate. You could connect to the broker or server using that information. You might think that's not a big deal. You're just going to get information about that TCU. Depending on how you have set up authentication and access control, you might be able to get information about other cars, which is obviously not good. That means we need to employ some level of authentication. We already said that authentication is not required by default. You can configure your broker to authenticate clients. If you are using some kind of paid-for service like AWS IoT, they probably make this even easier for you. You can pass in a username and password to authenticate devices against a device list. But what would be even better than that is to have individual client certificates. Of course, this makes the manufacturing and provisioning process more difficult and more expensive. But in this scenario, if you were to buy a TCU off of eBay and hack it, and you have set up access control correctly, you can only connect as that device. You can't guess other usernames or passwords, especially if you're doing something that is guessable, like the username is the VIN or the IMEI or something like that. If you have authentication set up, you still need to think about authorization. What kind of data or functionality should a single device have access to? Ideally, cars should only be able to see information about that car, not other cars in the fleet, and not system-wide information. If they aren't using individual client certificates, then the authorization might be based off of either the username or the client ID that you have to provide. You should try both. Brokers can be configured to disconnect clients that are asking for unauthorized topics. I don't know how common this is in the wild. For example, I know that AWS IoT lets you configure all kinds of security access violation rules, but I haven't actually seen anyone use it for production. If you manage to get connected in whatever way, what you should try then is to see if the broker allows wildcards. Can you use hashtag or pound sign to connect to all topics? If not, then you need to have a little bit more nuance. Try connecting to, for example, from earlier, car data, and then either a pound sign after that for everything under car data, or car data, and then a plus sign, and then topic names that you already know about from your car. For example, location, latitude, and see if you can get information that way. Just because they have restricted wildcards at one level doesn't necessarily mean that they have filtered them out correctly at all levels, so try a couple different permutations. You should also try the system level topics to see if you can find information about the connected clients. And then if they have locked down all of the wildcards, which hopefully they're doing, you might be able to guess what the other IDs are and essentially go through the same process, but manually trying out different VINs or IMEIs instead of making use of the wildcard. For example, if the ID is a VIN, you can probably guess other valid VINs or look them up somehow. They might also be using the IMEI or the ICC ID of the telematics control unit. Ideally, they're checking your client name or username or certificate to determine whether you're authorized to view this, but if they had to roll their own access control setup, maybe they've made mistakes somewhere. There are other security features that you could use. For example, the access control violation rules mentioned earlier or a VPN to close the attack surface up even more. I haven't used these tools a whole lot, but I found them while making this talk and I thought I'd include them. MQTT Pwn is a whole framework around MQTT testing. The second one is a fuzzer and then the last one is less for security testing and more on the development side. It has a ton of great links for frameworks and client code and things like that in a bunch of different languages. It's a great resource. So, in summary, MQTT is a PubSub protocol that runs on ports 1883 or 8883, depending on whether you're using TLS or not. You have one broker and multiple clients. In the automotive world, the clients are likely TCUs, but might be other things as well, like mobile apps. Information is separated out by topic hierarchies as defined by each system. MQTT security is important because of privacy concerns. You have car location that could be shared over MQTT. You have car safety, if you can do remote lock or unlock, and then over there, updates, where if you're somehow able to get in the middle of that, you could download malicious firmware onto the device. Hopefully, again, you have defense in depth and you have other checks for that. But MQTT is insecure by default, and it is up to the developers to implement authentication, authorization, encryption, and access control correctly. And lastly, MQTT is something that you can use in car hacking, if you have a car with a telematics component. If you don't have that, MQTT is also very common in IoT, so you might be able to practice some of these things with IoT devices you have around your house. I hope this has been useful. I'll be around in Discord for a little bit afterwards. Feel free to hit me up on Discord, CarHackingVillageJamie, or message me on Twitter if you have any questions or anything that I can help with. All right. Jamie Lightfoot, everyone. Thank you very much for your talk. Jamie, I believe you're also in the channel currently. Good evening. Actually, we don't have any questions coming from the audience. If you do have questions and you want to ask Jamie right now, please go ahead and type them into the CHP 101 support text channel, and Jamie would be happy to answer them now. Or I'm sure Jamie's going to be around for some time, and maybe you can catch her direct chat with her or in one of the channels as well. So, Jamie, thank you very much for the talk today. It was really nice. Thank you, and thank you, everyone, for listening. Great. And once again, contact Jamie if you have any questions. If you want to make any comments or just talk about MQTT, excuse me, then talk with her directly. Jamie, thank you for the presentation again. And actually, this was our last presentation, our last talk of the day.