11

I was poking around in ZTE Speedport Entry 2i (CPE used mostly in Germany, Slovakia etc, probably custom made for Deutsche Telekom). It's possible to download backup of config from UI.

I found out it's different from other ZTE config backups. Usually it's zlib compressed XML. I suspect this one has a layer of some pseudo-encryption on it.


00000000  99 99 99 99 44 44 44 44  55 55 55 55 aa aa aa aa  |....DDDDUUUU....|
00000010  00 00 00 00 00 00 00 00  00 00 00 04 00 00 00 00  |................|
00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 40  |...............@|
00000040  00 02 00 00 00 00 00 80  00 00 57 c6 00 00 00 00  |..........W.....|
00000050  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00000080  04 03 02 01 00 00 00 00  00 00 00 12 53 70 65 65  |............Spee|
00000090  64 70 6f 72 74 20 45 6e  74 72 79 20 32 69 01 02  |dport Entry 2i..|
000000a0  03 04 00 00 00 02 00 00  00 00 00 00 57 a8 00 01  |............W...|
000000b0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
000000d0  00 00 00 00 00 00 00 00  00 00 00 00 57 60 00 00  |............W`..|
000000e0  57 60 00 00 00 00 be d3  f7 b3 fe 9e 99 a4 35 75  |W`............5u|
000000f0  ce db 7f c2 99 17 43 7f  1e e2 54 7a 63 72 6f c8  |......C...Tzcro.|
00000100  b7 2d cc e8 cb 32 6c 3a  f0 fd 55 19 10 ac ea d5  |.-...2l:..U.....|
00000110  e9 18 01 01 71 7c 20 68  ca 66 d0 d9 f9 12 03 3d  |....q| h.f.....=|
00000120  ee bd ad 2a 00 e2 c1 96  73 12 bd 5a 94 3e 6d 1a  |...*....s..Z.>m.|
00000130  a8 7f c8 a8 8b 3d b6 1e  d8 ae 9b 43 63 6a e3 ea  |.....=.....Ccj..|
00000140  94 33 55 57 dc 81 b2 22  c5 e7 39 fd 75 b9 ba 5b  |.3UW..."..9.u..[|
00000150  00 ca a1 29 9b e2 9f bd  8e 1f 00 98 30 62 8b d7  |...)........0b..|
00000160  c6 12 ae ef 27 55 30 2a  4c f8 de 7c e5 2a 33 b9  |....'U0*L..|.*3.|
00000170  8b 32 4a d2 2c da 2a 18  ff 72 cf 1c 42 d8 41 6b  |.2J.,.*..r..B.Ak|

Other examples of this config can be found here: RE Compressed backup file,router linux based so is it compresed with zlib?

Is there a way to figure out how to extract content of this config? Is there a way how to detect if some sort of simple XOR encryption is in place?

I was unable to obtain firmware of the device, it's CPE so it's pretty locked down. The device itself looks to be using stripped down version similar to ZTE E5502 (same lua based web UI) E5502 firmware

You can download the config here. config.bin

Edit:

