Getting started

Supported hardware & software

In order to run DRAKVUF Sandbox, your setup must fulfill all of the listed requirements:

  • Processor: Intel processor with VT-x and EPT features (how to check).

  • Host system: Debian 12 Bookworm/Ubuntu 22.04 (Jammy Jellyfish) with at least 2 core CPU and 8 GB RAM, running GRUB as bootloader.

  • Host linux kernel version: 5.11+ recommended

  • Guest system: Windows 10 (x64, 22H2 recommended), Windows 7 (x64)

  • Hypervisor: Xen (at least 4.17, 4.19 recommended)

Nested virtualization:

  • KVM does work, however it is considered experimental. If you experience any bugs, please report them to us for further investigation.

  • Due to lack of exposed CPU features, hosting DRAKVUF Sandbox in the cloud is not supported (although it might change in the future).

  • Hyper-V does not work.

  • Xen does work out of the box.

  • VMware Workstation Player does work, but you need to check Virtualize EPT option for a VM; Intel processor with EPT still required.

First steps: Basic installation

Step 1. Installation of Xen Hypervisor and DRAKVUF engine

First you need to perform Xen installation and install DRAKVUF engine itself. Official DRAKVUF installation instruction can be found on https://drakvuf.com/

The easiest way is to use prebuilt .deb Xen and Drakvuf packages from https://github.com/tklengyel/drakvuf-builds/releases

Step 1. alternative: Installation of Xen Hypervisor and DRAKVUF engine from sources

It’s recommended to build components from sources to include latest patches that may be crucial for the stability of the system.

Perform the Xen and DRAKVUF installation without installing Windows domain and creating JSON profiles. DRAKVUF Sandbox toolkit will assist you in creating the snapshot and its VMI profile. DRAKVUF Sandbox requires the following LibVMI/DRAKVUF CLI commands to be available in your PATH:

  • drakvuf

  • injector

  • vmi-win-guid

  • vmi-win-offsets

  • vmi-process-list

It’s required to perform all installation activities using root user. Below you can find the installation instruction that we’ve followed and it’s working on fresh Debian 12 installation:

First, install build dependencies and unpack Xen 4.19.2 sources

$ apt update
$ apt-get install wget git bcc bin86 gawk bridge-utils iproute2 libcurl4-openssl-dev bzip2 libpci-dev build-essential make gcc clang libc6-dev linux-libc-dev zlib1g-dev libncurses5-dev patch libvncserver-dev libssl-dev libsdl1.2-dev iasl libbz2-dev e2fslibs-dev git-core uuid-dev ocaml libx11-dev bison flex ocaml-findlib xz-utils gettext libyajl-dev libpixman-1-dev libaio-dev libfdt-dev cabextract libglib2.0-dev autoconf automake libtool libjson-c-dev libfuse-dev liblzma-dev autoconf-archive kpartx python3-dev python3-pip golang libsystemd-dev nasm ninja-build llvm lld meson

$ cd /opt
$ wget https://downloads.xenproject.org/release/xen/4.19.2/xen-4.19.2.tar.gz
$ tar -xvzf xen-4.19.2.tar.gz
$ cd xen-4.19.2

Note

Bug noted on 2025-04-24: Xen refers to old Tianocore OVMF version that refers to broken subhook submodule URL. If you’re affected by this bug, you’ll be asked for Git credentials while running make -j4 dist-tools and build process will be interrupted.

To overcome this issue, we changed the OVMF version to edk2-stable202408.01 by applying this patch to Config.mk:

- OVMF_UPSTREAM_URL ?= https://xenbits.xen.org/git-http/ovmf.git
- OVMF_UPSTREAM_REVISION ?= ba91d0292e593df8528b66f99c1b0b14fadc8e16
+ OVMF_UPSTREAM_URL ?= https://github.com/tianocore/edk2.git
+ OVMF_UPSTREAM_REVISION ?= 4dfdca63a93497203f197ec98ba20e2327e4afe4

Then build and install Xen:

$ chmod +x ./configure
$ ./configure --enable-githttp --enable-systemd --enable-ovmf --disable-pvshim
$ make -j4 dist-xen
$ make -j4 dist-tools
$ make -j4 debball
$ apt install ./dist/xen-upstream-4.19.2.deb

Then set default Xen cmdline to run Xen with Dom0 getting 4GB RAM assigned and two dedicated CPU cores (tune it as preferred):

$ echo "GRUB_CMDLINE_XEN_DEFAULT=\"dom0_mem=4096M,max:4096M dom0_max_vcpus=2 dom0_vcpus_pin=1 force-ept=1 ept=ad=0 hap_1gb=0 hap_2mb=0 altp2m=1 hpet=legacy-replacement smt=0\"" >> /etc/default/grub
$ echo "/usr/local/lib" > /etc/ld.so.conf.d/xen.conf
$ ldconfig

