In August I decided to check out the cool new Internet Of Things. I bought a WiFi-enabled colorful LED lightbulb. It was a cheap Chinese one that costs almost nothing on Alibaba, but I paid probably around $50 on Amazon. It’s built by a company called Zengge. It turned out that my new lightbulb was a router, an HTTP server, an HTTP proxy, and a lot more. None of the vulnerabilities have been fixed as of the writing of this blog post. To help with testing out these vulnerabilities I created a Go library and command line tool. It can do a lot of what the Android app can do, but it can be used in scripts and by web servers. I strongly encourage someone to let people control their lights over the Internet and do a live stream of it.
Reported – September 1, 2015
First response – September 1, 2015
Acknowledged the issue – September 1, 2015
First attempt at fix – September 14, 2015
First attempt defeated – 3 hours later
Second attempt step 1 (new version released) – ~ October 13, 2015
Checked up on them, still not done, giving 1 month notice – November 18, 2015
Published – December 19, 2015
How it works
The lightbulb is normally controlled with an Android app. It joins your WiFi network and can be controlled locally or over the Internet. Control over the Internet is disabled by default. That’s one thing they did right. There are three ports: TCP 80, TCP 5577 and UDP 48899. 80 serves a broken page. 5577 controls the ligthbulb. 48899 controls the router.
The router port allows you to do anything. You can flash the firmware, use it as a proxy, read the WiFi password, make it join a different network, etc. This port is normally exposed only to the internal network. The commands are of the form
AT+ followed by the name of the command and optional arguments.
When you set up the lightbulb for control over the Internet it uses no encryption, but all it allows you to do is control the light, so it’s not that bad.
More information can be found in the README for the Go library.
Summary of Vulnerabilities
This system has the same threat model as the WeMo baby monitor by Belkin. It assumes that all devices on the local network can be trusted.
I believe that this threat model is insufficient for the following reasons:
- People let others onto their network often. This is especially true for offices, restaurants, coffee shops, etc.
- Malware on any machine behind the network can use its privileged position to attack the rest of the network.
- My favorite law of computer security is “If it should never be on the Internet, someone has put it on the Internet”.
The following summarizes my findings:
Attacker | Control Lights | Replace Firmware | HTTP proxy | Read SSID + PASS Local* network | Y | Y | Y | Y MITM on the Internet | Y | N | N | N Anyone on the Internet** | Y | N | N | N
* The “local network” is anyone on the Internet if you expose the device to the Internet.
** This is the one attack that Zengge is trying to fix.
Local network attacks
AT commands are accessible from the network with the hard-coded password
HF-A11ASSISTHREAD. They can be used by simply sending UDP packets on port 48899.
AT+UPURL command allows anyone with access to flash it.
Reading the WIFI password
AT commands allow anyone with access to read the WIFI password.
Use as a proxy
AT+HTTPDT command and other related HTTP commands can be use to make the lightbulb make requests on the attacker’s behalf, acting similarly to an HTTP proxy. This can give the attacker the ability to potentially make requests from behind whatever firewall or NAT the lightbulb is within.
By design anyone who has ever been on the same network as the bulb gets access to the remote control feature. They just have to remember the MAC address of the lightbulb. This is a separate weakness from the “Remote control over the Internet” section. This weakness makes it impossible to revoke an attacker’s access to your lightbulb once they know the MAC address.
AT+MDCH feature configures whether or not the bulb will go back into wifi AP mode if it fails to connect to an access point in STA mode. It has a few options:
- on – 1 minute
- auto – 10 minutes
- 3-120 – minutes to reset
The default is 10 minutes. This means that if you can take down the wifi it connects to for 10 minutes, you can force the bulb to enter AP mode. In most cases (unless the user configured it otherwise) the AP will be open and an attacker can connect and execute any of the local attacks.
Dangers of exposing the bulb to the Internet
If the lightbulb is exposed to the Internet, an attacker from anywhere in the world can get access to the user’s internal network vy performing the proxy attack described above. They can also geolocate them by using the MAC address of the router and looking it up in Wigle or some other wardriving database. Since they have the wifi username and password they can go to the location and connect to the same access point as the lightbulb. If these attacks are not sufficient, the attacker can flash the lightbulb with their own software that allows additional attacks.
Getting access to a user’s internal network opens the door to a large number of possible attacks. Describing them is beyond the scope of this document.
I tried scanning the Internet for Zengge lightbulbs with exposed management ports exposed and I found at last two. I don’t have a good Internet connection and I didn’t scan every IP, so there are probably way more than two out there. The information disclosed by the lightbulb allowed my to geolocate the owner of the IP address and know their WiFi SSID and password.
Remote control over the Internet attacks
There is no authentication that proves that someone is allowed to control a lightbulb. If you know the MAC address and the bulb is configured to listen to commands over the internet, you can control it.
The MAC address prefix that the lightbulbs use is
ACCF23, which is registered to hi-flying. The last 3 bytes of the mac address identify a unique device. These are 16777216 possibilities, so it would take on the order of a year to scan the entire namespace. However, the MAC addresses are very close to each other because they are assigned sequentially, so in practice you can limit your scan to only valid MAC addresses if you know one of the MAC addresses.
The first non-manufacturer byte of the mac address for a lot of the lightbulbs is 5F. Once you know that, you can easily do a scan of the 65536 addresses in a matter of hours.
This means that it takes very little time and effort to gain control over almost all lightbulbs with the “remote” feature enabled.
I tried this attack and got access to 541 lightbulbs. This was a few months ago, so there are probably even more now.
This attack is prevented in the Hue lightbulb by automatically discovering devices using the source ip. This is further strengthened by having a button on the bridge that users have to press to allow their device to become discoverable.
The commands from the phone to the server are “signed” using AES256. This is similar to Hue’s use of AES for encrypting connections from their bridge to their website instead of using public key cryptography. In this case it was much easier to get the AES key because it was in the Android app.
Local friend’s device takeover
When the phone queries the “Remote Settings” it receives a list of authorized devices for the currently light bulb. The api call is “GetAuthUserDevice”. This list contains the device id of every phone that is authorized. This is a problem because an attacker can use the device id to “log in” as the device. This makes the following attack possible:
- A has a light bulb LA
- B is friends with A and has light bulb LB at home
- B comes to A’s house and A lets B control LA
Now we have:
A, B -> LA
B -> LB
- A queries the list of devices that can control LA and gets B’s device id
- A can log in as B and control LB.
Zengge responded to me, acknowledged the “Remote control over the Internet” attack and started trying to fix it. Their first attempt to fix it was to rotate their shared secret and obfuscate it in their app. They sent me the obfuscated app and within 3 hours I was able to get the new secret out of it. This discouraged them from trying to obfuscate it and they started working on a real fix.
They released a new version of the app that modifies the registration process slightly. It makes the app wait for the lightbulb to connect to their server first, then when the app connects to the server the server can make sure that the request is coming from the same IP. That makes this particular attack fail because the attacker doesn’t have the ability to make connections from the same IP address as the victim.
It has been two months since they’ve released the new app and almost four months since I reported the vulnerabilities. They have not enabled the check on the server side yet, so all of the attacks I described still work. Considering the fact that the impact of this vulnerability is not very serious – controlling strangers’ lightbulbs – I decided to just release my findings.