HTTP Tunneling with Chisel
The example we just covered is a perfect scenario for Chisel,
an HTTP tunneling tool that encapsulates our data stream within HTTP.
It also uses the SSH protocol within the tunnel so our data will be encrypted.
Chisel uses a client/server model.
A Chisel server must be set up,
which can accept a connection from the Chisel client.
Various port forwarding options are available
depending on the server and client configurations.
One option that is particularly useful for us is reverse port forwarding,
which is similar to SSH remote port forwarding.
Now that we know what Chisel is capable of, we can make a plan.
We will run a Chisel server on our Kali machine,
which will accept a connection from a Chisel client running on CONFLUENCE01.
Chisel will bind a SOCKS proxy port on the Kali machine.
The Chisel server will encapsulate whatever we send through the SOCKS port
and push it through the HTTP tunnel, SSH-encrypted.
The Chisel client will then decapsulate it and push it wherever it is addressed.
The traffic between the Chisel client and server is all HTTP-formatted.
This means we can traverse the deep packet inspection solution
regardless of the contents of each HTTP packet.
The Chisel server on our Kali machine will listen on TCP port 1080,
a SOCKS proxy port.
All traffic sent to that port will be passed back up the HTTP tunnel
to the Chisel client, where it will be forwarded wherever it’s addressed.
Let’s get the Chisel server up and running on our Kali machine.
In the Chisel usage guide, we find the --reverse flag.
Starting the Chisel server with this flag will mean that when the client connects,
a SOCKS proxy port will be bound on the server.
Before we start the server,
we should copy the Chisel client binary to CONFLUENCE01.
The Chisel server and client are actually run from the same binary,
they’re just initialized with either server or client as the first argument.
In this case, both CONFLUENCE01 and our Kali machine are amd64 Linux machines.
That means we can simply serve the same chisel binary
we have on our Kali machine,
and run it on CONFLUENCE01.
Let’s copy the Chisel binary to our Apache2 server’s webroot directory.
Next, we will build the wget command we’ll eventually
run through our web shell on CONFLUENCE01.
This command will download the chisel binary to
/tmp/chisel and make it executable:
Next, we’ll format this command to work
with our curl Confluence injection payload:
The Apache2 log file eventually shows the request for the chisel binary:
Now that we have the Chisel binary on both our Kali machine and the target,
we can run them.
On the Kali machine,
we’ll start the binary as a server with the server subcommand,
along with the bind port and the reverse flag to allow the reverse port forward.
The Chisel server starts up and confirms that it is listening on port 8080,
and has reverse tunneling enabled.
Before we run the Chisel client,
we’ll run tcpdump on our Kali machine to log the Chisel traffic.
We’ll start the capture filtering tcp port 8080 to isolate the Chisel traffic.
Next, we’ll start the Chisel client from the web shell,
applying the server address
and the port forwarding configuration options on the command line.
We will connect to the server running on our Kali machine,
creating a reverse SOCKS tunnel.
The R prefix specifies a reverse tunnel using a socks proxy,
which is bound to port 1080 by default.
The remaining shell redirections,
force the process to run in the background, which will free up our shell.
We’ll convert this into a Confluence injection payload,
and send it to CONFLUENCE01.
Tcpdump instantly reveals our traffic to the Chisel server,
some of which is familiar.
The traffic indicates that the Chisel client
has created an HTTP WebSocket connection with the server.
Our Chisel server has logged an inbound connection.
Next, we’ll check the status of our SOCKS proxy with ss.
Our SOCKS proxy port 1080 is listening
on the loopback interface of our Kali machine.
Let’s use this to connect to the SSH server on PGDATABASE01.
In Port Redirection and SSH Tunneling,
we created SOCKS proxy ports with both SSH remote
and classic dynamic port forwarding,
and used Proxychains to push non-SOCKS-native tools through the tunnel.
But we’ve not yet actually run SSH itself through a SOCKS proxy.
SSH doesn’t offer a generic SOCKS proxy command-line option.
Instead, it offers the ProxyCommand configuration option.
We can either write this into a configuration file,
or pass it as part of the command line with -o.
ProxyCommand accepts a shell command that is used to open a proxy-enabled channel.
The documentation suggests using the OpenBSD version of Netcat,
which exposes the -X flag and can connect to a SOCKS or HTTP proxy.
However, the version of Netcat that ships with Kali doesn’t support proxying.
Instead, we’ll use Ncat,
the Netcat alternative written by the maintainers of Nmap.
We can install this on Kali with sudo apt install ncat.
Now we’ll pass an Ncat command to ProxyCommand.
The command we construct tells Ncat to use the socks5 protocol
and the proxy socket at 127.0.0.1:1080.
The %h and %p tokens represent the SSH command host and port values,
which SSH will fill in before running the command.
Very nice!
We gained access to the SSH server, through our Chisel reverse SOCKS proxy,
tunneling traffic through a reverse HTTP tunnel.
In this Learning Unit, we created a reverse tunnel using Chisel,
and then used this tunnel to log in to an SSH server
on PGDATABASE01 within the internal network.
We did this with only HTTP-formatted traffic
to and from the compromised CONFLUENCE01 pivot server.