-
-
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
Much of this was bulk copy-pasted and needs to be transformed into a useful form
- Derive the PSK from the PSK identity or other known information, if that is even possible with the information we can obtain before a TLS connection is established.
The challenge of this issue is mapping known information (ie gwId) to the PSK (pskKey), which as mentioned before is indeed unique to every device. This is not possible to extract from the firmware, because to obtain the firmware would require we already know the PSK (or open the device at which point OTA becomes moot).
The previous implementation leaked information through the PSK ID (the MD5 of the auzKey), but this latest implementation uses already public information (the SHA256 of the gwId) as the PSK ID.
It may be that the pskKey is totally random and only stored on Tuya servers and the smart device. If this turns out to be the case, there is no solution to our challenge and this strategy of flashing firmware OTA is no longer viable.
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, it is the first part of thegwId. 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.
- 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
- this means that a given firmware backup will only run on the original device
- new factory written key found in flash,
"pskKey"- the app never has access to the PSK, it is only used between the IoT device and the cloud
- once written to flash it is never transmitted, period.
- stored in JSON blob at 0xFB000
- this is indeed the PSK key, unencrypted
- this means if you have a firmware backup you can use this to decrypt captures from the same device
- since obtaining the firmware requires a working hack or physically opening the device, this doesn't help us for OTA purposes
- the PSK key does not change with each new session
- previously the PSK key changed each session, computed using the PSK ID (fixed) and PSK hint from the server (variable)
- the previous implementation leaked information via the PSK ID while 02 does not
- 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- if we can figure out the format of this call, we could try faking it and seeing what it returns after multiple calls
- to do this, we'll need to capture network traffic from a device upgrading to this firmware from an older one without PSK 02
- PSK ID derivation:
- '\x02' + 'BAohbmd6aG91IFR1' + sha256(gwId)
- where gwId = prod_idx + mac_addr
- where prod_idx is an 8 digit ASCII identifier for that device model
- where mac_addr is the lowercase hex representation of the device MAC address
- 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.
- outside of updating a vulnerable device to the new firmware, the PSK never leaves Tuya's servers
- Since this communication is encrypted by the highest version of the encryption scheme that the device supports, this isn't too helpful. Currently we can only decrypt that communication if the device is on the old firmware or we have a firmware dumps from that particular device.
- the PSK is unique to each device, not shared among an entire model
- there is currently unused code for what I think is certificate pinning in the Tuya SDK (the one on the device)
- the server cannot tell Tuya devices to turn off encryption
- The devices will reject any connection not secured with the TLS_PSK_WITH_AES_128_CBC_SHA256 cipher suite.
- why do they use PSK, why not do the certificate pinning to the cloud?
- likely answer is that the public key cryptography necessary to validate a certificate or chain is too slow on the ESP8266
- The alphabet for both auz_key and pskKey seem to be (a-z, A-Z, 0-9)
- We know that is it likely not base64, as we have plenty of samples and no instances of the
+/characters - It is possible that it is base62, but it seems more likely that this is a random string generated at the factory and stored only on the device and the cloud.
- That would lead me to the guess, that they are not the result of any computation (like hashing the mac_addr or the like), because converting the binary result of such a computation into the above format is not straight forward.
- Does anybody have an idea, why the length of the pskKey is 37? That sounds rather random.
- We know that is it likely not base64, as we have plenty of samples and no instances of the
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
Could we get some insight into whether the new PSKs are being randomly generated by flashing a device back and forth between old and new patched firmwares?
For example:
- take a device with pre-patched Tuya firmware and back it up
- register the device to the app and get the updated patched firmware
- backup the new firmware to determine the new PSK
- flash the device back to the pre-patched firmware
- register the device again to the Tuya app to get the patched firmware
- backup the new firmware, extract the PSK and determine if it matches the PSK from step 3)
This assumes you have a device you can physically flash and that it's possible for us to flash a device with an older version of the Tuya firmware.
It may be when a device is first updated through the app, that the new randomly generated PSK is linked to the device MAC (or other device identifier), and that same PSK is issued again after downgrading and updating. Or a random PSK is generated each time.
To clarify: As I understood, we need a device with a firmware that can be converted but isnt yet or one that has been converted + a backup of its original backup availiable. Then follow the steps of @finnzz . Devices that can not be patched are around and afaik dont help.
In this case you know there is a patched firmware available, which may also be waiting in the Tuya app for devices still on the old firmware. And if you can open the device up to serially flash, then you can run through the procedure.
As @Schlabberanesi was saying, another option is that you have a device with Tasmota/ESPHome, you saved the stock firmware, and you know the device has the patched firmware waiting for it in the Tuya app. You could then serially flash that Tasmota/ESPHome device back to stock and go through the process of ungrading/downgrading described above.
Edit: The question here is how are devices with old firmware being integrated into Tuya's newer security scheme. And can this help us understand how these new PSKs are created.
Just to summarize what would be needed:
- need a Tuya device with old firmware, that works with TuyaConvert
- a patched firmware has to exist for that device model, and be available in the Tuya app for you to get.
- you need to be able to open the device up to serial flash it.
- AOFO Smart Power Strip (ZLD-44EU-W)
- Arlec GLD060HA lamp
- Arlec PC399HA
- Bakibo TB95
- Bakibo TP22Y
- BSD29
- BSD34 smart socket
- BW-LT29
- Deltaco SH-P01E
- DETA Quad Smart Switch (6904HA)
- DETA Triple Smart Switch
- Etersky WF-CS01 Curtain Switch
- Gosund 800l bulb
- Gosund SP 112
- Gosund WB4 bulb
- Jinvoo SM-PW713
- LOHAS E14 bulb
- loratap sc500w curtain switch
- Merkury MI-BW320-999W Light bulb
- Merkury MI-EW003-999W LED Light strip
- MoesHouse Smart Downlight
- NX-SM112
- NX-SM400
- Teckin SB50
- TreatLife Smart Dimmer Switch DS01C
- UCOMEN Outdoor Sockets PA-GEBA-01SWP2
- Zemismart 6 inch 14W WiFi RGBCW
- 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/4743192/gosund_sp112_capture.zip
- https://github.com/ct-Open-Source/tuya-convert/files/4755710/Merkaryv3.3.zip
- https://github.com/ct-Open-Source/tuya-convert/files/4812333/gosund-WB4.zip
- https://github.com/ct-Open-Source/tuya-convert/files/4875072/dxpow_WP1_original_fw.zip
- https://github.com/ct-Open-Source/tuya-convert/files/4903594/backup_20200709_112518.zip
- https://github.com/ct-Open-Source/tuya-convert/files/4907683/backup_20200711_210602.zip
- https://github.com/ct-Open-Source/tuya-convert/files/4981803/firmware-backup-devices.zip
- https://github.com/ct-Open-Source/tuya-convert/files/5011017/tuya1way_flash_1M.zip
- https://github.com/ct-Open-Source/tuya-convert/files/5015727/firmware-baf0cc.bin.zip
- https://github.com/ct-Open-Source/tuya-convert/files/5016179/Backup.zip
- https://github.com/ct-Open-Source/tuya-convert/files/5018720/Tuya_Backup_20200803_134931.zip
- https://github.com/ct-Open-Source/tuya-convert/files/5037513/old-original-fw.zip
- https://github.com/ct-Open-Source/tuya-convert/files/5059741/backup_BW-LT29.zip
- https://github.com/ct-Open-Source/tuya-convert/files/5067474/backup_20200812_163954.zip
- https://github.com/ct-Open-Source/tuya-convert/files/5069154/MoesGarageDoor.zip
- https://github.com/ct-Open-Source/tuya-convert/files/5071350/firmware-backup.zip
- https://github.com/ct-Open-Source/tuya-convert/files/5080563/firmware-backup.zip
5 firmware backups that tuya convert made. One from a smart plug and another four from smart switches.
firmware-9c52d8.bin.gz firmware-52a6fb.bin.gz firmware-a068f4.bin.gz firmware-a0709d.bin.gz
- 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
- https://github.com/ct-Open-Source/tuya-convert/files/4743192/gosund_sp112_capture.zip
- https://github.com/ct-Open-Source/tuya-convert/files/4755710/Merkaryv3.3.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
{"ip":"10.42.42.16","gwId":"22885450c44f33b5ed3e","active":2,"ability":0,"mode":0,"encrypt":true,"productKey":"key75ugrk53wuycc","version":"3.3"}
{"mac_addr":"c82b964e3b29","prod_idx":"64785071","auz_key":"eDOnWtAUy5gJOiKtcXkNplBMqOMjJmM3","pskKey":"ggD99i71cC7R7MTVnHadCtjaK28H2f6fOJLrG","prod_test":false}{"mac_addr":"c82b964e3b22","prod_idx":"64785071","auz_key":"in18hm8DJch2NzlkjkSVHVuFJ3kpUo6k","pskKey":"hcXNpRfvnob0zqZWQ4zL4oxa0BHHRzC6jns3X","prod_test":false}
https://github.com/ct-Open-Source/tuya-convert/issues/483#issuecomment-599560871 : {"mac_addr":"2462ab3989fe","prod_idx":"08488420","auz_key":"diI5mLzLQx5GBNCQQZsZ8J0dQLYMaAeT","pskKey":"Z9ir6z2hsTlRVJKwEZyqpfyIzfLyzkMBkwyGd","prod_test":false}
https://github.com/ct-Open-Source/tuya-convert/issues/483#issuecomment-570766710 :
{"mac_addr":"c44f33bc1794","prod_idx":"65046664","auz_key":"tKzPU69mMe3ns8PmA5M2cAuUUDOtrTeA","pskKey":"yhULg57DUA3Uo1xTP5xhoI0C1kRpWQOwqjMO8","prod_test":false}
https://github.com/ct-Open-Source/tuya-convert/issues/483#issuecomment-594468592 :
{"mac_addr":"98f4abc96ac3","prod_idx":"06402221","auz_key":"Yw0VAIvFe3aWlvdKEZfmBPg8xfQ3Jg4Q","pskKey":"kPJ6yZaAbTUqlk5fHrCN6DyWY2Flz9LLI49un","prod_test":false}