Hacking the Silvercrest (Lidl/Tuya) Smart Home Gateway

OK, I will try, thanks.

And I just saw that it’s not possible to have more than 1 gateway on the system … I’ve already buy and hack the second one :smile: !

Many thanks again

Dear all,
I follow all for hacking the lidl gateway and it’s works, thanks for that.
But I do something wrong, because when I start the gate, I need to connect to the gate with a console and type /tuya/serialgateway and HA find the gate.
So, I think I do something wrong with the file tuya_start… I don’t backup the files before so is anybody do it and if yes, could you send me the backup? Thanks for your help. Fabilan

Hi Fabien,

Here the ssh_monitor.original.sh : Ubuntu Pastebin
and here the tuya_start.original.sh : Ubuntu Pastebin

and the ls -l of the tuya directory to see the file’s rights :
-rwxr-xr-x 1 root 0 936 Jan 1 06:44 ssh_monitor.original.sh
-rwxrwxr-x 1 1000 1000 10 Jan 1 06:44 ssh_monitor.sh
-rwxr-xr-x 1 root 0 4266 Jan 1 00:01 tuya_start.original.sh
-rwxrwxr-x 1 1000 1000 32 Jan 1 00:01 tuya_start.sh

Hi Nicolas,
Thanks a lot, I try with this.
Last question, tuya_start.sh is in the gate or I create it during the hack? Because I remember I delete it and I create a new one. And when I see the file’s right, I haven’t got this right.

It’s better but not enough :wink:
I change the file’s rights for tuya_start.sh and now the gate have the good ip:8888
but I can’t connect it with HA
I don’t have " 1000 1000 " but " root 0 " and I don’t know how to change it.

Hi, I just hacked my Silvercrest Hub, and all seems to be working well, except… it doesn’t detect my devices correctly (a dimmer switch and an PIR motion sensor) in Home Assistant using Zigbee2mqtt Edge. As a compassion, my devices are correctly seen and integrated using a Tasmota Sonoff Zigbee Bridge in Home Assistant using Zigbee2mqtt Edge, but with the Silvercrest, I get ‘Interview failed’ (see screen grab). Any suggestions or insight would be a great help.

Your not pairing the same device to two hubs at the same time are you? Only one hub can be paired and able to interview the device and it sounds like the new gateway is not the one paired to the device.

Hi there. Our local Aldi were selling starter kits (Lightway Smart Home starter kit) containing a Zigbee gateway. I opened it up and found the standard Tuya gateway hardware inside and eventually found this thread. Now I’m hoping to work your magic and free the device from the cloud too. But unfortunately the root password extraction method does not work: I get a password but it is not accepted at the terminal prompt on the device or via ssh.

The tuya-label partition seems to contain the same data regions as Paul observed. I found the script in the github repository to dump the squashfs contents, so I’ll try that next.

Hmm, it was paired with the Sonoff, but that is turned off, it there a procedure for unpairing a device?

Any chance someone have time + interest to add auto-discovery to the Tuya/Lidl/Silvercrest gateway?

Hi @bool2 , first thank you for this great tutorial, you made it so easy for us!
I’m having an issue with my Gateway, and would like to ask for your help.
After hacking my gateway, and it was working as expected with home assistant, I tried to create a new user using the adduser command. After rebooting the device, the root password won’t work anymore.
So I dumped my SPI using your script to understand what was going on.
I found out that the passwd file was corrupted: instead of inserting a new line with the new user info, it appended it on the same line.

I would like to ask you if you could explain how to recreate the squashFS blob as you said you did the first time you tried to hack the gateway.
I already used binwalk to extract/unsquash it and was able to replace the /etc/passwd symlink with a file containing a known password.
I tried to recreate the blob using this command:
mksquashfs squashfs-root new.squashfs -comp xz -all-root
Then I used TFTP to write it on RAM and FLW to write it to the flash.
After that my device keeps on booting directly to the bootloader.

I think it may have to do with the new length and the checksum.
Could you point me to some documentation, or explain briefly how you recreated the blob ?

Thanks

@chepo @challs - I’ll document the process of squash-fs regneration and then update this post. Watch this space! :slight_smile:

3 Likes

@bool2 Thanks for promising to help us out! I’m now at the same stage as @chepo, where my device no longer boots after recreating the squashfs and uploading.

I started looking at the bootloader code in an online copy of the development kit and saw there is some checking of checksums there which would stop the boot process. But it looks like if there is a problem with that root filesystem, I should have seen an error message on the console. But if you have already worked out how the filesystem should look, I’d be really grateful for you to share that. Thank you!

These are the steps I followed:

Prepare the root image

  • Make an image of the complete flash memory contents using dump_flash.py

  • Extract the root filesystem image:

