As someone who has always been fascinated by small-scale embedded computing, I can hardly describe my excitement when I happened across this post on HackerNews: http://haxit.blogspot.com.es/2013/08/hacking-transcend-wifi-sd-cards.html
In short, the author, Pablo, was able to take advantage of vulnerabilities of the poorly coded CGI scripts of the Transcend WiFi SD card's web interface, to examine the filesystem, and ultimately upload his own binaries and modified files.
I, along with many others, were inspired: Wouldn't it be awesome to be able to customize our own Linux system on that device?
It could serve as...
- A small portable fileserver that can be powered by batteries and hidden in your wallet.
- A network application server run indefinitely off of batteries (and solar panel) without all the power-consuming doodads of a full blown Raspberry Pi.
- A discreet portable webserver/router with wiki/forum software to allow political dissidents to organize
- It could serve as a remote proxy connected to some free Starbucks Wifi and taped behind some toilet in the restroom... A spy device? etc.
- For me, it could serve as a cheap WiFi shield for an Arduino/AVR. The micro-controller could dump text files into the SD card. A script on the card would monitor, parse, and send the data to wherever it needs to go... and vice versa! When range isn't key, this solution is much cheaper than buying this: https://www.sparkfun.com/products/11287
As a 400 MHz Linux system with 32 MB of RAM, using only ~100 mA @ 3.3 V, the possibilities are endless!
Standing on the Shoulders of Giants
EDIT: Scroll down for scripts and program by another author who had came to the same result
As I don't have one of those cards on hand (~$40), I decided to download the firmware and see how far I can get with modifying it.
In the Firmware_V1.7 folder, we see the following:
$ ls -al total 6524 drwxrwxr-x 2 robert robert 4096 May 15 14:48 . drwxrwxr-x 7 robert robert 4096 May 22 11:43 .. -rw-rw-r-- 1 robert robert 2664833 Apr 17 18:03 image3 -rw-rw-r-- 1 robert robert 2807347 May 15 10:33 initramfs3.gz -rw-rw-r-- 1 robert robert 1048576 May 15 10:33 mtd_jffs2.bin -rw-rw-r-- 1 robert robert 110660 Apr 17 18:03 program.bin
Cool, some familiar names here... let's see if we can open some of these files:
$ file * image3: data initramfs3.gz: data mtd_jffs2.bin: Linux jffs2 filesystem data little endian program.bin: data
Hmm... despite the intuitive filenames, it looks like some of the files may be encrypted or obfuscated in some way. However, the real fruit is in getting access to the contents of initramfs3.gz
After Googling around, I happened across a Japanese blog detailing the hacking of the firmware for various other brands of WiFi SD cards: http://blog.osakana.net/archives/category/minor/flucard
The content looked applicable, so I followed the instructions there. The new insight from the blog was that for whatever arbitrary reason, I had to take off the first 8 bytes of the initramfs3.gz file in order to get the real initramfs3.gz file
$ expr 2807347 - 8 2807339 $ cat initramfs3.gz | tail -c 2807339 > initramfs3-real.gz $ file initramfs3-real.gz initramfs3-real.gz: gzip compressed data, from Unix, last modified: Tue May 14 19:33:08 2013
Woah, magic! We have a real gzip file now, this should be familiar territory- let's unzip and get the cpio archive.
$ gzip -dc initramfs3-real.gz > initramfs.cpio $ file initramfs.cpio initramfs.cpio: ASCII cpio archive (SVR4 with no CRC)
Cool! Unfortunately, the post on the Japanese blog leaves it at that... Let's keep going further:
$ mkdir root; cd root $ sudo cpio -i -d -H newc --no-absolute-filenames < ../initramfs.cpio 11783 blocks
... and voila!
$ ls bin dev etc home init lib linuxrc lost+found mnt proc root sbin sys tmp ts_version.inc usr var www $ cd www; ls back.gif blank.html dir.gif frame1.html index.html multi_download_decode.jar page page.jpg sd uploadto.html banner.jpg cgi-bin favicon.ico frame2.html mtd nothumb.jpg page.html script text.gif $ cat ../etc/version.txt Product Name : KeyASIC WIFI-SD Firmware Version : V150 Build Date : 17 APR 2013 Revision : V150 WiFi Model : Atheros AR6003 11n Linux Kernel : 126.96.36.199 Busybox : 1.18.5
Forging New Ground
Can I build my own binaries for this?
I was on my ARMv5 Chromebook running Ubuntu (using crouton) with your standard set of build tools... linking against uClibc would be trivial. The author of the original article was able to upload an ARMv5 busybox binary. I took a quick look at the existing busybox binary.
$ cd ../bin; file busybox busybox: ELF 32-bit LSB executable, ARM, version 1 (SYSV), statically linked, stripped $ ./busybox BusyBox v1.18.5 (2013-04-17 18:28:03 CST) multi-call binary. Copyright (C) 1998-2009 Erik Andersen, Rob Landley, Denys Vlasenko and others. Licensed under GPLv2. See source distribution for full notice.
Looks almost certain, but for a resounding yes, I would have to test my own binaries on a real device.
Can I put it back together again?
$ sudo find . | cpio -H newc -o > ../initramfs-real $ cd .. $ gzip -9 initramfs-real
However, recall that to obtain a working gzip file, we had to cut out the first 8 bytes.
Did these first eight bytes specify a checksum, the size of the file, or was it simply padding to prevent prying eyes?
Getting the "original" gzip may not be as simple as pre-pending those 8 bytes again.
To find out, I got an older version of the firmware to compare...
On the version 1.6 firmware:
$ hexdump -n 8 -C initramfs3.gz 00000000 4b 41 47 5a 00 28 a1 98 |KAGZ.(..| 00000008
On the version 1.7 firmware:
$ hexdump -n 8 -C initramfs3.gz 00000000 4b 41 47 5a 00 2a d6 2b |KAGZ.*.+| 00000008
At this point, we see that out of the 8 byte header padding, the difference is in the last four bytes. Let's see if these last four bytes represent the size of the file.
I printed the 4 bytes as a 32 bit int for the version 1.7 firmware:
$ printf "%i\n" 0x002ad62b 2807339 $ ls -al initramfs3-real.gz -rw-rw-r-- 1 robert robert 2807339 Aug 11 23:15 initramfs3-real.gz
Sweet! Now we know how to construct the header: "KAGZ" + 32bit size of gz
We come to a stop to our journey here... After a bit more Googling around, I happened upon a French blog, where the author, mars, came to the same conclusions with the PQI Aircard (WiFi microSD->SD Adapter Card) (A different product, but with similar hardware/software, and awesome in that you can put in your own microSD). http://lemoidului.wordpress.com/2013/03/18/linux-is-everywhere_pqi-aircard-partie-iv-flash-it/
Huge props to mars, as his/her solution is much more thorough, complete with two scripts to extract and build the initramfs. There is even a small C program to generate and append the header for you little-endian people. (The 4 bytes in the header representing the size of the gzip file is in big-endian format).
The author had the added benefit of having a serial console with which to test and debug his/her findings- the interesting discovery was that the size of the initramfs must remain below 3 MB. (If you have big files to add, do so in the JFFS2 program.bin)
All in all, it was an amazing experience of drawing together information form various sources- initial inspiration from Pablo's blog, insights from a Japanese blog, only to find that this has been fully covered in a French blog. International collaboration FTW!
Transcend WiFi Card Manual:
I've bought one on Amazon and will update with new discoveries and custom builds!