Skip to content
KitploitKITPLOIT
HerramientasBlog
Enviar
HerramientasBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

··Feeds·Contacto·Privacidad·© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
firmware-workshop — En esta sesión del taller, extraeremos el firmware de un cargador de vehículos eléctricos, profundizaremos en el firmware y, finalmente, lo emularemos para poder interactuar con los servicios en tiempo real. | Kitploit
Herramientas/GitHubGitHub/onekey-sec/firmware-workshop
Seguridad de Sistemas EmbebidosAnálisis Dinámico (Sandboxing)Seguridad IoTIngeniería InversaAnálisis de BinariosAprendizaje y EducaciónAnálisis de FirmwareLabs y Práctica
GitHubonekey-sec/firmware-workshop

firmware-workshop

En esta sesión del taller, extraeremos el firmware de un cargador de vehículos eléctricos, profundizaremos en el firmware y, finalmente, lo emularemos para poder interactuar con los servicios en tiempo real.

5913hace 1 mesRevisado por Kitploit

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
Compartir
Ver Repositorio

Extracción, exploración y emulación práctica de firmware

Únete a nosotros en esta demostración práctica de Unblob, el extractor de firmware flexible. Durante esta sesión del taller, extraeremos firmware de un cargador de vehículos eléctricos, indagaremos en el firmware y, finalmente, lo emularemos para poder interactuar con los servicios en tiempo real. Unblob funciona tanto con versiones de hardware como descargables de firmware, por lo que tenemos un entorno rico en objetivos. No se necesita experiencia previa, esta sesión es adecuada para todos los niveles y esperamos verte allí.

Nuestro objetivo

Nuestro objetivo es un controlador de estación de carga para vehículos eléctricos de Phoenix Contact. Puedes encontrar más detalles al respecto aquí.

CHARX control modular, controlador de carga de CA, con sistema Linux embebido, IEC 61851-1, modo de funcionamiento: independiente, cliente, servidor,

Interfaces:

  • Ethernet (2x)
  • Comunicación celular (4G/2G)
  • Bus de sistema modular CHARX control
  • MICRO-USB tipo C

Protocolos de comunicación:

  • OCPP 1.6J
  • Modbus/TCP
  • MQTT

Dispositivos periféricos conectables:

  • Medidor de energía
  • RFID
  • Detección de corriente residual de CC
  • Montaje en carril DIN

Requisitos previos

Hay algunas herramientas que necesitamos en este taller. Puedes instalarlas ejecutando el script install-prerequisites de la siguiente manera:```sh ./install-prerequisites

root@kitploit:~
## Obtención del firmware

El firmware se puede obtener desde el sitio web del proveedor. Hay un script llamado
`download-firmware` en este repositorio que puedes usar para descargar el firmware
sin necesidad de abrir un navegador.

Nuestro enfoque de hoy está en el firmware proporcionado por el proveedor, ya que contiene todo
lo que necesitamos. Pero se puede aplicar un flujo de trabajo similar a un volcado de memoria extraído de
un dispositivo real. Lo interesante aquí es que podemos extraer, explorar y
emular sin siquiera necesitar un dispositivo real.

## Extracción con Unblob

Comencemos asegurándonos de que todas las dependencias estén disponibles:```
unblob --show-external-dependencies
The following executables found installed, which are needed by unblob:
    7z                          ✓
    debugfs                     ✓
    jefferson                   ✓
    lz4                         ✓
    lziprecover                 ✓
    lzop                        ✓
    sasquatch                   ✓
    sasquatch-v4be              ✓
    simg2img                    ✓
    ubireader_extract_files     ✓
    ubireader_extract_images    ✓
    unar                        ✓
    zstd                        ✓

