Hacking the Silvercrest (Lidl/Tuya) Smart Home Gateway

I can’t interrupt the download, the gateway was purchased recently,
I use putty under windows, I tried esc and ctrl+[

Booting...

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@
@ chip__no chip__id mfr___id dev___id cap___id size_sft dev_size chipSize
@ 0000000h 0c84018h 00000c8h 0000040h 0000018h 0000000h 0000018h 1000000h
@ blk_size blk__cnt sec_size sec__cnt pageSize page_cnt chip_clk chipName
@ 0010000h 0000100h 0001000h 0001000h 0000100h 0000010h 000004eh GD25Q128
@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
DDR1:32MB

---RealTek(RTL8196E)at 2022.06.01-16:29+0800 v3.4T-pre2 [16bit](380MHz)
P0phymode=01, embedded phy
check_image_header  return_addr:05010000 bank_offset:00000000
no sys signature at 00010000!
get uboot flag failed
Jump to image start=0x80c00000...
decompressing kernel:
Uncompressing Linux... done, booting the kernel.
done decompressing kernel.
start address: 0x80003780
Linux version 3.10.90 (wsj@LAPTOP-MO8FQJRA) (gcc version 4.6.4 (Realtek RSDK-4.6.4 Build 2080) ) #13 Wed Jun 1 16:34:08 CST 2022
CPU revision is: 0000cd01
Determined physical RAM map:
 memory: 02000000 @ 00000000 (usable)
Zone ranges:
  Normal   [mem 0x00000000-0x01ffffff]
Movable zone start for each node
Early memory node ranges
  node   0: [mem 0x00000000-0x01ffffff]
icache: 16kB/16B, dcache: 8kB/16B, scache: 0kB/0B
Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 8128
Kernel command line:  console=ttyS0,38400 root=/dev/mtdblock2
PID hash table entries: 128 (order: -3, 512 bytes)
Dentry cache hash table entries: 4096 (order: 2, 16384 bytes)
Inode-cache hash table entries: 2048 (order: 1, 8192 bytes)
Memory: 27344k/32768k available (2763k kernel code, 5424k reserved, 562k data, 192k init, 0k highmem)

Greetings everyone!
I’m real newbie this wold and need step by step teaching.

I follow Paul instructions but my biggest problem was ssh connection, every time I need insert
“-oHostKeyAlgorithms=+ssh-dss” ,I modified firmware_uprgade.sh, everything goes almost good.
last minute updating and its give error, that box reading every minute Tuya_start or do something
but in time gateway reboots and putty showing serial gateway is enabled.

but I try install HA integration but its not working (serial connected putty show connection, status led goes on and connection closed. nothing error not showed.

I try again hardware upgrade but its do nothing, only ask 3 times password.

im sorry my bad English too :zipper_mouth_face:

Hi again,
anyone tested [REQUEST] Silicon Labs Zigbee EmberZNet NCP 7.1.x.x firmware images (for developers to test EZSP v9) · Issue #25 · grobasoz/zigbee-firmware · GitHub ? v 7.xxx
i think my broblem is fault firmware, i just try re-install…

and not working.
Traceback (most recent call last):
File “/Users/jouni/Desktop/lidl/upgrade_ncp.py”, line 91, in
upgrade_ncp(args.ip, args.port, args.firmware)
File “/Users/jouni/Desktop/lidl/upgrade_ncp.py”, line 26, in upgrade_ncp
while s.recv(1) != b"\x00":
^^^^^^^^^

im using mac mini and terminal, python 3.11.2

ssh connection works if usin -oHostKeyAlgorithms=+ssh-dss [email protected]

SOLVED!

but i dont know what i do…i try again and i only use -d (debuggin) and restart all, computer,gateway, and try again.
its working perfectly now!

are you sure using 3.3volt usb-serial ? if you use 5volt its burning board.

Hello
Yes I used 3.3V

I am unable to escape the bootloader. I have tried both PuTTY on windows and minicom on linux.

Yes, my TX and RX lines are crossed, and yes, my TTL adaptor is working as once the boot process is complete, I can hit enter, get the login prompt, etc.

Board is ZW05B0 Rev 2.

During this portion of the boot, keystrokes are disabled:

Booting...

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@
@ chip__no chip__id mfr___id dev___id cap___id size_sft dev_size chipSize
@ 0000000h 0c84018h 00000c8h 0000040h 0000018h 0000000h 0000018h 1000000h
@ blk_size blk__cnt sec_size sec__cnt pageSize page_cnt chip_clk chipName
@ 0010000h 0000100h 0001000h 0001000h 0000100h 0000010h 000004eh GD25Q128
@ 
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
DDR1:32MB
 
---RealTek(RTL8196E)at 2022.09.02-15:49+0800 v3.4T-pre2 [16bit](400MHz)
P0phymode=01, embedded phy
check_image_header  return_addr:05010000 bank_offset:00000000
no sys signature at 00010000!
get uboot flag failed
Jump to image start=0x80c00000...
decompressing kernel:
Uncompressing Linux... done, booting the kernel.
done decompressing kernel.
start address: 0x80003780
Linux version 3.10.90 (huangxh@embed) (gcc version 4.6.4 (Realtek RSDK-4.6.4 Build 2080) ) #5 Fri Sep 2 15:52:57 CST 2022
CPU revision is: 0000cd01
Determined physical RAM map:
 memory: 02000000 @ 00000000 (usable)
Zone ranges:
  Normal   [mem 0x00000000-0x01ffffff]
Movable zone start for each node
Early memory node ranges
  node   0: [mem 0x00000000-0x01ffffff]
icache: 16kB/16B, dcache: 8kB/16B, scache: 0kB/0B
Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 8128
Kernel command line:  console=ttyS0,38400 root=/dev/mtdblock2 
PID hash table entries: 128 (order: -3, 512 bytes)
Dentry cache hash table entries: 4096 (order: 2, 16384 bytes)
Inode-cache hash table entries: 2048 (order: 1, 8192 bytes)
Memory: 27344k/32768k available (2763k kernel code, 5424k reserved, 562k data, 192k init, 0k highmem)
SLUB: HWalign=32, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
NR_IRQS:128
console [ttyS0] enabled
Calibrating delay loop... 398.13 BogoMIPS (lpj=1990656)
pid_max: default: 4096 minimum: 301
Mount-cache hash table entries: 512
reg e0=0
reg e1=0
reg e2=0
reg e3=0
reg e4=0
reg e5=0
reg e6=0
reg e7=0
reg f0=0
reg f1=0
reg f2=0
reg f3=0
reg f4=0
reg f5=0
reg f6=0
NET: Registered protocol family 16
bio: create slab <bio-0> at 0
NET: Registered protocol family 2
TCP established hash table entries: 512 (order: 0, 4096 bytes)
TCP bind hash table entries: 512 (order: -1, 2048 bytes)
TCP: Hash tables configured (established 512 bind 512)
TCP: reno registered
UDP hash table entries: 256 (order: 0, 4096 bytes)
UDP-Lite hash table entries: 256 (order: 0, 4096 bytes)
NET: Registered protocol family 1
squashfs: version 4.0 (2009/01/31) Phillip Lougher
jffs2: version 2.2. (NAND) © 2001-2006 Red Hat, Inc.
msgmni has been set to 53
Block layer SCSI generic (bsg) driver version 0.4 loaded (major 254)
io scheduler noop registered
io scheduler deadline registered
io scheduler cfq registered (default)
Serial: 8250/16550 driver, 2 ports, IRQ sharing disabled
serial8250: ttyS0 at MMIO 0x18002000 (irq = 9) is a 16550A
serial8250: ttyS1 at MMIO 0x18002100 (irq = 13) is a 16550A
Realtek GPIO Driver for Flash Reload Default
tuya_gpio_init ok, scan expire time:50
SPI INIT
------------------------- Force into Single IO Mode ------------------------ 
|No chipID  Sft chipSize blkSize secSize pageSize sdCk opCk      chipName    |
| 0 c84018h  0h 1000000h  10000h  10000h     100h   84    0          GD25Q128|
 ---------------------------------------------------------------------------- 
SPI flash(GD25Q128) was found at CS0, size 0x1000000
boot+cfg offset=0x0 size=0x20000 erasesize=0x10000
linux offset=0x20000 size=0x1e0000 erasesize=0x10000
rootfs offset=0x200000 size=0x200000 erasesize=0x10000
tuya-label offset=0x400000 size=0x20000 erasesize=0x10000
jffs2-fs offset=0x420000 size=0xbe0000 erasesize=0x10000
5 rtkxxpart partitions found on MTD device flash_bank_1
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"
PPP generic driver version 2.4.2
nf_conntrack version 0.5.0 (427 buckets, 1708 max)
ip_tables: (C) 2000-2006 Netfilter Core Team
TCP: cubic registered
NET: Registered protocol family 10
sit: IPv6 over IPv4 tunneling driver
NET: Registered protocol family 17
l2tp_core: L2TP core driver, V2.0
8021q: 802.1Q VLAN Support v1.8
Realtek FastPath:v1.03

Probing RTL819X NIC-kenel stack size order[1]...
eth0 added. vid=9 Member port 0x10f...
eth1 added. vid=8 Member port 0x10...
[peth0] added, mapping to [eth1]...
VFS: Mounted root (squashfs filesystem) readonly on device 31:2.
Freeing unused kernel memory: 192K (80340000 - 80370000)
init started: BusyBox v1.13.4 (2022-09-02 15:48:01 CST)

Once Busybox is running, keypresses are enabled.

Hello I hope someone can help me I got the Lidl gateway and wanted to flash the and because I already have Passwort Kek now I connected to win10 putty ssh I enter root but I can’t enter a except Enter he takes nothing on.
What I have done wrong.
I’ve connected via the Fritzbox 6370 because the getaway is drann which is not connected to the Internet

Hi all

I think I have successfully updated the fw by instructions on Blakadder-page but how am I able to confirm everything is ok?

I’ve seen few ask the question below prior but can’t see to been answered to fit my need.

The problem I have is the ZHA doesn’t connect to socket://192.168.1.xxx:8888( or 8088, seen both in instructions) with any combination of speed and dfc. I am able to connect just fine via ssh so IP hasn’t changed anywhere. I do not think I have changed the def port to anything else.

I tried the Z2MQTT as well but can’t get that to work for some reason( doesn’t stay on for one and documentation-page ends in an error. Reinstalled it few times) so ZHA is the one to go with for now.

Please describe how can you change passwd file. I also read fullflash from my HUB. Thank you!

Hello
My firstLidl gateway was dead, bought another used one. This time I managed to interrupt the boot and enter the busybox!!
But I’m blocking now to get the root password!! I run the python script (python 3 installed!) after entering the “auskey” I have this error message:
“UnicodeDecodeError: ‘ascii’ codec can’t decode byte 0xe6 in position 0: ordinal not in range(128)”
I searched everywhere including on the 430 messages of this topic but found nothing!!
I ran the python scrypt on different machines (debian, ubuntu with putty and windows with power shell) but I still have this message.
I modified the script: “utf-8” instead of “ascii” without success! It works in Latin-1!! But the characters are useless!
Sorry to bother with this but if anyone has any idea I take!!
And sorry for my english !!
Thank you

My mistake I apologize I made something wrong when I copy/paste the instructions !!! I managed to decode the root password !
:innocent: :innocent:

Hello
Does this command sounds ok?
#!/bin/sh
should it not be !/bin/sh?
I took it from the website I follow to hack the LIDL gateway.
Can somebody explain what this command do excately ?
Thanks

Hello
I have the following error in putty serial communication
/tuya/tuya_start.sh: line 9: /tuya/serialgateway: Permission denied
is it linked to
-rw-r--r-- 1 root 0 69485 Jan 1 00:20 serialgateway
shall I change something with chmod command to serialgateway directory ?

Hi Paul
Thanks for all sharing on this gateway freeing up
I have this value on the serialgateway.bin I downloaded
4bb59358e6db08192e8aeda3f8d0e646 serialgateway.bin
It does not match at all with the value in the post.
Is this value correct … I guess not
I downloaded the file thru WSL
Thanks for your rely

I have success with locked bootloader, with no ESC enabled. I unsolder flash memory from TUYA-ZHUB, read it and save fulflash to file using CH341A prog. I Cut from address 0x00200000 with length 0x200000 (to address 0x00400000) rootfs using HexEdit and save to file rootfs.bin. Using instruction from Hacking the Silvercrest (Lidl) Smart Home Gateway - PaulBanks.Org i change symlink to file with known password and recreate squashfs. In hex editor i paste new newroot.bin partition to address 0x00200000 of fullflash, reflash the memory ic, solder it back to ZHUB and have root access in serial terminal. After that i start internal ssh server with cmd /tuya/tuyadropbear -p 22.
Using this instruction Cloud-free integration with Home Assistant - PaulBanks.Org i have working coordinator and connect to zeegbe2mqtt.

Try chmod +x /tuya/serialgateway

In step 2 on: “Cloud-free integration with Home Assistant - PaulBanks.Org” I made a copy paste error resulting in the loss of the original /tuya/tuya_start.sh on my 2nd edition Lidl gateway (the one with the rounded edges and esc enabled bootloader). Can someone please post the content of their /tuya/tuya_start.original.sh please (if it does not contain unique identifying data)?

Here is my original /tuya/tuya_start.sh (from a “compatible” device) :smiley:

#!/bin/sh
#Usage: sh tuya_start.sh UserAppRunDir
#=======================================================================
DEFULT_APP_RUN_DIR=/tuya
TY_START_CHILDREN_SHELL=tuya_start_children.sh
def_jsonvalue_NULL="defaultValue"

#echo "Tuya Gateway Application Normal Srart $0 UserAppRunDir:${1} JsonFile Path:${2}"
echo "Tuya Gateway Application Normal Srart $0 UserAppRunDir:${1}"
#set app run dir
app_run_dir=$DEFULT_APP_RUN_DIR

if [ -d "$1" ];then
        app_run_dir=${1%*/}
        echo "set run_dir:${app_run_dir}"
elif [ -n "$TY_ENV_APP_RUN_DIR" ];then
        app_run_dir=$TY_ENV_APP_RUN_DIR
        echo "find old TY_ENV_APP_RUN_DIR:${app_run_dir}"
else
        echo "set defult run_dir:${DEFULT_APP_RUN_DIR}"
fi
export TY_ENV_APP_RUN_DIR=$app_run_dir
LD_LIBRARY_PATH=$app_run_dir:$LD_LIBRARY_PATH
export LD_LIBRARY_PATH
echo "TY_ENV_APP_RUN_DIR=${app_run_dir}"
UserAppRunDir=$app_run_dir
JSON_PARSER_SH=${UserAppRunDir}/json_parser.sh

#load platform configure file
DEFULT_PLATFORM_CFG_FILE=${app_run_dir}/def.cfg
user_cfg_file=$DEFULT_PLATFORM_CFG_FILE
if [ -f "$DEFULT_PLATFORM_CFG_FILE" ];then
        #get user cfg file path
        jsonkey_USER_CFG_FILE="user_cfg_file"
        jsonvalue_USER_CFG_FILE=`sh ${JSON_PARSER_SH} ${DEFULT_PLATFORM_CFG_FILE} ${jsonkey_USER_CFG_FILE} | sed 's/\"//g'`
        if [ "$jsonvalue_USER_CFG_FILE" = "$def_jsonvalue_NULL" ] || [ ! -f "$jsonvalue_USER_CFG_FILE" ] ;then
                echo "get user cfg file error, load defult cfg file"
                user_cfg_file=$DEFULT_PLATFORM_CFG_FILE
        else
                echo "get user cfg file success."
                user_cfg_file=$jsonvalue_USER_CFG_FILE
        fi
else
        echo "defult cfg does not exist."
        exit 0
fi
echo "load platform configure file:${user_cfg_file}"
export TY_ENV_USER_CFG_FILE=$user_cfg_file
#sh $TY_PLATFORM_CFG_PARSER_SHELL $app_run_dir $user_cfg_file
JsonFile=$user_cfg_file

#tmp_dir
jsonkey_USER_TMP_DIR="tmp_dir"
def_jsonvalue_USER_TMP_DIR="/tmp"
jsonvalue_USER_TMP_DIR=`sh ${JSON_PARSER_SH} ${JsonFile} ${jsonkey_USER_TMP_DIR} | sed 's/\"//g'`
if [ "$jsonvalue_USER_TMP_DIR" == "$def_jsonvalue_NULL" ];then
    jsonvalue_USER_TMP_DIR=$def_jsonvalue_USER_TMP_DIR
fi
export TY_ENV_USER_TMP_DIR=${jsonvalue_USER_TMP_DIR%*/}

#platform
jsonkey_PLATFORM="platform"
def_jsonvalue_PLATFORM="RTL8196E"
jsonvalue_PLATFORM=`sh ${JSON_PARSER_SH} ${JsonFile} ${jsonkey_PLATFORM} | sed 's/\"//g'`
if [ "$jsonvalue_PLATFORM" == "$def_jsonvalue_NULL" ];then
    jsonvalue_PLATFORM=$def_jsonvalue_PLATFORM
fi
export TY_ENV_PLATFORM=${jsonvalue_PLATFORM}

#wan_interface
jsonkey_WAN_IF_NAME="wan_interface"
def_jsonvalue_WAN_IF_NAME="eth1"
jsonvalue_WAN_IF_NAME=`sh ${JSON_PARSER_SH} ${JsonFile} ${jsonkey_WAN_IF_NAME} | sed 's/\"//g'`
if [ "$jsonvalue_WAN_IF_NAME" == "$def_jsonvalue_NULL" ];then
    jsonvalue_WAN_IF_NAME=$def_jsonvalue_WAN_IF_NAME
fi
export TY_ENV_WAN_IF_NAME=$jsonvalue_WAN_IF_NAME

app_fold1=${app_run_dir}/tuya_user1
app_fold2=${app_run_dir}/tuya_user2
user_path=${app_fold1}

#restart dhcp
killall -9 udhcpc
echo 4 > /proc/sys/net/ipv4/tcp_syn_retries
killall udhcpc
udhcpc -i ${TY_ENV_WAN_IF_NAME} -s ${app_run_dir}/udhcpc.script -p /var/run/udhcpc0.pid & ##需要修改

#create user_tmp dir
if [ ! -d "$TY_ENV_USER_TMP_DIR" ]; then
        mkdir -p "$TY_ENV_USER_TMP_DIR"
fi

default() {
        echo "Into default funtion"
        user_path=$app_fold1
        if [ ! -d $user_path ];then
                echo "Error: no run dir:${user_path}"
                user_path=$app_fold2
                if [ ! -d $user_path ];then
                        echo "Error: no run dir:${user_path}"
                        exit 0
                else
                        echo "tuya_start_dir=${user_path}" > ${app_run_dir}/start.conf
                fi
        else
                echo "tuya_start_dir=${user_path}" > ${app_run_dir}/start.conf
        fi
}

cd $app_run_dir
if [ ! -r "$app_run_dir" ]; then
    echo "dir:${app_run_dir} error"
        exit -1
fi

if [ ! -w "$app_run_dir" ]; then
    echo "dir:${app_run_dir} read only!"
else
        if [ -s start.conf ];then
                echo "start.conf is exist"
                user_path=`cat start.conf | grep tuya_start_dir | cut -d "=" -f 2`
        else
                echo "start.conf is not exist"
                user_path=/tytest123
        fi

        if [ ! -d $user_path ];then
                echo "$user_path is not exist"
                default
        else
                if [ "$user_path" != "$app_fold1" ] && [ "$user_path" != "$app_fold2" ];then
                        echo "$user_path error."
                        default
                fi
        fi
fi

echo "current run dir:$user_path"
cd $user_path
./$TY_START_CHILDREN_SHELL $app_run_dir $user_cfg_file &
1 Like

@ur5dco,

I’ve mainly followed this part of the blog article: Hacking the Silvercrest (Lidl) Smart Home Gateway - PaulBanks.Org

Since I cannot use “ESC key trick” I’ve change the first step by unsoldering the flash rom and dump it from the eprom.

so I mainly :

  • carefully unsold (with hot air) the flash eprom
  • dumped it with my TL866II + (by selecting the right flash [GD25Q127]) and the right adapter.
  • within the TL866 tool, extracted the rootfs “partition” from offset 0x20000 to 0x400000 to rootfs.bin

then follow the blog article:

  • under linux run unsquashfs rootfs.bin to exctact ALL file from the rootfs
  • replace the /etc/passwd file
  • recreate the “complete file” : mksquashfs squashfs-root newroot.sqfs -comp xz -noappend
  • used the python script (https://paulbanks.org/download/files/lidl-zigbee/rootfs_tool.py) to recalculate the squashfs’s header

then go back to the TL866II tool to update the eprom:

  • i’ve replaced the “segment” at the offset 0x20000 with my new newrootsqfs file
  • finally carefully solder back the eprom

hope it help

2 Likes