Then enable necessary Xen modules, update GRUB and reboot system to Xen

$ echo "none /proc/xen xenfs defaults,nofail 0 0" >> /etc/fstab
$ echo "xen-evtchn" >> /etc/modules
$ echo "xen-privcmd" >> /etc/modules
$ echo "xen-gntdev" >> /etc/modules
$ systemctl enable xencommons.service
$ systemctl enable xen-qemu-dom0-disk-backend.service
$ systemctl enable xen-init-dom0.service
$ systemctl enable xenconsoled.service
$ update-grub
$ reboot

Once you are booted into Xen, verify that everything works as such:

$ xen-detect

Running in PV context on Xen V4.19.

$ xl list

Name                                        ID   Mem VCPUs  State   Time(s)
Domain-0                                     0  4096     2     r-----       6.9

Note

Issue noted on 2025-06-26: In certain cases, Xen might employ GDS mitigation by disabling AVX instruction set support entirely.

The mitigation is enabled if you can observe the following command output:

$ xl info | grep GDS (XEN) Mitigating GDS by disabling AVX … or … (XEN) Mitigating GDS by disabling AVX while virtualised - protections are best-effort

Some applications or guest OSes may crash without AVX support, although it doesn’t seem to be a requirement to run DRAKVUF Sandbox with Windows 7 / 10.

If you want to disable this mitigation:

  1. Add spec-ctrl=gds-mit=no option to GRUB_CMDLINE_XEN_DEFAULT in /etc/default/grub.

  2. Run update-grub and reboot.

Since your Xen installation is ready, install Drakvuf engine, starting from installation of LibVMI:

$ cd /opt
$ git clone --recursive https://github.com/tklengyel/drakvuf
$ cd drakvuf/libvmi
$ autoreconf -vif
$ ./configure --disable-kvm --disable-bareflank --disable-file
$ make
$ make install
$ echo "export LD_LIBRARY_PATH=\$LD_LIBRARY_PATH:/usr/local/lib" >> ~/.bashrc
$ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib
$ ldconfig

Check if vmi-win-guid command loads correctly

$ vmi-win-guid
Usage: vmi-win-guid name|domid <domain name|domain id> [<socket>]

Then install DRAKVUF itself:

$ cd /opt/drakvuf
$ meson setup build --native-file llvm.ini
$ ninja -C build
$ mv build/drakvuf build/injector /usr/local/bin/

Check if drakvuf and injector commands load correctly:

$ drakvuf
1745511832.661881 DRAKVUF v1.1-f46a733 Copyright (C) 2014-2024 Tamas K Lengyel
No domain name specified (-d)!

$ injector
DRAKVUF injector v1.1-f46a733 Copyright (C) 2014-2024 Tamas K Lengyel
Required input:
  ... (truncated help message)

Step 2. Installation of DRAKVUF Sandbox

  1. Install additional DRAKVUF Sandbox dependencies

$ apt update
$ apt install iptables tcpdump dnsmasq qemu-utils bridge-utils libmagic1 python3-venv redis-server
  1. Prepare virtualenv

$ cd /opt
$ python3 -m venv venv
$ . venv/bin/activate
$ pip install wheel
  1. Install DRAKVUF Sandbox package

$ pip install drakvuf-sandbox
  1. drakrun command should be available within created virtualenv

$ drakrun
Usage: drakrun [OPTIONS] COMMAND [ARGS]...

Options:
    --help  Show this message and exit.

Commands:
    analyze          Run a CLI analysis using Drakvuf
    drakshell        Run drakshell session
    drakvuf-cmdline  Get base Drakvuf cmdline
    injector         Copy files and execute commands on VM using injector
    install          Install guest Virtual Machine
    make-profile     Make VMI profile
    modify-vm0       Modify base VM snapshot (vm-0)
    mount            Mount ISO into guest
    postinstall      Finalize VM installation
    postprocess      Run postprocessing on analysis output
    vm-start         Start VM from snapshot
    vm-stop          Stop VM and cleanup network
    worker           Start drakrun analysis worker

Creating initial Windows VM snapshot

Step 1: Initial Windows installation

After all tools are installed correctly, we can proceed to actual VM installation. The command that start VM installation is drakrun install.

$ drakrun install
Usage: drakrun install [OPTIONS] ISO_PATH

Install guest Virtual Machine

Options:
  --vcpus INTEGER                 Number of vCPUs per single VM  [default: 2]
  --memory INTEGER                Memory per single VM (in MB)  [default:
                                  4096]
  --storage-backend [qcow2|zfs|lvm]
                                  Storage backend type  [default: qcow2]
  --disk-size TEXT                Disk size  [default: 100G]
  --zfs-tank-name TEXT            Tank name (only for ZFS storage backend)
  --lvm-volume-group TEXT         Volume group (only for lvm storage backend)
  --help                          Show this message and exit.

