Je me suis rendu compte que personne n’avait pas encore fait un tuto de comment modifier un firmware directement à partir d’une extraction de la mémoire. Pour les ONU avec accès root natif, ça a peu d’intérêt parce que de toute façon a une shell avec tous les droits. Mais il arrive souvent de ne pas avoir accès root ou même telnet/ssh. Et c’est pour ces cas que ce tuto peut être utile.
Une autre raison est celle de maîtriser et comprendre ce qu’on fait quand on installe un firmware ‘rooté’ par quelqu’un d’autre. Les motivations sont diverses : ne faire que confiance à soit même, comprendre ce qu’on fait, se former, …
Préalables: Installer binwalk
Installer squashfs-tools (pour les distros basées sur Arch. Je ne suis pas certain pour les distros Debian mais je pense que c'est pareil...)
Il faut bien évidement récupérer les images/firmwares que l'on souhaite modifier. Sur un ONU avec accès root c'est très facile mais ça se complique pour un MA5671A, par exemple. Si on a déjà l'accès root, ce tutoriel perd son intérêt... Il faut donc un bootloader débloqué et un accès en port de série pour extraire les firmwares vierges. Ou alors faire confiance à quelqu'un pour le faire à notre place
On utilise un outil très pratique, binwalk. Il permet d'analyser la structure d'un fichier binaire et il cherche automatiquement des partitions connues. On peut également l'utiliser pour extraire ces partitions.
[andrep@plaptop V8R017C00S200]$ binwalk V8R017C00S200_mtd5_stock.img
DECIMAL HEXADECIMAL DESCRIPTION
--------------------------------------------------------------------------------
0 0x0 uImage header, header size: 64 bytes, header CRC: 0xF58607E9, created: 2016-08-11 18:11:26, image size: 1207781 bytes, Data Address: 0x80002000, Entry Point: 0x80002000, data CRC: 0x6381A0A3, OS: Linux, CPU: MIPS, image type: OS Kernel Image, compression type: lzma, image name: "SFP_7.5.3"
64 0x40 LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 3510372 bytes
1207845 0x126E25 Squashfs filesystem, little endian, version 4.0, compression:xz, size: 2148294 bytes, 888 inodes, blocksize: 262144 bytes, created: 2016-08-11 18:11:28
3407872 0x340000 JFFS2 filesystem, big endian
On voit le bloc de mémoire qui nous intéresse, en squashFS (compression xz et un blocksize de 262144 bytes)
On doit ensuite isoler ce bloc de mémoire afin de l'extraire et le modifier.
Pour le faire il y a plusieurs solutions. J'utilise dd de façon très basique, je suis loin d'être un linux god! Mes excuses aux maîtres qui vont trouver que je suis bête et que je pouvais faire le même avec une seule commande
[root@plaptop WORK]# dd if=V8R017C00S200_mtd5_stock.img bs=1 skip=0 count=1207845 of=0_header.bin
1207845+0 records in
1207845+0 records out
1207845 bytes (1,2 MB, 1,2 MiB) copied, 2,21821 s, 545 kB/s
Explications: if=V8R017C00S200_mtd5_stock.img -> fichier d'entrée
bs=1 -> on utilise un bloc size de 1 byte, l'unité la plus petite possible
skip=0 -> dd commence à lire à partir de la position '0', soit le début du fichier
count=1207845 -> dd va effectuer l'opération sur 1207845 bytes, soit jusqu'au début du bloc avec le squashFS
of=0_header.bin -> fichier de sortie