
Hace unos días, decidí hacer ingeniería inversa del firmware de mi enrutador usando binwalk.
Me compré un . No es el mejor enrutador, pero para mis necesidades es suficiente.
Cada vez que compro un nuevo enrutador, instalo . ¿Por qué? Generalmente, los fabricantes no se preocupan mucho por el soporte de sus enrutadores y con el tiempo el software se vuelve obsoleto, surgen vulnerabilidades y así sucesivamente, ya entiendes. Por eso prefiero el firmware open-source OpenWRT, que es bien soportado por la comunidad.
Después de descargar OpenWRT, también para mi nuevo Archer C7 desde el sitio oficial y decidí analizarlo. Solo por diversión y para hablar de binwalk.
¿Qué es binwalk?
es una herramienta de código abierto para el análisis, ingeniería inversa y extracción de imágenes de firmware.
Creada en 2010 por Craig Heffner, binwalk puede escanear imágenes de firmware y encontrar archivos, identificar y extraer imágenes de sistemas de archivos, código ejecutable, archivos comprimidos, bootloaders y kernels, formatos de archivo como JPEG y PDF, y mucho más.
Puedes usar binwalk para realizar ingeniería inversa de firmware para entender cómo funciona. Buscar vulnerabilidades en archivos binarios, extraer archivos y buscar backdoors o certificados digitales. También se pueden encontrar opcodes para un montón de CPU diferentes.
Puedes descomprimir imágenes de sistemas de archivos para buscar ciertos archivos de contraseñas (passwd, shadow, etc.) e intentar romper hashes de contraseñas. Puedes realizar un análisis binario entre dos o más archivos. Puedes realizar un análisis de entropía de datos para buscar datos comprimidos o claves de cifrado codificadas. Todo esto sin necesidad de acceso al código fuente.
En general, todo lo necesario está ahí 🙂
¿Cómo funciona binwalk?
La característica principal de binwalk es su escaneo por firmas. Binwalk puede escanear una imagen de firmware para buscar varios tipos de archivos y sistemas de archivos embebidos.
¿Conoces la utilidad de línea de comandos file?
file /bin/bash
/bin/bash: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), linked dynamically, interpreter /lib64/l, para GNU/Linux 3.2.0, BuildID[sha1]=12f73d7a8e226c663034529c8dd20efec22dde54, strippedComando fileque mira el encabezado del archivo y busca una firma (número mágico) para determinar el tipo de archivo. Por ejemplo, si un archivo comienza con la secuencia de bytes 0x89 0x50 0x4E 0x47 0x0D 0x0A 0x1A 0x0A, ella sabe que este es un archivo PNG. En hay una lista de firmas de archivos comunes.
Binwalk funciona de manera similar. Pero en lugar de buscar firmas solo al comienzo del archivo, binwalk escaneará todo el archivo. Además, binwalk puede extraer archivos encontrados en la imagen.
Herramientas file y binwalk utiliza la biblioteca libmagic para identificar firmas de archivos. Pero binwalk también admite una lista de firmas mágicas personalizadas para buscar archivos comprimidos / archivados, encabezados de firmware, núcleos de Linux, cargadores, sistemas de archivos, etc.
¿Vamos a divertirnos?
Instalación de binwalk
Binwalk es compatible con varias plataformas, incluyendo Linux, OSX, FreeBSD y Windows.
Para instalar la última versión de binwalk, puedes y seguir o , disponible en el sitio web del proyecto.
Binwalk tiene muchas opciones diferentes:
$ binwalk
Binwalk v2.2.0
Craig Heffner, ReFirmLabs
https://github.com/ReFirmLabs/binwalk
Uso: binwalk [OPTIONS] [FILE1] [FILE2] [FILE3] ...
Opciones de escaneo de firma:
-B, --signature Escanea el archivo(s) de destino en busca de firmas de archivo comunes
-R, --raw= Escanea el archivo(s) de destino en busca de la secuencia de bytes especificada
-A, --opcodes Escanea el archivo(s) de destino en busca de firmas de código ejecutable comunes
-m, --magic= Especifica un archivo mágico personalizado para usar
-b, --dumb Desactiva las palabras clave de firma inteligente
-I, --invalid Muestra resultados marcados como inválidos
-x, --exclude= Excluye resultados que coincidan con
-y, --include= Muestra solo resultados que coincidan con
Opciones de extracción:
-e, --extract Extrae automáticamente los tipos de archivo conocidos
-D, --dd= Extrae firmas de , asigna a los archivos una extensión de y ejecuta
-M, --matryoshka Escanea recursivamente los archivos extraídos
-d, --depth= Limita la profundidad de recursión de matryoshka (por defecto: 8 niveles de profundidad)
-C, --directory= Extrae archivos/carpetas a un directorio personalizado (por defecto: directorio de trabajo actual)
-j, --size= Limita el tamaño de cada archivo extraído
-n, --count= Limita el número de archivos extraídos
-r, --rm Elimina los archivos tallados después de la extracción
-z, --carve Tallar datos de archivos, pero no ejecutar utilidades de extracción
-V, --subdirs Extrae en subdirectorios nombrados por el desplazamiento
Opciones de entropía:
-E, --entropy Calcula la entropía del archivo
-F, --fast Utiliza un análisis de entropía más rápido, pero menos detallado
-J, --save Guarda la trama como un PNG
-Q, --nlegend Omite la leyenda del gráfico de entropía
-N, --nplot No genera un gráfico de trama de entropía
-H, --high= Establece el umbral de activación de entropía del borde ascendente (por defecto: 0.95)
-L, --low= Establece el umbral de activación de entropía del borde descendente (por defecto: 0.85)
Opciones de diferencia binaria:
-W, --hexdump Realiza un hexdump / diferencia de un archivo o archivos
-G, --green Muestra solo las líneas que contienen bytes que son iguales en todos los archivos
-i, --red Muestra solo las líneas que contienen bytes que son diferentes en todos los archivos
-U, --blue Muestra solo las líneas que contienen bytes que son diferentes en algunos archivos
-u, --similar Muestra solo las líneas que son iguales entre todos los archivos
-w, --terse Diferencia todos los archivos, pero solo muestra un hexdump del primer archivo
Opciones de compresión RAW:
-X, --deflate Escanea en busca de flujos de compresión deflate en bruto
-Z, --lzma Escanea en busca de flujos de compresión LZMA en bruto
-P, --partial Realiza un escaneo superficial, pero más rápido
-S, --stop Detiene después del primer resultado
Opciones generales:
-l, --length= Número de bytes a escanear
-o, --offset= Comienza el escaneo en este desplazamiento de archivo
-O, --base= Agrega una dirección base a todos los desplazamientos impresos
-K, --block= Establece el tamaño del bloque de archivo
-g, --swap= Invierte cada n bytes antes de escanear
-f, --log= Registra resultados en un archivo
-c, --csv Registra resultados en un archivo en formato CSV
-t, --term Formatea la salida para ajustarse a la ventana del terminal
-q, --quiet Suprime la salida a stdout
-v, --verbose Habilita una salida detallada
-h, --help Muestra la salida de ayuda
-a, --finclude= Solo escanea archivos cuyos nombres coincidan con esta expresión regular
-p, --fexclude= No escanea archivos cuyos nombres coincidan con esta expresión regular
-s, --status= Habilita el servidor de estado en el puerto especificadoEscaneado de imágenes
Comencemos buscando las firmas de los archivos dentro de la imagen (imagen del sitio ).
Ejecutando binwalk con el parámetro —signature:
$ binwalk --signature --term archer-c7.bin
DECIMINAL HEXADECIMAL DESCRIPCIÓN
------------------------------------------------------------------------------------------
21876 0x5574 Cadena de versión de U-Boot, "U-Boot 1.1.4-g4480d5f9-dirty (20 de
mayo de 2019 - 18:45:16)"
21940 0x55B4 Tabla de polinomios CRC32, big endian
23232 0x5AC0 Encabezado de uImage, tamaño del encabezado: 64 bytes, CRC del encabezado:
0x386C2BD5, creado: 2019-05-20 10:45:17, tamaño de la imagen:
41162 bytes, Dirección de Datos: 0x80010000, Punto de Entrada:
0x80010000, CRC de datos: 0xC9CD1E38, SO: Linux, CPU: MIPS,
tipo de imagen: Imagen de Firmware, tipo de compresión: lzma, nombre de
imagen: "imagen de u-boot"
23296 0x5B00 Datos comprimidos LZMA, propiedades: 0x5D, tamaño del diccionario:
8388608 bytes, tamaño descomprimido: 97476 bytes
64968 0xFDC8 Documento XML, versión: "1.0"
78448 0x13270 Encabezado de uImage, tamaño del encabezado: 64 bytes, CRC del encabezado:
0x78A267FF, creado: 2019-07-26 07:46:14, tamaño de la imagen:
1088500 bytes, Dirección de Datos: 0x80060000, Punto de Entrada:
0x80060000, CRC de datos: 0xBB9D4F94, SO: Linux, CPU: MIPS,
tipo de imagen: Imagen de Múltiples Archivos, tipo de compresión: lzma,
nombre de imagen: "MIPS OpenWrt Linux-3.3.8"
78520 0x132B8 Datos comprimidos LZMA, propiedades: 0x6D, tamaño del diccionario:
8388608 bytes, tamaño descomprimido: 3164228 bytes
1167013 0x11CEA5 Sistema de archivos Squashfs, little endian, versión 4.0,
compresión:xz, tamaño: 14388306 bytes, 2541 inodos,
tamaño de bloque: 65536 bytes, creado: 2019-07-26 07:51:38
15555328 0xED5B00 Datos comprimidos gzip, desde Unix, última modificación: 2019-07-26
07:51:41Ahora tenemos mucha información sobre esta imagen.
La imagen utiliza como cargador de arranque (encabezado de la imagen en la dirección 0x5AC0 y la imagen comprimida del cargador en la dirección 0x5B00). A partir del encabezado de uImage en la dirección 0x13270, sabemos que la arquitectura del procesador es MIPS y el núcleo de Linux es la versión 3.3.8. Y basándonos en la imagen encontrada en la dirección 0x11CEA5, podemos ver que rootfs es el sistema de archivos squashfs.
Ahora descomprimamos el cargador (U-Boot) usando el comando dd:
$ dd if=archer-c7.bin of=u-boot.bin.lzma bs=1 skip=23296 count=41162
41162+0 registros entrantes
41162+0 registros salientes
41162 bytes (41 kB, 40 KiB) copiados, 0.0939608 s, 438 kB/sDado que la imagen está comprimida con LZMA, necesitamos descomprimirla:
$ unlzma u-boot.bin.lzmaAhora tenemos la imagen de U-Boot:
$ ls -l u-boot.bin
-rw-rw-r-- 1 sprado sprado 97476 Feb 5 08:48 u-boot.bin¿Qué tal buscar el valor por defecto para bootargs?
$ strings u-boot.bin | grep bootargs
bootargs
bootargs=console=ttyS0,115200 board=AP152 rootfstype=squashfs init=\/etc\/preinit mtdparts=spi0.0:128k(factory-uboot),192k(u-boot),64k(ART),1536k(uImage),14464k@0x1e0000(rootfs) mem=128MVariable de entorno U-Boot bootargs se utiliza para pasar parámetros al núcleo de Linux. Y a partir de lo anterior, entendemos mejor la memoria flash del dispositivo.
¿Qué tal si extraemos la imagen del núcleo de Linux?
$ dd if=archer-c7.bin of=uImage bs=1 skip=78448 count=1088572
1088572+0 registros en
1088572+0 registros fuera
1088572 bytes (1,1 MB, 1,0 MiB) copiados, 1,68628 s, 646 kB/sPodemos verificar que la imagen se ha extraído correctamente con el comando file:
$ file uImage
uImage: u-boot legacy uImage, MIPS OpenWrt Linux-3.3.8, Linux/MIPS, Multi-File Image (lzma), 1088500 bytes, Vie Jul 26 07:46:14 2019, Load Address: 0x80060000, Entry Point: 0x80060000, Header CRC: 0x78A267FF, Data CRC: 0xBB9D4F94El formato del archivo uImage es básicamente una imagen del núcleo de Linux con una cabecera adicional. Ahora eliminemos esta cabecera para obtener la imagen final del núcleo de Linux:
$ dd if=uImage of=Image.lzma bs=1 skip=72
1088500+0 registros en
1088500+0 registros fuera
1088500 bytes (1,1 MB, 1,0 MiB) copiados, 1,65603 s, 657 kB/sLa imagen está comprimida, así que descomprimámosla:
$ unlzma Image.lzmaAhora tenemos la imagen del núcleo de Linux:
$ ls -la Image
-rw-rw-r-- 1 sprado sprado 3164228 Feb 5 10:51 Image¿Qué podemos hacer con la imagen del núcleo? Podríamos, por ejemplo, buscar cadenas en la imagen y encontrar la versión del núcleo de Linux y obtener información sobre el entorno utilizado para compilar el núcleo:
$ strings Image | grep "Linux version"
Linux version 3.3.8 (leo@leo-MS-7529) (gcc version 4.6.3 20120201 (prerelease) (Linaro GCC 4.6-2012.02) ) #1 Lun May 20 18:53:02 CST 2019A pesar de que el firmware fue lanzado el año pasado (2019) cuando escribo este artículo, utiliza una versión antigua del núcleo de Linux (3.3.8) lanzada en 2012, compilada con una versión muy antigua de GCC (4.6) también de 2012!
(nota del traductor, ¿todavía confías en tus routers en la oficina y en casa?)
Con la opción --opcodes también podemos usar binwalk para buscar instrucciones de máquina y determinar la arquitectura del procesador de la imagen:
$ binwalk --opcodes Image
DECIMAL HEXADECIMAL DESCRIPCIÓN
--------------------------------------------------------------------------------
2400 0x960 instrucciones MIPS, epílogo de función
2572 0xA0C instrucciones MIPS, epílogo de función
2828 0xB0C instrucciones MIPS, epílogo de función¿Qué pasa con el sistema de archivos raíz? En lugar de extraer la imagen manualmente, utilicemos la opción binwalk --extract:
$ binwalk --extract --quiet archer-c7.binEl sistema de archivos raíz completo se extraerá en un subdirectorio:
$ cd _archer-c7.bin.extracted/squashfs-root/
$ ls
bin dev etc lib mnt overlay proc rom root sbin sys tmp usr var www
$ cat etc/banner
MM NM MMMMMMM M M
$MMMMM MMMMM MMMMMMMMMMM MMM MMM
MMMMMMMM MM MMMMM. MMMMM:MMMMMM: MMMM MMMMM
MMMM= MMMMMM MMM MMMM MMMMM MMMM MMMMMM MMMM MMMMM'
MMMM= MMMMM MMMM MM MMMMM MMMM MMMM MMMMNMMMMM
MMMM= MMMM MMMMM MMMMM MMMM MMMM MMMMMMMM
MMMM= MMMM MMMMMM MMMMM MMMM MMMM MMMMMMMMM
MMMM= MMMM MMMMM, NMMMMMMMM MMMM MMMM MMMMMMMMMMM
MMMM= MMMM MMMMMM MMMMMMMM MMMM MMMM MMMM MMMMMM
MMMM= MMMM MM MMMM MMMM MMMM MMMM MMMM MMMM
MMMM$ ,MMMMM MMMMM MMMM MMM MMMM MMMMM MMMM MMMM
MMMMMMM: MMMMMMM M MMMMMMMMMMMM MMMMMMM MMMMMMM
MMMMMM MMMMN M MMMMMMMMM MMMM MMMM
MMMM M MMMMMMM M M
M
---------------------------------------------------------------
For those about to rock... (%C, %R)
---------------------------------------------------------------Ahora podemos hacer muchas cosas diferentes.
Podemos buscar archivos de configuración, hashes de contraseñas, claves criptográficas y certificados digitales. Podemos analizar archivos binarios para y vulnerabilidades.
Con y incluso podemos ejecutar (emular) un archivo ejecutable desde la imagen:
$ ls
bin dev etc lib mnt overlay proc rom root sbin sys tmp usr var www
$ cp /usr/bin/qemu-mips-static .
$ sudo chroot . ./qemu-mips-static bin/busybox
BusyBox v1.19.4 (2019-05-20 18:13:49 CST) binario de múltiples llamadas.
Copyright (C) 1998-2011 Erik Andersen, Rob Landley, Denys Vlasenko
y otros. Licenciado bajo GPLv2.
Vea la distribución de origen para el aviso completo.
Uso: busybox [función] [argumentos]...
o: busybox --list[-full]
o: función [argumentos]...
BusyBox es un binario de múltiples llamadas que combina muchas utilidades Unix comunes
en un solo ejecutable. La mayoría de las personas crearán un enlace a busybox para cada función que desean usar y BusyBox
actuará como lo que se invocó.
Funciones actualmente definidas:
[, [[, addgroup, adduser, arping, ash, awk, basename, cat, chgrp, chmod, chown, chroot, clear, cmp, cp, crond, crontab, cut, date, dd, delgroup, deluser, dirname, dmesg, echo, egrep, env, expr, false,
fgrep, find, free, fsync, grep, gunzip, gzip, halt, head, hexdump, hostid, id, ifconfig, init, insmod, kill, killall, klogd, ln, lock, logger, ls, lsmod, mac_addr, md5sum, mkdir, mkfifo, mknod, mktemp,
mount, mv, nice, passwd, pgrep, pidof, ping, ping6, pivot_root, poweroff, printf, ps, pwd, readlink, reboot, reset, rm, rmdir, rmmod, route, sed, seq, sh, sleep, sort, start-stop-daemon, strings,
switch_root, sync, sysctl, tail, tar, tee, telnet, test, tftp, time, top, touch, tr, traceroute, true, udhcpc, umount, uname, uniq, uptime, vconfig, vi, watchdog, wc, wget, which, xargs, yes, zcat¡Genial! Pero ten en cuenta que la versión de BusyBox es 1.19.4. Es una versión muy antigua de BusyBox, lanzada en abril de 2012.
Así que TP-Link lanza la imagen del firmware en 2019 utilizando software (GCC toolchain, kernel, BusyBox, etc.) de 2012!
Ahora entiendes por qué siempre instalo OpenWRT en mis enrutadores?
Esto no es todo
Binwalk también puede realizar un análisis de entropía, imprimir datos de entropía sin procesar y generar gráficos de entropía. Generalmente, una alta entropía se observa cuando los bytes en la imagen son aleatorios. Esto puede significar que la imagen contiene un archivo cifrado, comprimido u ofuscado. ¿Un clave de cifrado escrita a mano? ¿Por qué no?

También podemos usar el parámetro --raw para buscar una secuencia personalizada de bytes sin procesar en la imagen o el parámetro --hexdump para realizar un volcado hexadecimal que compara dos o más archivos de entrada.
pueden ser añadidas a binwalk ya sea a través de un archivo de firmas personalizadas especificado en la línea de comandos con el parámetro --magic, o añadiéndolas al directorio $ HOME / .config / binwalk / magic.
Puedes encontrar más información sobre binwalk en .
La extensión de binwalk
Hay un de binwalk, implementado como un módulo de Python, que puede ser utilizado por cualquier script de Python para realizar escaneos de binwalk programáticamente, y la utilidad de línea de comandos binwalk puede ser casi completamente replicada en solo dos líneas de código Python.
import binwalk
binwalk.scan()Con la API de Python también puedes crear para personalizar y extender binwalk.
También existe un y una versión en la nube .
Entonces, ¿por qué no descargas una imagen de firmware de Internet y pruebas binwalk? Prometo que te divertirás mucho 🙂
Fuente: habr.com