If you want to use defaults and qcow2 storage, download Windows installation ISO file into Dom0 and run:

$ drakrun install ./Win10_22H2.iso

Note

Hint: If you have only 8GB RAM on your system, the default –memory 4096 setting may not fit in the memory and you’ll see “RuntimeError: Failed to launch VM vm-0” with “can’t allocate low memory for domain: Out of memory” message in the logs above it. In this case, provide a smaller value.

If you are struggling with another type of error, check out the /var/log/xen directory for extra logs, especially these ending with vm-0.log.

This command will initialize all necessary configuration files and will create the template VM called vm-0.

Then proceed to Windows installation via VNC client connected to <ip>:5900, with password provided in the message.

Initial configuration turns off the Internet access for the VM to not be bothered with setting up a Microsoft account. We will change that later.

Note

Troubleshooting: If you want to change or restore the VNC password, it is stored in plaintext in /etc/drakrun/install.json file.

Your VNC connection will be terminated after the VM reboots. In this case, just reconnect the VNC client.

If you can’t, check if vm-0 is running using xl list. If you can’t find it there, check the logs in /var/log/xen for possible errors.

When you’re ready to recover the VM: run xl create /var/lib/drakrun/configs/vm-0.cfg to cold boot the VM manually.

After finished installation, log in the user on Windows to the desktop.

Step 2: Making initial snapshot and VMI profile

When VM looks ready, we can make an initial snapshot. To do this, run drakrun postinstall

$ drakrun postinstall

This command will:

  • retrieve VMI kernel information

  • inject drakshell helper agent

  • take the reference snapshot (vm-0)

  • restore the analysis VM (vm-1)

  • retrieve VMI information from other system modules

Don’t worry if you see “FileNotFoundError” in logs, we’ll fix that in further steps.

Modifying Windows VM snapshot

Now, we have freshly installed Windows VM that is almost ready for analysis. In practice, such installation isn’t best environment for executing files because of missing dependencies, pending updates that will execute in the background and so on.

That’s why we want to make another, better reference snapshot. To do this, let’s enable the Internet first.

To do this, change the line net_enable in /etc/drakrun/config.toml from “false” to “true”.

Then we can use drakrun modify-vm0 utility.

$ drakrun modify-vm0
Usage: drakrun modify-vm0 [OPTIONS] COMMAND [ARGS]...

  Modify base VM snapshot (vm-0)

Options:
  --help  Show this message and exit.

Commands:
  begin     Safely restore vm-0 for modification
  commit    Commit changes made during vm-0 modification
  rollback  Rollback changes made during vm-0 modification

Let’s use drakrun modify-vm0 begin for restoring the VM and connect once again to the 5900 port using VNC client.

$ drakrun modify-vm0 begin

At this point you might optionally install additional software. You can execute:

$ drakrun mount /path/to/some-cd.iso

which would mount a virtual CD disk containing additional software into your VM.

Things that are highly recommended to do are:

  • turn off the User Account Control

  • turn off the Windows Defender (be aware that it turns on automatically if you just switch it off in the Control Panel)

  • run Powershell at least once to speed-up its execution

  • install Visual C++ Redistributable in various versions

  • install .NET Framework in various versions

  • generate .NET Framework native image cache e.g. by executing the following commands in the administrative prompt of your VM.

    cd C:\Windows\Microsoft.NET\Framework\v4.0.30319
    ngen.exe executeQueuedItems
    cd C:\Windows\Microsoft.NET\Framework64\v4.0.30319
    ngen.exe executeQueuedItems
    

You can also install Xen PV drivers if you’re experiencing performance issues. However, keep in mind that making such modifications can alter your environment, making it different from a typical user’s setup. This could potentially be exploited by malware as an indicator for sandbox detection.

If your VM is ready to go, run drakrun modify-vm0 commit

$ drakrun modify-vm0 commit

It does similar thing as drakrun postinstall by safely applying your changes onto reference snapshot and recreating VM profile.

If you have any problems and you want to rollback VM to the pre-begin state, use rollback subcommand:

$ drakrun modify-vm0 rollback

Note

Hint: If you want to cold-boot VM-0 that was spinned up via “modify-vm0 begin” e.g. after unexpected shutdown or other exceptional situation, you can use xl create /var/lib/drakrun/configs/vm-0.cfg to boot it up.

These configuration files are generated on VM restore by drakrun.

Checking if Drakvuf works correctly

To ensure that everything works, use drakrun vm-start command to start the vm-1. You can also connect via VNC to the port 5901 to check if the Windows is in correct state.

Then, run drakvuf tool with “procmon” plugin. Drakvuf Sandbox will help you do that by generating a base command-line.

