├── images ├── hack.jpg └── gateway.jpg ├── scripts └── decode.py └── README.md /images/hack.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parasite85/tuya_dmd2cc_gateway_hack/HEAD/images/hack.jpg -------------------------------------------------------------------------------- /images/gateway.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parasite85/tuya_dmd2cc_gateway_hack/HEAD/images/gateway.jpg -------------------------------------------------------------------------------- /scripts/decode.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python3 2 | from Crypto.Cipher import AES 3 | from Crypto.Util.Padding import pad, unpad 4 | 5 | def swapPos(list, pos1, pos2): 6 | list[pos1], list[pos2] = list[pos2], list[pos1] 7 | return list 8 | 9 | def getKey(): 10 | f_key = open("License.key", mode="rb") 11 | key = list(f_key.read()) 12 | print("key before change") 13 | print(list(map(hex,key))) 14 | swapPos(key,0,8);swapPos(key,1,9); 15 | swapPos(key,2,10);swapPos(key,3,11); 16 | 17 | swapPos(key,4,12);swapPos(key,5,13); 18 | swapPos(key,6,14);swapPos(key,7,15); 19 | 20 | # swap bytes 21 | converted = bytearray([]) 22 | for i in range(int(len(key)/2)): 23 | converted += bytearray([ key[i*2+1], key[i*2] ]) 24 | print("key after change") 25 | print(list(map(hex,converted))) 26 | return bytes(converted) 27 | 28 | def getData(): 29 | # validation of data can be added 30 | # basically, at the beginning of license file 31 | # there is 4 byte magic cookie next, 4 byte length 32 | # and at the end also 4 bytes magic 33 | f_data = open("License.file1", mode="rb") 34 | data = list(f_data.read())[8:-4] 35 | print("Encrypted data"); 36 | print(list(map(hex,data))) 37 | return bytes(data) 38 | 39 | key = getKey() 40 | data = getData() 41 | decipher = AES.new(key, AES.MODE_ECB) 42 | decoded = decipher.decrypt(data) 43 | print("Decrypted data") 44 | print(decoded) 45 | f_outdata = open("License.out", mode="wb") 46 | f_outdata.write(decoded) 47 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Hacking Tuya Zigbee Ethernet Gateway 2 | 3 | Hello, I want you to present the method of hacking Tuya Zigbee Gateway. This time we will be talking about ethernet model. 4 | I`m in possession of DMD2CC-V1.0 gateway. There is a lot of other devices with same PCB board. Including LIDL Gateway. 5 | Just open your model and check if board is similar. 6 | 7 | ![Picture of gatewa](/images/gateway.jpg) 8 | 9 | I have marked few things on picture. 10 | - Yellow dot - our target, CPU, realtek one. Responsible for the logic. Tuya Linux is working on it. 11 | - Pink dot - Zigbee Module. Details: [TYZS Datasheet](https://developer.tuya.com/en/docs/iot/zigbeetyzs4module?id=K989rhycrz23f). 12 | - Red dot - Flash module, contains bootloader and linux opearting system. This flash module uses SPI interface to communication. 13 | Can be easily read by CH341a Programmer. [Reading flash](https://www.youtube.com/watch?v=4qX2zihB6UE). 14 | In my case i had to desolder chip from board 15 | - Blue dot - Connector. Exposes serial interface and SWD for TYZS module. 16 | ## Communicating with device 17 | To be able to do some unusuall stuff you need to buy a USB<>RS232 Converter with 3.3V, 18 | You also will need to buy goldpins/cables to connect converter to board. Some 19 | soldering skills are required. 20 | ## Bootloader 21 | Once you connect your converter, run program to communicate. In my case i have used Putty or GNU Screen. 22 | Default bitrate 38400. 23 | Once you connect it, you should see something similar 24 | ending discover... 25 | 26 | Booting... 27 | 28 | @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 29 | @ 30 | @ chip__no chip__id mfr___id dev___id cap___id size_sft dev_size chipSize 31 | @ 0000000h 0XXXXXXh 0000XXXh 0000040h 0000018h 0000000h 0000018h 1000000h 32 | @ blk_size blk__cnt sec_size sec__cnt pageSize page_cnt chip_clk chipName 33 | @ 0010000h 0000100h 0001000h 0001000h 0000100h 0000010h 000004eh GD25Q128 34 | @ 35 | @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 36 | DDR1:32MB 37 | 38 | ---RealTek(RTL8196E)at 2022.03.29-15:59+0800 v3.4T-pre2 [16bit](380MHz) 39 | P0phymode=01, embedded phy 40 | check_image_header return_addr:05010000 bank_offset:00000000 41 | no sys signature at 00010000! 42 | get uboot flag failed 43 | Jump to image start=0x80c00000... 44 | decompressing kernel: 45 | Uncompressing Linux... done, booting the kernel. 46 | done decompressing kernel. 47 | start address: 0x80003780 48 | Linux version 3.10.90 (wsj@LAPTOP-MO8FQJRA) (gcc version 4.6.4 (Realtek RSDK-4.6.4 Build 2080) ) #8 Tue Mar 29 16:04:50 CST 2022` 49 | ... 50 | ... 51 | Creating 5 MTD partitions on "flash_bank_1": 52 | 0x000000000000-0x000000020000 : "boot+cfg" 53 | 0x000000020000-0x000000200000 : "linux" 54 | 0x000000200000-0x000000400000 : "rootfs" 55 | 0x000000400000-0x000000420000 : "tuya-label" 56 | 0x000000420000-0x000001000000 : "jffs2-fs" 57 | 58 | 59 | You finally will get a Linux login. Unfortunately, password is not known and in many cases is unique to each device. 60 | Most probably, password assigment is done on connection to Tuya cloud (when you have added your device to tuya) 61 | In some cases you can break the boot procedure and you can try to manipulate flash memory. To do this, hit ESC at the begining of boot. 62 | In my case bootloader has been locked (checked bootloader code). I had to use SPI Flash reader device to hack this gateway for the first time. 63 | 64 | ## ESC key is not giving you realtek prompt 65 | Still, I`m suggeting you to check all other possible ways for getting prompt. If nothing is working for you, there is a huge chance that 66 | you have Zigbee gateway with locked bootloader. 67 | 68 | Fortunately, there is a way to get Realtek boot prompt even if it is locked. Boot program is doing initial configuration and it is performing Linux kernel loading 69 | to memory, verification and running Image from memory. We will get prompt when something has fail. For me, easiet method was to "corrupt" FLASH :-). 70 | To do this you will need following stuff: 71 | - thin wire or wire with pins. 72 | - a hand 73 | 74 | Connect one end of wire somewhere you have a ground. I just attatched it to ethernet port. There is a shield around ethernet port. This 75 | shield is grounded. **Do not connect** second end of cable. 76 | ![Hack](/images/hack.jpg) 77 | 78 | This method might wont work out of the box. All you need is practice. 79 | Regarding second end of cable: we will be trying to do a glich. You need to do it when bootloader starts. Once you will see some bootloader text from screen 80 | you will need to connect second end of wire to SPI Flash memory. Check your flash and connect it to SCLK interface. 81 | 82 | When you do it properly you will get following text on terminal: 83 | 84 | ---RealTek(RTL8196E)at 2022.03.29-15:59+0800 v3.4T-pre2 [16bit](380MHz) 85 | P0phymode=01, embedded phy 86 | check_image_header return_addr:05010000 bank_offset:00000000 87 | no sys signature at 00010000! 88 | […] 89 | no sys signature at 0003D000! 90 | no sys signature at 0003E000! 91 | no sys signature at 0003F000! 92 | no sys signature at 00040000! 93 | get uboot flag failed 94 | P0phymode=01, embedded phy 95 | 96 | 97 | ---Ethernet init Okay! 98 | 99 | 100 | Hooray. 101 | 102 | Next, we will need to get root password. 103 | Now depending on your device you may need to read tuya-label flash or decode file. 104 | 105 | ## Method 1 AUZKEY is stored on Tuya-Label 106 | This is simple situation. Your key is stored on part of flash memory called tuya-label. 107 | All you need to to is to read a flash memory section with key. 108 | Creating 5 MTD partitions on "flash_bank_1": 109 | 110 | 0x000000400000-0x000000420000 : "tuya-label" 111 | Follow procedure described in: 112 | [Hacking Lidl Gateway](https://community.openhab.org/t/hacking-the-lidl-silvercrest-zigbee-gateway-a-step-by-step-tutorial/129660). 113 | 114 | ## Method 2 We dont care about AUZKEY 115 | In this method you will not need to have AUZKEY. You will write your own password. 116 | Follow [Paul Banks Hack](https://paulbanks.org/projects/lidl-zigbee/#firmware-hacking) 117 | 118 | ## Method 3 We care about AUZKEY 119 | If method 2 fails, you can try method 3. Get AUZKEY from `jffs2-fs` section of memory. 120 | I did little research on tuyamd executable and I have succesfully extracted (or decoded) auzkey. 121 | To extract auzkey you need to: 122 | - dump jffs2 partition (you can dump memory by using previous method or using programmer) 123 | - extract jffs2 partition - [Jefferson github](https://github.com/sviehb/jefferson) 124 | - get two files: config/License.file1 and config/License.key 125 | 126 | Then, use following program to decode. 127 | 128 | [AUZKEY decode script](scripts/decode.py) 129 | 130 | It will give you output: 131 | 132 | 133 | Decrypted data: 134 | 135 | b'{"bsn":"XXXX","master_mac":"XXXXXX","auzkey":"XXXXXXXXXXXXX","uuid":"XXXXXXXXXX","prodtest_exit":"true"}\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f' 136 | Also file License.out with decrypted data will be produced. 137 | 138 | Last 8 digits of AUZKEY is your password 139 | 140 | Once you get root, you can adopt device to your needs. 141 | --------------------------------------------------------------------------------