Ahora podemos extraer el firmware con unblob:``` unblob CHARXSEC3XXXSoftwareBundleV190.raucb

root@kitploit:~
La extracción tarda unos 3 minutos en un portátil decente. Deberías ver una barra de progreso avanzando:

![unblob_progress](https://assets.kitploit.com/production/public/readmes/48963/9bdd3fefdf4e600ee070a461172a3ef07e482cde75b8e8a5d881021c7fa341e6.png)

Una vez que la extracción ha terminado, debería ser visible un directorio llamado
`CHARXSEC3XXXSoftwareBundleV190.raucb_extract`. Puedes entrar
en él y listar su contenido.

### Fragmentos, Fragmentos Desconocidos

Unblob funciona identificando fragmentos de datos dentro de los archivos. Si un fragmento es un
flujo comprimido, se descomprime. Si es un sistema de archivos o un archivo,
se extrae. Si la extracción o descompresión fue exitosa, el fragmento
que fue extraído al disco se elimina para recuperar espacio.

Aquí, un fragmento SquashFS version 4 little-endian fue extraído al disco,
extraído y eliminado. Los archivos (y por lo tanto los directorios de extracción) se nombran con
la nomenclatura `{start_offset}-{end_offset}.{type}`.

Podemos ver que aparecen 11KB de fragmento "desconocido" después del sistema de archivos squashfs.```
./0-132173824.squashfs_v4_le_extract
./132173824-132184833.unknown

Puedes ejecutar binwalk sobre él para ver qué contiene:``` binwalk 132173824-132184833.unknown

DECIMAL HEXADECIMAL DESCRIPTION

0 0x0 Object signature in DER format (PKCS header length: 4, sequence length: 10997 58 0x3A Certificate in DER format (x509 v3), header length: 4, sequence length: 4372 4434 0x1152 Certificate in DER format (x509 v3), header length: 4, sequence length: 4387

root@kitploit:~
Puedes comprobar los certificados con openssl:```
dd if=132173824-132184833.unknown bs=1 skip=58 | openssl x509 -in /dev/stdin -inform der -noout -text
dd if=132173824-132184833.unknown bs=1 skip=4434 | openssl x509 -in /dev/stdin -inform der -noout -text

Esto significa que los firmware probablemente están firmados con la clave privada del proveedor para que los dispositivos puedan asegurarse de que los firmware sean auténticos.

Esa es una de las ventajas de unblob: convertir incógnitas desconocidas en incógnitas conocidas que pueden investigarse.

Sistemas de archivos

Veamos el contenido de nuestro sistema de archivos squashfs:``` ls -al 0-132173824.squashfs_v4_le_extract total 460532 drwxrwxr-x 4 kali kali 4096 dec 5 09:51 . drwxrwxr-x 3 kali kali 4096 dec 5 09:51 .. -rw-rw-r-- 1 kali kali 20971520 sep 8 09:59 bootimg.vfat drwxrwxr-x 3 kali kali 4096 dec 5 09:51 bootimg.vfat_extract -rwxrwxr-x 1 kali kali 2654 sep 19 2022 hook -rw-rw-r-- 1 kali kali 442 sep 8 09:59 manifest.raucm -rw-rw-r-- 1 kali kali 450584576 sep 8 09:59 root.ext4 drwxrwxr-x 22 kali kali 4096 sep 8 09:57 root.ext4_extract

root@kitploit:~
Podemos ver un manifiesto en texto plano, un script de shell, un MBR y un sistema de archivos EXT4:```
find -maxdepth 1 -type f -exec file {} \;
./manifest.raucm: ASCII text
./hook: a /usr/bin/env sh script, ASCII text executable
./bootimg.vfat: DOS/MBR boot sector, code offset 0x3c+2, OEM-ID "mkfs.fat", sectors/cluster 4, reserved sectors 4, root entries 512, sectors 40960 (volumes <=32 MB), Media descriptor 0xf8, sectors/FAT 40, sectors/track 63, heads 255, hidden sectors 163158016, reserved 0x1, serial number 0xd09aad9c, label: "KERNEL     ", FAT (16 bit)
./root.ext4: Linux rev 1.0 ext4 filesystem data, UUID=8ed19606-02c4-42e7-9cfb-1a2839f93ec4 (extents) (large files) (huge files)

