-
-
Notifications
You must be signed in to change notification settings - Fork 523
Collaboration document for PSK Identity 02
Here we will share and organize our findings and data from #483
- firmware OS SDK version did not change, but the hash and build time did
OS SDK ver: 2.0.0(e8c5810) compiled @ Jan 25 2019 14:26:04-
OS SDK ver: 2.0.0(29f7e05) compiled @ Sep 30 2019 11:19:12- interesting that this build date corresponds with the release of tuya-convert 2.0, coincidence?
- psk begins with
02rather than01- guessing this will tell us the psk algorithm version
- disabled most of the serial debugging output
- unfortunate as this was a useful reverse engineering resource
- did not respond to our
smartconfigprocedure- it may use a new mechanism or additional restrictions have been imposed
- MAC address in flash appears to be compared with actual device MAC
- likely to foil reverse engineering attempts by running firmware on a dev board
- new factory written key found in flash,
"pskKey"- this may mean the encryption key will no longer be derived deterministically, big bummer
- only found in @rsbob's backup, looks like @Farfar's was updated to this firmware and thus lacks this factory written key
- this may mean there is still hope for devices that came with a lower firmware, since updating to this firmware would require fetching the key
- this is a very interesting new endpoint:
tuya.device.uuid.pskkey.get
It appears a unique preshared key is programmed into each device at the factory. Unlike before where the key could be derived from the TLS identity, now the identity is a hash of the device's id and MAC address. For those following along, the new identity derivation is:
'\x02' + 'BAohbmd6aG91IFR1' + sha256(prod_idx + mac_addr)
where prod_idx is the ASCII of the 8 digit product ID, and mac_addr is the MAC address of the device in hex, all lowercase, no punctuation. These parameters are all stored in the flash in a JSON blob at 0xfb000.
What changed was before the PSK was derived directly from the hint. Now it seems the key is preprogrammed at the factory, not computed on the device, and no information about it is ever sent to the server. The device sends its unique ID (basically MAC address) and the server figures out (presumably from a database) what the key should be. The device can request the server downgrade to the old authentication, but the server cannot ask the device to downgrade. Since we emulate the server, the downgrade path doesn't help us.
I tried to load the firmware backup onto a Node-MCU-like board, but I got this error
Yeah, they worked pretty hard on that. There a ton of checks and countermeasures to make running the firmware on anything other than the Tuya device very difficult. I'd assume the concern was counterfeit devices mooching off their cloud services. But as a result, getting this firmware running under a debugger is probably a real challenge. I relied on static analysis personally, so I didn't try it. They do many checks against the MAC address and hardware identifiers and each device is given a unique (?) API key, so if one was cloned, they could easily blacklist all of the cloned devices.
Curious constant (in tuya_tls.c, perhaps?)
Yes. It seems Tuya copied the xkcd getRandomNumber function (https://xkcd.com/221/). The "randomness" comes from a small fixed pool (the string you see there). There's a computation I don't fully understand at the beginning, but it effectively memcpys a substring of that pool to use as the random data for the TLS connection. Now I have no background in cryptography, but as far as I can tell, that is not actually exploitable for us because of the pre-shared key.
The missing part is how to compute the PSK from the PSK identity, if that is possible with the information we have.
As @iracigt has said, the
prod_idxis used to compute the PSK identity. This is handed to the server by the client during the handshake, so it is not secret information.
prod_idxis not secret information either, it is the first part of thegwIdas you have noticed, @CHAZICLE. In fact thegwIdis what is being hashed here, which isprod_idx+mac.
The point is that the previous implementation did leak secret information through the PSK identity, which we could use to compute the PSK. Now that it does not, our job is harder.
In order to solve this, we will need samples of actual communications between the client (smart device) and the server (Tuya cloud), along with a copy of that device's firmware. If anyone is able to provide both we may be able to crack this.
One possible procedure to accomplish this would be:
- Start with a new device
- Create a bridged hotspot using
create_ap- Start recording the network interface with
tcpdumpor WireShark- Connect smart phone
- Use the vendor app to connect the smart device to the hotspot
- Disconnect and stop recording
- Open the device and read the firmware over serial using
esptool.py
- Install
create_ap
git clone https://github.com/oblique/create_ap
cd create_ap
sudo make install
cd ..
- Setup a pass through AP (assuming your interface is
wlan0)
sudo create_ap wlan0 wlan0 MyAccessPoint MyPassPhrase
- Start recording
tcpdump -i wlan0 -w capture.pcap
- Connect your phone to
MyAccessPoint(or whatever you decide to call it) - Use the app (SmartLife or vendor branded app) to pair the device
- Wait for registration to complete
- Disconnect the device
- Go back to
tcpdumpand pressCtrl+C - Disassemble the device and connect to the serial port of the ESP
- Download the firmware using
esptool
esptool.py read_flash 0 0x100000 firmware.bin
- Upload both
capture.pcapandfirmware.bin
Get: https://github.com/espressif/esptool Issue command: esptool.py read_flash 0 0x100000 firmware-backup.bin
- BSD34 smart socket
- BSD29
- Deltaco SH-P01E
- Bakibo TB95
- Bakibo TP22Y
- MoesHouse Smart Downlight
- loratap sc500w curtain switch
- Teckin SB50
- Gosund 800l bulb
- Merkury MI-EW003-999W LED Light strip
- DETA Quad Smart Switch (6904HA)
- DETA Triple Smart Switch
- Arlec GLD060HA lamp
- AOFO Smart Power Strip (ZLD-44EU-W)
- Gosund SP 112
- Arlec PC399HA
- https://github.com/ct-Open-Source/tuya-convert/files/4021684/BSD34--image1M.zip
- https://github.com/ct-Open-Source/tuya-convert/files/4052386/Deltaco_SH-P01E_20200110_image1M.zip
- https://github.com/ct-Open-Source/tuya-convert/files/4287008/moeshouse_downlight_1m.zip
- https://github.com/ct-Open-Source/tuya-convert/files/4303944/BSD29_firmware_1M.zip
- https://github.com/ct-Open-Source/tuya-convert/files/4338606/module1.zip
- https://github.com/ct-Open-Source/tuya-convert/files/4360647/tuya_pairing.zip
- https://github.com/ct-Open-Source/tuya-convert/files/4364709/tuya_pairing.zip
- https://github.com/ct-Open-Source/tuya-convert/files/4732853/AOFO_ZLD-44EU-W_20200604_image1M.bin.gz
- https://github.com/ct-Open-Source/tuya-convert/files/4732914/firmware-backup.zip
- https://github.com/ct-Open-Source/tuya-convert/files/4142919/bakibo_bulp_pcap.zip
- https://github.com/ct-Open-Source/tuya-convert/files/4205411/bakiboT22Y.pcap.zip
- https://github.com/ct-Open-Source/tuya-convert/files/4338606/module1.zip
- https://github.com/ct-Open-Source/tuya-convert/files/4360647/tuya_pairing.zip
- https://github.com/ct-Open-Source/tuya-convert/files/4364709/tuya_pairing.zip
OS SDK ver: 2.0.0(29f7e05) compiled @ Sep 30 2019 11:19:12 [N]%s:%d metedata is without encryption, cover this partition with encrypted data [N]%s:%d var block [%d] last version is without encryption,now need to encrypt data and cover this partition [ERR]%s:%d flash_aes128_ecb_encrypt err [ERR]%s:%d !!!!!!CHIP_MAC:%s FLASH_MAC:%s!!!!!! aes-internal-dec.c aes-internal-enc.c lhttps://a3.tuyacn.com/gw.json https://a3.tuyaeu.com/gw.json https://a3-ueaz.tuyaus.com/gw.json https://a3.tuyaus.com/gw.json {"mac_addr":"500291e8f141","prod_idx":"26636676","auz_key":"wg7xdxUcsi7W0EmnPUlEtuwoyZwcF2W2","pskKey":"GUKgTWzsxGCn8UR5tIFFluuKD2qA8FYmaZwY2","prod_test":false} {"ap_ssid":"SmartLife","ap_pwd":null} {"CC":"CN"} vtrust-flash ESP_E8F141 vtrust-flash