
From Facebook's Hackathon, TCP re-implemented over chat in a post-SOPA world - xxbondsxx
For Facebook's Hackathon finals between the finalists from 15 different colleges, myself and the two other hackers from UC Berkeley decided to imagine a post-apocalyptic world in which SOPA has passed and is enforced _to the letter_. We took it to the extreme by imagining that file transfer is no longer possible for US citizens. Corporations now control the internet, and we are forced to use only their products.<p>To re-implement file transfer, we decided to hijack Facebook's speedy chat service to do our own packet transmission. This is the way it works:<p>-A python localhost server converts binary data into base64 ASCII and forms packets with uuid's, timestamps, seqnums, and the whole 9 yards.<p>-These packets get pumped over localhost to a user script (aka a Greasemonkey script) running on Facebook.com.<p>-This user script handles the scrubbing of incoming chat messages (packets) and populating the chatbox with outgoing packets.<p>-Facebook does _not_ make sending a chat message easy with custom JS, so in order to actually send a chat message, we signal the python localhost server to run a bash script that tells applescript to emulate a keydown event. Hacked up, I know, but it works! Also, this works for any application (desktop, flash embedded, etc) because it's as legit as a real keypress.<p>Just pumping the packets was the first challenge which we finished around 2am. The second obstacle was that facebook decides to drop about 50% of our packets after the first 15, so we then implemented a crude TCP style acknowledgement/handshake method that ensures each packet gets delivered. Implementing TCP inside of TCP... as meta as you get.<p>If you want to watch a video of a nyan cat GIF transmission, go here:<p>http://www.youtube.com/watch?feature=player_detailpage&#38;v=tk5m0mqsrFs#t=74s<p>The main point is that despite even the most extreme legal restrictions on the internet, the next generation will always find a way :D<p>Github:
https://github.com/pcottle/emotiface<p>Happy to answer any questions. Techcrunch also showed up and filmed / walked around the office (which was surprising considering the relationship between the two). I remember the techcrunch guy specifically saying "I feel like I'm at the Deathstar" when he walked through Facebook's double doors.
======
xtacy
Actually, I am not sure why you would implement TCP inside TCP. You could have
just tunneled the IP packets (raw sockets, or NF_QUEUE or some equivalent) and
TCP would have taken care of everything like ACKs and packet retransmissions.

There are various interesting ways to tunnel TCP inside many other protocols
like ICMP, DNS, etc. The underlying principle is that since many protocols run
over IP, as long as you're able to route IP, you're pretty much done.

EDIT: I didn't mean to sound pessimistic. :)

~~~
xxbondsxx
What you said is completely true, but we were going for 1984-esque post
apocalyptic scenarios. Imagine every ISP shuts down traffic to all domains /
addresses except a small whitelist of mega corporations (fox.net, facebook,
msn, etc). Great Firewall of China status, but far far worse. You literally
have no way to transmit data over the internet except through "using" a
website on a browser.

Obviously not a scenario that we will see any time soon (hopefully), but it
was certainly a fun challenge to work on. It was also extremely hilarious to
see two computers, side-by-side, chat each other actual network packets inside
a browser.

~~~
xtacy
Interesting worst case scenario. (Random thought) Encoding data inside video
streams might give more bandwidth, as chat msgs seem to be heavily throttled.

~~~
xxbondsxx
Good idea! That would definitely require ripping open the plugin or compiling
your own (and swapping it out when the page is loaded), but it would certainly
enable a ton more bandwidth. I was really impressed when I first saw this
image stenography on the Wikipedia article:

[http://en.wikipedia.org/wiki/Steganography#Digital_steganogr...](http://en.wikipedia.org/wiki/Steganography#Digital_steganography)

If you couldn't inject your own code into the chat plugin (or had trouble
faking the packets from your own), you could do the extremely low-tech
solution of videochatting a screen of a slowly-changing QR code. It would make
encoding super simple and still allow for a decent amount of bandwidth
transmission :D

Damnit! That's a good idea. 3k bytes per QR code, a conservative estimate of
15 fps, and you are at decent 45k a second with no code injection!

~~~
gresrun
You could fit many QR codes on screen at a time.

Or, better yet, you could just send raw pixels as bits, white = 0, black = 1.
With 1024x768 HD video, that's a possible 768K/Frame => 22.5M/s @ 30 FPS!

