Model ZXHN H108N V2.3 Hardware Version V1.1 Software Version V2.3.0_ES1C5 Boot Loader Version V1.1.0 DSL Firmware Version 4923c118
En este caso vamos a intentar conseguir el volcado de la flash y acceso como root para el dipositivo ZTE H108N v2.3
. Como siempre la versión de la flash es determinante ya que cada firmware puede diferir bastante. En este caso es la versión V2.3.0_ES1C5
.
Una alternativa un poco más complicada pero efectiva es conseguir acceso a nuestro router usando UART/RS232, acceder al bootloader, y usar comandos del bootloader para volcar la memoria del dispositivo.
Conectarnos al puerto serie
Adjunto las capturas de pantalla para identificar los pines y como conectarnos al puerto serie.
Como es habitual usamos microcom
y nos conectamos al dispositivo:
$ microcom -p /dev/ttyUSB0
Es muy recomendable en mi opinión, guardar un bootlog completo ya que nos será muy útil a la hora de entender la organización del a flash y direcciones de memoria, y poder consularlo de manera cómoda y sencilla.
En mi caso antes de iniciar el router, accedo al menú de microcom
y configuro el log de la sesión. Para acceder al menú hay que presionar ctrl + 4 y ejecutar el comando log <logfile>
, y posteriormente escribir exit
para salir del menú. Ej:
> log zte-h108n-bootlog.log
exit
Este es mi bootlog: https://gitlab.com/-/snippets/3680856
Acceder al bootloader
Si observamos el bootloog, hay dos opciones al iniciar el dispositivo: console y debug.
Start to decompress!
Booting
Press '1' to enter BOOT console...
Press '2' to enter DEBUG mode......
Ext. phy is not found.
Boot from NOR/SPI flash
To read reset key,if on,to update
https://gitlab.com/-/snippets/3
Presionamos 1 y accedemos a la consola del bootloader, y escribimos help para ver qué opciones tenemos:
Booting
Press '1' to enter BOOT console...
Press '2' to enter DEBUG mode......
Ext. phy is not found.
Boot from NOR/SPI flash
To read reset key,if on,to update
(c)Copyright Realtek, Inc. 2011
Project RTL8676 LOADER (LZMA)
Version V1.1.0 (Mar 5 2013 19:39:22)
<RTL867X>help
help
info
reboot
run [app addr] [entry addr]
r [addr]
w [addr] [val]
d [addr] <len>
resetcfg
mac ["clear"/"osk"/mac address]
bootline
entry [address]
load [address]
xmodem [address]
tftp [ip] [server ip] [file name]
web
flashsize [256(k)/128(k)/1(M)/2(M)/4(M)/8(M)/16(M)]
memsize ROW[2k/4k/8k/16k] COL[256/512/1k/2k/4k] BANK[2/4]
uart [0(enable)/1(disable)]
Como siempre, cuanta más información recopilemos, mejor, por eso vamos a echar un vistazo a info
y a bootline
<RTL867X>info
(c)Copyright Realtek, Inc. 2011
Project RTL8676 LOADER (LZMA)
Version V1.1.0 (Mar 5 2013 19:39:22)
<RTL867X>BootLine:
MAC Address [0]: 00:23:79:11:22:33
Entry Point: 0x80000000
Load Address: 0x80000000
Application Address: 0xBD020000
Flash Size: 16M
Memory Configuration: ROW:8K COL:512 Bank:4Banks
MII Selection: 0 (0: Int. PHY 1: Ext. PHY)
UART is enabled
Más adelante veremos que tanto el entry proint
como application address
nos serán de ayuda.
Dumpear la flash
Para evitar las limitaciones del sistema operativo, usamos el bootloader que nos permite volcar por consola direcciones de memoria. Lo que haremos es poner a logear microcom
dumplear toda la flash, por consola, limpiar el fichero y convertirlo a binario, luego pasaremos binwalk
para identificar y extraer contido del firmware.
Entonces, con el router en el bootloader, como vimos anteriormente, configuramos el log control + 4 y log zte-h108n-wholeflash.hex y exit. Con esto ya empezamos a logear el contenido.
A continuación dumpeareamos la flash usando el comando d
, para ello necesitamos saber la dirección de memoria donde empezar a leer y la longitud a leer.
d 0xbd000000 0x1000000
Le damos al enter, y a esperar unas horas…
Cómo identificar las zonas de memoria a dumpear.
Para poder identificar dónde está la zona de memoria que corresponde a la flash, tendremos que leer detenidamente el bootlog, ya que nos da la información necesaria para entender el mapa de memoria del dispositivo.
En este caso lo importante es:
flash device: 0x800000 at 0xbd000000
spi probe...
SFCR:0xb8001200 SFCSR:0xb8001208 SFDR:0xb800120c
can not get SPI chip driver!
MXIC matched!!get SPI chip driver!
Flash size is 0x1000000
Physically mapped flash: Found an alies 0x1000000 for the chip at 0x0, mxic device detect.
Creating 7 MTD partitions on "Physically mapped flash":
0x000000000000-0x000001000000 : "whole_flash"
0x000000000000-0x000000020000 : "bootloader"
0x000000020000-0x000000080000 : "userconfig"
0x000000080000-0x000000600000 : "filesystem1"
0x000000600000-0x000000840000 : "kernel1"
0x000000840000-0x000000a80000 : "kernel2"
0x000000a80000-0x000001000000 : "filesystem2"
Como vemos la memoria flash comienza en 0xbd000000
flash device: 0x800000 at 0xbd000000
El tamaño de la flash es 0x1000000
Flash size is 0x1000000
Extraer la imagen binaria del volcado hexadecimal
Una vez que el volcado haya termiando ( dura horas ) deberías echar un ojo al fichero de log zte-h108n-wholeflash.hex por si hubiera alguna linea extra de log que no nos interesa. El fichero de log tiene un aspecto como este:
d 0xBD000000 0x1000000
0xBD000000: 10 00 00 FF 00 00 00 00 10 00 01 05 00 00 00 00 ................
0xBD000010: 00 00 00 00 00 00 00 00 10 00 FF F9 00 00 00 00 ................
0xBD000020: 10 00 FF F7 00 00 00 00 10 00 FF F5 00 00 00 00 ................
0xBD000030: 10 00 FF F3 00 00 00 00 10 00 FF F1 00 00 00 00 ................
0xBD000040: 10 00 FF EF 00 00 00 00 10 00 FF ED 00 00 00 00 ................
La herramienta que nos permite convertir este volcado hexadecimal a binario es xdd
o hacertelo a mano claro. En mi caso como necesito unos ligeros cambios en el fichero para que xdd
lo lea correctamente, hago lo siguiente:
cat zte-h108n-wholeflash.hex | sed 's/^.*0x//g' | xxd -r > zte-h108n-wholeflash.bin
Este comando elimina «0x» del comienzo de linea y lo pasa a xdd. El problema es que como tenemos una dirección base de 0xBD000000, tenemos desde la dirección 0x00000000 a la 0xBD000000 solamente con 0. Eso son gigas en el disco sin necesidad.
Supuestamente se podría usar xdd de esta manera para evitar este comportamiento
xxd -r -s "-0xBD000000"
Aunque en mi caso no funciona y lo soluciono, cortando el fichero. Es muy cutre, pero eficaz.
dd if=zte-h108n-wholeflash.bin of=zte-h108n-wholeflash.strip.bin skip=$((0xBD000000)) iflag=skip_bytes,count_bytes
Analizar la memoria flash con binwalk
Binwalk es una herramienta excepcional para la búsqueda de estructuras. En nuestro caso lanzamos binwalk directamente para ver qué identifica.
$ binwalk zte-h108n-wholeflash.strip.bin
DECIMAL HEXADECIMAL DESCRIPTION
--------------------------------------------------------------------------------
131708 0x2027C Zlib compressed data, compressed
197244 0x3027C Zlib compressed data, compressed
230012 0x3827C Zlib compressed data, compressed
237580 0x3A00C Zlib compressed data, compressed
250492 0x3D27C PEM RSA private key
251455 0x3D63F PEM certificate
262780 0x4027C Zlib compressed data, compressed
270232 0x41F98 Zlib compressed data, compressed
270452 0x42074 Zlib compressed data, compressed
270724 0x42184 Zlib compressed data, compressed
328316 0x5027C Zlib compressed data, compressed
524288 0x80000 Squashfs filesystem, little endian, version 4.0, compression:lzma, size: 4227847 bytes, 869 inodes, blocksize: 131072 bytes, created: 2015-06-22 08:45:55
6291712 0x600100 LZMA compressed data, properties: 0x5D, dictionary size: 33554432 bytes, uncompressed size: 4704904 bytes
8651008 0x840100 LZMA compressed data, properties: 0x5D, dictionary size: 33554432 bytes, uncompressed size: 4704904 bytes
11010048 0xA80000 Squashfs filesystem, little endian, version 4.0, compression:lzma, size: 4227847 bytes, 869 inodes, blocksize: 131072 bytes, created: 2015-06-22 08:45:55
Es importante recuperar ahora otra parte del bootlog
en la que se muestran las zonas de memoria de la flash
Creating 7 MTD partitions on «Physically mapped flash»:
0x000000000000-0x000001000000 : «whole_flash»
0x000000000000-0x000000020000 : «bootloader»
0x000000020000-0x000000080000 : «userconfig»
0x000000080000-0x000000600000 : «filesystem1»
0x000000600000-0x000000840000 : «kernel1»
0x000000840000-0x000000a80000 : «kernel2»
0x000000a80000-0x000001000000 : «filesystem2»
Podemos ver las coincidencias de las particiones de la memoria con lo que encuentra binwalk. Hay una ligera diferencia de los comienzos de bloques pero podemos observar que son cabeceras y que realmente las estructuras lzma o sqashfs están justamente donde binwalk las localiza.
Para acabar una forma sencilla de seccionar el fichero de la flash en las partes correspondientes y trabajar con el sería así:
dd if=zte-h108n-wholeflash.strip.bin of=bootloader count=$((0x20000)) iflag=skip_bytes,count_bytes
dd if=zte-h108n-wholeflash.strip.bin of=userconfig skip=$((0x20000)) count=$(( $((0x80000)) - $((0x20000)) )) iflag=skip_bytes,count_bytes
dd if=zte-h108n-wholeflash.strip.bin of=filesystem1 skip=$((0x80000)) count=$(( $((0x600000)) - $((0x80000)) )) iflag=skip_bytes,count_bytes
dd if=zte-h108n-wholeflash.strip.bin of=kernel1 skip=$((0x600000)) count=$(( $((0x840000)) - $((0x600000)) )) iflag=skip_bytes,count_bytes
dd if=zte-h108n-wholeflash.strip.bin of=kernel2 skip=$((0x840000)) count=$(( $((0xa80000)) - $((0x840000)) )) iflag=skip_bytes,count_bytes
dd if=zte-h108n-wholeflash.strip.bin of=filesystem2 skip=$((0xa80000)) count=$(( $((0x1000000)) - $((0xa80000)) )) iflag=skip_bytes,count_bytes
Siguientes pasos…
En próximos artículos entramos a analizar el contenido de filesystem para localizar las credenciales que nos permitan acceder al dispositivo como root, o como cualquier otro usuario.
También hablaremos de como descifrar y cifrar el fichero de configuración del modelo H108N
Para acabar formas alternativas de conseguir información acerca del dispositivo cuando no tenemos acceso a él.
Deja una respuesta