====== Hacking the LaCie d2 Network 2 ====== {{.:lacie:lacie_d2_network.jpg?160 |LaCie d2 Network}} The **LaCie d2 Network 2** is very similar to the **[[lacie_d2_network|LaCie d2 Network]]**, luckily enough the hardware is better and gives better performances. Just one thing is worst than before: the Wake-On-LAN is not longer handled by the U-Boot code, it is handled by the init scripts. This means that if you install a plain GNU/Linux system, you must install special software to get the Wake-On-LAN function. The LaCie software is changed a lot. May be it is possible get root access without disassembling it, have a look at the [[#the_auto-update_function|Auto-Update function]]. Main features of this device are: * **CPU** ARM926EJ-S rev 1 (v5l) at **1200 MHz** * Clocks: L2 400 MHz, SysClock 400 MHz, TClock = 166 MHz * **256 Mb RAM** * **512 kb** of Flash Memory * Aluminium case works as heatsink, **no cooling fan** * **Gigabit Ethernet** * **Wake-On-LAN** (handled by system software, not by firmware) * **Linux** kernel version **2.6.22.18** * **DHCP** client * **File server**: SMB, AFP, FTP, HTTP, Apple Bonjour * Compatible with Active Directory Windows domains * Interoperate with [[wp>Universal_Plug_and_Play|UPnP A/V]] and [[wp>Dlna|DLNA]] * **BitTorrent** client * **USB 2.0** and eSata connector for external storage * **USB port B** for printer * **Hard disk Samsung** 1.00 Tb, SAMSUNG HD103SI (929.5 Gb available) ===== Serial connection ===== The JTAG connector is the same as the LaCie d2 Network model, see [[lacie_d2_network#jtag_serial_connector_pin-out|JTAG Serial Connector Pin-out]]. On the serial line there is a login prompt, but unfortunately we don't know the root password. This is the hash (if someone wants to break it): root:$1$$1RDUuTsVHjre9juUvuICX.:12542:0:99999:7::: ===== U-Boot NetConsole ===== It is possible to have a **boot prompt** without using the serial port. The boot loader U-Boot waits some time before booting, for a special LaCie UDP magic packet (see the message //Waiting for LUMP// on the serial console), if it receives it from an host, it will enter a special remote console, communicating on port 6666 UDP. I used this {{:doc:appunti:hardware:lacie:clunc-head-e199d11.tar.gz|Clunc snapshot}}, downloaded from the [[http://git.lacie-nas.org/|Git repository]]. See the notes about the [[lacie_d2_network#u-boot_netconsole|NetConsole on the old LaCie model]]. This is {{.:lacie:d2net2_u-boot_help_printenv.txt|the output}} of **''help''** and **''printenv''** commands. I was able to boot the device from the U-Boot NetConsole: Marvell>> ide reset Marvell>> ide info Marvell>> boot Theoretically **the NetConsole is exploitable** on the local network: just run Clunc and wait for a LaCie to be powered on, you will get a NetConsole prompt. Then feed an hacked boot image using ''tftpboot''. Here it is an example of net boot, feeding the original uImage to the device (you must configure the ''tftp'' daemon on the host running clunc and provide the uImage file renamed as searched by the U-Boot client): Marvell>> tftpboot tftpboot *** Warning: no boot file name; using 'C0A80325.img' Using egiga0 device TFTP from server 192.168.3.2; our IP address is 192.168.3.37 Filename 'C0A80325.img'. Load address: 0x2000000 Loading: ################################################################# ##################################################### done Bytes transferred = 1931568 (1d7930 hex) Marvell>> bootm bootm ## Booting image at 02000000 ... Image Name: Linux-2.6.22.18 Created: 2010-01-14 20:27:21 UTC Image Type: ARM Linux Kernel Image (uncompressed) Data Size: 1931504 Bytes = 1.8 MB Load Address: 00008000 Entry Point: 00008000 Verifying Checksum ... OK OK Starting kernel ... ===== Starting the SSH daemon (disassembling required) ===== A computer running GNU/Linux is required to perform these steps. First of all, set the password for the **admin** account. Disassemble the LaCie removing the 4 screws from the back cover and the 3 screws from the bottom side. Then take the hard disk apart, removing the 4 screws holding the disk on the bottom side. Attach the disk to the GNU/Linux machine and mount the **''/dev/sd//N//8''** partition, where N is the letter assigned to the drive. Search the last snapshot available into the **''/snaps/''** directory; onto a new system it should be **''/snaps/00/''**. Edit **''/snaps/00/etc/shadow''** and set the encrypted root password, see **''man 5 shadow''** if you need help. You can copy the hash from the admin account, or you can copy the following, which is the hash for **''d2network2''** password: root:$1$ZgjvVEBo$xxB4Bk7ppNTERbbSHIaNm/:12542:0:99999:7::: Edit the **''/snaps/00/etc/initng/runlevel/default.runlevel''** file. If it does not exists, create it with all the subdirectories path, the file must be executable (chmod 755). Add a line at the end, telling to start **''sshd''**: sshd Optional: edit **''/snaps/00/etc/passwd''** and set a valid shell for the admin account: admin:x:500:100:None:/home:/bin/sh Umount the partition from the GNU/Linux computer and reassemble the LaCie. At next boot you will have an ssh daemon and you can logis as root. ===== The filesystems ===== At **boot time** the rootfs is ''/dev/sda7'', during bootstrap the command **''pivot_root(8)''** is used to switch to a different rootfs, so at runtime **the rootfs is an unionfs** of ''/dev/sda8'' + ''/dev/sda9'' (see the table below). ^ Device ^ Start ^ End ^ Blocks ^ Id ^ System ^ Note ^ ^ /dev/sda1 | 1 | 250 | 2008093 | 5 | Extended | Contains sda5 … sda10. | ^ /dev/sda2 | 251 | 121601 | 974751907 | 83 | Linux | This is the user's data partition, formatted as **xfs**, it is mounted under **''/media/internal_6''**. Several subdirectories (e.g. one for each share) are mounted with the ''-o bind'' option under other mounting points. | ^ /dev/sda5 | 1 | 32 | 256977 | 82 | Linux swap | Used as **swap** partition. | ^ /dev/sda6 | 33 | 33 | 8001 | 83 | Linux | Not a filesystem, contains an **u-boot uImage** with the kernel and the initramfs. | ^ /dev/sda7 | 34 | 34 | 8001 | 83 | Linux | **Initial root filesystem** used by the kernel (ext3). Contains the scripts to assemble a running root filesystem via unionfs. Available at runtime under **''/oldroot''**. | ^ /dev/sda8 | 35 | 140 | 851413 | 83 | Linux | **Runtime root filesystem** (ext3), read-only part in unionfs. Also available at runtime under **''/oldroot/var/original''**. | ^ /dev/sda9 | 141 | 249 | 875511 | 83 | Linux | **Runtime root filesystem** (ext3), read/write part in unionfs. Also available at runtime under **''/oldroot/snapshots''**. The system can save several snapshots, unionfs uses the last one available, which is **''/oldroot/snapshots/snaps/00/''** in a clean device.\\ This partition contains also the directories **''EDMINI/tmp/''** and **''EDMINI/var/''**, which are mounted at runtime with the ''-o bind'' option, under ''/tmp'' and ''/var''. | ^ /dev/sda10 | 250 | 250 | 8001 | 83 | Linux | Empty partition. If it contains an U-Boot image, it will used instead of /dev/sda6. Probably used to boot from disk2 if disk1 fails, on Lacie RAID models. | ===== Looking around at the shell prompt ===== * The **{{.:lacie:dmesg_d2net_v2.txt|dmesg}}** text after the boot. * The **{{.:lacie:lacie_d2n2_boot_log.txt|boot log}}** captured on the serial line. The boot process is interrupted by the device entering the //Deep Sleep Mode//, see the //Wake up the board// message when the Wake-On-LAN packet is received. * The **{{.:lacie:diagnostics.zip|diagnostics.zip}}** file saved when you click on the configuration download. It is an archive containing most of the **''/etc/''** directory. [root@LaCie-d2 ~]# free total used free shared buffers Mem: 256848 123736 133112 0 7216 Swap: 256968 0 256968 Total: 513816 123736 390080 [root@LaCie-d2 ~]# fdisk -l /dev/sda Disk /dev/sda: 1000.2 GB, 1000204886016 bytes 255 heads, 63 sectors/track, 121601 cylinders Units = cylinders of 16065 * 512 = 8225280 bytes Device Boot Start End Blocks Id System /dev/sda1 1 250 2008093+ 5 Extended /dev/sda2 251 121601 974751907+ 83 Linux /dev/sda5 1 32 256977 82 Linux swap /dev/sda6 33 33 8001 83 Linux /dev/sda7 34 34 8001 83 Linux /dev/sda8 35 140 851413+ 83 Linux /dev/sda9 141 249 875511 83 Linux /dev/sda10 250 250 8001 83 Linux [root@LaCie-d2 ~]# mount rootfs on / type rootfs (rw) /dev/sda7 on /oldroot type ext3 (ro,data=ordered) none on /oldroot/proc type proc (rw) none on /oldroot/sys type sysfs (rw) udev on /oldroot/dev type tmpfs (rw) devpts on /oldroot/dev/pts type devpts (rw) none on /oldroot/dev/shm type tmpfs (rw) /dev/sda8 on /oldroot/var/original type ext3 (ro,data=ordered) /dev/sda9 on /oldroot/snapshots type ext3 (rw,data=ordered) unionfs on / type unionfs (rw,dirs=/oldroot/snapshots/snaps/00=rw:/oldroot/var/original=ro) proc on /proc type proc (rw) sys on /sys type sysfs (rw) /dev/sda9 on /var type ext3 (rw,data=ordered) udev on /dev type tmpfs (rw) /dev/sda9 on /tmp type ext3 (rw,data=ordered) usbfs on /proc/bus/usb type usbfs (rw) /dev/sda2 on /media/internal_6 type xfs (rw,nosuid,nodev,usrquota,prjquota) /dev/sda2 on /lacie/tmp type xfs (rw,nosuid,nodev,usrquota,prjquota) /dev/sda2 on /lacie/var type xfs (rw,nosuid,nodev,usrquota,prjquota) /dev/sda2 on /lacie/torrent_dir type xfs (rw,nosuid,nodev,usrquota,prjquota) /dev/sda2 on /lacie/autoupdate type xfs (rw,nosuid,nodev,usrquota,prjquota) /dev/sda2 on /lacie/afp_db type xfs (rw,nosuid,nodev,usrquota,prjquota) /dev/sda2 on /shares/Share type xfs (rw,nosuid,nodev,usrquota,prjquota) /dev/sda2 on /shares/Public type xfs (rw,nosuid,nodev,usrquota,prjquota) /dev/sda2 on /shares/prova type xfs (rw,nosuid,nodev,usrquota,prjquota) ===== The Auto-Update function ===== The AUTO-Update function will connect to an FTP site and search for a new archive to install. This is the FTP account used: ^ host | update.lacie.com | ^ login | d2network2 | ^ password | d2network2 | The LaCie will serach for an update with a version number greater than the version installed on the device. With a version 1.0.8 the LaCie downloaded the following two files: * **''/1.0/prod/1.0.90/d2network2_1.0.90.capsule''** * **''/1.0/prod/1.0.90/d2network2_1.0.90.xml''** After the version 1.0.90 was installed, the LaCie will search for **''/1.1/prod/1.1.x/d2network2_1.1.x.{xml|capsule}''** files. The capsule file is just a tar archive, with an XML header. The .xml file contains the release notes (details) for the update. Every capsule file available on the LaCie site contains a new **kernel image** and a new **rootfs image**, it seems that no signature is verified so it should be possible to upload an hacked image just using a fake DNS server and a local FTP server. ===== Wake-On-LAN ===== The Wake-On-LAN works when the device is put into **Deep Sleep Mode**, send a Wake-On-LAN //Magic Packet// e.g. with the **''etherwake(8)''** tool: etherwake -i eth0 00:D0:4B:8B:4F:C2 The Wake-On-LAN is **not handled by the U-Boot code** (like in the LaCie d2 Network). When the power switch is onto the ON position, the U-Boot always begins the boot process spinning-on the disk, during the boot process a script checks if the Deep Sleep Mode is active, in that case it halts the disk and wait for the Magic Packet. If you install a plain Debian operating system, you can use the **[[#fake_wake-on-lan|Fake Wake-On-LAN]]** software to simulate a Wake-On-LAN. ===== Installing Debian ===== ^ Device ^ Mounting point ^ Type ^ Note ^ | /dev/sda1 | | Extended | Contains sda5, sda6 and sda7. | | /dev/sda2 | /home | ext3 | | | /dev/sda5 | swap | swap | | | /dev/sda6 | | None | U-Boot image with kernel, etc. | | /dev/sda7 | / | ext3 | | ==== Creating the root filesystem ==== Fortunately I have an already debianized LaCie, so I used that box to make a minimal Debian installation using **''debootstrap''**. It is mandatory to use an **armel** box to run ''debootstrap'' (at least the second stage of the installation, see ''%%--foreign%%'' and ''%%--second-stage%%'' switches of ''debootstrap''), so it is not possible to use a standard Intel PC. This is the recipe for the installation: mkdir /home/squeeze debootstrap squeeze /home/squeeze cd /home/squeeze/ mount -o bind /dev /home/squeeze/dev mount -o bind /proc /home/squeeze/proc chroot /home/squeeze aptitude install locales aptitude install less dpkg-reconfigure locales dpkg-reconfigure tzdata Several files must be configured in the ''chroot'' environment: * ''/etc/fstab'' * ''/etc/hosts'' * ''/etc/inittab'' * ''/etc/network/interfaces'' Because the original LaCie kernel does not support ''udev'', some devices must be created statically in ''/dev/'', using ''**mknod**'': crw------- 1 root root 5, 1 2010-12-09 22:02 /dev/console brw-rw---- 1 root disk 8, 0 2010-12-09 22:01 /dev/sda brw-rw---- 1 root disk 8, 1 2010-12-09 22:01 /dev/sda1 brw-rw---- 1 root disk 8, 2 2010-12-09 22:01 /dev/sda2 brw-rw---- 1 root disk 8, 5 2010-12-09 22:01 /dev/sda5 brw-rw---- 1 root disk 8, 6 2010-12-09 22:01 /dev/sda6 brw-rw---- 1 root disk 8, 7 2010-12-09 22:01 /dev/sda7 crw------- 1 root root 4, 64 2010-12-09 22:01 /dev/ttyS0 Finally exit the ''chroot'' environment and create an archive of the installation: exit umount /home/squeeze/dev/ umount /home/squeeze/proc/ tar zcvf /home/lacie_d2net2_sda7_squeeze.tgz --numeric-owner /home/squeeze/ The root filesystem is contained into the **[[http://www.rigacci.net/listing/lacie_d2net2/debian_squeeze/lacie_d2net2_sda7_squeeze.tgz|lacie_d2net2_sda7_squeeze.tgz]]** archive. ==== Dissecting the original kernel ==== The contents of the original ''/dev/sda6'' is an **u-boot legacy uImage**. The image was probably created with **''mkimage''** (provided by the uboot-mkimage package), it contains a kernel image and an initramfs archive. Probably the initramfs is embedded into the kernel using the ''CONFIG_INITRAMFS_SOURCE'' kernel option. First of all, attach the disk to a GNU/Linux box and extract the image (suppose that the box assigned ''/dev/sdb'' to the disk): dd if=/dev/sdb6 of=sda6.bin The file sda6.bin is an exact copy of the whole disk partition, we can get some details of the image using the **''file''** command: file sda6.bin sda6.bin: u-boot legacy uImage, Linux-2.6.22.18, Linux/ARM, OS Kernel Image (Not compressed), 1931504 bytes, Thu Jan 14 20:27:21 2010, Load Address: 0x00008000, Entry Point: 0x00008000, Header CRC: 0x231CA472, Data CRC: 0xF95DD173 If the header added by ''mkimage'' is 64 bytes long, we can restore the original **vmlinux** image: dd if=sda6.bin of=vmlinux bs=1 skip=64 count=1931504 To restore the original **uImage** we use instead: dd if=sda6.bin of=uImage bs=1 count=1931568 The command line to create the uImage was probably something like: mkimage -A arm -O linux -T kernel -C none -a 0 -e 0x8000 -n "Linux-2.6.22.18" -d vmlinux uImage **How to extract the initramfs from the vmlinux image.** First of all search for a gzip signature (**''1F 8B 08''**) into the vmlinux file: Say the gzip signature offset is 12504, extract the gzip data and expand it: dd if=vmlinux of=vmlinux_data1.gz bs=1 skip=12504 gunzip vmlinux_data1.gz Search again for a gzip signature, extract the gzip data and expand it. The resulting file is the **{{.:lacie:d2net2_initramfs.cpio.gz|initramfs cpio}}** archive: dd if=vmlinux_data1 of=vmlinux_data2.gz bs=1 skip=88928 gunzip vmlinux_data2.gz mv vmlinux_data2 initramfs.cpio mkdir initramfs cd initramfs cat ../initramfs.cpio | cpio --extract --make-directories --no-absolute-filenames === Useful links === * [[http://www.kernel.org/doc/Documentation/filesystems/ramfs-rootfs-initramfs.txt|ramfs, rootfs and initramfs]] * [[http://www.gossamer-threads.com/lists/linux/kernel/1015140|Initramfs from existing vmlinuz]] * [[http://en.gentoo-wiki.com/wiki/Initramfs|Dismantling the Kernel]] * [[http://blog.harrylau.com/2009/08/generate-uboot-uimage.html|Generate uboot image]] * [[http://wiki.dns323.info/howto:uboot|Cross-compile an u-Boot image]] ==== Making a new kernel ==== Before preparing a new kernel image remember that the boot loader (U-boot) passes a //machine ID// to the kernel via the //r1// register (see [[lacie_d2_network#testing_a_kernel_image|Testing a kernel image, tip #1]]), the kernel checks that number against a list of known IDs; if no match is found, the boot will halt with the following message on the serial console: Uncompressing Linux... done, booting the kernel. Error: unrecognized/unsupported machine ID (r1 = 0x0000089b). Available machine support: ID (hex) NAME 000008ea LaCie d2 Network Please check your kernel config and/or bootloader. With the old LaCie model it was possible to change the machine ID passed to the kernel using the **''setenv arcNumber''** command at the boot prompt. This seems no longer possible with the new model. ==== Cross compile a Debian kernel ==== We choose to **cross-compile** a kernel on a **Debian i386 Squeeze** box. The procedure is very similar to the [[lacie_d2_network#cross_compile|cross-compile for the old LaCie d2 Network]]. On the Squeeze box install the following packages: * build-essential * kernel-package * libncurses5-dev * lzma * uboot-mkimage Add to ''/etc/apt/sources.list'' the **[[http://www.emdebian.org/|Emdebian]]** repository which provieds a cross-compile **[[http://wiki.debian.org/EmdebianToolchain|toolchain]]** for the arm architecture deb http://www.emdebian.org/debian/ squeeze main Get and install the repository key: wget http://www.emdebian.org/0x97BB3B58.txt apt-key add 0x97BB3B58.txt Then install the following packages: * linux-libc-dev-armel-cross * libc6-armel-cross * libc6-dev-armel-cross * binutils-arm-linux-gnueabi * gcc-4.3-arm-linux-gnueabi * g++-4.3-arm-linux-gnueabi Install the **[[http://packages.debian.org/experimental/linux-source-2.6.37|linux-source-2.6.37]]** package from Debian experimental. We need 2.6.37 because previous versions does not have support for LaCie d2 Network 2 hardware. Using the kernel config file provied by Debian for the kirkwood architecture as a starting point, we made some changes to add support for our LaCie machine (**''MACH_D2NET_V2''**), the RTC clock (**''RTC_DRV_MV''**), etc. This is the final **{{.:lacie:config-2.6.37-rc5_lacie2dn2.0.15.txt|config}}** file and **[[http://www.rigacci.org/pub/Linux/kernel-lacie/linux-image-2.6.37-rc5_lacie2dn2.0.15_armel.deb|linux-image]]** package. Prepare the source tree: cd /usr/src tar jxf linux-source-2.6.37-rc5.tar.bz2 ln -s linux-source-2.6.37-rc5 linux cd linux cp /root/config-2.6.37-rc5_lacie2dn2.0.14 .config These are the commands create the linux-image .deb package and the uImage: cd /usr/src/linux export CROSS_COMPILE=arm-linux-gnueabi- export ARCH=arm make menuconfig make-kpkg --arch armel --cross_compile=arm-linux-gnueabi- clean make-kpkg --revision=lacie2dn2.0.14 --initrd --arch=armel --cross_compile=arm-linux-gnueabi- kernel_image make uImage The U-Boot image is saved in **''arch/arm/boot/uImage''**. Copy both the **linux-image** .deb and the **uImage** into the LaCie and execute: dpkg -i linux-image-2.6.37-rc5_lacie2dn2.0.14_armel.deb dd if=uImage of=/dev/sda6 ===== Fake Wake-on-LAN ===== The Ethernet chip does not have WoL capabilities (whereas the old d2 Network does), so we can only simulate it. This is my first attempt to make a software Wake-on-LAN. At an early stage of the boot process the **''fake-on-lan''** program suspends the USB power, turn off the blue LED and suspend the disk. Then the program waits for a Wake-on-LAN Magic Packet or for a Power Button press/release before to proceed. The device is effectively powered-on and running the Linux kernel, just the USB, the LED and the disk are turned off. I'm running the program with a **Debian Squeeze** installation. You can download the program here: **{{.:lacie:fake-on-lan-20110324.tar.gz|fake-on-lan-20110324.tar.gz}}**. ===== The EEPROM ===== The content of the EEPROM is exposed for read and write via the pseudo file **''/sys/bus/i2c/devices/0-0050/eeprom''**, like with the previous d2 Network model, but the meaning is changed. This is what I know: ^ Offset ^ Length ^ Content ^ | 0 | 2 | 0x00 0x02 | | 2 | 6 | Ethernet MAC address. |