I'm trying to extract the PPPoE username and password from a ZTE ZXHN F680 V6 router. I have obtained several files from the router and can get access to other files if needed. Here is where I'm at.

I have obtained the cspd file after reading this Q&A. I also have a config.bin file but was unable to determine any information from it using binwalk or strings commnads. Both returned empty results and indicated high level of entropy.

Here is a link to the files extracted from router.

I assume that the PPPoE file will be in an encoded or encrypted or both .xml file. So, my search in the cspd file for strings resulted in potentially useful information.

$ strings cspd | grep .xml
CP download xml doc failed!
please input cfg file(/proc/cfg/db_user_cfg.xml) eg.
at %d line of xml file
sbsize(%d) xmlsize(%d)

I think the best candidates for containing the PPPoE username and password are /userconfig/cfg/db_backup_cfg.xml, /userconfig/cfg/db_user_cfg.xml and /etc/db_default_cfg.xml.

I have checked those files using binwalk and it seems they are high level of entropy with only one section (no obvious header), so have been encrypted, not simply encoded:

binwalk -E db_user_cfg.xml

WARNING: Failed to import matplotlib module, visual entropy graphing will be disabled

0             0x0             Rising entropy edge (0.954061)

I following the above linked post I have used Ghidra 10 to de-compile the cspd file and searched for these strings, as well as functions for decryption. I found the following files:

  • AES_set_decryption_key
  • AESDecrypt
  • AESCBCDecry
  • dbcCfgSetAesKey
  • DecryByAES
  • DecryByAESCBC

I think the most likely candidate to get a key for decryption is dbcCfgSetAesKey, but that's only because of the name of the function and the target .xml files have cfg in their names.

The body of the dbcCfgSetAesKey function is below. It only accepts one variable and :

undefined4 dbcCfgSetAesKey(void *param_1)

  if (param_1 != (void *)0x0) {
    return 0;
  return 0xffffffff;

I searched Ghidra for g_szMD5Key and found there was only a Label with that name, no function. It appears to me that the above dbcCfgSetAesKey function is copying the config file AES key to a memory location to be accessed later by the decryption process. They key may be some type of MD5 hash?

My questions are:

  1. What are my options for extracting the key to decrypt the .xml files? Am I right that they PPPoE data will likely be in the above mentioned .xml files?
  2. Am I generally on the right track to extract config data from a ZTE router such as ZTE ZXHN F680 V6? I know that they are all different, and have looked at some other tools such as zte-config-utility which I see requires having a key to extract the config files.
  3. What am I missing about this approach to reverse-compiling the router configuration.

I know my questions will be rather noob since I am just starting to learn reverse engineering / compiling. I am fairly good with encryption and modes, but not create with Ghidra or C++. If my question is much to simple and uninformed just let me know.

  • Can you upload cspd file?
    – xax
    Apr 23 at 6:05
  • @xax I have uploaded a zip file of the files extracted from the router. There is also a directory tagparam with a p12 certificate, and config.bin. All seem encrypted. drive.google.com/file/d/1UEV9xGcFIq4aQfRj-k9_uJx4CEPirykA/… Apr 23 at 7:08
  • This config file using AES-256-CBC algorithm and deflate zlib compression. key_str = "C1DB7A773d634602dc8c", iv_str = "ZTE%FN$GponNJ025" -> key = sha256(key_str), iv = first 16byte of sha256(iv_str) -> key = 4a5e07466a0777eb2650bbd4fc85bb7498e3048d4219916c5f50576ad5c25bce iv = 83197b65889558bb6723df979895bb36 Decrypt method in function DecryByAESCBC and key_str C1DB7A773d634602dc8c I find from paramtag file. But this decrypt success only file db_backup_cfg.xml.
    – xax
    Apr 23 at 14:34
  • Thanks for that info. I assume that the zlib decompress must happen first because when I open the file as bytes in Python3 and check the length of the db_backup_cfg.xml file print(len(payload) % 16) the output is 8. So the file is not padded the right length for AES 256 CBC mode decryption. But when I try to zlib decompress using python3, payload = zlib.decompress(payload) I get the error, zlib.error: Error -3 while decompressing data: incorrect header check. Apr 23 at 18:35
  • hex view You can use decode.py db_backup_cfg.bin db_backup_cfg.xml after decrypt or using my script using zcu zte_f608.py zte_f608.py --key-prefix C1DB7A773d634602dc8c --iv-prefix ZTE%FN$GponNJ025 db_backup_cfg.xml out.xml
    – xax
    Apr 24 at 3:34


Browse other questions tagged or ask your own question.