$ drakrun drakvuf-cmdline
drakvuf -o json -F -k 0x1aa002 -r /var/lib/drakrun/profiles/kernel.json -d vm-1 --json-ntdll /var/lib/drakrun/profiles/native_ntdll_profile.json --json-wow /var/lib/drakrun/profiles/wow64_ntdll_profile.json --json-win32k /var/lib/drakrun/profiles/native_win32k_profile.json --json-kernel32 /var/lib/drakrun/profiles/native_kernel32_profile.json --json-wow-kernel32 /var/lib/drakrun/profiles/wow64_kernel32_profile.json --json-tcpip /var/lib/drakrun/profiles/native_tcpip_profile.json --json-sspicli /var/lib/drakrun/profiles/native_sspicli_profile.json --json-kernelbase /var/lib/drakrun/profiles/native_kernelbase_profile.json --json-iphlpapi /var/lib/drakrun/profiles/native_iphlpapi_profile.json --json-mpr /var/lib/drakrun/profiles/native_mpr_profile.json --json-clr /var/lib/drakrun/profiles/native_clr_profile.json
$ $(drakrun drakvuf-cmdline) -a procmon

After running the second command, you should see a stream of JSONs from “procmon” plugin. You can try to run new processes via VNC to check if Windows is responsive and you’re correctly notified about new events.

If you finished, press CTRL-C to interrupt the Drakvuf trace and then destroy the VM using drakrun vm-stop command.

$ drakrun vm-stop

Setting up analysis worker and web UI

An important components of every sandbox are analysis queue, API and dashboard. v0.19.0 comes with Flask-based web application and rq-based worker for running analyses.

If you want to quickly start the whole stack, run these two commands in separate shells:

$ drakrun worker --vm-id 1

$ flask --app drakrun.web.app:app run --with-threads --host 0.0.0.0

The first command starts a worker that executes analyses using Drakvuf. The second command starts a web server on port :5000. Both elements communicate using Redis server that is running by default on localhost:6379.

But you probably see the warnings about “development” server and you suspect that this is not how production setup should be built. Therefore recommended setup is to use the production-ready WSGI server like Gunicorn.

$ pip install gunicorn

$ gunicorn -w 4 drakrun.web.app:app -b 0.0.0.0:5000

Instead of running it in the terminal session, you can create systemd services that will run the web and the worker parts in the background.

Create /etc/systemd/system/drakrun-web.service file (use your virtualenv path instead of /opt/venv)

[Unit]
Description=Drakrun web service
After=network.target

[Service]
Type=simple
ExecStart=/opt/venv/bin/gunicorn -w 4 drakrun.web.app:app -b 0.0.0.0:5000
User=root
Group=root
Restart=on-failure
RestartSec=5
StartLimitInterval=60s
StartLimitBurst=0
WorkingDirectory=/var/lib/drakrun
KillMode=process

[Install]
WantedBy=default.target

You can also adapt the systemd template from Gunicorn documentation

Then create /etc/systemd/system/drakrun-worker@.service file

[Unit]
Description=Drakvuf-Sandbox worker service
After=network.target

[Service]
Type=simple
ExecStart=/opt/venv/bin/drakrun worker --vm-id %i
User=root
Group=root
Restart=on-failure
RestartSec=5
StartLimitInterval=60s
StartLimitBurst=0
WorkingDirectory=/var/lib/drakrun
KillMode=process
TimeoutStopSec=120

[Install]
WantedBy=default.target
$ systemctl daemon-reload
$ systemctl enable drakrun-web
$ systemctl start drakrun-web

$ systemctl enable drakrun-worker@1
$ systemctl start drakrun-worker@1

If you want to run more VMs in parallel, you can also enable and start services drakrun-worker@2, drakrun-worker@3 and so on, depending on the available resources on your machine. Each worker will run analyses on vm-%i, so e.g. drakrun-worker@10 will use vm-10.

Note

You can harden your installation by dropping the permissions of drakrun-web from root to less privileged user.

Just make sure that it has read-write access to /var/lib/drakrun/analyses.

drakrun-worker needs root permissions to work properly

Building from sources

  1. Clone Drakvuf Sandbox repository including submodules

$ git clone --recursive git@github.com:CERT-Polska/drakvuf-sandbox.git
  1. Build and install DRAKVUF from sources just like in Basic installation section.

  2. Install DRAKVUF Sandbox system dependencies

$ apt install tcpdump genisoimage qemu-utils bridge-utils dnsmasq libmagic1
  1. Install additional Web build dependencies

$ apt install nodejs npm
  1. Make and install DRAKVUF Sandbox Python wheel. It’s highly recommended to use virtualenv.

$ python3 -m venv venv
$ source venv/bin/activate
$ cd drakvuf-sandbox
$ make
$ make install
  1. Follow the rest of instructions, starting from Creating initial Windows VM