How to hide (obfuscate) SSH traffic using obfs4

Overview

In the previous post, I talked about pt-spec-v1 and obfs4 and explained how obfs4proxy can be setup and used outside of Tor. You are advised to read it to get the most out of this post.

In this post I’m going to give you a real example of obfs4proxy being used to obfuscate SSH traffic.

For this, I’ll be using two Ubuntu 18.04 Servers. But with a little to no adjustment, any other decent distro should work.

Assumptions

  • Both server and client are running Ubuntu 18.04 Server
  • Server IP address is 10.0.0.1
  • Client can access the obfs4proxy server port (2222 in our example)

Common configurations

These are configurations that needed on both sides:

Installing obfs4proxy

You can either compile it from source or use your distro’s repository:

sudo sh -c 'apt-get update && apt-get install obfs4proxy'

Setting up the user and pt_state

There should be no reason to run obfs4proxy as root. So we create a dedicated user/group for it:

sudo adduser \
  --system \
  --home "/var/lib/obfs4proxy-ssh/" \
  --shell "/usr/sbin/nologin" \
  --group \
  --gecos "obfs4proxy for ssh" \
  obfs4-ssh

Note that in the process, we also made a home directory with the required permissions. Later we’ll use that as the TOR_PT_STATE_LOCATION value.

Server configurations

These are configurations that needed on the server side:

Configuring SSH daemon

Obviously openssh-server must be already installed and correctly configured.

Apart from that, I also recommend setting it to bind to localhost only (to not expose the non-obfuscated port to the public).

We can do that by adding an extra line to /etc/ssh/sshd_config :

ListenAddress 127.0.0.1

And then restarting the sshd:

sudo systemctl restart sshd.service

Using a privileged port for obfs4proxy

This step is optional. If you really need to make obfs4proxy to listen to a privileged port (a port lower than 1024), I recommend using an additional NAT rule for it instead.

In this setup, instead of actually binding obfs4proxy server to a privileged port, we redirect incoming traffic to it.

For example assuming obfs4proxy is listening on port 2222 and you want the incoming traffic to be sent to port 550, this is how it may be done:

sudo iptables -A PREROUTING -t nat -i eth0 -p tcp \
--dport 550 -j REDIRECT --to-port 2222

In Ubuntu you may also take advantage of UFW to make such rule persistent across reboots.

Running obfs4proxy server

Now we are ready to run obfs4proxy in server mode:

sudo -u obfs4-ssh env \
TOR_PT_MANAGED_TRANSPORT_VER="1" \
TOR_PT_STATE_LOCATION="/var/lib/obfs4proxy-ssh/" \
TOR_PT_SERVER_TRANSPORTS="obfs4" \
TOR_PT_SERVER_BINDADDR="obfs4-0.0.0.0:2222" \
TOR_PT_ORPORT="127.0.0.1:22" \
obfs4proxy -enableLogging -logLevel DEBUG

stdout will contain couple of messages like these:

VERSION 1
SMETHOD obfs4 [::]:2222 ARGS:cert=/IHHeIOw7yPM77GZn3cKvLH4pzBB8WscwjwP/HGP5phk0nSXNLZPzZYZNVGmd2dRLlPeUg,iat-mode=0
SMETHODS DONE

obfs4proxy server now stays in the foreground ready to accept new connections on port 2222. Also notice the cert value that is being reported.

Client configuration

These are configurations that needed on the client side:

Installing nmap

openssh-client, supports SOCKS proxy via ProxyCommand option.

Unfortunately, nc is not good enough for the job as netcat-openbsd still doesn’t support authentication for SOCKS proxies.

So we’re going to use ncat instead (part of the nmap package):

sudo sh -c 'apt-get update && apt-get install nmap'

Running obfs4proxy client

Now we are ready to run obfs4proxy in client mode:

sudo -u obfs4-ssh env \
TOR_PT_MANAGED_TRANSPORT_VER="1" \
TOR_PT_STATE_LOCATION="/var/lib/obfs4proxy-ssh/" \
TOR_PT_CLIENT_TRANSPORTS="obfs4" \
obfs4proxy -enableLogging -logLevel DEBUG

stdout will contain couple of messages like these:

VERSION 1
CMETHOD obfs4 socks5 127.0.0.1:39047
CMETHODS DONE

obfs4proxy client now stays in the foreground ready to accept local traffic on it’s SOCKS5 port 39047 (This port changes on each run).

Running SSH client

Now open up another shell and run this command:

ssh \
-o 'ProxyCommand ncat \
 --proxy "127.0.0.1:39047" \
 --proxy-type "socks5" \
 --proxy-auth "cert=/IHHeIOw7yPM77GZn3cKvLH4pzBB8WscwjwP/HGP5phk0nSXNLZPzZYZNVGmd2dRLlPeUg;iat-mode=:0" %h %p' \
-p 2222 [email protected]

Notice that the cert and iat-mode arguments are separated with a “;”. Also the last character (the mode of iat) is set as the password.

And voilà! You just made your SSH traffic obfuscated using obfs4.

Good for you!

To exit obfs4proxy, you need to press Ctrl-C twice.

And finally, I would love to know your thoughts on this article. Please leave a comment below and share them with me!

Hamy
Hamy
a sysadmin in the wind
comments powered by Disqus

Related