KVM Malware Lab Guide

10 min read

This is my guide for setting up your very own malware lab using KVM.

Before you start, this guide assumes you have an AirVPN subscription or another equivalent one, which provides a .ovpn file.

NOTE: I like to have internet enabled on my analysis VMs and this comes with extra security considerations and potential risk if you do not perform the setup correctly. It is recommended that you have your KVM host machine on a DMZ. Most home routers do have DMZ settings, just consult your manual. This guide is not intended for beginners.

If you have used VirtualBox or VMWare Workstation in the past, Spice is just like the guest tools for these but for KVM, which allows you to copy/paste and copy samples to your VMs from your host machine.

NOTE: This is not a very stealthy setup as of yet, so do expect some malware to detect your VMs. I will continue to update this guide for stealth once I have a server or workstation. This requires forking the qemu code and modifying it.

Once this guide is completed, you should have networking that looks like this:

│Host Machine│ Kernel Virtual Machine (KVM) on DMZ
    │NAT│ (default)
  ┌───┴───┐ ┌────────┐
  │PFSense├─┤Isolated│ LAN (vmbr0)
  └───────┘ └───┬────┘
             │Remnux│ Static Analysis and Interception
            │Isolated│ Analysis LAN (vmbr1)
              │      │
      ┌───────┴───┐ ┌┴──────┐
      │Analysis VM│ │Windows│ Dynamic Analysis
      └───────────┘ └───────┘

Install KVM

This section of the guide will show you how to install KVM on your Linux host.

  • Verify you have virtualization enabled
grep -Po '(vmx|svm)[^\x20]+' /proc/cpuinfo | sort | uniq # For Host Machine
cat /sys/module/kvm_intel/parameters/nested              # Nested Virtualization Only (intel)
cat /sys/module/kvm_amd/parameters/nested                # Nested Virtualization Only (amd)
  • Enable Nested Virtualization (optional)
sudo nano /etc/modprobe.d/kvm.conf # Nested Virtualization Configuration File
# Add the following configuration
: '
options kvm_intel nested=1
' # save then reboot
sudo reboot
  • If there is any output from the previous command then virtualization is enabled, otherwise, enable it in your bios and try again
  • Install dependencies
sudo apt update
sudo apt install -y virt-manager qemu-kvm build-essential python-is-python3
  • Verify that libvirtd service is running
sudo systemctl enable libvirtd
sudo systemctl start libvirtd
  • Add current user to the libvirt group
sudo usermod -a -G libvirt $USER
  • Install modified version of SeaBios (modifies src/config.h to more realistic values)
git clone https://github.com/c3rb3ru5d3d53c/seabios.git
cd seabios/
sudo cp /usr/share/seabios/bios.bin /usr/share/seabios/bios.bin.bak
sudo cp out/bios.bin /usr/share/seabios/bios.bin
  • If you want virt-manager to be able to access your home directory, you may need to set upstream permissions (this step is optional)
sudo setfacl -m u:libvirt-qemu:rx /home/$USER
  • Once all has been completed do a reboot
sudo reboot

Create VMS

This section will guide you through the creation of the malware lab with KVM using virt-manager.

Create Virtual Networks

  • Edit -> Connection Details -> + -> vmbr0 Isolated (PFSense LAN)
    • Disable both IPV4 and IPv6 (Provided by PFSense)
  • Edit -> Connection Details -> + -> vmbr1 Isolated (Analysis LAN)
    • Disable both IPV4 and IPv6 (Provided by Remnux)

Create PFSense VM

The primary purpose of the PFSense VM is to provide an easy way to manage firewall rules between your home or work network and the internet. I know most people disable their internet when analyzing malware. However, I like to use an anonymous VPN and with that comes additional risk and considerations.

qemu-img create -f qcow2 pfsense.qcow2 16G
  • Create a new virtual machine
    • Import Existing Disk Image
    • Select pfsense.qcow2 as the storage path
    • Select FreeBSD as the OS
    • Name: pfsense
    • Customize configuration before install
    • Set first NIC to NAT
    • Add Hardware -> Network -> vmbr0 (PFSense Network)
    • Add Hardware -> Network -> CDROM Device -> Manager -> PFSense ISO
    • Boot Options -> Set CDROM device as first in boot order
  • Start the VM
  • Set LAN as in PFSense setup

Create Remnux VM (Ubuntu 22.04)

The primary purpose of this VM is to allow you to perform static analysis of binaries using IDA, Ghidra or Cutter but also acts as the gateway for your entire analysis subnet. This gives you full control over the DNS and DHCP server for traffic interception and more.