Tanto bootimg.vfat como root.ext4 fueron procesados y extraídos por unblob. La partición VFAT contiene todo lo relacionado con el arranque y el sistema operativo (kernel de Linux, DTB, TEE):``` oftree: Device Tree Blob version 17, size=27469, boot CPU=0, string block size=1657, DT structure block size=25756 tee.bin: data zImage: Linux kernel ARM boot executable zImage (little-endian) zImage-imx6ul-ksp0632.dtb: Device Tree Blob version 17, size=27469, boot CPU=0, string block size=1657, DT structure block size=25756

root@kitploit:~
Verás que unblob es un poco codicioso y extraerá un archivo ELF y un archivo CPIO
del kernel de Linux (`zImage`); estos corresponden al kernel mínimo y al
ramdisk.

El sistema de archivos EXT4 contiene el sistema de archivos raíz que monta el
kernel de Linux al arrancar:```
ls -alh root.ext4_extract 
total 88K
drwxrwxr-x 22 kali kali 4,0K sep  8 09:57 .
drwxrwxr-x  4 kali kali 4,0K dec  5 09:51 ..
drwxrwxr-x  2 kali kali 4,0K dec  5 09:51 bin
drwxrwxr-x  3 kali kali 4,0K dec  5 09:51 boot
drwxrwxr-x 16 kali kali 4,0K sep  8 09:56 data
drwxrwxr-x  2 kali kali 4,0K jul 18 00:09 dev
drwxrwxr-x 53 kali kali 4,0K dec  5 09:51 etc
drwxrwxr-x 18 kali kali 4,0K sep  8 09:56 home
drwxrwxr-x  2 kali kali 4,0K jul 18 03:13 identity
drwxrwxr-x  9 kali kali 4,0K dec  5 09:51 lib
drwxrwxr-x  2 kali kali 4,0K jul 18 03:14 log
drwxrwxr-x  2 kali kali 4,0K sep  8 09:57 lost+found
drwxrwxr-x  2 kali kali 4,0K jul 18 00:09 media
drwxrwxr-x  2 kali kali 4,0K jul 18 00:09 mnt
drwxrwxr-x  2 kali kali 4,0K jul 18 00:09 proc
drwxrwxr-x  2 kali kali 4,0K sep  8 09:57 run
drwxrwxr-x  2 kali kali 4,0K dec  5 09:51 sbin
drwxrwxr-x  2 kali kali 4,0K jul 18 03:14 sdcard
drwxrwxr-x  2 kali kali 4,0K jul 18 00:09 sys
drwxrwxrwx  2 kali kali 4,0K jul 18 00:09 tmp
drwxrwxr-x 11 kali kali 4,0K sep  8 09:56 usr
drwxrwxr-x 11 kali kali 4,0K dec  5 09:51 var

Exploración

Visualización de firmware

Hagamos un poco de exploración utilizando un conjunto diferente de opciones de unblob:``` unblob -e /tmp/out -f -k -d 3 --report /tmp/report.json
--log /tmp/unblob.log CHARXSEC3XXXSoftwareBundleV190.raucb

root@kitploit:~
Aquí seguimos extrayendo (`-e`) en `/tmp/out`, pero forzamos (`-f`) la sobrescritura
mientras conservamos (`-k`) los fragmentos extraídos pero limitando la profundidad de recursión (`-d`) a
3. Escribimos un informe detallado (`--report`) en `/tmp/report.json` y el archivo de registro
(`--log`) en `/tmp/unblob.log`.

Echa un vistazo al archivo de registro, verás el funcionamiento interno de unblob.

El archivo de informe contiene información detallada sobre los archivos analizados (tamaño, tipo de archivo,
ruta, magic, tipo MIME, hashes MD5/SHA1/SHA256), los fragmentos (tamaño, desplazamientos,
distribución de entropía) y las tareas (extracción, descompresión, carving). Es
posible generar visualizaciones interesantes a partir de estos archivos de informe con un poco
de Python.

Puedes crearlos tú mismo con el script de Python `diagram.py` disponible en
este repositorio:```
python3 diagram.py /tmp/report.json sunburst
python3 diagram.py /tmp/report.json treemap

Estos comandos abrirán el navegador en una página que contiene una visualización basada en plotly como las que se muestran a continuación:

sunburst

treemap

Recopilación de Información

Ahora que tenemos una mejor idea de lo que hay dentro, es momento de enumerar lo que necesitamos para realizar una emulación adecuada del dispositivo.

Idealmente, necesitamos recopilar esta información:

  1. Plataforma
spoilerPhytec phyBOARD-Segin i.MX6 UltraLite
2. Arquitectura
spoilerARMv6
3. CPU
spoilerCortex-A7
4. Cargador de arranque
spoilerU-Boot
5. Versión del sistema operativo
spoilerLinux version 5.15.195
6. Periféricos
spoiler2 Ethernet interfaces, 1 CANUSB, 1 USB OTG

Device Tree Blobs

Para obtener algunos detalles sobre la plataforma, la CPU y la arquitectura, podemos examinar los device tree blobs integrados en el firmware.