~~~
X4
Fun I had a similar idea on April this year, I thought about using streaming
png's (nodejs) as information source, first I was thinking about using some
qr-code technique to make transmissions secure. Then I thought, I could use
something better like qr-code multiplication inside of a png stream that looks
like a video with some qr-codes that flash from time to time. A smart-phone
application would make the data readable again (decryption). You would need to
whisper a secret key personally into your friends ear, so he can enter the
sequence into his smartphone app. All-in-all it was a concept to use png's
like videos with "cut-scenes" a-like qr-code's that get multiplied and cross-
checksummed afterwards. Might sound stupid, but think about it. I wasn't
approaching to solve your post-apocalyptic scenario, but to make something
speedier+secure than wifi/bluetooth/infrared.

What do you think? A friend who's exceptional at maths (I'm not) told me it's
not possible, however I don't like when naysayers come and tell it's
impossible. Still it demotivated me. Do you think it's possible?

Explained in two words: "Optical Transmission"

~~~
X4
I saw a friend doing a transaction, that inspired me. Here's a video to it:
<http://www.youtube.com/watch?v=GOQeZGe83YM>

------
lowglow
As someone who grew up with the internet being a symbol of hope and freedom,
it's depressing for me to even have to imagine this being a reality.

~~~
tomjen3
To me it is not depressing but uplifting.

Yes taking over the inter is a diaster, but even something like that isn't
enoughvto close the gates completely.

And the truth is, they can't.

------
code-dog
Now the idea of open digital communication is well established, legal
frameworks will not be able to do anything but slow it down. Whilst the US
government is producing laws to stop free/open digital coms they are also
developing stuff like internet-in-a-suitcase which is designed to get around
'repressive governments' which do to allow open access to the internet. This
indicates the stupidity of using legal systems to control communication in
this way.

------
noonespecial
Its like modern day duck-and-cover drills for the plutocratic apocalypse.

~~~
steve-howard
Is Bert the Turtle on hand for PR?

~~~
noonespecial
Be like Bert. Know how to encapsulate whenever you sense danger.

------
imrehg
Cool! Could there be a "bittorrent-style" transmission as well, with the group
chat feature? :)

Edit: I mean multiple source, of this is already "broadcasted", so no need to
take care of multiple receivers.

~~~
xxbondsxx
Certainly! It's actually 90% there already. All incoming packets are handled
the same way regardless of the sender. The JS does this by querying DOM for a
div with the "fbChatMessage" class but without the "read" class. Once it has
this div, it processes it and then marks it as read by adding the "read"
class. It does not depend on which chat box this div lives in though, so if
you received 50 packets from one friend and 50 from another (and they had the
same UUID and filename), it would compile and display as normal.

The only challenge would be dividing up the packet requesting, but you could
do this manually by pasting in two handshake packets, one with startat at 0
and the other with startat at 50:

{"handshake":true,"uuid":"somethingRandom",type:"whichToSend","startAt":0,"filename":"nyancat"}

{"handshake":true,"uuid":"somethingRandom",type:"whichToSend","startAt":50,"filename":"nyancat"}

And then boom! Receive as normal and enjoy your ultra-slow bittorrent-style
bandwidth

------
ptarjan
Great job on the project and thanks for coming to the hackathon.

~~~
xxbondsxx
No problem Paul! Thanks for hosting everything and being an awesome emcee.

------
geuis
Could you link to the bit in the github repo where you're emulating key
presses between applescript and python?

~~~
xxbondsxx
Sure! It's as simple as running the system command "osascript" and passing in
the file here:

[https://github.com/pcottle/emotiface/blob/master/backend/key...](https://github.com/pcottle/emotiface/blob/master/backend/keystroke.app)

As you can see, it just keeps hitting return 20 times (for 20 packets). The JS
does the majority of the heavy lifting. It continually checks the chat
textarea and waits for it to empty (when a keydown happens). When that
happens, it loads the next packet and waits again. Code snippet:

//check if it's nothing

    
    
        console.log('waiting for next return key');
    
        var theVal = $j('.fbNubFlyoutInner').find('textarea').val();
    
        console.log(theVal);
    
        if(theVal)
        {
    
            //need to wait
    
            var timeoutStr = "keydownCheck('" + filename + "'," + String(numPacket) + ");";
    
            setTimeout(timeoutStr,keydownSleep);
    
            return;
        }
    
        //actually put the next packet in
    
        var packetText = JSON.stringify(files[filename].packetMap[numPacket]);
    
        $j('.fbNubFlyoutInner').find('textarea').val(packetText);
    
    

Link:

[https://github.com/pcottle/emotiface/blob/master/backend/sta...](https://github.com/pcottle/emotiface/blob/master/backend/static/thejs.js)

~~~
geuis
Thanks, this will help out with a hackety thing I've been wanting to do.

