Soho NAS Smardisk-Verbatim
De LagaSchiex.
Tentative de hack du NAS Smartdisk/Verbatim.
Il existe deux versions de ce NAS au moins. Une 250 Go et une 500 Go. C'est de la première variante (Rev. D, achetée 69€ chez LuxDisk) dont je dispose mais la seconde est vraisemblablement identique (hors du modèle de disque installé).
Ce NAS est équipé d'une CPU ARM/STORLINK FA52Xid(wb) utilisé dans de très nombreux NAS (D-LINK, NAS 2000...) pour lesquels des firmwares alternatifs existent. Qu'est il possible de faire ?
De base, le SOHONAS offre un noyau linux 2.6.10 avec 64 Mo de RAM. Il dispose de 8Mo de mémoire flash accessible via le driver mtd. D'un port USB 1.1, d'une if ethernet 100Mbps (deux en interne apparemment sont visibles) et peut aussi être directement utilisé via USB 2.0 (mais pas en même temps qu'ethernet ?).
Avec le firmware de base, le NAS permet
* un accès au disque et imprimante (USB 1.1) via SAMBA * un accès NFS * un accès FTP (proftpd) * un accès telnet * s'annonce via Bonjour (Avahi sous linux) * peut faire serveur DHCP (pas franchement utile quand la moindre box ADSL le fait)
Mais, contrairement à ce que certaines documentations annoncent, ne fait pas fonction de serveur audio (DAAP) par exemple.
Apparemment, la mémoire flash est coupée en différentes zones:
dev: size erasesize name mtd0: 00040000 00010000 "RedBoot" mtd1: 00180000 00010000 "Kernel" mtd2: 00200000 00010000 "Ramdisk" mtd3: 00400000 00010000 "Application" mtd4: 00010000 00010000 "VCTL" mtd5: 00020000 00010000 "CurConf" mtd6: 00010000 00010000 "FIS directory"
* RedBoot (256 Ko = 262144o) est le Bootloader * Kernel (1.5 Mo = 1572864o) doit contenir le noyau linux * Ramdisk (2 Mo = 2097152o) un initrd pour booter * Application (4Mo = 4194304o) de quoi restaurer la partition de 100Mo du HD qui contient les applications * VCTL: (64Ko = 65536 o) ? * CurConf: (128Ko = 131072) la sauvegarde de la conf courante (qqs fichiers de /etc et rc.conf...) * FIS directory: (64Ko = 65536 o) sans doute la configuration de la FLASH en zone.
Total: 8Mo.
Des sources, le firmware et des outils de développement sont disponibles chez Smartdisk [1]
Le firmware est une simple archive tar. Contenu:
-rw-r--r-- 1 tom tom 1,5K 2006-07-24 06:15 curconf.tgz -rw-r--r-- 1 tom tom 3,8M 2006-07-24 06:15 hddapp.tgz -rwxr--r-- 1 tom tom 343 2006-07-24 06:15 ImageInfo* -rw-r--r-- 1 tom tom 1,8M 2006-07-24 06:15 rd.gz -rwxr-xr-x 1 tom tom 1,5M 2006-07-24 06:15 zImage*
Il est vraisemblable que chacun des fichiers, hors ImageInfo, correspond à une des zones de la flash. Total: env 7Mo. A compléter avec RedBoot, VCTL et FIS.
Il est possible aussi de sauvegarder le firmware directement sur le NAS vis un simple "dd". Voir [2]. C'est fait !
-rw-r--r-- 1 root root 256.0k Dec 31 20:44 redboot.bin -rw-r--r-- 1 root root 64.0k Dec 31 20:44 VCTL.bin -rw-r--r-- 1 root root 128.0k Dec 31 20:45 curconf.tgz -rw-r--r-- 1 root root 4.0M Dec 31 20:44 hddapp.tgz -rw-r--r-- 1 root root 64.0k Dec 31 20:45 fid.dat -rw-r--r-- 1 root root 1.5M Dec 31 20:44 zImage -rw-r--r-- 1 root root 2.0M Dec 31 20:44 rd.gz
RedBoot est un bootloader assurant la possibilité de reflasher le NAS via une ligne série (interne, et en 3.3 V (CMOS)) ou, plus sympathiquement via un trivial FTP (TFTP). Tant que cette zone de la mémoire flash n'est pas touchée, le NAS est ressuscitable. Le site sur le NAS2000 est plein d'infos la dessus [3] et une documentation utilisayeur est dispo ici [4].
Par défaut, au boot du NAS, il est possible d'accéder a RedBoot pour reflasher le NAS via TFTP. L'accès se fait à une adresse IP par défaut (192.168.2.71, port 9000). Pour plus de détails, voir [5]. Allons-y !
... Escape character is '^]'. ==> enter Ctrl+C to abort booting within 2 seconds ...... ^C Boot Menu ==================================================================== 1: Start the Kernel Code 2: List Image 3: Delete Image 4: Create New Image 5: Command Line Interface 6: Set IP adderss 7: Setting MAC address X:Upgrade Boot Y:Upgrade Kernel => Select:
Le 1 active le boot du noyau.
Tentons un 2:
=> Select: 2 Name FLASH addr Mem addr Datalen Entry point RedBoot 0x70000000-7001FFFF 0x00000000 0x0001E7EC 0x00000000 FIS directory 0x707F0000-707FFFFF 0x707F0000 0x00000000 0x00000000 Kern 0x70040000-701AFFFF 0x01600000 0x001673B0 0x01600000 Ramdisk 0x701C0000-7038FFFF 0x00800000 0x001CA908 0x00800000 Application 0x703C0000-7078FFFF 0x00000000 0x003C8BE4 0x00000000 CurConf 0x707D0000-707DFFFF 0x00000000 0x000005F4 0x00000000 VCTL 0x707C0000-707CFFFF 0x00000000 0x00010000 0x00000000
On retrouve les zones de flash avec adresses, taille...
Il est possible de supprimer une zone avec 3, créer (écraser, redéfinir) une zone avec 4. Tentons un 5 (Command Line interface)
Start Redboot CLI RedBoot> help Display/switch console channel channel [-1|<channel number>] Display (hex dump) a range of memory dump -b <location> [-l <length>] [-s] [-1|2|4] Execute an image - with MMU off exec [-w timeout] [-b <load addr> [-l <length>]] [-r <ramdisk addr> [-s <ramdisk length>]] [-c "kernel command line"] [<entry_point>] Manage FLASH images fis {cmds} Execute code at a location go [-w <timeout>] [entry] Help about help? help [<topic>] Set/change IP addresses ip_address [-l <local_ip_address>] [-h <server_address>] Load a file load [-r] [-v] [-h <host>] [-m <varies>] [-c <channel_number>] [-b <base_address>] <file_name> Network connectivity test ping [-v] [-n <count>] [-l <length>] [-t <timeout>] [-r <rate>] [-i <IP_addr>] -h <IP_addr> Reset the system reset Display RedBoot version information version Display (hex dump) a range of memory x -b <location> [-l <length>] [-s] [-1|2|4] RedBoot> version RedBoot(tm) bootstrap and debug environment [ROMRAM] Storlink release, version S000.9016 - built 21:17:16, Apr 4 2006 Platform: Storlink Sword (ARM9) Copyright (C) 2000, 2001, 2002, Red Hat, Inc. Use Internal PCI Clock Processor: SL3316a3 IDE0 Enable AHB Bus Clock:108MHz Ratio:3/2 RAM: 0x00000000-0x04000000, 0x00049f80-0x03fef000 available FLASH: 0x70000000 - 0x70800000, 135 blocks of 0x00010000 bytes each.
Il est possible de changer l'adresse IP utilisée par défaut par Redboot. J'ai mis la même adresse que le NAS une fois booté, compatible avec mon subnet pour éviter la nécessité de changer l'IP pour se connecter. Cela fonctionne.
Le but étant de remplacer telnet par SHH, d'ajouter daapd, commençons à jouer avec le firmware. Pour commencer, je récupère le firmware d'un autre NAS de la même famille: NAS 2000 de chez raidSonic. Il est disponible ici [6] (2_3_2_IB_2(20070309).tar.gz | MD5: f72d18d944d877eb1f3e91429cd9a50c).
Voyons voir le contenu:
-rwxr-xr-x 1 tom tom 1,5K 2007-03-09 12:34 curconf.tgz* -rwxr-xr-x 1 tom tom 4,0M 2007-03-09 12:34 hddapp.tgz* -rwxr-xr-x 1 tom tom 354 2007-03-09 12:34 ImageInfo* -rw-r--r-- 1 tom tom 1,9M 2007-03-09 12:34 rd.gz -rwxr-xr-x 1 tom tom 1,5M 2007-03-09 12:34 zImage*
La ressemblance avec le FW du sohonas smartdisk est frappante:
-rw-r--r-- 1 tom tom 1,5K 2006-07-24 06:15 curconf.tgz -rw-r--r-- 1 tom tom 3,8M 2006-07-24 06:15 hddapp.tgz -rwxr--r-- 1 tom tom 343 2006-07-24 06:15 ImageInfo* -rw-r--r-- 1 tom tom 1,8M 2006-07-24 06:15 rd.gz -rwxr-xr-x 1 tom tom 1,5M 2006-07-24 06:15 zImage*
Les applis et le ramdisk sont plus gros. En comparant, cela est du principalement à la présence de daapd et une version plus récente de proftpd (mais d'autres choses: raid1 possible, cela pourrait expliquer l'initrd plus gros et pas de telnet visible...).
Je décide de me lancer dasn un premier test: construction d'un firmware avec la version du serveur proftpd du NAS 2000. La différence en taille faible devrait permettre d'éviter d'avoir à redimensionner les images flash.
# je détarre les deux firmwares: #* tar xvfz 2_3_2_IB_220070309.tar.gz #* tar xvfz SOHONAS_v2_3_2_03b.tar.gz # je détarre les hdapp.tgz (attention, c'est du bz2) #* cd 2_3_2_IB_220070309; tar xvfj hddapp.tgz #* cd ../SOHONAS_v2_3_2_03b; tar xvfj hddapp.tgz
Je copie le proftpd du NAS2000 dans le directory du SOHONAS, je vire au passage les traduction non françaises et anglaises (dans webroot/locale/) et je personnalise 2 images du site web du SOHONAS dans webroot/image/.
Je refait un tar, compression bzip2:
* tar cvfj ../hddapp.tgz hddapp/ lib/ sausalito/ webroot/
Verdict: hddapp.tgz fait 4010449 octets, soit moins que 4Mo = 4194304 octets. Ca devrait passer.
Deux façons de procéder pour la suite:
# refaire le tar complet du firmware via l'interface web. : 25 minutes d'attente # flasher en passant par redboot.
On va tenter le seconde approche. Il faut installer un serveur TFTP. Sous mon ubuntu, j'installe tftpd-hpa. Je copie hddapp.tgz dans /var/lib/tftpboot, je relance RedBoot.
=> Select: 4 Image Name: Application Flash Address: 0x703C0000 Memory Address: 0x00000000 Entry Point: 0x00000000 An image named 'Application' exists - continue (y/n)? y 1: Download by X-modem 2: Download by TFTP 2 TFTP Server IP Address: 192.168.0.1 Image Path and name(EX. /images/zImage): hddapp.tgz Waiting to receive file .... |
J'ai utilisé les mêmes adresses que dans la liste des images précédentes. Le caractère | tourne doucement en / \...le temps passe. Le caractère |\/ ne tourne plus... Le temps passe... En train de flasher ? Pas causante la bête. Quelques minutes plus atrd:
Raw file loaded 0x01000000-0x013d31d0, assumed entry at 0x01000000 Erase flash ... ... Erase from 0x703c0000-0x707a0000: .............................................................. OK! ... Program from 0x01000000-0x013d31d1 at 0x703c0000: .............................................................. OK! Update FIS ... ... Erase from 0x707f0000-0x70800000: . ... Program from 0x00400000-0x00410000 at 0x707f0000: . OK! Upload 'Application' code successfully!
Ouf ! Tentons maintenant de rebooter (item 1 du menu de RedBoot). C'est parti ! Tentons un FTP:
ftp sohonas Connected to sohonas. 220 ProFTPD 1.3.0 Server (NAS FTPD) [192.168.0.9]
Cela fonctionne. Le serveur 1.2.10 a été remplacé par un 1.3.0.
Les travaux sur le NAS2000 sont très avancés et un firmware alternatif appelé tinky a été développé [7]. Un premier pas serait de customiser l'image flash tinky.
Je pars de tinkyy-2_3_2-mu-02.2 [8]. Après extraction de l'archive, on obtient:
-rw-r--r-- 1 tom tom 4,2M 2007-05-07 22:20 Application -rw-r--r-- 1 tom tom 46 2007-05-07 22:21 Application.md5 -rw-r--r-- 1 tom tom 2,2K 2007-05-07 21:12 Changelog -rw-r--r-- 1 tom tom 2,0M 2007-05-07 22:20 Ramdisk -rw-r--r-- 1 tom tom 42 2007-05-07 22:21 Ramdisk.md5 -rw-r--r-- 1 tom tom 13K 2007-05-07 21:09 README -rw-r--r-- 1 tom tom 8,0M 2007-05-07 22:20 tinky-2_3_2-mu-02.2 -rw-r--r-- 1 tom tom 54 2007-05-07 22:21 tinky-2_3_2-mu-02.2.md5
Il me semble hasardeux de directement flasher tinky-2_3_2-mu-02.2 qui contient visiblement une image flash complète car cela écraserait le RedBoot du SOHONAS avec celui du NAS2000, sans garantie de compatibilité (même si les probabilités sont fortes que cela fonctionne, car la plateforme matérielle sous jacente est très similaire, à base de chipset Storlink type "Centroid" [9].
Le problème de tinky est que le layout de la flash est évidemment modifié puisque la zone "Applications" fait 4.2 Mo (qui ne tiennent pas dans 4mo).
Il faudrait donc revoir le "layout" actuel pour faire un peu de place. En observant le layout courant, il y a pas mal de place perdue:
RedBoot 0x70000000-7001FFFF 0x0001E7EC 20000 20000 octets perdus Kern 0x70040000-701AFFFF 0x001673B0 170000 10000 perdus Ramdisk 0x701C0000-7038FFFF 0x001CA908 1D0000 30000 perdus Application 0x703C0000-7078FFFF 0x003C8BE4 3D0000 30000 perdus VCTL 0x707C0000-707CFFFF 0x00010000 10000 CurConf 0x707D0000-707DFFFF 0x000005F4 10000 10000 perdus FIS directory 0x707F0000-707FFFFF 0x00000000 10000
Soit un total de A0000 octest perdus (640 Ko). Les codes étant copiés en RAM avant d'être exécutés (modèle ROMRAM indiqué dans la version de RedBoot), pas de question de Position Independant Code (PIC). Esperons que le nom des images donne le point d'accès.
Je tente de déplacer le Kernel pour le coller à "RedBoot". On va le mettre entre 0x70020000-7018FFFF (au lieu de 0x70040000-701AFFFF).
On se reconnecte à RedBoot, j'efface l'image Kern, je recrée l'image en la déplaçant (et en utilisant le fichier zImage du firmware original récupérée par TFTP). Résultat du layout:
Name FLASH addr Mem addr Datalen Entry point RedBoot 0x70000000-7001FFFF 0x00000000 0x0001E7EC 0x00000000 FIS directory 0x707F0000-707FFFFF 0x707F0000 0x00000000 0x00000000 Kern 0x70020000-7018FFFF 0x01600000 0x001673B0 0x01600000 Ramdisk 0x701C0000-7038FFFF 0x00800000 0x001CA908 0x00800000 Application 0x703C0000-7079FFFF 0x00000000 0x003D31D1 0x00000000 CurConf 0x707D0000-707DFFFF 0x00000000 0x000005F4 0x00000000 VCTL 0x707C0000-707CFFFF 0x00000000 0x00010000 0x00000000
On reboote... Ca marche toujours. Je vais déplacer le ramdisk en 0x70190000. Panique... J'ai oublié le 0x devant l'adresse hexa.
=> Select: 4 Image Name: Ramdisk Flash Address: 70190000 Memory Address: 0x00800000 Entry Point: 0x00800000 1: Download by X-modem 2: Download by TFTP 2 TFTP Server IP Address: 192.168.0.1 Image Path and name(EX. /images/zImage): rd.gz Waiting to receive file .... - Raw file loaded 0x01000000-0x011ca907, assumed entry at 0x01000000 Erase flash ... ... Erase from 0x042f0000-0x044c03b0: FAILED! Can't erase region at 0x042f0000: Driver timed out waiting for device OK! ... Program from 0x01000000-0x011ca908 at 0x042f03b0: ............................. OK! Update FIS ... ... Erase from 0x707f0000-0x70800000: . ... Program from 0x00400000-0x00410000 at 0x707f0000: . OK! Upload '<Not a string: 0x400300>' code successfully!
Plus rien ne fonctionne. La liste des images est cassée. Peut-être RedBoot aussi. Je vais tenter d'éviter la brique en reflashant tout le firmware (que j'avais sauvegardé, ouf !). Ca va être long.
=> Select: X 1: Download by X-modem 2: Download by TFTP 2 TFTP Server IP Address: 192.168.0.1 Image Path and name(EX. /images/zImage): firmware.save Waiting to receive file .... \ Raw file loaded 0x01000000-0x017fffff, assumed entry at 0x01000000 image not found !! Creating ... Do not power-off this device while flash programming is proceeding!! Are you sure to program Boot code (Y/N) ?
Damned. Ce message "image not found !!" n'est pas rassurant. Tant pis... let's go !
Erase flash ... ... Erase from 0x70000000-0x70800000: ................................................................................................................................ OK! ... Program from 0x01000000-0x01800000 at 0x70000000: ................................................................................................................................ OK! Update FIS ... Upgrade Boot Code successful!
Cela semble fonctionner ! Me revoila parti avec le layout d'origine, et le vieux ProFTPD. Je recommence... Déplacement du noyau...Fait. Déplacement du Ramdisk...(adresse en hexa 0x70190000 !). Fait. On déplace Application. Comme il faut 0x200000 pour le Ramdisk de tinky, je vais mettre Applications en 0x70190000+0x200000 = 0x70390000. C'est parti... Je déplace CurConf contre FIS directory (en 0x707E0000). Il faut enfin déplacer VCTL contre CurConf (en 0x707D0000). Layout obtenu:
Name FLASH addr Mem addr Datalen Entry point RedBoot 0x70000000-7001FFFF 0x00000000 0x0001E7EC 0x00000000 Kern 0x70020000-7018FFFF 0x01600000 0x001673B0 0x01600000 Ramdisk 0x70190000-7035FFFF 0x00800000 0x001CA908 0x00800000 Application 0x70390000-7076FFFF 0x00000000 0x003D31D1 0x00000000 VCTL 0x707D0000-707DFFFF 0x00000000 0x00010000 0x00000000 CurConf 0x707E0000-707EFFFF 0x00000000 0x000005F4 0x00000000 FIS directory 0x707F0000-707FFFFF 0x707F0000 0x00000000 0x00000000
Malheureusement, le Sohonas n'achève pas son démarrage. Le site web n'est pas nourri des fichiers idoines ce qui laisse penser que le déplacement de Application n'est pas "transparent". La lecture de Applications doit s'effectuer depuis un script du initrd (Ramdisk).
Pour examiner le ramdisk du firmware d'origine:
mkdir InitRd gunzip rd.gz sudo mount -o loop rd InitRd/
Un examen du script de démarrage "rc.start" montre que la partition Flash est lue depuis le /dev/mtd "Applications". Malheureusement, Les adresses des mtd (cat /proc/mtd) n'ont pas changé. Elles doivent être en dur dans le noyau.
Partons donc à la chasse dans les sources du noyau, gentiment fournies par SmartDisk [10].
On trouve ces sources dans "RD669_V2_3_2/source/kernel". Le driver MTD est dans "linux/drivers/mtd". Dans le directory "maps", le fichier "sl2312_flashmap.h" contient:
// --> Vic.Tsai 24/02/06 14:48:17 // Added structure for 256k bootloader // 256K Bootloader static struct mtd_partition sl2312_partitions[] = { { name: "RedBoot", offset: 0x00000000, size: 0x00040000, }, { name: "Kernel", offset: 0x00040000, size: 0x00180000, }, { name: "Ramdisk", offset: 0x001C0000, size: 0x00200000, }, { name: "Application", offset: 0x003C0000, size: 0x00400000, }, { name: "VCTL", offset: 0x007C0000, size: 0x10000, }, { name: "CurConf", offset: 0x007D0000, size: 0x20000, }, { name: "FIS directory", offset: 0x007F0000, size: 0x00010000, } }; // <-- Vic.Tsai 24/02/06 14:48:32
Le layout vu par Linux n'est donc pas lu dans la flash, mais cablé en dur. Une zImage étant très pénible à décortiquer, le plus simple (sic !) serait de recompiler un noyau. Avant de se lancer dans cette avnture (cross-compilation...), je vais tenter une chose simple: greffer le redboot de SmartLink sur l'image Flash de NAS2000. Serait il possible que le noyau NAS2000 tourne sous le Smartlink ? La greffe se fait en ajoutant les 128 premiers Ko de la sauvegarde redboot à la flash de tinky, amputée de ses 128 premiers Ko. Après le flashage, le NAS démarre et...s'éteint aussitôt. Flippant ?
Redémarrage par RedBoot et on reflash le firmware de sauvegarde. Et ça redémarre sans problème.
Lançons nous donc dans la compilation d'un noyau-sohonas !