This blog post will discuss the implementation of Codegrabbing / RollJam, just one method of attacking AM/OOK systems that implement rolling codes (such as keeloq) — these systems are commonly found on modern vehicles and entry systems such as gates and garages. This technique has been used and spoken about for a number of years (Marko Wolf describes it in “Security Engineering for Vehicular IT Systems” from 2009).
However the advancement in easy to use and cheap hardware has made this a readily available research path for almost anyone. Samy Kamkar showed it at Defcon 2015, you can read about that and his device at http://www.wired.com/2015/08/hackers-tiny-device-unlocks-cars-opens-garages/. This blog entry will be more discussing the integral parts of how it works and how easy it is to do.
I was optimistic that the 2015 talk @elasticninja and myself did at zacon on this topic would be published so that I could lazily just link to the video instead of having to write it up, but alas, here we are! ;)
Naturally its important to have a spoiler before the long boring text. Here is a video carefully crafted by my friend Roelof Temmingh showing us opening a VW car with two YS1 (YardStick One):
For this post already knowing the basics of AM/OOK and retransmitting these codes is pretty useful. If you are unsure feel free to check out the previous entries on Hacking fixed key remotes with (only) RFCat :)
Alternatively you can view the entire playlist of 6 videos (about 2 minutes each) that do the various tasks relating to AM/OOK signals, see https://www.youtube.com/watch?v=rMOKdVrHQKo&list=PLAetK6ObzqE4Hpgrrb7xnbx5LIH29PqOV
The code used in this blog post can be found at https://github.com/AndrewMohawk/RfCatHelpers
The sections are as follows:
* Automating replay attacks
** What are Rolling codes and how do they work
** How do we attack rolling codes?
*** Missing Link attack
*** Code grabbing (aka RollJam)
Automating Replay Attacks
As I was looking to essentially bypassing/circumventing a car alarm/remote system that use multiple different codes (the codes change) — I needed to optimise my method of capturing and replaying the AM/OOK codes. Previously I had done it manually with an RTLSDR where I would use an RTLSDR to record a demodulated wav and then use some python to take that wav file to the actual signal transmitted. From there I would use the awesome RFcat with a compatible device (Such as a YardStickOne or CC1111EMK) to transmit the codes and open/unlock the device. That was even a pain to type out, it definitely wasn’t efficient.
To improve upon this the next step was to cut out the analog step and use digital only (which meant not working with the audio and allowing the hardware to handle the decoding and transmission for me). Even when doing it only in digital it was still fairly manual process where I used one script to analyse and return the the code that was being transmitted and another to do the actual transmission.
Because of the generosity of @michaelossmann I was lucky enough to have received a few YardStickOnes and was interested in improving the previous attack. There were a number of ways I considered doing this, naturally the first method was using a YS1 to continually scan frequencies and should it pick up a transmission then it should capture and resend this (when neccessary).
This method however proved difficult as taking apart the SpecCan application (which does scanning in the RFCat libraries) was a tricky beast to grapple and largely slower than what I needed to do.
However I did manage to build a single script that would automatically jam signals using two rfcats ( see https://github.com/AndrewMohawk/RfCatHelpers/blob/master/DualRF.py ) but I would not recommend this method, as it was not that stable.
The only take away was that if I made the amount of space to scan small enough (say 500mhz around 433 or 403 — which is most remotes) I could almost reliably jam any of my test devices that implemented rolling code… almost being the key word.
The best method that I found was simply to have a jammer and another device with two stages, one which waits for the signal and captures it and a second one which replays it. Because I was particularly lazy, the easiest way was to take the raw output (in rfcat this is called lowball mode) and look for the change in values from the device (usually about 15 zeros) and start capturing.
The correct way would have been to also decode that data into the raw binary rather than capturing the raw data (however using the raw data still works flawlessly — so far). This is what Samy Kamkar *did* actually implement on his devices. Once the ‘signal’ (raw data) was captured I could merely replay that signal (by sending the packets back out that I captured) whenever I decided
The script used for this is https://github.com/AndrewMohawk/RfCatHelpers/blob/master/RFSimpleReplay.py and allows you to ‘dumb replay’ almost any signal just by specifying the frequency, but also gives you some other options such as channel bandwidth to modify the signal so that it can be used on more complicated signals that use more than one frequency. Hopefully it is useful for people pulling apart similar systems.
What are rolling codes and how do they work
Previous attacks I demonstrated, used fixed key remotes, whereby the devices transmitting AM/OOK signals used the same code every time — think of this as a password that you have to speak to open a door, except the password never changes.. and you have to scream it at the top of your lungs… where anyone cal hear it. These kind of devices include garages, gate remotes, aftermarket car remotes and home automation devices.
Most of these devices are on the low end in terms of quality and pricing and because of this very little work has been put into the security of them. Specifically the radio security of the transmitted codes.
Really what that meant was that any code you transmitted to open your car/garage or turn on a device in your house could be captured. Once it was captured this same code could be re-transmitted at any time to perform the exact same task. A lot of the open/close systems such as doors and cars would use the same code for both lock/close and unlock/open and just run it on different frequencies.
To improve on this system a number of changes were made to essentially prevent replay attacks (somewhat). This is called rolling code. The way this was done was by making the remotes and cars (or other devices) have a synchronised starting code that was sent and an algorithm that determined the following code to be sent next so that the same code was never repeated. This is very similar to the OTPs used by RSA 2FA tokens.
The implementation of this is that both the car and the remote are sync’d to an initial number (A PRNG’d seed). This is usually called “pairing” a remote and relies on some configuration of the device (car,garage,etc) such as pressing a button or using a ‘master’ key. You can see this in the image above.
Once the remote and device are synchronised they use an algorithm to take that initial number (let’s call it x) and then transform it to the next number in the sequence (x+1). The following keypress will take the result of the previous keypress as the input. In this way it means that even if a single remote press is intercepted/captured there is no way to determine the next code to use the device.
The devices do not only store the next code that needs to be transmitted to validate it but also store a number of them (often this is around 255). The reason for this is that if the device is pressed away from the receiver or where the receiver cannot ‘hear’ the transmission for reasons such as there being noise or you are too far away, then the devices will not go out of sync. This is why your remote to open the car still works even if you first accidentally pressed it inside your house before walking over to your car.
To keep sync as soon as a button keypress that is valid is received, the “list” (again, often 255) is updated to be x iterations from that keypress. For example if the algorithm for each keypress simply added 1 to the number (which it wouldn’t be hopefully as that is easily reversible) and the car and the remote sync’d at a PRNG of 1 then the car would store values from 1 to 255 initially. The button would then transmit ‘1’ as its first number, and ‘2’ as it second. Once two codes had been sent and picked up by the car then the car will store the values from 3 to 258. And so on.
This does however mean that all rollingcode systems suffer from a denial of service situation where if the button is pressed too many times without it being received from the device the buttons lose sync and will stop working. There are some other edge cases we may have discovered but at this stage are unproven.
How do we attack rolling codes?
Rolling code systems are vulnerable to a number of attacks that have been presented over the years. A number of these are attacks on the hardware itself through things like power analysis to determine the seed number or maths algorithm used. One example is the side channel attacks (see https://en.wikipedia.org/wiki/KeeLoq#Side-channel_attacks )
I will only look at the basic attacks that are against the radio transmissions rather than the hardware. In some ways this makes these more generic as they are hardware neutral, and also a lot easier to implement as the hardware and software requirements are a lot lower. The two attacks are one based on the previous replaying and one to look at the vulnerabilities of the rolling code system itself.
Missing Link Attack (for lack of a better name)
The first (and technically the second) relies on the device that you are targeting to not be able to receive any of the radio transmissions from the remote. Essentially this can be done in two ways, one is as simple as capturing the signal while someone is away from the device and the other is to jam.
Essentially you listen for the button and capture it (using something like the RFSimpleReplay.py) whilst the remote is out of range of the device (say the car or garage). You then move to the device and use the captured code to open it. This is similar to the video below that just shows doing this with a non-rolling code. NB obviously when doing this with a rolling code the replay will ONLY work once:
The second method of doing this is to jam the signal near the vehicle or receiver so the receiver cannot actually ‘hear’ the code, and once that is happening you can simply capture and replay the code when you have stopped jamming. An example of jamming with RFcat and the YS1 can be seen below:
Whilst this jamming done here is with SDRs (in this case YardStickOne) you can also easily jam with any remote on a similar frequency. The reason for this is because of the drift that is often seen in these remotes — sometimes caused because of things like components operating at different temperatures or the batteries being flat. As such the devices themselves have a larger receive window than just that of the remote and if the jamming is anywhere within that receive window then the device will be effectively jammed. This technique is often used by thieves to block peoples remotes from locking their cars when they press the remote allowing them easy access to an open vehicle. Simply searching youtube for this will reveal many of these techniques caught on camera: https://www.youtube.com/results?search_query=remote+jamming
Code Grabbing Attack ( aka ‘RollJam’ )
While remote jamming works, it is of course noticable as if the person locking the car simply tests the doors to ensure they are locked they would notice the car unlocked. Additionally if they were aware of such attacks they could even listen to the fact that the doors never made the lock sound or the cars lights never flashed when they pressed the ‘lock’ button.
However there is another technique that if done correctly will be mostly indistinguishable from the standard operating procedure of the car. This technique relies on using both the jamming and replaying discussed above. Take a look at the standard signal of a car remote (in this case around 403hmz) of a rolling code lock:
In the first image you can see the signal as well as the jamming taking place, this is to illustrate the highlighted sections more. In the second image (both taken with GQRX) you can see a red line for the jamming frequency used and you can also see the yellow line for where the attackers device is listening. The green highlighted area shows the entire receive window.
In the image the car remote is effectively being jammed, however at the same time we can also capture the code from the remote. This is because the jamming is not on the exact frequency of the remote. For the party trick, what usually happens when someone cannot get a remote to work is that they will press the button a second time, most people do this instinctively and don’t even notice it happening. As soon as this happens we can capture not just a single key press but a secondary one as well.
Armed with two ‘valid’ codes, what the attacker can then do is transmit the codes back in the captured order (the first captured code sent first), this will perform the action that the target user intended to happen (lock/unlock sequence) and as such the end user will be unaware of anything suspicious happening. However this also means that as an attacker we have a secondary code that is still valid and can be used on the car at a later stage.
An attack scenario would be as follows:
- Target parks their car, gets out the car
- Attacker launches a jammer that prevents the car from receiving the code from the remote
- Target presses the remote, car does NOT lock and the attacker obtains the first keypress
- Target presses the remote a second time and the attacker obtains the second keypress
- Attacker then sends the first key press to lock the car, car locks as per normal
- Target assumes all is well and carries on about their day
- Attacker then sends the second keypress to the car, unlocking it
- Target returns to the vehicle and remote works as per normal
As a demonstration here is a simple video of opening a rolling code based gate system that is used in many complexes within South Africa:
This is of course the same technique used to open the VW car in the teaser video:
There are however some technical problems with these kind of attacks.
The first and most noticeable is that many modern cars use different frequencies for lock and unlock. This means that should an attacker use this attack on say the ‘unlock’ frequency he or she would only be able to unlock the car with the additional code. If the system uses the same rolling code for both lock and unlock (which I believe is fairly common), than if the target locked the car it would increment the rolling code making the attackers second ‘unlock’ code void.
One way around this is to permanently jam the lock frequency, causing the user to have to manually lock the car, this however is very noticeable. The second way around it is that often the rolling code implementation on both frequencies is poorly implemented. It has been seen that simply sending the same code to the other frequency allows access. For example an attacker could send a code captured on the ‘lock’ frequency to the ‘unlock’ frequency and have the car open. Other implementations seen in specifications show that the rolling code is a portion of the total code sent. Ie the code sent is a 24 bit key where the first 12 are the rolling code, the second 8 are the command (such as lock or unlock) and the last 4 is the checksum. Vehicles implementing this type are also naturally susceptible as the attacker merely needs to replace the rolling code segment to be able to use any rolling code on both frequencies.
The technique and attacks described in this blog post are specifically looking at AM/OOK codes, however some cars use different modulations such as FSK which makes the jamming and capturing of the codes much more difficult (and naturally my scripts would not work with those unless they were modified). However the attack in theory should still work against it.
Testing against an aftermarket rolling code system installed on a car, sending the same code twice immediately activated the alarm and immobiliser providing a unique denial of service opportunity. Ironically the means of disabling the alarm and immobiliser was to press the remote, providing an attacker with the ability to continually perform this attack.
We also found that when testing against a VW family car we managed to disable one of the remotes with the following sequence of events:
- Capture unlock codes
- Send unlock code one ( car unlocks )
- Lock car with specific VW remote
- Send unlock code two ( car does not unlock )
- Remote no longer functional for locking/unlocking car
Unfortunately this is only our current assumption ( we do not have vehicles we can test this on — feel free to send us some or even just the locking systems ), and the car had to have the second key reprogrammed before it would work again. However if it does work as described it means that it would be possible to disable the ability for a person to use the remotes, and in some cases when using the key, means the alarm is deactivated even though the doors are locked.
While the scripts provided will give you enough information to fully automate the attack there are a number of things left out (if we are honest not because its dangerous, but because I am lazy):
- The Jamming needs to happen automatically when a signal is seen — I found using the RSSI values worked rather than looking for the starting sequence of the transmitted code (often a string of 0’s)
- The Code capturing needs to do more than capture the ‘raw’ data, it would need to actually decode the transmitted code so that it can be sent as the code rather than throwing the raw data back at the vehicle.
- The retransmission needs to be automated so that as soon as the second code is received the first is sent back to the vehicle. This needs to be optimised for speed so that the target user is as unaware as possible.
Samy Kamkar in his 2015 Defcon talk showed a device that he had built using two of the same chips that are used within the YS1’s (This is actually where ‘RollJam’ comes from). While the code is currently not available it seems very possible to perform this attack with two YS1s or even an RTLSDR (for scanning/decoding) and a YS1 because of the simplicity of it.
There are a number of methods that could be implemented on vehicles to make these attacks more difficult but each comes at a cost. The root problem is that the remote and the vehicle for most vehicles do not communicate to each other so there is no current way to verify the integrity of the remote (is this MY remote or someone who is sending the same code?)
2 different frequencies
As discussed in the problem section, using two different frequencies and NOT having a ‘data’ segment essentially in plaintext (or not having one and only using a rolling code) mitigates a lot of these attacks.
2 way communication means that you can set up a secure session between the remote and the car (think SSL), this however is far more expensive to implement and has its own problems (think SSL).
Codes that expire
Because there is no timeout on the codes it means that an attacker can use these at any stage. However implementing a timeout on the code means that should you be away from your vehicle for a while, say on holiday, your remotes would lose sync.
Code Hopping / FHSS
Implementing these methods on how the codes are sent on the physical level means that it is a lot harder to jam and to transmit valid codes. This would set the barrier to having hardware that can match the vehicles and remotes much higher and hopefully mitigate a number of attacks (for a brief period of time).
Smaller Receive Windows
Having higher quality components means that the receive window could be made much smaller. If this was the case an attacker would need to transmit something that he knows, then remove that from the analog signal before converting it to digital.
Thanks to everyone who helped with this project and provided assistance, specifically:
Mike Davis – Doing the talk with me, sitting around in coffee shops looking way too suspicious, and proof-reading
Mike Ossman – Literally shipped us 5x YS1s to play with
#RFCat ( Samy^^, Mossman, Dominicgs, etc) – for putting up with hours of my annoying questions
Paul Richards – for letting me break his LOLcar (it doesnt implement rolling code)
Roelof Temmingh – For letting me slack at work and bounce ideas off him, moral support
Rogan Dawes – Donating me the rolling code system, it meant I wasnt standing in the street with a bunch of radio equipment (I understand it might be a long term loan at this stage — Let me know if you want it back :)
Atlas of d0om (aka at1as) – Mostly for RFcat, but also for the words of encouragement ;)
Mike’s Wife – Donating her VW to be bricked, sorry about that, just remember it was Mike who used the code!