NOTE: The official remnux distribution OS is quite outdated, to solve this it is recommended to use the latest LTS image from Ubuntu as the VM and instead use remnux within that VM as a container.

qemu-img create -f qcow2 remnux.qcow2 40G
  • Create a new virtual machine
    • Import existing disk image
    • Select remnux.qcow2 as the storage path
    • Select Ubuntu as the OS
    • Name: remnux
    • Customize configuration before install
    • Set first NIC to vmbr0 (PFSense Network)
    • Add Hardware -> Network -> vmbr1 (Analysis Network)
    • Add Hardware -> Storage -> CDROM Device-> Manage -> Ubuntu ISO Image
    • Boot Options -> Set CDROM device as first in boot order
  • Start VM
  • Install dependancies
sudo apt update
sudo apt install dnsmasq isc-dhcp-server openvpn docker.io spice-vdagent
sudo systemctl enable spice-vdagent
sudo systemctl enable docker
sudo usermod -a -G docker $USER
# logout and login again
  • Create your remnux docker container
docker run --rm -it -v $(pwd):$HOME -u remnux remnux/remnux-distro:focal bash
  • Set up the interfaces
sudo nano /etc/netplan/01-network-manager-all.yaml
# Replace it with the following contents
: 'network:
  version: 2
  renderer: networkd
      dhcp4: yes
  • Disable dnsmasq conflicts with systemd-resolved
sudo nano /etc/systemd/resolved.conf
# Append DNSStubListener=no to the end of the file and save
sudo systemctl restart systemd-resolved
sudo systemctl enable dnsmasq
sudo systemctl restart dnsmasq
  • Setup the dhcp server
sudo nano /etc/dhcp/dhcpd.conf
# Add the following content to the configuration
: 'subnet netmask {
   option domain-name "malware.wtf";
   default-lease-time 600;
   max-lease-time 7200;
   option routers;
   option subnet-mask;
   option broadcast-address;
   option domain-name-servers;
sudo systemctl enable isc-dhcp-server
sudo systemctl restart isc-dhcp-server
  • Browse to and login with admin:pfsense and setup your own password for PFSense.
    • Add firewall rules to block your local network, in my case it was to block everything from LAN net to
    • Apply the changes
  • Setup internet forwarding
sudo iptables -t nat -A POSTROUTING -o tun0 -j MASQUERADE
sudo apt install iptables-persistent # Say yes to both prompts
sudo nano /etc/sysctl.conf # Uncomment the line with net.ipv4.ip_forward=1
sudo sysctl -w net.ipv4.ip_forward=1
  • Create a script to allow to you start your VPN
nano vpn.sh
# Add the following contents and save
: '
#!/usr/bin/env bash
openvpn --daemon --config AirVPN_All-servers_UDP-443.ovpn
chmod +x vpn.sh
sudo ./vpn.sh
  • Setup TLS Decryption with MITMProxy
sudo apt update
sudo apt install -y wireshark tshark # Say yes to non-super user packet capture
sudo usermod -a -G wireshark $USER   # logout then login again
wget https://snapshots.mitmproxy.org/8.1.0/mitmproxy-8.1.0-linux.tar.gz
tar -xzvf mitmproxy-8.1.0-linux.tar.gz
sudo mv mitmdump /usr/bin/
sudo mv mitmproxy /usr/bin/
sudo mv mitmweb /usr/bin/
wget https://gist.githubusercontent.com/c3rb3ru5d3d53c/d9eb9d752882fcc630d338a6b2461777/raw/f56cbef4b98c7bad8f265534eabf696923b649a2/mitmpcap
chmod +x mitmpcap
sudo mv mitmpcap /usr/bin/
wget https://gist.githubusercontent.com/c3rb3ru5d3d53c/3bc8041a182467ccae0207394c1e16b3/raw/33bf201da721ae8f8dc057480221a3c6612e7c11/mitmhttp
chmod +x mitmhttp
sudo mv mitmhttp /usr/bin/
sudo mkdir /root/.mitmproxy

Once completed, you should be able to reboot and run sudo ./vpn.sh to get connected to the internet. NOTE: The internet will not work on the Analysis LAN unless you have VPN enabled as we set the internet to be forwarded through tun0 for openvpn. This is a good thing, this means it will force you to use an anonymous VPN and reduce risk of leaking your actual IP address.

Create Windows VM

This VM will sit on the Analysis LAN, its main purpose is to dynamically analyze malware by executing it. This includes debugging, tracing API calls and more.

NOTE: With a Windows VM it is very important to ensure your boot drive is using the VirtIO drivers.

