1

I’m from Indonesia.

I have a ZTE F670 (Software Version V6.0.10) router provided by my ISP, and I'm trying to retrieve certain credentials stored in the configuration.

Previously, with a different router, I could download the config.xml file directly from the web interface and extract the needed information. However, with this new router, the backup file is in an encrypted config.bin format.

So far, I've tried the following:

  • Downloaded the config.bin file from the router's web interface. Used tools like the ZTE config utility, but the router appears to use a newer encryption algorithm (payload type 5), which isn't supported by the tools I've found.
  • I tried to use the serial number as an encryption key, without success.
  • Then I tried using https://github.com/mkst/zte-config-utility but no success.

Telnet are open and I can access root user. I can download telnet file like cspd, dataprotocol and etc… but don’t know to use it.

Can someone help me decrypt the config.bin file, or suggest any tools that work with newer ZTE models?

Giacomo1968
  • 58,727

1 Answers1

2

So there was a rabbithole I had to go through.

Step 1: Download the firmware - https://www.tripleoxygen.net/files/devices/zte/f670l/v1/firmware/stock/?SD

Step 2: Extract with binwalk - it has a jffs2-root of the file system

Step 3: Interact with the file system enough to see the httpd service - js files associated and the httpd ELF file that is the server binary

Step 4: load httpd into IDA - See that it uses libdb.so to manage the database. Load libdb.so into IDA - it uses libharcode.so

Step 5: libhardcode.so uses /etc/hardcode as input to decrypt files in /etc/hardcodefile - See CspHardCodeParamGet - both key and IV are derived from SHA256 of parts of /etc/hardcodefile

Step 6: RE the implementation to decrypt the file /etc/hardcodefile/dataprotocol to reveal

DefAESCBCKey=L04&Product@5A238dc79b15726d5c06
DefAESCBCIV=ZTE%FN$GponNJ025678b02a85c63c706
AESENCRYKey=
userkey=608158c36497b00221db14afb845c9e3

for the files attached in the question

Step 7: With - https://github.com/mkst/zte-config-utility

$ python examples/auto.py --key "L04&Product@5A238dc79b15726d5c06" --iv 'ZTE%FN$GponNJ025678b02a85c63c706' /tmp/f670/user_cfg.bin /tmp/f670/some.xml

and voila you can decrypt the file too

Script to decrypt the harcodefiles

from struct import unpack
import glob

from Crypto.Cipher import AES from Crypto.Hash import SHA256

def decrypt(): key_file = "./etc/hardcode" config_paths = glob.glob("./etc/hardcodefile/*")

with open(key_file, "rb") as f:
    key_data = f.readline().strip()
offset_bytes = lambda data, offset: bytes(b + offset for b in data)

key = SHA256.new(offset_bytes(key_data[5:21], 3) + key_data[64:]).digest()
iv = SHA256.new(offset_bytes(key_data[7:39], 1)).digest()[:16]

for path in config_paths:
    cipher = AES.new(key, AES.MODE_CBC, iv)
    try:
        with open(path, "rb") as config:
            print(f"Decrypting {path}")
            header = config.read(8)
            magic1, magic2 = unpack(">II", header)
            if magic1 != 0x01020304 or magic2 != 0x00000003:
                print(f"{path} is not a valid config file, skipping")
                continue
            config.read(52)
            with open(f"{path}.decrypted.txt", "wb") as output:
                while True:
                    chunk_header = config.read(12)
                    if not chunk_header:
                        break
                    plain_len, cipher_len, eof = unpack(">III", chunk_header)
                    plaintext = cipher.decrypt(config.read(cipher_len))[:plain_len]
                    output.write(plaintext)
                    if not eof:
                        break
    except FileNotFoundError:
        print(f"File {path} not found, skipping")

if name == "main": decrypt()

hold-me
  • 121