Sidestep Wireless Logins
Route your Traffic Through Measly Little Ping Packets
The problem:
- There's an unencrypted access point which requires a login you don't have.
- But, you can
ping
any address on the internet. - You think,
"Wait, since an ICMP payload can be any arbitrary data (read, traffic)..."
The Gameplan
Set up a series of "layers" that sit within the ICMP payload and then route your internet traffic through this magic ping technology.
This guide goes over:
- Opening up an ICMP tunnel on a server you have somewhere.
- Forwarding the server's SSH port to a local port on your laptop.
- Using SSH to set up a SOCKS proxy using this local port.
- And then, ambitiously use
sshuttle
to push all your internet traffic through the setup.
Blam!
Now you'll have a completely transparent layer that works over ICMP.
You'll be able to do any internet thing you want.
And all without ever having to log in to the access point. Score!
What you'll need normal internet access for
You need to set some things up and get software on your laptop with either a normal internet connection beforehand or tethered over a smartphone.
Specifically, you'll need to do:
- The server setup.
- Downloading of
ptunnel
andsshuttle
on the client (a.k.a your laptop).sshuttle
is written in Python version 2. Make sure you have that installed on your laptop.
Server Setup
The server setup uses ptunnel which is available through apt-get
in debian-based distributions. You'll need to have sudo
access to the server because ptunnel
needs to do some privileged operations.
Running ptunnel
without any arguments should work. It's probably a good idea to make it a respawnable program in case it crashes.
There's very proper complex ways to respawn things.
There's also a very easy one. We'll do that.
The snippet below does the following:
- Creates a script (file) named
ptunnel-loop.sh
. [line 1] - Make it run
ptunnel
until it crashes (err, exits), then starts it up again. [lines 2-6] - Make the script executable. [line 7]
- Run the script as
root
and send it to the background. [line 8] - Disown the process (don't worry if this spits an eror). [line 9]
- Tell the kernel to not respond to ping requests. [line 10]
- Log out. [line 11]
$ cat > ptunnel-loop.sh #!/bin/sh while [ 0 ]; do ptunnel done ^D $ chmod +x ptunnel-loop.sh $ sudo ./ptunnel-loop.sh & $ disown $ sudo sysctl net.ipv4.icmp_echo_ignore_all=1 $ logout
The server setup is completely done now.
Client Setup
You should probably start up atmux
or screen
session before going on (although this is not a technical requirement at all).
On the client side (your laptop), after installing ptunnel
, run something like this in the terminal:
$ sudo ptunnel -p <server> -lp 8005 -da 127.0.0.1 -dp 22
Where:
server
is the server hostname or ip address from above.da
anddp
are thedestination
host and port from the perspective of how the server sees the world. The settings used above are equivalent to the more common syntax of "127.0.0.1:22" meaning port 22 on the server's idea of "127.0.0.1".lp
is the forwarded client port that will be tunneled, in our case, to "127.0.0.1:22" on the server.
Here is a rundown of what is happening:
- The laptop's
ptunnel
negotiates with the server'sptunnel
saying"Hey, I want you to forward traffic to 127.0.0.1:22"
. - The laptop's
ptunnel
then opens up, in our case, port 8005 locally and will take any traffic that hits it and send it to the server'sptunnel
(all over ICMP). - The server's
ptunnel
will take this traffic and send it to "127.0.0.1:22".
So if everything works you should be able to do something like
$ ssh localhost -p 8005
And log-in in to the remote server.
Congratulations, you just ssh'd over ICMP pings.
Here is a video of it in action.
If you get the errorkey_verify failed for server_host_key
from ssh, make sure you are only running 1 instance of ptunnel
on the server.
Setting up a SOCKS proxy
SSH has a feature which allows you to create a SOCKS proxy from an ssh
connection with the -D
option.
If you can ssh
, you can probably create a SOCKS proxy.
Start this up and leave it running:
$ ssh -v -N -D localhost:8080 -p 8005 localhost
Where -D localhost:8080
states that
- we want to have a SOCKS proxy listening on port 8080 of our local machine (your laptop)
- and send this traffic to port 8005
- which is forwarded (via ptunnel) to the SSH port on our remote machine
- and all over ICMP.
-v
and-N
are optional arguments for showing verbose output, and not spawning a remote shell, respectively. You can leave them out if you want (although the "as many vs as possible" method of debugging seems to almost always do the trick).
Congratulations, now you have a SOCKS proxy over SSH over ICMP.
You *could* stop here. Most applications can be configured to connect through a SOCKS proxy if you poke around enough.
But that's nonsense, this is Linux! We can do better!
Getting everything to work without special configuration
sshuttle is a clever little program that gets all of our internet traffic to tunnel through our SSH connection with very little effort.
It is available through apt-get
in debian-based distributions or can be git-cloned from the above linked-to github page.
For me, I cd'd
into the git
cloned version and ran:
$ sudo ./sshuttle <username>@localhost:8005 0.0.0.0/0 -v
Where username
is my non-root user, and localhost:8005
is the port I'm forwarding through ptunnel
.
You'll see iptables
messages pass by - it's doing all that confusing hard work for you.
Now go to your web browser and watch a cat video. Really, that's it. Have fun.
-v
is an optional argument for verbose output. Highly recommended.
How well does this work?
I've done this various times and my speedtest.net ratings are always at least 1MB/s up and down ... usually around 3MB/s or so.
Of course I could carefully measure "regular" internet speed and then state this ICMP tunneling technique as a quotient, but really, if you are going from 0 internet to 2MB/s then who cares?!
It's not like you'll ever see the "regular" speed for that network anyway.
Wait, none of this stuff is working.
I tried to keep the guide dead-simple so not to be confusing, but I did leave a few trouble-shooting tips out:
You may need to:
- On the server:
- Set
sudo sysctl net.ipv4.icmp_echo_ignore_all=1
to avoid responding to ICMP inquiries. - Set
sudo sysctl net.ipv4.icmp_ratelimit=0
to disable rate limiting of ICMP pings. - Make sure you have only 1 instance of
ptunnel
running
- Set
- On the client:
- Flush your
iptables
. (runningiptables -X
, theniptables -F
, and theniptables -t nat -X
seems to do the trick) - Tweak your
GatewayPorts
setting in/etc/ssh_config
so that the-D
option of ssh works.
- Flush your
And if all else fails, run everything again with a -vvvvvvvvvv
option. ;-)
There's a reddit post associated with this article for commenting. I'll happily answer any technical questions there.