
Enfoque de principiante para el hacking de firmware
Este documento es mi experiencia personal como novato en la reversión y explotación de firmware.

Para la demostración, analizaremos y reproduciremos CVE-2023-27216.
Para explotar cualquier firmware, se deben seguir los siguientes pasos:
gdbserver de forma estática para depurar.Por lo general, un archivo binario de firmware contiene un bootloader (uBoot), un archivo de kernel, un encabezado de kernel para el bootloader (uImage), un sistema de archivos comprimido (generalmente en formato SquashFS), una tabla CRC/MD5 (para verificar la integridad del archivo) y otros archivos varios.
Busca una forma de analizar el firmware primero, investiga un poco, obtuve algunos recursos:

Extraer firmware usando binwalk: binwalk -Me DSL-3782_A1_EU_1.01_07282016.bin

Obtuve la carpeta squashfs-root extraída y algunos archivos extraños.

Bonificación: Si no ves la carpeta squashfs-root, usa unsquashfs en cualquier archivo ".squashfs" que veas. Son como archivos zip 😅.
Verifica la arquitectura y el endianness del firmware. Esto se puede comprobar examinando algunos binarios extraídos del firmware. Verifica la arquitectura y el firmware: file <binary>

Aquí podemos confirmar casi con certeza que el firmware se ejecuta en arquitectura MIPS de 32 bits MSB. La razón de "casi" es que algunos firmwares pueden ejecutarse en una arquitectura diferente con MIPS Compatible, como Lexra.
Revisa la carpeta squashfs-root y encontré algunos archivos interesantes:
usr/etc/init.d/rcS => Este es el script que se ejecuta cuando el firmware arrancausr/etc/passwd => Este es el archivo que contiene la información del usuariouserfs/romfile.cfg => Hay una credencial admin:adminRevisa el archivo rcS y encontré un código interesante:
echo "admin:$1$$iC.dUsGpxNNJGeOm1dFio/:0:0:root:/:/bin/sh" > /usr/etc/passwd
passwdBoa es un servidor web antiguo, utilizado principalmente en dispositivos embebidos como routers en los años 2000. Sin embargo, el servidor Boa detuvo su desarrollo en 2005. Aunque el servidor Boa está muerto desde hace casi 20 años, aún vive hoy en día gracias a nuestros fabricantes.

Recomiendo usar un sistema operativo basado en Debian para el proceso de emulación, como Ubuntu o Kali. Existe otro sistema operativo centrado en la manipulación de firmware llamado AttifyOS. En este documento, utilicé Kali Linux. Comienza con el proceso de estimulación, hay 2 herramientas:

Veamos cómo usar FAT para emular completamente un firmware. Primero, clonamos el repositorio desde github a tu máquina Kali. Y pasamos por el proceso de configuración. También necesitas modificar el archivo fat.config, de lo contrario no funcionará.
git clone https://github.com/attify/firmware-analysis-toolkit.git
cd firmware-analysis-toolkit
./setup.sh
vi fat.config # Modificar a tu contraseña de sudo.
Luego copiamos el binario del firmware (el que descargamos del fabricante) a la carpeta de FAT en nuestra máquina Kali y lo ejecutamos.
./fat.py DSL-3782_A1_EU_1.01_07282016.bin
Nota: Durante el proceso de configuración de FAT, podemos encontrar errores. Puede decir que falta libmagic.

Simplemente ejecuta
pip unistall python-magic
pip install python-magic
Esto debería solucionar el problema, luego ejecutamos el comando de construcción nuevamente. Ahora debería funcionar perfectamente.

Presiona Enter para ejecutar. El proceso de emulación debería funcionar correctamente, puedes navegar a http://192.168.1.1 (en la máquina Kali) para verificar si funciona o no.

También puedes iniciar sesión en la consola si tienes las credenciales. Aquí está admin:admin.

Si decides apagar el firmware emulado, solo presiona Ctrl+A X. Cuando necesites ejecutarlo de nuevo, no vuelvas a ejecutar fat.py porque el firmware ya se ha compilado en una imagen. Solo necesitas ejecutar el script que ya se ha generado.
cd firmadyne/scratch/<Image-ID>
./run.sh