En la partición VFAT tenemos estos DTBs:``` oftree: Device Tree Blob version 17, size=27469, boot CPU=0, string block size=1657, DT structure block size=25756 zImage-imx6ul-ksp0632.dtb: Device Tree Blob version 17, size=27469, boot CPU=0, string block size=1657, DT structure block size=25756

root@kitploit:~
Estos archivos son la representación binaria de los árboles de dispositivos. Podemos recuperar su
fuente en texto plano usando `device-tree-compiler`:```
dtc -I dtb -o zImage-imx6ul-ksp0632.dts zImage-imx6ul-ksp0632.dtb         
dtc -I dtb -o oftree.dts oftree

Echa un vistazo al DTS, y pronto encontrarás detalles interesantes como el modelo:``` /dts-v1/;

/ { #address-cells = <0x01>; #size-cells = <0x01>; model = "Phytec phyBOARD-Segin i.MX6 UltraLite"; <----- right here compatible = "phytec,imx6ul-pbacd-10\0phytec,imx6ul-pcl063\0fsl,imx6ul";

root@kitploit:~
La CPU:```
cpus {
    #address-cells = <0x01>;
    #size-cells = <0x00>;

    cpu@0 {
        compatible = "arm,cortex-a7"; <---- here
        device_type = "cpu";
        reg = <0x00>;
        clock-latency = <0xee6c>;
        operating-points = <0xa9ec0 0x137478 0x80e80 0x11edd8 0x60ae0 0xfa3e8 0x30570 0xe7ef0>;
        fsl,soc-operating-points = <0xa9ec0 0x137478 0x80e80 0x11edd8 0x60ae0 0x11edd8 0x30570 0x11edd8>;
        clocks = <0x01 0x5d 0x01 0x1a 0x01 0x26 0x01 0xdb 0x01 0x38 0x01 0x39 0x01 0x19>;
        clock-names = "arm\0pll2_bus\0pll2_pfd2_396m\0secondary_sel\0step\0pll1_sw\0pll1_sys";
        arm-supply = <0x02>;
        soc-supply = <0x03>;
        dc-supply = <0x04>;
    };
};

O incluso periféricos:``` --snip-- ethernet@2188000 { compatible = "fsl,imx6ul-fec\0fsl,imx6q-fec"; reg = <0x2188000 0x4000>; interrupts = <0x00 0x76 0x04 0x00 0x77 0x04>; clocks = <0x01 0x90 0x01 0x91 0x01 0x30 0x01 0x2c 0x01 0x2c>; clock-names = "ipg\0ahb\0ptp\0enet_clk_ref\0enet_out"; fsl,num-tx-queues = <0x01>; fsl,num-rx-queues = <0x01>; status = "okay"; pinctrl-names = "default"; pinctrl-0 = <0x23>; phy-mode = "rmii"; phy-handle = <0x24>;

root@kitploit:~
mdio {
    #address-cells = <0x01>;
    #size-cells = <0x00>;

    ethernet-phy@1 {
        reg = <0x01>;
        interrupt-parent = <0x0b>;
        interrupts = <0x02 0x08>;
        micrel,led-mode = <0x01>;
        clocks = <0x01 0x2c>;
        clock-names = "rmii-ref";
        status = "okay";
        linux,phandle = <0x24>;
        phandle = <0x24>;
    };

    ethernet-phy@2 {
        reg = <0x03>;
        micrel,led-mode = <0x01>;
        clocks = <0x01 0x2d>;
        clock-names = "rmii-ref";
        status = "okay";
        linux,phandle = <0x13>;
        phandle = <0x13>;
    };
};

};

--snip-- flexcan@2090000 { compatible = "fsl,imx6ul-flexcan\0fsl,imx6q-flexcan"; reg = <0x2090000 0x4000>; interrupts = <0x00 0x6e 0x04>; clocks = <0x01 0x94 0x01 0x95>; clock-names = "ipg\0per"; status = "okay"; pinctrl-names = "default"; pinctrl-0 = <0x0f>; xceiver-supply = <0x10>; };

flexcan@2094000 { compatible = "fsl,imx6ul-flexcan\0fsl,imx6q-flexcan"; reg = <0x2094000 0x4000>; interrupts = <0x00 0x6f 0x04>; clocks = <0x01 0x96 0x01 0x97>; clock-names = "ipg\0per"; status = "disabled"; };

root@kitploit:~
### Información de la versión del kernel de Linux

Podemos identificar la versión del kernel de Linux buscando con grep dentro de la partición VFAT
que contiene el kernel comprimido:```
grep 'Linux version' . -ra 
./zImage_extract/7296-6371487.lzo_extract/7296-6371487:
Linux version 5.15.195 (oe-user@oe-host) (gcc version 8.3.0 (GCC)) #1 SMP PREEMPT
./zImage_extract/7296-6371487.lzo_extract/7296-6371487:
Linux version %s (%s)Bluetooth subsystem version %u.%uHCI socket registration failed