qemu-img create -f qcow2 windows.qcow2 128G
  • Create a new virtual machine
    • Import existing disk image
    • Select windows.qcow2 as the storage path
    • Select Windows as the OS
    • Name: windows
    • Customize configuration before install
    • Set first NIC to vmbr1 (Analysis LAN)
    • Add Hardware -> Storage -> CDROM Device-> Manage -> Windows ISO Image
    • Add Hardware -> Storage CDROM Device -> Manage -> VirtIO ISO
    • Boot Options -> Set CDROM device for Windows ISO to boot first
    • Remove the SATA Disk and replace with one for VirtIO pointing to windows.qcow2
    • Start installation
  • During the Windows install the VirtIO disk will not show unless you browse to the VirtIO ISO and select the folder with the drivers for your version of Windows. Once completed, you can proceed with the installation.
  • Once Windows is installed, open Device Manager and identify all the drivers with question marks and update them using the VirtIO ISO CDROM.
  • Download and install Spice Guest Tools
  • Reboot the VM

If you are unable to boot using the VirtIO driver, try the following troubleshooting steps:

  • Open an elevated command prompt and set the VM to boot into safe mode by typing
    • bcdedit /set {current} safeboot minimal
  • shut-down the VM and change the boot device type to virtio
  • boot the VM. It will enter in safe mode.
  • in the booted VM reset the bcdedit settings to allow the machine to boot into the Normal mode by typing (in an elevated command prompt again):
    • bcdedit /deletevalue {current} safeboot

Reference: Windows 10 in KVM: change boot disk to Virtio

Once you have completed all necessary steps, it is recommended to remove the CDROM drive for the VirtIO drivers.

Installing TLS Decryption Certificates

This section of the guide will discuss how to get TLS decryption working on your Remnux VM so you can transparently decrypt TLS and capture secrets and pcaps from the analysis network as long as the devices have the root CA installed.

  • On your Remnux machine do the following commands
sudo mitmhttp -i <analysis-network-interface> --enable
mitmproxy --mode transparent --listen-host --listen-port 8080
  • On your Windows VM open a browser and go to mitm.it then follow either the Manual or Automated install instructions
    • Manual Install
      • On the webpage download the certificate for Windows
      • Double click the P12 file to start the import wizard
      • Select a certificate store location. This determines who will trust the certificate – only the current Windows user or everyone on the machine. Click Next.
      • Click Next again
      • Leave Password blank and click Next
      • Select Place all certificates in the following store, then click Browse, and select Trusted Root Certification Authorities. Click OK and Next
      • Click Finish
      • Click Yes to confirm the warning dialog.
    • Automated Install
      • certutil.exe -addstore root mitmproxy-ca-cert.cer
    • In your browser visit https://example.com to verify a successful decryption in the mitmproxy interface

If the above steps were successful, you can now use the tool mitmpcap to view traffic live with mitmproxy but also use it to capture TLS secrets and a pcap for analysis later.

mitmpcap -i enp7s0 -w dump.pcap -m transparent -p 8080 -s secrets.txt -v 1 -f libpcap

Once you have finished your capture, press Q then Y to exit mitmproxy. You should then notice you have the files dump.pcap and secrets.txt. The following steps will show you how to use Wireshark to analyze your capture.

  • Open dump.pcap with Wireshark
  • Edit -> Preferences -> Protocols -> TLS -> (Pre)-Master-Secret log filename Browse -> select secrets.txt
  • In the filter bar type http and press Enter
  • You should now have decrypted TLS traffic

Once you have completed capturing your traffic and no longer wish to perform interception, disable the redirection by executing the following.

sudo mitmhttp -i <analysis-network-interface> --disable

Install Malware Analysis Tools

Once you have completed the networking and VM creation, you can install your favorite malware analysis tools!

You can get a list of my favorite tools here.

Establishing a Clean Environment

Once you have completed installing your favorite tools, establish a clean environment by taking snapshots of every VM. This will ensure you can go back to those clean states after you have completed an analysis.


Once you have the PFSense and Remnux VMs setup, you can create additional VMs on your Analysis LAN to suit your needs.

Creating a malware lab using KVM can be a daunting task for beginners compared to using VMWare Workstation or VirtualBox. However, it can benefit your lab in the following ways.

  • Access to source code you can edit to make your VMs super stealthy
  • CPU Emulated VMs (MIPS, ARM, etc.) for IoT malware
  • PCI pass through of hardware

Again I cannot recommend KVM enough, it is great for malware analysis!



I have acquired over my career, skills that make me a nightmare for threat actors.