Compila gdbserver para fines de depuración. Hay muchas formas de compilar gdbserver. También puedes descargar un servidor compilado estáticamente. Hay un repositorio que almacena algunos compilados estáticamente. Sin embargo, prefiero compilar gdbserver yo mismo, ya que los del repositorio de github son bastante antiguos y pueden tener problemas de compatibilidad.
Consulta esta publicación de blog como referencia: https://sheran.sg/blog/cross-compile-gdb-for-mips/. La publicación se subió el 30 de julio de 2024, justo antes de este proyecto, por lo que funciona perfectamente.
Nota: La publicación está compilada para MIPS x32 LSB, pero nosotros necesitamos MIPS x32 MSB. Necesitamos cambiar mipsel-linux-gnu por mips-linux-gnu.
Necesitamos instalar la cadena de herramientas para MIPS. Afortunadamente, el paquete Debian ya lo tiene.
**apt update && apt upgrade -y
apt install -y build-essential m4 gcc-mips-linux-gnu g++-mips-linux-gnu**
Para compilar gdbserver para MIPS, hay algunos paquetes que necesitamos compilar e instalar. Aquí es donde obtengo el código fuente.
Obtener el código fuente
wget https://sourceware.org/pub/gdb/releases/gdb-15.1.tar.xz
wget https://gmplib.org/download/gmp/gmp-6.3.0.tar.xz
wget https://www.mpfr.org/mpfr-current/mpfr-4.2.1.tar.xz
Compilar bibliotecas con la cadena de herramientas Es crucial tener privilegios de root al compilar estas bibliotecas. Primero debemos compilar GMP porque es un requisito para compilar MPFR.
tar xvf gmp-6.3.0.tar.xz && cd gmp-6.3.0
./configure --host=mips-linux-gnu
make -j$((`nproc`+1))
make install
cd ..
Luego compilamos MPFR:
tar xvf mpfr-4.2.1.tar.xz && cd mpfr-4.2.1
./configure --host=mipsel-linux-gnu --with-gmp-build=<YOUR-FOLDER>/gmp-6.3.0
make -j$((`nproc`+1))
make install
cd ..
Ahora podemos compilar gdbserver finalmente:
tar xvf gdb-15.1.tar.xz && cd gdb-15.1
./configure --host=mipsel-linux-gnu --with-gmp-lib=/usr/local/lib --with-mpfr-lib=/usr/local/lib --with-gmp-include=<YOUR-FOLDER>/gmp-6.3.0 --with-mpfr-include=<YOUR-FOLDER>/mpfr-4.2.1/src
make -j$((`nproc`+1)) LDFLAGS=-static
El binario compilado gdbserver debería estar en la carpeta gdb-15.1/gdbserver.
El firmware emulado no tiene wget, nc, curl, /dev/tcp, ... No podemos alojar un servidor HTTP Python para transferir archivos. Tampoco tenemos ssh. Sin embargo, podemos colocar nuestro gdbserver en la máquina emulada montando la imagen.
sudo ./scripts/mount.sh 1gdbserver compilado estáticamente en cualquier lugar de la carpeta montada.sudo ./scripts/umount.sh 1./run.sh de nuevo para estar seguro).

A partir de ahora, puedes realizar depuración y hacking dentro de la máquina Kali. Sin embargo, podemos ir un paso más allá redirigiendo los puertos de la máquina emulada a nuestra máquina anfitriona (Windows o Mac).
Primero, verifiquemos la red usando ifconfig.

