Not Your Grandfather’s Empire I’ve wanted to put this blog together since returning home from DEFCON. Anytime we ran into someone who recognized our swag, they mentioned how much they loved Empire back in the day and didn’t realize it was being actively maintained. This made me reflect on all [...]
Hacking Jeeps is nothing new in the media, but we wanted to give it a try and see how difficult it is for ourselves. So we dug out our SDRs, and got to work. In a surprisingly short amount of time, we learned that remotely unlocking, locking, and even starting a Jeep Wrangler is possibly the easiest task that we have set out to accomplish. This is due to the rolling code algorithm the Jeep employs to protect against replay attacks of key fob transmissions. Rolling code algorithms use a pseudorandom number generator to sync a block of usable codes (typically 256) between the transmitter and receiver. As transmissions are received, the old code is discarded and both the key fob and Jeep roll to the next code (hence the name rolling code algorithm). However, if a transmission from the key fob is not received by the vehicle, the vehicle doesn’t roll forward on the synced block list. This makes it possible to capture a key fob transmission away from the vehicle and replay it as a valid transmission at a later time.
This issue has previously been reported by Caleb Madrigal, but we were able to take things a step further. By setting a signal on repeat we were able to eliminate the need to capture a fob transmission that was not received by the vehicle because a rolling code repeated in the next block. For our test, we used a HackRF One and our very own Jeep Wrangler (Anthony’s wife’s but who is really counting). Our starting goal was to recreate Caleb’s work from April 2016 and then we would see if we could expand upon it.
We setup SDRSharp to confirm that our key fob was transmitting at 315 MHz, the default frequency for many U.S. car manufacturers’ remotes. With that verification, we were able to capture the unlock command from the Jeep’s remote.
Then we replicated the block diagram into GNUradio. The goal was to output a data file that contained the unlock command for the Jeep and also give ourselves a waterfall diagram to confirm that we received the command.
We extracted the unlock signal from the raw data file which mirrored the signal that Caleb analyzed in his experiment. It appears that Jeep hasn’t changed much over the years and the signals from their key fobs are relatively consistent across makes and models.
Now to test out our newly captured unlock command, we used a simple script to replay the signal. It didn’t come as a huge surprise to the team that replaying the unused unlock command worked on the Jeep. However, it did come as a shock that putting the signal on repeat would unlock the Jeep after a few minutes. The number of unique codes for this key fob should be around 2^48 and makes the theoretical chances of a key collision infinitesimal. (The true number of codes is significantly less, but that is a topic for a later time.) However, we see that reusing a rolling code can consistently trigger a Jeep which should not happen or at least not within such a short period.
While the re-usability of the unlock command was surprising, we wanted to see if we could accomplish something more interesting. The first task was to re-accomplish the previous test with an unused remote start command. Next, we would see if repeating an un-used command would trigger a remote start for the Jeep. We tuned our SDR back to 315 MHz and captured the remote start command.
Replaying the remote start command successfully triggered the starter on our vehicle. This confirmed our suspicion that there were no real underlying differences between a remote start command and an unlock command.
So we moved on to the next phase of the test to see if a captured remote start command can be reused. Having captured and filtered the signal to the essential elements there were not many changes that needed to be made from our unlock command test. A difference that we found was that remote starting a vehicle was limited to a single time. In other words, you cannot remote start a Jeep if you have previously remote started it unless you start the vehicle with a key and turn it back off. This may seem a bit ridiculous, but the intent behind it is so you do not continuously turn the vehicle on and off. This discovery may also have initially led us to believe we had accidentally bricked the jeep when it stopped responding to the remote start both from the SDR and the actual key fob.
Having identified that key limitation we moved on to our final test. We setup our script to send the remote start command on repeat. Once again, after a few minutes, our Jeep turns on with our previously used (supposedly expired) remote start command. There are also some other interesting unintended side effects from setting the remote start command on repeat after the vehicle kills the engine the first time. The result is that the Jeep does not start for reasons stated above, it cannot be remote started again, and it will randomly not start with the key or die almost instantly. It appears that the vehicle gets stuck in some sort of loop or state where it cannot accept any more commands from the key fob and this the unstable state appears to impede the physical key authentication as well (keys have microchips in them that also authenticate with the vehicle, this is why you sometimes see spare keys that will unlock the vehicle but not start it).
Overall, we came out with a few interesting lessons learned that we felt were important:
We can only remotely start a Jeep once (so we better make it count!).
Continuously replaying any signal at 315 MHz would jam out all other transmissions (see Roll Jamming for a technique to exploit this).
There is a 10% chance that repeating the signal will work for the remote start.
Failing to start the Jeep can put you in an unstable state and prevent most functionality from working.
As you may know, you are unable to drive off without a key in the ignition and may not see the value in remote starting random Jeeps. However, let’s take this one final step further and imagine that these vehicles are parked safely in garages and you can use your imagination for what cyber-physical effect happens when a car is left running all night in an enclosed space.