the_open_door
coffee
ESEN
← Back to index

Local port forwarding (SSH tunnel)

Local port forwarding forwards a port on our machine through an SSH connection toward a destination reachable from the remote server. It is used to reach services the target only exposes internally (to 127.0.0.1 or its local network) and that from outside are filtered or return errors.

Mechanism

The classic case: a service listens on the target but only accepts connections from localhost or internal IPs, so connecting from our external IP is rejected (for example, with a 403 Forbidden). If we have SSH credentials on that machine, we make the traffic "originate" inside the server itself. OpenSSH's syntax is -L <local-port>:<destination>:<destination-port>:

ssh <user>@<ip> -L 8443:127.0.0.1:8443            # internal service of the target itself
ssh <user>@<ip> -L 5432:<internal-db>:5432        # a third host only the target can see
ssh <user>@<ip> -L 8443:127.0.0.1:8443 -Nf        # -N no shell, -f to background

From then on, connecting to 127.0.0.1:8443 on our machine goes out through the tunnel and reaches the service as if it came from the target's 127.0.0.1: to the service the source is local and trusted, so the IP restriction no longer applies.

The three directions and pivoting

ssh covers three modes, and it is worth being clear which one applies:

ssh <user>@<ip> -D 1080 -Nf
proxychains nmap -sT -Pn <internal-net>/24        # or: proxychains firefox / curl

When there is no SSH on the target, the same result is achieved with chisel (server/agent over HTTP), ligolo-ng (a TUN interface, convenient for whole networks), socat or, on Windows, plink -L/netsh interface portproxy and sshuttle as a "VPN over SSH".

Requirements

An SSH channel (or another tunnel tool) to the pivot with valid credentials, and a destination service reachable from that pivot. It does not escalate privileges: it only changes the traffic's point of origin.

How to detect it. On the compromised server, an ss -tnp/netstat shows sshd with outbound connections to 127.0.0.1 or internal hosts on the forwarded port that come from no local client: that is the traffic the tunnel originates on the attacker's behalf. In the auth logs, the prior signal is a legitimate remote login followed by activity toward internal services that user rarely touches. An sshd child with -D/-L/-R in its command line, or binaries like chisel/ligolo on disk, are direct signatures.

Defence. Do not trust a service's security to a source-IP filter (anyone with access to the machine can originate "local" traffic); disable AllowTcpForwarding in sshd where it is not needed, segment the internal network, and watch for anomalous outbound connections from servers. It is a sibling of the rest of pivoting and tunnelling.

ToolssssshchiselproxychainssocatLigolo-ngsshuttleplink

Machines where it's used