El resultado nos indica que hay 2 interfaces: eth0 y tap1_0. Por lo que sabemos, la interfaz eth0 es la red compartida con el anfitrión y tap1_0 es la interfaz de la máquina de firmware emulada.
Para una comprensión más fácil, la red de eth0 es como una red pública donde podemos acceder a la máquina Kali desde la máquina anfitriona. tap1_0 es como una red privada a la que solo podemos acceder desde la máquina Kali. Necesitamos redirigir la conexión desde eth0 al puerto 192.168.1.1:80 de la interfaz tap1_0.
Hay muchas herramientas que pueden ayudarnos con esto. Sin embargo, iptables parece funcionar mejor, si sabes cómo configurarlo, claro.
Primero debemos permitir la redirección de puertos. Ejecuta este comando:
echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward
Esto solo se aplica para una sesión. Si deseas aplicarlo permanentemente, modifica el contenido de /etc/sysctl.conf.
net.ipv4.ip_forward=1 # Encuentra esta línea, descoméntala.
Guarda y cierra el archivo cuando hayas terminado.
Luego aplica la configuración de este archivo. Ejecuta el siguiente comando:
sudo sysctl -p
sudo sysctl --system
Normalmente, podemos ejecutar un montón de comandos iptables. Pero sería demasiado tedioso 😵💫. Podemos instalar una herramienta iptables-persistent. Te permite escribir un archivo de configuración, cargarlo en el archivo o extraer cadenas a un archivo. Todo se puede hacer rápidamente.
apt install iptables-persistent
El archivo de configuración que queremos modificar aquí es /etc/iptables/rules.v4. Cambiamos el contenido del archivo al siguiente.
*filter
:INPUT ACCEPT [37:22880]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [35:2330]
# Forward HTTP Port
-A FORWARD -i eth0 -o tap1_0 -p tcp --dport 80 -d 192.168.1.1 -j ACCEPT
-A FORWARD -i tap1_0 -o eth0 -p tcp --sport 80 -s 192.168.1.1 -j ACCEPT
# Forward Debugger port
-A FORWARD -i eth0 -o tap1_0 -p tcp --dport 31337 -d 192.168.1.1 -j ACCEPT
-A FORWARD -i tap1_0 -o eth0 -p tcp --sport 31337 -s 192.168.1.1 -j ACCEPT
COMMIT
# Completed on Wed Aug 7 09:32:11 2024
# Generated by iptables-save v1.8.10 (nf_tables) on Wed Aug 7 09:32:11 2024
*nat
:PREROUTING ACCEPT [60:5405]
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [1096:50947]
-A PREROUTING -i eth0 -p tcp -j DNAT --to-destination 192.168.1.1
-A POSTROUTING -o tap1_0 -p tcp -d 192.168.1.1 -j MASQUERADE
Atención: Permitir todos los puertos genera muchos problemas de seguridad. Se recomienda hacer
DROPa todos los puertos y luego soloFORWARDalgunos según tu gusto.
Guarda y renueva la cadena de iptables.
service netfilter-persistent reload
Ahora puedes acceder desde fuera del anfitrión.

Múltiples puntos finales para explotar. Dos de ellos están dentro del binario cfg_manager. Solo demostraré uno, el otro te dejo que lo descubras por ti mismo.
Lanza el binario a tu descompilador favorito, busca todos los comandos system, puedes ver esto. El comando ejecuta un archivo llamado /etc/lanconfig.sh.

Revisando otros lugares que puedan usar este archivo, encontré un lugar donde podemos escribir el archivo.

Explicando lo que hace:
/etc/lanconfig.shmxmlElementGetAttr que supongo que encuentra un atributo de un objeto, podría ser directa o indirectamente de una Solicitud HTTP, podría ser XML.sprintf para crear una cadena a partir de los atributos obtenidos de mxmlElementGetAttr.fputs para escribir en el archivo.Inmediatamente, busqué cualquier cosa en la carpeta web boaroot que esté relacionada con IP, netmask y encontré esto. La documentación para el servidor web Boa es extremadamente limitada, solo puedo suponer que coloca el parámetro POST lan_ip1 en los parámetros IP de un XML que es llamado desde el binario.

En la interfaz, podemos encontrar la solicitud que desencadena el error. Está en Configuración > Red.

Intercepta la solicitud con Burpsuite cuando presionamos Guardar.

El payload 192.168.1.1;utelnetd -p 8090 -l /bin/sh; es una shell inversa. Podemos ejecutar y conectarnos a ella.

Similar, podría ser mejor que FAT, no lo he probado -> FirmAE.
Binary Ninja cuesta solo 74$ si tienes estatus de estudiante. La licencia se puede compartir con cualquiera.
Otros errores relacionados con el CVE:

Esto también puede llevar a RCE, te lo dejo para que lo hagas tú mismo. La memoria en esa ubicación data_4c0160 puede ser inyectada en algún lugar 🫡.

