The research paper “IoT Goes Nuclear: Creating a ZigBee Chain Reaction” by Ronen, O’Flynn, Shamir, and Weingarten garnered moderate media attention (here, here, here, etc) in early November, 2016. As I have worked extensively in ZigBee offensive and defensive security, but never specifically on the ZigBee Light Link (ZLL) profile, I was interested to dig-in and see what the main techniques and issues were, and what lessons other device manufacturers should take away from this disclosure.
So, if you didn’t read the entire paper and don’t trust news articles to give you the technical meat, what’s the bottom-line?
As mentioned earlier, if you were an attacker with a ZigBee sniffing/injection platform such as the ApiMote with an external antenna & amplifier (or another platform such as an SDR) you could spoof the “proximity” heuristic used by Touchlink by simply increasing the power that you transmit at and the sensitivity when receiving. That however doesn’t work for the worm use case.
The Atmel stack used in the Hue lights, as disclosed by serial logs, had an implementation bug in the state machine. I’ll describe it here.
In the Atmel stack, the value of “transaction ID” is checked against an array of 3 state structures which are all initialized to zero on boot. This is usually OK as zero is a non-supported transaction ID value, so they know to ignore that entry in the array (as invalid/unfilled). However, the check to make sure the input value (provided by the RF message) is not zero is only done in the “expected” protocol path — when a “Scan Request” message is received. This check is not done again when the reset message comes in – and thus the actual reset message can be sent with a transaction ID of 0 and it will be accepted if any of the 3 slots are not filled with legitimate Touchlink states at that time.
Despite this issue on the “reset” path, there were checks that blocked an attacker from directly using the “join to a new network” command (even though the message is handled similarly to a reset) as Atmel’s function for the decryption of network keys used to join to the new network checked that the transaction ID was not 0. Thus the bug to get the message received with an ID of zero was ineffective. However, this issue does not prevent performing the simple reset.
This part of the work was, in my opinion, the most concerted effort by the researchers to overcome a security mechanism, and represents significant effort applied by an advanced “attacker.” It’s important to note AES-CCM* as used by ZigBee had already been attacked in previous works, but this research targeted the AES-CCM used in the firmware authenticated encryption. As a result, the constraints were different, especially with number of blocks and the nonce setup being unknown.
I will not attempt to make a short summary of the different attack techniques (including two side-channel power analysis attacks) combined to achieve the extraction of the key. What I found interesting was the choice to attack the AES-CBC used in the authentication portion of CCM, as they can flash firmware which will be run through the verification, and thus they control the cipher text which the AES-CBC is being computed over. When they recover the key via this, that’s the same key as used for the CTR encryption portion of CCM. (As a reminder, AES-CCM uses the same symmetric key for AES-CTR to provide confidentiality and AES-CBC to provide integrity by producing an authentication tag.)
As someone who has done many reports of vulnerabilities, both privately for manufacturers and some published, I feel like we all-to-often focus only on what was “wrong,” at the expense of acknowledging some things that were done right. Let’s look at what was done well to secure this device:
Even with these things done “right” – including some items that I see overlooked in many devices on the market – it wasn’t enough to stop a determined attacker. I would argue, however, that doing these things significantly raised the level of effort needed to attack the system.
I think this is excellent work, and I’d love to see some parts of their tools published so they can be reused by the security community – specifically (a) the Python code they wrote for handling the ZLL protocol (similar to the Scapy code used with KillerBee) and (b) the integration of the CC2531 transmit/receive code into KillerBee, so that other people can leverage that hardware (in addition to the devices supported today such as the RZUSBSTICK and ApiMote) in a common platform.
I saw only one minor potential flaw in the write-up version I read, which said on Page 5 that “For this encryption, a secret “Master ZLL key” is used. This key is shared by and stored on all ZLL certified products. It is not specified in the standard and is only provided to ZigBee alliance members that are developing ZLL certified products. Unsurprisingly this master key was leaked in 2015 and can be found on-line [10]”. I think it’s important to note that the key referenced in the cited work is included in some ZigBee standards, the distribution of those documents is not limited to only ZigBee alliance members (so it wasn’t leaked as much as “republished” in the cited work).