Otra forma es examinar los módulos del kernel dentro del sistema de archivos raíz EXT4:``` modinfo ./CHARXSEC3XXXSoftwareBundleV190.raucb_extract/0-138014720.squashfs_v4_le_extract/root.ext4_extract/lib/modules/5.15.195/kernel/net/bluetooth/bnep/bnep.ko.xz filename: ./CHARXSEC3XXXSoftwareBundleV190.raucb_extract/0-138014720.squashfs_v4_le_extract/root.ext4_extract/lib/modules/5.15.195/kernel/net/bluetooth/bnep/bnep.ko.xz alias: bt-proto-4 license: GPL version: 1.3 description: Bluetooth BNEP ver 1.3 author: Marcel Holtmann [email protected] srcversion: 86266D360814678CE0C94E9 depends:
intree: Y name: bnep vermagic: 5.15.195 preempt mod_unload modversions ARMv7 thumb2 p2v8 parm: compress_src:Compress sources headers (bool) parm: compress_dst:Compress destination headers (bool)

root@kitploit:~
## Emulación

Es posible que ya tengamos un kernel compilado dentro del paquete de firmware, pero este kernel está compilado específicamente para una máquina concreta (la Phytec phyBOARD-Segin i.MX6 UltraLite). 

Para usar este kernel correctamente, necesitaríamos poder ejecutarlo en una emulación de esa misma máquina para la que está compilado. Esto requiere mucho tiempo si no está ya listada en la lista de máquinas de QEMU. Nota: una placa de evaluación está disponible en QEMU (`mcimx6ul-evk - Freescale i.MX6UL Evaluation Kit (Cortex-A7)`) pero no coincide exactamente.

En su lugar, en teoría, podemos elegir una máquina QEMU y usar varios metadatos que encontremos en la imagen del firmware para configurar y construir un kernel para esa máquina, que también pueda ejecutar todo en nuestro sistema de archivos, lo más parecido posible al original.

A partir de aquí, tenemos algunas opciones:
- *emulación de espacio de usuario*: Podríamos arrancar en nuestro propio ramfs/rootfs personalizado y luego cargar el rootfs del firmware objetivo y hacer chroot en él para emular.
- *emulación de sistema completo*: Podríamos intentar arrancar el rootfs del firmware objetivo directamente (pasándolo directamente a la máquina QEMU).

La emulación de espacio de usuario suele ser limitante, pero es una excelente manera de investigar, depurar y explotar binarios específicos. Recomendamos encarecidamente echar un vistazo a [EMUX](https://github.com/therealsaumil/emux) de Saumil Shah para todas sus necesidades de emulación de espacio de usuario.

Independientemente, todavía necesitamos un kernel que pueda arrancar dentro de una máquina QEMU y que coincida lo más posible con lo que el firmware objetivo espera.

### Máquinas QEMU

Solo hay unos pocos candidatos para máquinas de propósito general que ofrezcan flexibilidad. Después de bastante experimentación, `virt` (https://qemu.readthedocs.io/en/latest/system/arm/virt.html) parece tener una buena relación flexibilidad/potencia para nuestros propósitos. 

Al construir el kernel para una máquina QEMU determinada, probablemente sea mejor asegurarnos de que podemos usar el dispositivo virtio general que QEMU incluye. En la configuración, esto puede significar una o más de las siguientes opciones:```
CONFIG_VIRTIO=y
CONFIG_SCSI_VIRTIO=y
CONFIG_VIRTIO_PCI=y
CONFIG_VIRTIO_BLK=y

¡Y más! Esta lista está incompleta.

Construyendo un kernel "suficientemente cercano"

