I’m having issues extracting the encrypted rootfs of this AGZHP 1.2.1 ZTE H388X firmware. I’m quite new to firmware reverse engineering and I’d appreciate any pointers. Here is what I got so far.
The header contains the firmware version (AGZH_1.2.1), the device model (ZXHN H388X) and length/offset for kernel/rootfs.
$ head -c 256 AGZHP_1.2.1_CLOSED.bin | hexdump -C
00000000 99 99 99 99 44 44 44 44 55 55 55 55 aa aa aa aa |....DDDDUUUU....|
00000010 28 00 00 00 46 6d 2a 81 f6 57 24 e7 ba 84 d3 28 |(...Fm*..W$....(|
00000020 df 23 f9 96 34 19 67 b3 4a 7e d5 1c e7 63 29 a2 |.#..4.g.J~...c).|
00000030 2c 05 51 ca b5 89 cf df c6 4d 15 eb 00 00 00 00 |,.Q......M......|
00000040 00 00 00 00 66 02 00 00 21 00 00 00 41 47 5a 48 |....f...!...AGZH|
00000050 50 5f 31 2e 32 2e 31 00 00 00 00 00 00 00 00 00 |P_1.2.1.........|
00000060 00 00 00 00 00 00 00 00 01 00 00 00 3c 02 9a 02 |............<...|
00000070 f7 08 3f 00 5c 02 10 00 04 63 d6 12 00 00 4a 02 |..?.\....c....J.| kernel: len, off, crc, rootfs: len
00000080 3c 02 50 00 83 4f ad 51 00 00 70 00 00 00 20 03 |<.P..O.Q..p... .| rootfs: off, crc, mtd kernel: addr, len
00000090 00 00 00 00 00 00 00 01 00 00 90 03 00 00 20 03 |.............. .|
000000a0 00 00 00 00 00 00 00 01 5a 58 48 4e 20 48 33 38 |........ZXHN H38|
000000b0 38 58 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |8X..............|
000000c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
000000d0 3c 02 00 00 5d 1d 48 06 01 00 00 00 01 00 00 00 |<...].H.........|
000000e0 a0 9b 06 28 32 30 32 31 30 38 32 34 31 36 32 36 |...(202108241626|
000000f0 31 31 00 00 00 00 00 00 ff ff ff ff ff ff ff ff |11..............|
The firmware rootfs is encrypted with AES. By running binwalk I see a gzip compressed data section at 0x10025c, which corresponds to the kernel offset in the header.
$ binwalk AGZHP_1.2.1_CLOSED.bin
DECIMAL HEXADECIMAL DESCRIPTION
--------------------------------------------------------------------------------
247812 0x3C804 CRC32 polynomial table, little endian
249788 0x3CFBC AES Inverse S-Box
253572 0x3DE84 AES S-Box
1049180 0x10025C Flattened device tree, size: 4131063 bytes, version: 17
1049428 0x100354 gzip compressed data, maximum compression, from Unix, last modified: 1970-01-01 00:00:00 (null date)
5170620 0x4EE5BC Flattened device tree, size: 8779 bytes, version: 17
To figure out where the decryption key is, I extract the kernel with dd if=AGZHP_1.2.1_CLOSED.bin bs=1 skip=$((16#10025c)) count=$((16#3f08f7)) of=kernel.img 2>/dev/null
Running binwalk on it I get:
$ binwalk parts/kernel.img
DECIMAL HEXADECIMAL DESCRIPTION
--------------------------------------------------------------------------------
0 0x0 Flattened device tree, size: 4131063 bytes, version: 17
248 0xF8 gzip compressed data, maximum compression, from Unix, last modified: 1970-01-01 00:00:00 (null date)
4121440 0x3EE360 Flattened device tree, size: 8779 bytes, version: 17
There is a gzip image at offset 0xF8. I run dd if=kernel.img bs=1 skip=248 | zcat > Image
to extract it. file Image
reveal that it’s a Linux kernel ARM64 boot executable Image, little-endian
. Here is where I get stuck. I’ve tried loading the image on IDA, disassembling as a ARM64 little-endian only the initial bytes seem to contain meaningful instructions. How to proceed?