viernes, 12 de febrero de 2010

BitlyFS: Another Filesystem Abusing a URL Shortener

It has been a while since I notice the existence of GmailFS and I also wanted to use FUSE (File System in Userspace) to implement some parasitic storage on Internet free services. Parasitic storage is explored in detail in Zalewski's book and is a very new field in security research. Check this paper for an academic research effort on this field. After reading Mario Vilas's post on URL shorteners fun I decided to experiment abusing URL shorteners. I also notice that the Bitly service provides custom URLs, a valuable feature when encoding data to be stored. Mario also implemented a file uploaders abusing storage on TinyURL and and rfreebern also implemented a multiple URL shortener parasitic uploader on PHP. Aparrently, TinyDisk was also released on 2005 to abuse TinyURL, but as everyone notices the implementation is not available now. So let's roll our own implementation!

I decided to use Bitly's custom short url to avoid the use of local storage of short url for each data chunk. My Python prototype code using FUSE wrapper is based on pyraid and only supports one file, read-only.. Then the first time you mount the filesystem you specify that you are uploading the file, next time anyone with the correct key can mount the filesystem and read the file as long as they have access to the Internet. I use base64 encoding for the false URLs containing the data chunks and MD5 hashes for the custom URLs. Base64 encoding 768-byte chunks leads to 1024 bytes of base64 data in the false URLs. I also tried with 2KB with negative results.

http// data to complete 1024 base64 bytes...

Something remarkable of Mario's implementation on is that he uses a chain of short urls to encoded the file. In my case, I hash the filename, the sequential chunk number, the chunk size and the access key to generate the custom short urls. This is desirable because as I wanted to implement a transparent filesystem you may want to seek any file offset an read data from there. TinyURL chunks can be much bigger as our implementation using Bitly is very slow.

Installation (tested on Ubuntu Linux):

$ sudo apt-get install python-fuse
$ wget
# unzip

Example usage storing conscience.txt:

$ cd bitlyfs
$ mkdir mountpoint
$ ./ --initialize --mount-point mountpoint --key secret conscience.txt
full url:
block count: 0 of 5
block_id dcc83fb03f3bc05b712e3b5ad95370aa
full url: ...
(in another shell test differences)
$ ls -l mountpoint/conscience.txt
-r--r--r-- 1 root root 3881 1969-12-31 21:00 mountpoint/conscience.txt
$ diff conscience.txt mountpoint/conscience.txt
$ cat mountpoint/conscience.txt

After the file is uploaded then you can mount anywhere the filesystem to access it. For example you can access a photo I stored using the default key without any initialization.

$ ./ -m mountpoint pibito.jpg &
$ gimp mountpoint/pibito.jpg

Future steps should include using custom URLs to reference URL shorteners with larger supported URL size, to achieve realtime reproduction of MP3! Bitly Underground Radio!

Source code: