Introduction

Par simple curiosité, je voulais comprendre le fonctionnement de mon NAS Thecus N2310, et faire un peu de reverse engineering pour, pourquoi pas, mettre un jour un firmware alternatif.

Pour cela je suis partit du zip de mise à jour de la nand, mais j’aurai tout aussi bien pu dumper la nand avec les mtdtools.

Commençons les recherches sur le firmware

Récupérations des infos sur les partitions de la nand :
strings N2310_OS6.build_770.t2.bin > strings.txt
Recherche dans le fichier strings.txt de tailles de partitions.
Quelques données intéressantes :
[code]partition@0,0
bNAND 256MiB 1,8V 08-bit
partition@0,1
bfirmware
partition@0c0000
benvironment
partition@100000
bkernel
partition@600000
bdevice-tree
partition@700000
bversion
partition@720000
bvalid
partition@820000
bramdisk
partition@1C00000
bos6disk[/code]

Pour plus d’information, il faut extraire la partition device tree qui semble être entre 0x600000 et 0x700000, donc utilisation de la commande :
dd if=N2310_OS6.build_770.t2.bin of=device-tree bs=1 skip=$((0x600000)) count=$((0x100000))

Extrations des données du device-tree

dtc -I dtb ./device-tree > dts
Ouverture avec un éditeur de texte du fichier dts, nous avons donc, entre autre, toutes les données de partitions :
[code] nand {
#address-cells = <0x1>;
#size-cells = <0x1>;

partition@0,0 {
label = "NAND 256MiB 1,8V 08-bit";
reg = <0x0 0x10000000>;
};

partition@0,1 {
label = "firmware";
reg = <0x0 0xc0000>;
};

partition@0c0000 {
label = "environment";
reg = <0xc0000 0x40000>;
};

partition@100000 {
label = "kernel";
reg = <0x100000 0x500000>;
};

partition@600000 {
label = "device-tree";
reg = <0x600000 0x100000>;
};

partition@700000 {
label = "version";
reg = <0x700000 0x20000>;
};

partition@720000 {
label = "valid";
reg = <0x720000 0x100000>;
};

partition@820000 {
label = "ramdisk";
reg = <0x820000 0x27e0000>;
};

partition@1C00000 {
label = "os6disk";
reg = <0x3000000 0xd000000>;
};
};[/code]

Il est maintenant possible d’extraires les différentes partitions avec dd donc petit script :
[code]#!/bin/sh
dd if=N2310_OS6.build_743.t2.bin of=firmware bs=1 skip=$((0x0)) count=$((0xc0000))
dd if=N2310_OS6.build_743.t2.bin of=environment bs=1 skip=$((0xc0000)) count=$((0x40000))
dd if=N2310_OS6.build_743.t2.bin of=kernel bs=1 skip=$((0x100000)) count=$((0x500000))
dd if=N2310_OS6.build_743.t2.bin of=device-tree bs=1 skip=$((0x600000)) count=$((0x100000))
dd if=N2310_OS6.build_743.t2.bin of=version bs=1 skip=$((0x700000)) count=$((0x20000))
dd if=N2310_OS6.build_743.t2.bin of=valid bs=1 skip=$((0x720000)) count=$((0x100000))
dd if=N2310_OS6.build_743.t2.bin of=ramdisk bs=1 skip=$((0x820000)) count=$((0x27e0000))
dd if=N2310_OS6.build_743.t2.bin of=os6disk bs=1 skip=$((0x3000000)) count=$((0xd000000))[/code]

L’outil file peut donner quelques informations sur les partitions :
file ramdisk
ramdisk: u-boot legacy uImage, InitRamFS 2.3.0-2.t2.ppc, Linux/PowerPC, RAMDisk Image (gzip), 15014381 bytes, Wed Jun 11 14:38:12 2014, Load Address: 0x00000000, Entry Point: 0x00000000, Header CRC: 0x7A5957CD, Data CRC: 0x67486288

C’est donc bien une partition InitRamFS.

file os6disk
os6disk: HIT archive data

En l’ouvrant avec ghex, il est possible de voir que les 3 premiers octets donne les caractères UBI, c’est donc une partition ubifs

Exploration de la partition InitRamFS

Il faut extraire le fichier gzip du ramdisk, pour cela il faut rechercher 00 00 1F 8B, avec une utilisation de ghex, on extrait tout ce qui est après 1F 8B inclu, donc 0x40 soit 64 :
dd if=ramdisk of=ramdisk.gz ibs=1 skip=64
Une petite vérification du fichier ramdisk.gz avec la commande file :
file ramdisk.gz
donne :
ramdisk.gz: gzip compressed data, from Unix, last modified: Tue Apr 15 18:24:42

Puis on extrait le ramdisk :
gunzip ramdisk.gz

On obtient un fichier cpio :
file ramdisk
qui renvoit :
ramdisk: ASCII cpio archive (SVR4 with no CRC)

On extrait le tout :
cpio -i -d -H newc -F ramdisk --no-absolute-filenames

Et voilà, un beau filesystem à explorer.

Exploration de la partition ubifs

Pour cela il faut simuler une nand, y copier la partition et monter le tout
sudo modprobe mtd
sudo modprobe nandsim first_id_byte=0x20 second_id_byte=0xaa third_id_byte=0x00 fourth_id_byte=0x15
sudo modprobe ubi
sudo dd if=os6disk of=/dev/mtd0 bs=2048
sudo ubiattach -m 0
sudo mount -t ubifs /dev/ubi0_0 partition/

La partition est maintenant montée sur le répertoire partition, il est possible d’en extraire les fichiers.