After reading something about difference between compression and entropy, I came to conclusion that the file is probably encrypted and not just obfuscated with something like XOR (because that doesn't change the entropy)

I obtained config file from another ZTE device (one with zlib compression)

$ binwalk -E -N config_f660.bin

DECIMAL       HEXADECIMAL     ENTROPY
--------------------------------------------------------------------------------
1024          0x400           Rising entropy edge (0.973932)
10240         0x2800          Rising entropy edge (0.958898)
14336         0x3800          Rising entropy edge (0.966971)
17408         0x4400          Rising entropy edge (0.968328)

$ binwalk -E -N config_encrypted.bin

DECIMAL       HEXADECIMAL     ENTROPY
--------------------------------------------------------------------------------
1024          0x400           Rising entropy edge (0.974513)
22528         0x5800          Falling entropy edge (0.737589)

As far as I can interpret this data is that the first rising edge is unencrypted header in both configs. In the compressed config other rising edges should represent compressed zlib blocks. If you actually plot the graph with binwalk you can see that there are still some rising edges in entropy but much smaller the line is almost flat. (Cannot include graphs due to low reputation). I'm now confident that's caused by applying encryption over those compressed zlib blocks.

Are my assumptions correct or am I missing something? Is there a method I could try to break or at least guess the encryption type without the firmware image?

12
  • I am not answring you question, but maybe this can help you. I have the same problem and i think we have same ecryption algoritm but diferrent keys. This is my config.bin I also find out, that a number 0x57 is often there maybe it can decide the sections. In my config file is 0xb6. Maybe it can be helpful for you to solve it.
    – lukas kiss
    Commented Feb 17, 2016 at 22:19
  • Thanks, I downloaded your config and the entropy looks very similar to mine that's true. Unfortunately I still haven't found any more info or ideas on how to solve this problem.
    – J91321
    Commented Mar 1, 2016 at 21:58
  • Did you ever make any progress on this? I'm also looking at the config.bin from my new home router, from ZTE as well.
    – Juicy
    Commented Sep 24, 2016 at 18:13
  • Not really, I would probably need to obtain a sample of firmware and reverse engineer it to find out what is happening with config.bin. But if you are willing to share your config.bin sample I'll take a look. Just remember to remove any confidential information before exporting it.
    – J91321
    Commented Sep 24, 2016 at 20:38
  • 1
    @danca can you give me your mac address, I thinks that key for config is md5 mac addres
    – Vido
    Commented Jun 3, 2019 at 14:45

3 Answers 3

11

Updated for August 2020:

The below information is accurate to the best of my knowledge. It has been used to decrypt config.bin on 2 different routers at the time of writing.

The obfuscated section of your config file is a series of ZLIB-compressed sections that have been encrypted with AES in ECB mode with a 16-byte key.

There is an application named cspd on the router that does lots of different things. One of those things is to encrypt/decrypt the configuration file.

Some of the ZTE routers have the AES key hardcoded into the cspd binary; some of them don't. Unfortunately, yours is one that does not.

There is a function within cspd named PdtDBSetAESEncryKey (code courtesy of Ghidra) that is used to set the key:

undefined4 PdtDBSetAESEncryKey(char *param_1,int param_2)

{
  byte bVar1;
  char cVar2;
  undefined4 uVar3;
  int iVar4;
  size_t sVar5;
  undefined4 *puVar6;
  undefined4 *puVar7;
  byte bVar8;
  undefined4 local_48;
  undefined4 local_44;
  undefined4 local_40;
  undefined4 local_3c;
  undefined4 local_38;
  undefined local_18;

  local_48 = 0;
  local_44 = 0;
  local_40 = 0;
  local_3c = 0;
  memset(&local_38,0,0x21);
  uVar3 = 0xffffffff;
  if ((param_1 != (char *)0x0) && (param_2 != 0)) {
    iVar4 = _getTagparamMD5(&local_48);
    if (iVar4 != 0) {
      ProcUserLog("dbc_mgr_pdt_encry.c",0x9c,"PdtDBSetAESEncryKey",5,0,0,
                  "_getTagparamMD5 failed! Use default");
      sVar5 = strlen("Hello! world,");
      CspGetMD5("Hello! world,",sVar5,&local_48);
    }
    puVar7 = &local_48;
    puVar6 = &local_38;
    do {
      bVar1 = *(byte *)puVar7 >> 4;
      if (bVar1 < 10) {
        cVar2 = '0';
      }
      else {
        cVar2 = 'W';
      }
      bVar8 = *(byte *)puVar7 & 0xf;
      *(byte *)puVar6 = bVar1 + cVar2;
      if (bVar8 < 10) {
        bVar8 = bVar8 + 0x30;
      }
      else {
        bVar8 = bVar8 + 0x57;
      }
      puVar7 = (undefined4 *)((int)puVar7 + 1);
      *(byte *)((int)puVar6 + 1) = bVar8;
      puVar6 = (undefined4 *)((int)puVar6 + 2);
    } while (puVar7 != &local_38);
    local_18 = 0;
    strncpy(param_1,(char *)&local_38,param_2 - 1);
    uVar3 = 0;
  }
  return uVar3;
}

Which:

  1. Reads a file named tagparam_m and generates the MD5 of it's content; _getTagparamMD5()
  2. If this function fails, the MD5 of 'Hello! world,' is used instead; iVar4 != 0
  3. Converts the MD5 to (lowercased) hex digest; (the do-loop)

This key is fed to the set key function, AES_set_decrypt_key, from libcrypto, with the 2nd parameter ('bits') set to 128 (i.e. 16 byte KEY_LENGTH).

The tagparam_m file is found in /var and is created when the router starts.

I have seen two examples of this file. Each data entry is preceded by a mini header preamble comprising:

  • 2 byte identifier
  • 2 byte length and
  • 2 byte padding.

Example 1:

0100 0006 0000                     // 0100: MAC 0, 0006: 6 bytes, 0000: padding
aabb ccdd eef2                     // MAC Address 0 (raw hex)
0101 0006 0000                     // 0101: MAC 1, 0006: 6 bytes, 0000: padding
aabb ccdd eef3                     // MAC address 1 (raw hex)
0102 0006 0000                     // .. etc
aabb ccdd eef4
0103 0006 0000
aabb ccdd eef5
0104 0006 0000
aabb ccdd eef6
0105 0006 0000
aabb ccdd eef7
0106 0006 0000
aabb ccdd eef8
0107 0006 0000
aabb ccdd eef9
0108 0006 0000 
aabb ccdd eefa
0109 0006 0000
aabb ccdd eefb
0200 000f 0000                     // 0200: Serial No, 000f: 15 bytes, 0000: padding
4142434445464748494a4b4c4d4e4f     // Serial Number (ASCII)
0400 000e 0000                     // 0400: BSSID, 000e: 14 bytes, 0000: padding
4142434445464748494a4b4c4d4e       // BSSID (ASCII)
0510 0010 0000                     // 0501: BSSID Password, 0010: 16 bytes, 0000: padding
4142434445464748494a4b4c4d4e4f50   // BSSID Password (ASCII)
0601 0005 0000                     // 0601: Admin Username, 0005: 5 bytes, 0000: padding
4142434445                         // Username (ASCII)
0701 0008 0000                     // 0701: Admin Password, 0008: 8 bytes, 0000: padding
4142434445464748                   // Password (ASCII)
0300 0006 0000                     // 0300: Manufacturer MAC, 0006: 6 bytes, 0000: padding
414243444546                       // Manufacturer MAC (ASCII)
0806 0006 0000                     // 0806: Hardware revision
5631 2e30 2e30                     // Hardware revision (ASCII)
0807 0001 0000                     // 0807: Trailer?
30                                 // "0" ASCII

Example 2:

0100 0006 0000                     // 0100: MAC 0, 6 bytes
5078 b3aa bbc0                     // 50:78:b3:aa:bb:c0
0101 0006 0000                     // 0101: MAC 1, 6 bytes
5078 b3aa bbc1                     // 50:78:b3:aa:bb:c1
0102 0006 0000                     // 0102: MAC 2, 6 bytes
5078 b3aa bbc2                     // 50:78:b3:aa:bb:c2
0103 0006 0000                     // 0103: MAC 3, 6 bytes
5078 b3aa bbc3                     // 50:78:b3:aa:bb:c3
0200 000f 0000                     // 0200: Serial Number, 15 bytes
323638454142434445464748494a4b     // 268EABCDEFGHIJK
0400 000b 0000                     // 0400: BSSID, 11 bytes
4142434445464748494a4b             // ABCDEFGHIJK
0510 0010 0000                     // 0510: BSSID Password, 16 bytes
4142434445464748494a4b4c4d4e4f50   // ABCDEFGHIJKLMNOP
0701 0008 0000                     // 0701: Admin Password, 8 bytes
4142434445464748                   // ABCDEFGH
0300 0006 0000                     // 0300: Manufacturer MAC, 6 bytes
353037384233                       // 5078B3
0806 0006 0000                     // 0806: Hardware Revision, 6 bytes
56312e302e31                       // V1.0.1
0807 0001 0000                     // 0807: Trailer?
30                                 // "0" ASCII

Note: I have used dummy values for MAC/BSSID/Password etc!

If you can locate this file and perform the MD5 of it (e.g. md5sum /var/tagparam_m), the first 16 chars of the hex digest are your key.

For a good key, the first 8 bytes of the decrypted block should look like 0x0102030400000000 which is the start of the header for the ZLIB section.

For a bit more info on this file format you can take a look at the zcu module I wrote.

Notes:

The second tagparam_m file was byteswapped but the key was the MD5 after the file was byteswapped back and a trailing 00 was truncated.

If anyone wants to send me a copy of their tagparam_m file I will update this post!

Credits:

  • Dimitris for figuring out the MD5 of his tagparam_m file was the key!
  • @Vido for the second example tagparam_m file
8
  • Awesome, I'll take a look into it as soon as I have some time. cspd seems to be responsible for encrypting and decrypting configs on several ZTE devices like mentioned here for F660 reverseengineering.stackexchange.com/questions/13391/… But the method seems to differ between different type of devices. You can always try use quemu to run the code.
    – J91321
    Commented Oct 24, 2016 at 23:04
  • Im also trying to identify whats encryptions used on backup file, Im usint ZTE ZXV10 H201L V2 and my thred is located here reverseengineering.stackexchange.com/questions/14711/…
    – Vido
    Commented Mar 1, 2017 at 16:29
  • I have shell access and strace as well as gdbserver on Speedport Entry 2i. I indefined process which is called when backup button is pressed so what I can do further to investigate and get password for backup file ?
    – Vido
    Commented Aug 30, 2020 at 10:29
  • @Vido I have just updated the post based on information I received yesterday, if you can locate the tagparam_m file, the MD5 of this file ought to be your key.
    – mkst
    Commented Aug 31, 2020 at 11:01
  • That's great tnx @streetster
    – Vido
    Commented Aug 31, 2020 at 20:30
3

came across these keys and sharing

Known AES keys:

  zxhn h118n ert5                      - 'MIK@0STzKpB%qJZe'
  zxhn h118n V2.1.3_ROSCNT?            - 'MIK@0STzKpB%qJZf'
  zxhn h168n v3                        - '402c38de39bed665'
  zxhn h298n hv17_fv116_mts?t1         - 'Wj' (due to bug, orig. is 'Wj%2$CjM')
  zxhn h298a hw1.1.20_fw1.1.20_ros_t1? - 'm8@96&ZG3Nm7N&Iz'
  zxhn h108n hw1.2_fw2.5.4_eg1t8_ted,
  zxhn h108n hv11_fv2_5_4_*            - 'GrWM2Hz&LTvz&f^5'
  zxhn h168n hv10_fv310t3_belt         - 'GrWM3Hz&LTvz&f^9'
  zxhn h208n hv10_fv1010_belt16t1      - 'Renjx%2$CjM'
  zxhn h267n hv10_fv100t3_belt         - 'tHG@Ti&GVh@ql3XN'
1

In order to get key you need to check CSPDBGetFileEncryKey function

0

Not the answer you're looking for? Browse other questions tagged or ask your own question.