[Back to 2020] ESPHome leak authentication key
TL;DR
Hi all, This is my first blog actually. I found this one in 2020 but I just report to HomeAssistant and public market and no CVE reg
Vulnerability
I found when working with a smart home “platform” (this isn’t actually a platform but at here I will call it is). This bug allow leak the password of connection between device using ESPHome (EH) and gateway using Home Assistant (HASS) of IoT system (link will be published below). I will explain why this bug happened. The problem at the way to connect between EH and HASS. The HASS possesses the “auto-reconnecting with devices” feature. Auto-reconnect is a normal and necessary feature in IoT system, but way to perform it not secure. I read the doc of EH and I found the protocol:
In the handshake phase, the EH device is the server, listening to the connection, HASS is client, will send the request to connect. The password of API was config in EH device and the user has to provide this password to HASS to connect with the EH device. The steps of the handshake was described like below:
For the first time, the second time,… or any time to connect, they also will do the same. But this is not 3-way handshake (3-way handshake example like TCP), so what happens? Because connection only verifies from one side (EP), so password of connection has to be saved on one side (HASS) and this password will be used for each time of handshake. Thus, if I can fake the EP device that connected before, I will leak the password of the connection. I continue to read the doc and source code in EH’s github and I found the code of implement for protocol be used. In that code, I found out the interesting info. This is data fields EH provide for HASS:
HASS has to discern different EH devices to send the correct password for auto-reconnect. Only mac_address
value can be used for identification. Thus, if I can fake “mac_address”, I will leak the password. Continue reading the source code of EH, I saw that EH was build base on Platform-IO
using ESP8266Wifi.h
, ESP32Wifi.h
,… libraries.
With a little experience with Arduino, ESP8266Wifi.h
(same with ESP32Wifi.h
, Wifi.h
,…) provide wifi_set_macaddr
function to change the MAC (done :)) ). Let setup the exploit.
Exploitation
- Firstly, I build a HASS on Raspberry and EH on ESP8266 to control a light with a password. Then, I use other ESP8266 device with my modified EH code. At here, I am using
WifiAP::set_ssid
at “/components/wifi/wifi_component.cpp” to sure that my code will be executed before connecting wifi.
- Moreover, I insert some code to log the password received. I choice
APIConnection::connect
at/components/api/api_connection.cpp
- Finally, config the wifi ssid and password, upload firmware and wait result:
The API’s key can use for attacker’s HASS server to get the control permission of ESPHome device. I called it is Take over
vulnerability.
Conclusion
After 2 years, I cameback and mail to vendor, having a fix version for it. The vendor added the encryption
option in yaml
file config to help encrypt the data when transfering.
First memory when finding vulnerability. :))