Nos resulta beneficioso usar un kernel que tenga una cadena vermagic idéntica (o al menos muy similar). Todo tipo de componentes dentro de un sistema podrían estar comprobando el vermagic del kernel, y fallando si es diferente de lo esperado. Esto es más común en los módulos del kernel: un kernel normalmente se negará a cargar un módulo que no tenga un vermagic que coincida con el suyo. Si bien podemos parchear el kernel para ignorar esto a nivel de kernel, aún necesitamos que la parte inicial de "kernel release" de la cadena coincida con la cadena de release de los módulos del kernel, ya que se usa como ruta de búsqueda para modules.dep.

En el firmware de Phoenix Contact, el vermagic es 5.15.195 preempt mod_unload modversions ARMv7 thumb2 p2v8.

La cadena vermagic tiene un formato como (de include/linux/vermagic.h):```c #define VERMAGIC_STRING
UTS_RELEASE " "
MODULE_VERMAGIC_SMP MODULE_VERMAGIC_PREEMPT
MODULE_VERMAGIC_MODULE_UNLOAD MODULE_VERMAGIC_MODVERSIONS
MODULE_ARCH_VERMAGIC

root@kitploit:~
- Kernel release = la versión del kernel + la cadena `CONFIG_LOCALVERSION`.
- SMP = `CONFIG_SMP`
- PREEMPT = `CONFIG_PREEMPT`
- mod_unload = `CONFIG_MODULE_UNLOAD`
- modversions = `CONFIG_MODVERSIONS`
- ARMv7 thumb2 p2v8 = `MODULE_ARCH_VERMAGIC` (relacionado con la arquitectura para la que se compila el kernel y, por tanto, con la opción de compilador/arquitectura pasada.)

 Una vez que tenemos el código fuente del kernel extraído, podemos parchearlo para que no sea tan estricto al comparar las cadenas vermagic. En kernel/module.c, podemos simplemente comentar return -ENOEXEC:```diff
} else if (!same_magic(modmagic, vermagic, info->index.vers)) {
    pr_err("%s: version magic '%s' should be '%s'\n", info->name, modmagic, vermagic);
-   return -ENOEXEC;
+    // return -ENOEXEC;
}

