A small Python tool for decrypting, editing, and rebuilding config.bin backups from ZTE ZXHN H298A V1.0.
This is a continuation of the root-enabler work for the same router. After getting root access and tracing the firmware, I reversed the working backup format enough to support a full offline decode/edit/encode workflow.
Tested on firmware/build:
TTN.26_240416
- Decrypts
config.binto XML - Rebuilds
config.binfrom edited XML - Supports fetching the device-specific MD5 directly from the router over SSH/CLI
- Produces a byte-identical round-trip for an untouched original backup
- Produces modified backups that can be re-uploaded successfully
Already rooted H298A(Only to get MD5)- Python 3
pycryptodome- Optional for
--router:pexpect
Install dependencies:
pip install pycryptodome pexpectIf you do not use --router, pexpect is not required.
Decode a backup:
python3 h298a_config_tool.py decode --md5 <md5> config.binRebuild a backup after editing the XML:
python3 h298a_config_tool.py encode --md5 <md5> config.bin.xmlOr let the tool fetch the MD5 from the router directly:
python3 h298a_config_tool.py decode --router config.bin
python3 h298a_config_tool.py encode --router config.bin.xmlThe tool writes:
config.bin.xmlafter decodereencrypted.config.binafter encode
The tool needs the MD5 of the router's tag partition.
Run this on the router to get it manually:
openssl dgst -md5 /dev/mtd2Example output:
MD5(/dev/mtd2)= <md5>
Use the hash value:
python3 h298a_config_tool.py decode --md5 <md5> config.binIf the router is already rooted and SSH is available, the tool can fetch the MD5 automatically:
python3 h298a_config_tool.py decode --router config.binIt will prompt for:
- router IP
- SSH username/password
- shell username/password
This mode supports both SSH flows that are observed on the H298A:
- SSH password ->
CLI>->shell-> BusyBox login - SSH password -> direct BusyBox
Login:/Password:prompt
If the SSH flow does not match either of these, or SSH is not enabled, use --md5 manually instead.
- Download
config.binfrom the router web UI - Get the router MD5 using
openssl dgst -md5 /dev/mtd2or just let the tool fetch it with--router - Decode:
python3 h298a_config_tool.py decode --md5 <md5> config.bin- Edit
config.bin.xml - Rebuild:
python3 h298a_config_tool.py encode --md5 <md5> config.bin.xml- Upload
reencrypted.config.binback to the router
The tool implements the runtime path actually used by this router for config backup import/export.
The important points are:
config.binis base64-wrapped- after base64 decoding, the first
0x1bbytes are an outer wrapper - the inner payload is an AES-CBC chunked container
- the decrypted output is another chunked container holding zlib-compressed chunks
- the actual device-specific key source used at runtime is:
MD5(/dev/mtd2)
That MD5 is then used as the input to the final AES derivation:
- AES key =
SHA256(md5_blob) - AES IV = first 16 bytes of
SHA256(md5_blob)
Both encrypted and compressed containers use:
- 60-byte headers
- 12-byte chunk headers
- big-endian fields
- This tool was built from reversing the H298A V1.0 firmware path
- The firmware still contains the older
dbcSetEncryKey()path using hidden tag0x1004, but for this product build the runtime export/import buffers are later overwritten by product-specific logic based onMD5(/dev/mtd2) - The untouched original
config.binreamains byte-identically through this tool
If you need root access first, use the root-enabler project for the same router:
This config tool assumes you either already have a backup file and MD5, or already have root access.
- Always keep the original
config.binuntouched - Test with a small change first
- Use only on hardware and networks you own or are authorized to test