How to circumvent Firewall blocks

How to circumvent Firewall blocks

This a quick guide on how to use ssh tunneling to circumvent Firewall blocks (tested on a Fortigate)


You can can achieve this in many ways, but ill outline the following

  • Local Tunneling
  • Forward Tunneling
  • Dynamic port forwading
  • Reverse Tunneling

Local Tunneling

In the below example, we can assume that you are allowed to ssh to 192.168.0.135, BUT you are not allowed to RDP to that machine.

ssh -L 8181:192.168.0.135:3389  [email protected]

Traffic sent to localhost:8181 on your machine is forwarded to 192.158.0.135, port 3389 via 192.168.0.135, bypassing any explicit firewall blocking.


Forward Tunneling

In the below example, we can assume the following

  • You are allowed to ssh to 192.168.0.2 (next hop)
  • You are NOT allowed to ssh to 192.168.0.3 (end host)
  • 192.168.0.2 IS allowed to ssh to 192.168.0.3

Step 1: Stage It

ssh [email protected] -fNL 8081:192.168.0.3:22

Explaining the flags

  • -f:Puts the SSH session into the background after authentication. This is useful for running the command non-interactively (e.g. as part of a script).
  • -N: Instructs SSH not to execute a remote command, meaning it only sets up the tunnel and doesn't start a shell session on the remote machine.
  • -L 8081:192.168.0.3:22: Sets up a local port forwarding rule:
    • 8081: The local port on your machine that will listen for incoming traffic.
    • 192.168.0.3:22: The destination address and port on the remote network, which the traffic will be forwarded to. Here, it's pointing to 192.168.0.3 on port22 (SSH).

Step 2: SSH to localhost

ssh end-host-username@localhost -p 8081

You can also now copy files etc

scp -r -P 8081 end-host-username@localhost:/path/to/files .

Dynamic port forwarding

The below example assume

  • You are allowed to SSH to 192.168.0.135
  • You are NOT allowed to do anything else (ie browse web etc)

ssh -D 8181 [email protected] 

This creates a dynamic "Socks proxy"

Essentially all connections to localhost 8081 will be proxied through the tunnel, to 192.168.0.135.
You can then enable "Socks" proxy on any browser, and once this is set up, all web requests will be forwarded to 192.168.0.135.
Dont forget to kill the process after you are done, with sudo ps -aux | grep 8081 and then kill <pid>


Reverse tunneling

Example: Remoting into work computer from home, or setting up a backdoor on a victim

Step 1: Stage the listener on the victim's PC

ssh -R 8181:localhost:3389 [email protected] 

Step 2: Connect to the listner

open up RDP and connect to port localhost:8181
If this fails, then check /etc/ssh/sshd_config for the following:

GatewayPorts yes
AllowTcpForwading yes

Unpacking the command

  • R: Specifies a reverse port forwarding. It tells SSH to forward a port on the remote machine (where you're connecting) to a port on the local machine.
  • 8181: This is the port on the remote machine (192.168.0.135 in this case) where incoming connections will be forwarded.
  • localhost: This specifies that the traffic forwarded to the remote machine will be sent to localhost on the local machine (the one running the SSH command).
  • 3389: This is the port on the local machine to which the forwarded traffic will be directed. Port 3389 (RDP)
  • [email protected]: This specifies the user and the IP address (192.168.0.135) of the remote machine to connect to.

Whats is actually happening

  1. The command establishes an SSH connection to the remote machine at 192.168.0.135 as the "user" user.
  2. A reverse tunnel is set up:
    • Any connection to port 8181 on the remote machine (192.168.0.135) will be forwarded to port 3389 on the local machine (localhost).
  3. This allows someone on the remote machine to connect to localhost:8181 to access services running on port 3389 of the local machine (victim).

The Elephant in the room

When using SSH tunneling, you're essentially encapsulating one TCP connection inside another, which can lead to inefficiencies and issues:

  • Interference between congestion control mechanisms
  • Increased latency and jitter
  • Head-of-line blocking
  • Inefficient use of bandwidth
  • Buffer bloat

This is where sshshuttle comes in.
In summary:

sshuttle assembles the TCP stream locally, multiplexes it statefully over an ssh session, and disassembles it back into packets at the other end. So it never ends up doing TCP-over-TCP. It’s just data-over-TCP, which is safe.

Example Usage:
sudo sshuttle -r user@server 0/0

This will tunnel everything 0.0.0.0/0to a remote host