if (!get_modinfo(info, "intree")) {

Puede que no sea necesariamente útil a largo plazo, pero es bueno para probar, siempre que haya ligeras discrepancias entre nuestro vermagic del kernel y el vermagic del módulo. Los módulos (en su mayoría) seguirán cargándose.

NOTA: aquí proporcionamos un kernel ya compilado que coincide con los requisitos del objetivo, por lo que no necesitas compilar uno tú mismo. Fue compilado con un script interno que:

  • obtiene el código fuente del kernel correspondiente a la versión que necesitamos
  • llama a multi_v7_defconfig para establecer la configuración inicial
  • parchea el código de verificación de vermagic en kernel/module.c
  • parchea la configuración para habilitar todas las opciones de VIRTIO y subsistemas específicos como USB o CANBUS
  • compila el kernel

Arranque mínimo

Repasemos los diferentes parámetros de nuestro comando qemu-system-arm. Proporcionamos el kernel de esta manera:```sh qemu-system-arm -M virt,highmem=off
-m ${AVAILABLE_MEM_GB}G -smp ${CPU_CORES} -cpu cortex-a15
-kernel zImage

root@kitploit:~
La imagen del sistema de archivos EXT4 está conectada como un disco SCSI:```sh
-device virtio-scsi-device \
-device scsi-hd,drive=SystemDisk \
-drive file=${FIRMWARE_IMAGE},format=raw,if=none,id=SystemDisk

Configuramos una salida de consola adecuada de esta manera:```sh -append "${BOOT_PARAMS}"
-no-reboot
-nographic
-serial mon:stdio \

root@kitploit:~
Los `BOOT_PARAMS` se establecen en `config.ini` y corresponden al bootcmd real del kernel
con dos pequeñas adaptaciones (ruta de la consola y ruta del rootfs).

### Redes

Ahora que tenemos un sistema emulado funcional, es hora de configurar la red. El objetivo tiene lo siguiente:
- dos interfaces Ethernet (`eth0` y `eth1`)
- una interfaz CANbus (`can0`)
- una interfaz USB que puede actuar como Ethernet sobre USB (`usb0`)
- un módem celular Qualcomm High Sierra (`ppp0`)

Emular el módem celular y las interfaces USB es complicado con QEMU, y no es realmente
necesario para el funcionamiento del dispositivo, ya que esas interfaces son "opcionales". La
interfaz CAN está ahí para permitir que el controlador se comunique con otros controladores o
estaciones de carga. La interfaz `eth0` proporciona conectividad ascendente al
solicitar una concesión DHCP por defecto, mientras que `eth1` está configurada con
192.168.4.1 y está ahí si quieres encadenar varios controladores.

Las interfaces Ethernet se configuran como interfaces TAP y se conectan de la siguiente manera:```
-netdev tap,id=tap0net,ifname=${ETH_1},script=no,downscript=no \
-device virtio-net-device,netdev=tap0net,mac=${ETH_1_MAC} \
-netdev tap,id=tap1net,ifname=${ETH_0},script=no,downscript=no \
-device virtio-net-device,netdev=tap1net,mac=${ETH_0_MAC} \

La interfaz CANBUS es simplemente una interfaz PCI, conectada de esta manera:``` -object can-bus,id=canbus0
-device kvaser_pci,canbus=canbus0
-object can-host-socketcan,id=canhost0,if=can0,canbus=canbus0 \

root@kitploit:~
El siguiente diagrama muestra cómo se ve la configuración de la red:

![server_networking](https://assets.kitploit.com/production/public/readmes/48963/3253473ecbc1aedcb1890abd579e9424774e4434fb6daf7dcb1306d441cc8ce4.png)

Si quieres probar la comunicación entre controladores mediante conexión en cascada (daisy-chain), como recomienda Phoenix Contact, puedes usar algo como esto:

![client_server_networking](https://assets.kitploit.com/production/public/readmes/48963/a750e648bc60d9617402f5b4c26163ceda381a37d2f4eb54bb9bbf8b69054654.png)


## ¿Listos? Preparados. ¡A lanzar!

Ahora que todo está en su sitio, ¡es hora de arrancarlo!

Primero, necesitas configurar todas las interfaces de red de esta manera:```
sudo ./ifup.sh

Asegúrate de que tu interfaz ascendente esté correctamente configurada en config.ini:```

interface will be transparently bridged

OUT_IF="eth0"

root@kitploit:~
A continuación, puedes lanzar el emulador:```
sudo ./launch.sh

Verás las direcciones obtenidas en los registros:``` Dec 5 10:07:46 ev3000 daemon.info avahi-daemon[1047]: Registering new address record for 192.168.4.1 on eth1.IPv4. Dec 5 10:07:46 ev3000 daemon.info avahi-daemon[1047]: Registering new address record for 192.168.88.181 on eth0.IPv4.

root@kitploit:~
### Access over SSH

A continuación, puede conectarse por SSH al dispositivo emulado utilizando el usuario `user-app`:```sh
ssh [email protected]

La contraseña es "user". Tendrás que cambiarla en el primer inicio de sesión:```sh ssh [email protected] The authenticity of host '192.168.88.181 (192.168.88.181)' can't be established. ED25519 key fingerprint is SHA256:qMupzEehNFpx6eaGZ4d3AY5Jlms3Pmxh3/yg9OGA28o. This key is not known by any other names Are you sure you want to continue connecting (yes/no/[fingerprint])? yes Warning: Permanently added '192.168.88.181' (ED25519) to the list of known hosts. [email protected]'s password: WARNING: Your password has expired. You must change your password now and login again! Changing password for user-app Old password: Enter the new password (minimum of 5 characters) Please use a combination of upper and lower case letters and numbers. New password: Re-enter new password: passwd: password changed. Connection to 192.168.88.181 closed.

root@kitploit:~
### Interfaz web

Puedes acceder a la interfaz web en http://192.168.4.1. Puede mostrar un mensaje
de error mientras el dispositivo se está iniciando. Cuando todo esté en marcha,
deberías ver esto:

![web_interface](https://assets.kitploit.com/production/public/readmes/48963/06fdbcd33d7c83012311e2a3ecee8b91531847fe082a6de0f0657c09f346a42f.png)

Puedes iniciar sesión con las siguientes cuentas:

| usuario | contraseña |
|----------|----------|
| manufacturer | manufacturer |
| operator | operator |


### Tráfico CAN

Cuando todo esté en marcha, puedes capturar el tráfico CAN emitido por el
controlador:```
candump -i can0
  can0  701   [1]  00000101
  can0  701   [1]  00000101
  can0  701   [1]  00000101
  can0  701   [1]  00000101
  can0  701   [1]  00000101
  can0  701   [1]  00000101

NOTA: parece que QEMU versión 8.x tiene algunas dificultades para conectar el controlador CAN por alguna razón.

Descargar herramienta