Closed engelant closed 6 years ago
I haven't heard of anyone doing that, although I do know that at least one person has cracked their device open and directly flashed new firmware onto the board.
According to Tuya's docs (scroll/search for section 3.10), it may be possible.
If you manage to, let me know. 😃
I was fortunate enough to get a device that needed a firmware update and hence captured the traffic from my router between the device and the outside world. Here is a run down of what it did - I have tried to identify my private information by substituting
I have attempted to replicate the ota process by running a local mqtt and webserver and redirecting locally - I have got as far as it downloading the 64 byte header of the Sonoff-Tasmota firmware.
MQTT - App Triggered MQTT Publish via Cloud which seems to kick off the OTA update
Topic: smart/device/in/
HTTP:
Post http://a.tuyaeu.com/gw.json?a=tuya.device.upgrade.get&gwId=
HTTP:
Post: http://a.tuyaeu.com/gw.json?a=s.gw.upgrade.updatestatus&gwId=
Response: {"t":1544007193,"e":false,"success":true}
HTTP: Header: Range: bytes=0-63 Get: http://s3-us-west-2.amazonaws.com/airtake-public-data/smart/firmware/upgrade/201810/1539875023-oem_esp_dltj_ug_1.1.0.bin
Partial Response: UªUª1.1.03M#gMGM#'\½ªUªUê @À
... must perform some validation of the first 64 bytes of the firmware probably looking for the version number and it contains the sizing and offset for the next request ... offset in hex: 00064D47 (dec: 412999) and size in hex: 00064D14 (825947 [file length] - 412999 [offset] = 412948 [section])
HTTP: Header: Range: bytes=412999-825946 Get: http://s3-us-west-2.amazonaws.com/airtake-public-data/smart/firmware/upgrade/201810/1539875023-oem_esp_dltj_ug_1.1.0.bin
Partial Response:
MQTT:
Topic: smart/device/out/
... a number of progress MQTT Publish...
MQTT:
Topic: smart/device/out/
... tuya device did a reboot ...
DNS Query: mq.gw.tuyaeu.com
MQTT Connect:
Client ID:
DNS Query: a.tuyaeu.com
HTTP:
Post: http://a.tuyaeu.com/gw.json?a=s.gw.update&gwId=
Response: {"t":1544007229,"e":false,"success":true}
This seems to be exactly what I was looking for, so thanks. You didn't happen to dump the original bin file, did you? I'll have a closer look at this the next weeks, since I'm a little busy these days. afaik the signature is just a hash of some post vars from the request, salted with the device secret key. I'll have to look into my code from back in august, since unfortunatly a few months passed by and I don't remember everything. At first glance it looks like the bin is not encrypted, but X-mas is coming, so I'll find a few days to go into more detail I guess.
No I didn't dump the original bin file however I have a second device that is still needs to be updated. When I get time I will make an attempt - recently moved and need to find the soldering iron.
In the meantime I will continue to see if I can get the firmware header correct. Right now the device is downloading my header multiple times.
Here's an older version of the firmware http://s3-us-west-2.amazonaws.com/airtake-public-data/smart/firmware/upgrade/201806/1528276183-esp_bsd_jl_plug_America_ug_1.0.5.bin
I think mine came with 1.0.0 or 1.0.1, though
anything new on this ?
The 1.1.0 firmware linked above has a header that is 51 bytes long and is then followed by the actual firmware image. Esptool reports the following about the firmware:
Image version: 2
Entry point: 40100004
4 segments
Segment 1: len 0x5b9c0 load 0x00000000 file_offs 0x00000008
Segment 2: len 0x066ac load 0x40100000 file_offs 0x0005b9d8
Segment 3: len 0x004dc load 0x3ffe8000 file_offs 0x0006208c
Segment 4: len 0x02788 load 0x3ffe84e0 file_offs 0x00062570
Checksum: a5 (valid)
What might work for OTA updating is replacing the tuya image with a tasmota one. You might also have to update the firmware version number in the header (located at bytes 4 - 8).
The bad news is I've managed to brick my plug by forcing it to install 1539875023-oem_esp_dltj_ug_1.1.0.bin firmware. The good news is that now I have an excuse to take it apart and try to fix it. I guess the firmware wasn't intended for my plug.
In other news, it turns out the firmware file actually has 2 different firmwares in it. Here is what I'm guessing the header contains:
55 aa 55 aa - Prefix
31 2e 31 2e 30 00 00 - Version "1.1.0"
00 00 00 00 - Don't know (could be zero padding of version string)
00 00 00 02 - Number of firmwares in file
00 00 00 33 - File offset to first firmware
00 06 4d 14 - Length of first firmware
02 23 00 67 - Sum of all bytes in 1st firmware
00 06 4d 47 - File offset to second firmware
00 06 4d 14 - Length of second firmware
02 23 27 5c - Sum of all bytes in 2nd firmware
00 00 05 bd - Sum of all previous header bytes
aa 55 aa 55 - Suffix
I can get the tuya plug to download and install the sonoff-basic firmware by constructing a binary using the above format header with 2 copies of the sonoff-basic appended. Unfortunately the plug no longer boots once its installed. I suspect that I'll have to get it to install some interim firmware and then get this to install sonoff-basic. I've posted in the SonoffUsers group and hopefully somebody will have some ideas on how to proceed.
I'm on the edge-of-my-seat here 😃 Did you try the minimal version of the firmware ?
The minimal version is the same. At the moment I'm looking at what SonOTA did to see if I can adapt that.
fwiw, there is also an Espurna core version which is only 299 KB, created to simplify OTA updates. https://github.com/xoseperez/espurna/wiki/TwoStepUpdates
SUCCESS I used the stage 2 firmware from SonOTA (image_user2-0x81000.bin) and when the plug rebooted it acted as an AP with an SSID of "FinalStage". A bit of messing around with setting my wifi to connect to that SSID and setting up a HTTP server to let it download sonoff-basic (renamed to image_arduino.bin) and I now have the sonoff-basic firmware on my plug.
can you do a detailed write-up ? I'm aching to try this on one of the lightbulbs where I can not reach the serial pins without destroying the lamp.
Will do.
WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING THIS IS EXPERIMENTAL, IT IS POSSIBLE THAT FOLLOWING THESE INSTRUCTIONS WILL TURN YOUR DEVICE INTO A PAPERWEIGHT WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
Files tuya.zip
Instructions for Updating Tuya device OTA
I did this on a linux machine running openSUSE 15.0 but there is no reason why it shouldn't work on other flavours of linux and should be easily adaptable to windows.
Prerequisites
NOTE Although three computers are mentioned above everything can run on one computer provided that the web server is not listening to either port 80 or port 8080
Setting Everything up
Web Server
You need store the firmware tuya-sonoff.bin
under a directory called ota
. Download your target firmware and store it as ota/image_arduino.bin
.
DO NOT USE sonoff-minimal.bin
I recommend using version 6.2.1 of sonoff.bin
and if everything works you can then use its OTA mechanism install a different version.
Redirecting HTTP requests (the difficult bit)
If you are in Europe then your Tuya device probably makes HTTP request to a.tuyaeu.com
. If you are in another part of the world then it could be a.tuyacn.com
or a.tuyaus.com
. You should be able to find out which one it is by snooping port 80 traffic from your device. Once you know what it is then you need to redirect these request to one of your computers.
I did this by using dnsmasq
to return my address when the device did a DNS query for a.tuyaeu.com
. An alternative would be to have a firewall redirect requests. Whatever method you use, the computer you are redirecting to must be able to lookup the correct address and access the remote site.
Running the Scripts
There are 2 scripts, tuyaproxy.pl
and finalstage.sh
.
In tuyaproxy.pl
change the $WEBSERVER
variable to point to the web server with the firmwares.
In finalstage.sh
change DEVICE
to your WiFi device (usually wlan0)
and WEBSERVER
and PORT
to your web server.
tuyaproxy.pl
needs to run as root on the computer you are redirecting the http requests to.
finalstage.sh
needs to run as root on the computer with WiFi
Installing the Firmware Once both scripts are running, http requests are being redirected and both firmwares are on the web server then power off your device, power it on and go and have a cup of coffee.
After everything has finished follow the sonoff getting started instructions.
Acknowledgements Thanks to Mirko Vogt for the original SonOTA. This uses the second stage firmware from that project.
Awesome. Will try it with my plugs and let you know. I will also try with my lightbulbs.
This definitely changes things! Have a plug I can flash the Tuya junk back on it and test with.
Don't have a full blown Linux build going except my media server but I think a wired raspberry Pi should work with this right since it has Wi-Fi capabilities as well?
There is no reason a Pi wouldn't work.
@SynAckFin , is this you ? https://community.home-assistant.io/t/cheap-uk-wifi-bulbs-with-tasmota-teardown-help-tywe3s/40508/6?u=tommmii
No, that's not me
In tuyaproxy.pl change the $WEBSERVER variable to point to the web server with the firmwares.
Shouldn't the port be edited to whatever port the webserver is listening on ?
I feel like I am close.. I saw one plug request firmware with the log from the pl script but on the webserver I am not seeing any requests for the bin file though. I did a wget from that Pi just to make sure the bin was accessible and that works but I just don't see the plug asking for that bin yet.
@digiblur did you edit line nr 8 in tuyaproxy.pl ?
my $WEBSERVER = "http://YourWebServer:8000/";
If you add:
print("URL: $Firmware->{result}{url}\n");
to the pl file just before the while
statement (about line 29) then it will output the url it sends to the device. You can then check this is valid using wget on the Pi.
Another thing you should check is that the Pi can reach the tuya site. Try:
ping a.tuyaeu.com
to check it can
@SynAckFin so the Pi running the PL still needs to reach the real a.tuyaus.com? That would be my issue then as my whole network is redirecting.
ahhh...I added that print and it was doing a ....server:8000// I removed the trailing / from the variable and the URL looks right now. Now to get it to request a firmware again. Patience...
@SynAckFin so the Pi running the PL still needs to reach the real a.tuyaus.com? That would be my issue then as my whole network is redirecting.
Are you doing that with a firewall or dnsmasq?
Have PiHole running along with a rule on my firewall that redirects any devices that don't listen to the DHCP DNS config to go through the PiHole for DNS. I can ping that address fine though.
Seeing these in the perl logs... trying to get a plug to ask for a firmware update but it just wants to do these. I'll keep messing with them. It seemed if I did another pairing session it would check for firmware pretty quickly but now it's being a pain.
/gw.json?a=s.gw.dev.pk.active&gwId=685010.......
for me, the proxy script isn't feeding the firmware URL :
user@debian:~/tuya$ sudo ./tuyaproxy.pl
URL: http://192.168.11.222:8000/ota/tuya-sonoff.bin
/gw.json?a=atop.online.debug.log&gwId=14801348b4e62d1d5c5e&t=10&sign=3bc1197785bc420d72139535906f0cd2
I had one device hit twice with this at one time but I had the incorrect URL...now to get it to ask again.
/gw.json?a=tuya.device.upgrade.silent.get&gwId=03200.....
Within about a minute of powering the device off and then on you should see
Sending Firmware Response...
/gw.json?a=s.gw.upgrade.updatestatus&gwId=
The device only seems to send it one time after powering up. You may see other log entries before the upgrade one.
@SynAckFin can you add more debug info to the proxy script ? such as the ip of the device that is requesting ?
The device definately isn't looking for updates any more...perhaps only 1x per day ?
To find tuya devices on your network run the following:
nc -u -l -k -p 6666 | strings
If strings
isn't found (it isn't always installed) then just run:
nc -u -l -k -p 6666
The output wont be as pretty but you can find out the IP addresses of the devices
I'm just re- flashing tuya onto one of my devices and once I've done that I'll add more output to the script.
it's detected alright...it just doesn't want to ask for available update
user@debian:~$ sudo nc -u -l -k -p 6666 | strings
{"ip":"192.168.11.140","gwId":"14801348b4e62d1d5c5e","active":2,"ability":0,"mode":0,"encrypt":true,"productKey":"key4fv3sx8twchhy","version":"3.1"}Z
errr, i just saw this in the proxy output :
/gw.json?a=tuya.device.upgrade.silent.get&gwId=14801348b4e62d1d5c5e&t=40&v=4.1&sign=302b82d250cd057342b8175f3774ba85
but the proxy script didn't send the FW response ??
Same here...just had one ask and saw the Sending firmware response... URL is showing correct though and works. It didn't pull the bin. Hmmm...
either the device isn't getting the response, or it isn't happy with what it receives and ignores it.
I noticed I'll see the tuya.device.upgrade.silent.get line but takes several minutes to post the Sending Firmware Response... line.
I've just realised something here. If the url uses a hostname and not an IP then it needs to be fully qualified and resolvable by whatever dns server the device uses (specified in the DHCP response). For example:
http://myserver/ota/tuya-sonoff.bin
will fail even if other computers on your network can resolve it. On the other hand:
http://myserver.somewhere.com/ota/tuya-sonoff.bin
will succeed provided the dns server resolves myserver.somewhere.com
to your machine. On the other hand:
http://192.168.1.10/ota/tuya-sonoff.bin
should work.
my URL to be injected is :
URL: http://192.168.11.222:8000/ota/tuya-sonoff.bin
The device is indeed asking at regular interval :
/gw.json?a=tuya.device.upgrade.silent.get&gwId=14801348b4e62d1d5c5e&t=40&v=4.1&sign=302b82d250cd057342b8175f3774ba85
The answer is very slow, a minute or so :
Sending Firmware Response...
but nothing happens
I noticed I'll see the tuya.device.upgrade.silent.get line but takes several minutes to post the Sending Firmware Response... line.
That looks like something is going wrong fetching the response from the tuya server.
You are right...dhcp kicked in and modified the dns... what happens if the device is turned off after tuya-sonoff.bin was flashed , but before sonof-minimal.bin gets flashed ?
Think I may have missed your response, so the device running the perl script needs to be able to reach the real a.tuyaus.com site?
yes it does. easy test, right before running the proxy perl script, do a ping to the tuya server, and make sure you are getting the real-world ip address in return.
Here's an updated tuyaproxy.pl script that gives more details tuyaproxy.zip
If its working then the output should be something like:
192.168.31.45 Requesting http://a.tuyaeu.com/gw.json?a=atop.online.debug.log ...
Response: 200 OK
Content: {"result":true,"t":1547053595,"e":false,"success":true}
192.168.31.45 Requesting http://a.tuyaeu.com/gw.json?a=tuya.device.upgrade.silent.get ...
Response: 200 OK
Content: {"t":1547053615,"e":false,"success":true}
Sending Firmware Response...
192.168.31.45 Requesting http://a.tuyaeu.com/gw.json?a=s.gw.upgrade.updatestatus ...
Response: 200 OK
Content: {"t":1547053615,"e":false,"success":true}
i've already flashed tuya-sonoff.bin , now struggling with the finalstage... the ssid is there, but 192.168.4.1 isn't pinging , normal ?
Are you running the finalstage script on a computer with wifi?
Nice..so got that fixed. Saw the sending firmware response go quick... Saw 3 requests for some reason on the webserver for the bin. No Final Stage SSID showing yet. I'll give it time.
As I find it hard to find some information on if sombody managed to update the firmware of a tuya device utilizing any kind of OTA update, I thought this might be the right place to ask.