dd if=spiflash.bin of=rootfs.bin bs=1 \
   skip=$((0x000000200000)) count=$((0x000000400000-0x000000200000))`
unsquashfs rootfs.bin
  • Edit /etc/passwd, removing the link and replacing with a new password that I know:
mkpasswd -m descrypt NewPassword
  • Create a new image:
mksquashfs squashfs-root newroot.squashfs -noappend -always-use-fragments -all-root -comp xz

Upload the image

On the serial console, set the IP address you wish to use on your network, and disable auto flashing the tftp image (this only works if you transfer an image starting with a new linux kernel)

<Realtek> ipconfig 192.168.10.10
Target Address=192.168.10.10
<RealTek>autoburn 0
AutoBurning=0

Then start the TFTP transfer in binary mode. I needed to use this command:

$ tftp 172.28.1.6 -m binary -c put newroot.squashfs

On the console I observed:

**TFTP Client Upload, File Name: newroot.squashfs
**TFTP Client Upload File Size = 000E1000 Bytes at 80500000

I then needed to write the transferred image to flash memory:

<RealTek>FLW 200000 80500000 000E1000
Write 0x000e1000 Bytes to SPI flash#1, offset 0x00200000<0xbd200000>, from RAM 0x80500000 to 0x805e1000
(Y)es, (N)o->y
<RealTek>

Boot from within the bootloader prompt

At this point, the device does not boot any more and remains in the bootloader.

I found a way to manually boot the device from here by looking at where the boot image is expected to be placed in memory and the code is executed:

FLR 80500000 20000 001E0000
J 80c00000

@chepo you can try the above commands on your box.

Entering the above commands results in the kernel booting:

<RealTek>FLR 80500000 20000 001E0000
Flash read from 00020000 to 80500000 with 001E0000 bytes	?
(Y)es , (N)o ? --> y
<RealTek>J 80c00000
---Jump to address=80C00000
decompressing kernel:
Uncompressing Linux... done, booting the kernel.
done decompressing kernel.
start address: 0x80003780
Linux version 3.10.90 (dingsl@dingsl-pc) (gcc version 4.6.4 (Realtek RSDK-4.6.4 Build 2080) ) #27 Mon Oct 12 20:33:38 CST 2020

From there, I was able to follow the rest of the instructions, disable tuya, install the serial gateway and connect Homeassistant. However, the box still ends up in the bootloader when power cycled.

Hi @challs ,
I tried to boot into kernel using the commands you provided, I get a kernel panic…
Is it possible to restore the device using the previously dumped flash content ?

With the command FLW 0 80500000 201C0C

Do you have a copy of the log of it booting normally before you flashed it? I got the address 80c00000 from there - maybe yours used a different address? See the line marked with >>> <<< below:

---RealTek(RTL8196E)at 2020.10.12-20:27+0800 v3.4T-pre2 [16bit](400MHz)
P0phymode=01, embedded phy
check_image_header  return_addr:05010000 bank_offset:00000000
no sys signature at 00010000!
P0phymode=01, embedded phy

---Ethernet init Okay!
tuya:start receive production test frame ...
>>> Jump to image start=0x80c00000... <<<<
decompressing kernel:

Also, are you sure you uploaded the tftp image in binary mode? I got that wrong first time around. What log messages do you get before the panic?

Is it possible to restore the device using the previously dumped flash content ?
With the command FLW 0 80500000 201C0C

No I wouldn’t recommend you try that!!

If you start writing from address 0, you will overwrite the bootloader (the one giving you the prompt… and if you break that, the box will be bricked unless you desolder the flash chip and flash it again.

Here’s the flash memory map dumped by the LInux kernel when it boots:

Creating 5 MTD partitions on "flash_bank_1":
0x000000000000-0x000000020000 : "boot+cfg"
0x000000020000-0x000000200000 : "linux"
0x000000200000-0x000000400000 : "rootfs"
0x000000400000-0x000000420000 : "tuya-label"
0x000000420000-0x000001000000 : "jffs2-fs"

The boot+cfg part is the bootloader which you do not want to touch.

You could try cutting the image and uploading from 0x000000020000 onwards. I did start trying that but I’m not sure whether I actually wrote it back to flash.

Here are dd commands I wrote to split the image up according to the layout above:

 dd if=spiflash.bin of=boot_cfg.bin bs=1 skip=$((0x00)) count=$((0x000000020000-0x000000000000)) 
 dd if=spiflash.bin of=linux.bin    bs=1 skip=$((0x000000020000)) count=$((0x000000200000-0x000000020000)) 
 dd if=spiflash.bin of=rootfs.bin   bs=1 skip=$((0x000000200000)) count=$((0x000000400000-0x000000200000)) 
 dd if=spiflash.bin of=tuya.bin     bs=1 skip=$((0x000000400000)) count=$((0x000000420000-0x000000400000)) 
 dd if=spiflash.bin of=jffs2.bin    bs=1 skip=$((0x000000420000)) count=$((0x000001000000-0x000000420000)) 

No I didn’t specify binary mode, this may be the reason for my failures (except for the checksum).
As for the memory map, I had the same as you before trying to flash it.
I’ll retry with binary mode tomorrow.

I also have an idea on how you could complete your hack if you can boot and login as root:

  • Copy you /etc/passwd file to /tuya/passwd

  • Reflash your original rootfs.bin

As the tuya-start.sh script and the passwd files are in the tuya partition, reflashing the original rootfs won’t revert your changes and the /etc/passwd symlink will point to the file you modified with your own root password.
I hope this helps you.

I also don’t know if the autoburn 0 command has any use in the process. It seems like, using it, you can directly upload to the flash instead of uploading to the RAM then writing to flash.

Thanks. I was actually already able to complete the hack and get it working with HomeAssistant… as long as it is not rebooted :slight_smile:

I disabled it to have more control over the start address that the image is written to.

Normally, you simply need to restart the pairing process or reset the device. If it was a Hue device, this information on the Zigbee page might help.

@challs @chepo

This tool can be used to create an RTL compatible rootfs with checksum. Enjoy.

Run like this:

python rootfs_tool.py build newroot.squashfs newroot.bin

Then upload the newly created newroot.bin instead.

1 Like

That works! Thanks @bool2! Now my box will boot on power on. So that means that the bootloader will silently fail if a rootfs image is written to flash that does not include a modified squashfs image including checksum.

@chepo I think it will probably solve your problem too.

This worked for me too, thank you @bool2 and @challs for your help!