A trio of researchers split between Italy and the UK have recently published a paper about cryptographic insecurities they found in a widely-known smart light bulb.
The researchers seem to have chosen their target device, the TP-Link Tapo L530E, on the basis that it is “currently [the] best seller on Amazon Italy,” so we don’t know how other smart bulbs stack up, but their report has plenty to teach us anyway.
The researchers say that:
We dutifully contacted TP-Link via their Vulnerability Research Program (VRP), reporting all four vulnerabilities we found.
They acknowledged all of them and informed us that they started working on fixes both at the app and at the bulb firmware levels, planning to release them in due course.
For better or for worse (the authors of the paper don’t say whether any disclosure dates were agreed with TP-Link, so we don’t know how long the company has been working on its patches), the researchers have now revealed how their attacks work, albeit without providing any copy-and-pastable attack code for wannabe home-hackers to exploit at will.
We therefore thought that the paper was worth looking into.
Wireless setup
Like many so-called “smart” devices, the Tapo L530E is designed so it can be set up quickly and easily over Wi-Fi.
Although wireless-based configuration is common even for battery-powered devices that can be charged and set up via built-in USB ports, such as cameras and bike accessories, light bulbs generally don’t have USB ports, not least for space and safety reasons, given that they’re designed to be plugged into and left in a mains light socket.
By turning a Tapo L530E light bulb on and off repeatedly at the wall switch for one second at a time, you can force it into setup mode (apparently, the bulb automatically blinks three times to tell you when it’s ready for configuration).
Like most automatically configurable devices, this causes the smart bulb to turn itself into a Wi-Fi access point with an easy-to-recognise network name of the form Tapo Bulb XXXX
, where the X’s form a string of digits.
You then connect to that temporary access point, which isn’t password protected, from an app on your smartphone.
Then you tell the bulb how to connect both to your password-protected home Wi-Fi network and to your TP-Link cloud account in future, after which the bulb’s firmware can reboot and connect itself up to the internet, allowing you to manage it from the app on your phone.
The bulb can join home network, which means means you can contact it directly over via your own Wi-Fi when you’re at home, even if your ISP is offline at the time.
And the bulb can connect over the internet to your cloud account, so you can also send commands to it indirectly via your cloud account while you’re on the road, for example to turn lights on and off if you’re late getting back in order to give the impression that there’s someone at home.
Beware imposters
You can probably guess where this is going.
If the app on your phone doesn’t have any cryptographically strong way of figuring out that it really has connected to a genuine light bulb when you go through the setup process…
…then a nearby attacker who just happens to start up a fake Tapo Bulb XXXX
access point at the right moment could lure you into sending those important setup secrets to their “imposter bulb” device instead of to the real thing, thus capturing both your Wi-Fi password and your TP-Link account details.
The good news is that the researchers noticed that both the Tapo app and the L530E firmware included a basic safety check to help the app and your bulbs to find each other retliably, thus reducing the risk that the app would blurt out your passwords when it shouldn’t.
But the bad news is that protocol used for this are you really a light bulb? exchange was clearly designed to avoid mistakes rather than to prevent attacks.
Loosely put, the app locates any light bulbs on its network by broadcasting special UDP packets to port 20002 and seeing which devices reply, if any.
To help any listening light bulbs decide that an are you there? request came from the Tapo app, rather than from some other unknown product or service that just happens to use port 20002 as well, the request includes what’s known in the jargon as a keyed hash.
The I am here! reply from the light bulb includes the same sort of keyed checksum to help the app filter out unexpected and unwantwed UDP replies.
Simply put, the keyed hash is a checksum based not only on the data in the UDP packet but also some additional key bytes that are folded into the checksum as well.
Unfortunately, the Tapo protocol uses fixed key bytes for its checksum, with the same “key” hard-wired into the app and into the firmware of every Tapo bulb.
In other words, once someone has decompiled either the app, or the light bulb firmware, or both, and recovered this “key”, you should assume that anybody and everybody will know what it is, making those are you there?/I am here! messages trivial to forge.
Worse, the researchers found that they didn’t need to decompile anything, because this not-so-secret “key” is only 32 bits long, which means that by setting your own Tapo bulb into setup mode and then feeding it are you there? messages using all 232 possible checksum keys, you’ll eventually hit on the right key by what’s known as brute force.
That’s the cryptographic equivalent of spinning the dials to try every combination on a bike lock, say from 000
to 999
, until you get lucky and the lock pops open. (On average, you’ll open the lock after trying half the possible combinations, but it will never take you more than 1000 goes.)
In fact, they didn’t need to send 232 messages from the app to a light bulb to crack the key.
By capturing just one known-genuine message with a valid keyed hash in it, they could then test all possible keys offline until they produced a message that had the same keyed hash as the one they’d saved.
That means the brute force attack could proceed at CPU speed, not merely at Wi-Fi network packet speed, and the researchers state that “in our setup, the brute force attack always succeeded in 140 minutes on average.”
(We’re assuming they tried it repeatedly just to test that their cracking code was working correctly, although with a hard-wired key shared by all Tapo bulbs, just their first crack would have been enough.)
As long as you’ll speak securely, I don’t care you who are
The next cryptographic problem turned up in the next stage of the light bulb setup process, and was a similar sort of mistake.
After accepting a light bulb as genuine based on a keyed-hash-that-doesn’t-actually-have-a-key, the app agrees on a session key to encrypt its traffic with the “genuine” bulb…
…but once again has no way of checking whether the key agreement took place with a real bulb or an imposter.
Agreeing on a session key is important, because it ensures that no one else on the network can snoop on the Wi-Fi and Tapo passwords when they are subsequently sent from the Tapo app to what it thinks is a Tapo light bulb.
But having no verification process for the key agreement itself is a bit like connecting to a website over HTTPS, and then not bothering to perform even the most basic check on the web certificate that it sends back: your traffic will be secure in transit, but could nevertheless be going straight into the hands of a crook.
The Tapo app identifies itself to the light bulb (or what it thinks is a light bulb) by sending it an RSA public key, which the other end uses to encrypt a randomly generated AES key to secure the data exchanged during the session.
But the light bulb device doesn’t provide any sort of identification, not even a checksum with a hard-wired 32-bit key, back to the Tapo app.
So, the app has no choice but to accept the session key without knowing whether it came from a real light bulb or an imposter device.
The combined outcome of these two flaws is that an attacker on your network could first convince you that their rogue access point was a genuine light bulb waiting to be configured, and thus lure you to the wrong place, and then convince you to to send it an encrypted copy of your own Wi-Fi and Tapo passwords.
Ironically, those leaked passwords really would be secure against everyone… except the imposter with the rogue access point.
Number-used-once that’s used over and over
Unfortunately, there’s more.
When we said above that “those leaked passwords really would be secure,” that wasn’t entirely correct.
The session key that’s established during the key agreement process we described earlier isn’t handled correctly, because the programmers made a blunder in their use of AES.
When the app encrypts each request that it sends to a light bulb, it uses an encryption mode called AES-128-CBC.
We won’t explain CBC (cipher-block chaining) here, but we’ll just mention that CBC mode is designed so that if you encrypt the same chunk of data more than once (such as repeated requests to turn light on and turn light off, where the raw data in the request is the same each time), you don’t get the same output every time.
If every light on and light off request came out identically, then once an attacker had guessed what a turn it off packet looked like, they could not only recognise those packets in future without decrypting them, but also replay those same packets without needing to know how to encrypt them in the first place.
As it happens, CBC-based encryption effectively relies on “seeding” the encryption process for each chunk of data by first mixing a unique, randomly-chosen block of data into the encryption process, thus creating a unique sequence of encrypted data in the rest of the chunk.
This “seed” data is known in the jargon an IV, short for initialisation vector, and although it isn’t meant to be secret, it does need to be unpredictably different every time.
Simply put: same key + unique IV = unique ciphertext output, but same key + same IV = predictable encryption.
The TP-Link coders, unfortunately, generated an IV at the same time that they created their AES session key, and then used the same IV over and over again for every subsequent data packet, even when previous data was repeated exactly.
That’s a cryptographic no-no.
Did I send six packets, or only five?
The last cryptographic problem that the researchers found is one that could still harm security even if the initialisation vector problem were fixed, namely that old messages, whether an attacker knows what they mean or not, can be played back later as if they were new.
Typically, this type of replay attack is handled in cryptographic protocols by some sort of sequence number, or timestamp, or both, that’s included in each data packet in order to limit its validity.
Like the date on a train ticket that will give you away if you try to use it two days in a row, even if the ticket itself never gets cancelled by a ticket machine or punched by a ticket inspector, sequence numbers and timestamps in data packets serve two important purposes.
Firstly, attackers can’t record traffic today and easily play it back later and potentially create havoc.
Secondly, buggy code that sends requests repeatedly by mistake, for example due to dropped replies or missing network acknowledgements, can reliably be detected and controlled.
What to do?
If you’re a Tapo light bulb user, keep your eyes open for firmware updates from TP-Link that address these issues.
If you’re a programmer responsible for securing network traffic and network-based product setups, read through the research paper to ensure that you haven’t made any similar mistakes.
Remember the following rules:
- Cryptography isn’t only about secrecy. Encryption is just one part of the cryptological “holy trinity” of confidentiality (encrypt it), authenticity (verify who’s at the other end), and integrity (make sure no one tampered with it along the way).
- Ensure any one-time keys or IVs are truly unique. The common jargon term nonce, used for for this sort of data, is short for number used once, a word that clearly reminds you that IVs must never be re-used.
- Protect against replay attacks. This is a special aspect of ensuring the authenticity and integrity we mentioned above. An attacker should not be able to capture a request you’re making now and blindly replay it later without getting spotted. Remember that an attacker doesn’t need to be able to understand a message if they can replay it and potentially create havoc.