Introduction
DRAKVUF® is a virtualization based agentless black-box binary analysis system. DRAKVUF® allows for in-depth execution tracing of arbitrary binaries (including operating systems), all without having to install any special software within the virtual machine used for analysis.
Hardware requirements
DRAKVUF® uses hardware virtualization extensions found in Intel CPUs. You will need an Intel CPU with virtualization support (VT-x) and with Extended Page Tables (EPT). DRAKVUF® is not going to work on any other CPUs (such as AMD) or on Intel CPUs without the required virtualization extensions.
Supported guests
DRAKVUF® currently supports monitoring the following operating systems:
- Windows 7-8, both 32-bit and 64-bit
- Windows 10 64-bit
- Linux 2.6.x - 5.x, both 32-bit and 64-bit
Malware analysis
DRAKVUF® provides a perfect platform for stealthy malware analysis as its footprint is nearly undectebable from the malware's perspective. While DRAKVUF has been mainly developed with malware analysis in mind, it is certainly not limited to that task as it can be used to monitor the execution of arbitrary binaries.
Demos
Using DRAKVUF® to trace Windows internal kernel functions, including heap allocations.
This demo shows the process injection component of DRAKVUF® that can start arbitrary executables within the guest, without the aid of any in-guest helper. In the demo we hijack the execution of the standard Windows Task Manager to initiate the execution of our tasks.
Extracting deleted files from memory before they are actually discarded by the operating system. Many files created by malware droppes are only present in memory and never show up on disk.
Presentations
This is a presentation describing the system at the Annual Computer Security Applications Conference (ACSAC) 2014
This presentation also describes some of the features of DRAKVUF®, which was released at Hacktivity in 2014
Our latest talk at Hacktivity 2016 sheds more light on DRAKVUF®'s internals and recent developments
Current status
Currently the following core features are available:
- Agentless start of binary execution on both Windows and Linux.
- Agentless insertion of files into Windows.
- Agentless monitoring of Windows and Linux internal kernel functions.
- Agentless monitoring of Windows userspace
- Guest multi-vCPU support.
Plugins are also available for Windows to monitor several system aspects, for example:
- Tracing heap allocations.
- Tracing files being accessed.
- Extracting files from memory before they are deleted.
- Tracing UDP and TCP connections
- ... and many more!
There are many opportunities to improve and extend DRAKVUF®. Take a look at our Issues page and also, just to name a few more:
- Automatic submission of extracted files to VirusTotal.
- Integration into malware analysis operations, such as IntelOwl.
As DRAKVUF® is an open-source project, patches and bug reports are always welcome on the Github page! More information can be found in the DRAKVUF® Wiki about working with the project.
Installation guide
UPDATED 12/29/2022 DRAKVUF® now runs best on Xen 4.17
The system has been mainly tested on Ubuntu 22.04 LTS. You can find pre-built debian packages of the latest DRAKVUF builds at https://github.com/tklengyel/drakvuf-builds/releases
To build DRAKVUF® from source the following packages are normally required on Debian/Ubuntu based Linux distros:
sudo 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 libsdl-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 python-dev libsystemd-dev nasm ninja-build llvm lld
Some python packages are unfortunately quite old in Debian so we will install them with Python's pip3 tool:
sudo pip3 install pefile construct
cd ~
git clone https://github.com/tklengyel/drakvuf
cd drakvuf
git submodule update --init
cd xen
./configure --enable-githttp --enable-systemd --enable-ovmf --disable-pvshim
make -j4 dist-xen
make -j4 dist-tools
make -j4 debball
To install Xen with dom0 getting 4GB RAM assigned and two dedicated CPU cores (tune it as preferred):
sudo su
apt-get remove xen* libxen*
dpkg -i dist/xen*.deb
echo "GRUB_CMDLINE_XEN_DEFAULT=\"dom0_mem=4096M,max:4096M dom0_max_vcpus=4 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
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
Also make sure you are running a relatively recent kernel, 5.11+ at least. Older kernels in your dom0 will not work properly!
uname -r
Once you are done with these steps, you can finalize your setup:
sudo reboot
Once you are booted into Xen, verify that everything works as such:
sudo xen-detect
The output should be: Running in PV context on Xen
xl list
The output should be something similar:
Name ID Mem VCPUs State Time(s)
Domain-0 0 4096 2 r----- 614.0
Setup an LVM Volume Group to hold your VMs disks (see this tutorial for help), then create a volume:
lvcreate -L20G -n windows7-sp1 vg
Install Windows 7 from your ISO using the following template (tune it as needed):
arch = 'x86_64'
name = "windows7-sp1"
maxmem = 3000
memory = 3000
vcpus = 2
maxvcpus = 2
builder = "hvm"
boot = "cd"
hap = 1
on_poweroff = "destroy"
on_reboot = "destroy"
on_crash = "destroy"
vnc = 1
vnclisten = "0.0.0.0"
vga = "stdvga"
usb = 1
usbdevice = "tablet"
audio = 1
soundhw = "hda"
viridian = 1
altp2m = 2
shadow_memory = 32
vif = [ 'type=ioemu,model=e1000,bridge=xenbr0' ]
disk = [ 'phy:/dev/vg/windows7-sp1,hda,w', 'file:/path/to/your/windows7.iso,hdc:cdrom,r' ]
Enter the LibVMI folder in and build it:
cd ~/drakvuf/libvmi
autoreconf -vif
./configure --disable-kvm --disable-bareflank --disable-file
make
sudo make install
sudo echo "export LD_LIBRARY_PATH=\$LD_LIBRARY_PATH:/usr/local/lib" >> ~/.bashrc
cd ~/drakvuf/volatility3
python3 ./setup.py build
sudo python3 ./setup.py install
Now we will create the JSON configuration file for the Windows domain. First, we need to get the debug information for the Windows kernel via the LibVMI vmi-win-guid tool. For example, in the following my domain is named windows7-sp1-x86:
$ sudo xl list
Name ID Mem VCPUs State Time(s)
Domain-0 0 4024 4 r----- 848.8
windows7-sp1-x86 7 3000 1 -b---- 94.7
$ sudo vmi-win-guid name windows7-sp1-x86
Windows Kernel found @ 0x2604000
Version: 32-bit Windows 7
PE GUID: 4ce78a09412000
PDB GUID: 684da42a30cc450f81c535b4d18944b12
Kernel filename: ntkrpamp.pdb
Multi-processor with PAE (version 5.0 and higher)
Signature: 17744.
Machine: 332.
# of sections: 22.
# of symbols: 0.
Timestamp: 1290242569.
Characteristics: 290.
Optional header size: 224.
Optional header type: 0x10b
Section 1: .text
Section 2: _PAGELK
Section 3: POOLMI
Section 4: POOLCODE
Section 5: .data
Section 6: ALMOSTRO
Section 7: SPINLOCK
Section 8: PAGE
Section 9: PAGELK
Section 10: PAGEKD
Section 11: PAGEVRFY
Section 12: PAGEHDLS
Section 13: PAGEBGFX
Section 14: PAGEVRFB
Section 15: .edata
Section 16: PAGEDATA
Section 17: PAGEKDD
Section 18: PAGEVRFC
Section 19: PAGEVRFD
Section 20: INIT
Section 21: .rsrc
Section 22: .reloc
The important fields are:
PDB GUID: 684da42a30cc450f81c535b4d18944b12
Kernel filename: ntkrpamp.pdb
If vmi-win-guid fails to find the Windows kernel in memory, you can gather the required information from the VM's disk directly by examining ntoskrnl.exe:
sudo su
kpartx -a /dev/vg/windows7
mount -o ro /dev/mapper/vg-windows7p1 /mnt
python3 tools/pdbguid.py /mnt/Windows/System32/ntoskrnl.exe
umount /mnt
kpartx -d /dev/vg/windows7
Now generate the JSON configuration file (make sure to adjust the kernel name and GUID as necessary):
cd /tmp
python3 ~/drakvuf/volatility3/volatility/framework/symbols/windows/pdbconv.py --guid 684da42a30cc450f81c535b4d18944b12 -p ntkrpamp.pdb -o windows7-sp1.json
sudo mv windows7-sp1.json /root
With this profile ready we can create the LibVMI config:
sudo su
printf "windows7-sp1 {\n\tvolatility_ist = \"/root/windows7-sp1.json\";\n}" >> /etc/libvmi.conf
exit
Test if LibVMI is working by running vmi-process-list:
sudo vmi-process-list windows7-sp1
Output should be something similar:
Process listing for VM windows7-sp1 (id=7)
[ 4] System (struct addr:84aba980)
[ 220] smss.exe (struct addr:85a44020)
[ 300] csrss.exe (struct addr:85f67a68)
[ 336] wininit.exe (struct addr:8601e030)
[ 348] csrss.exe (struct addr:84ba4030)
[ 384] winlogon.exe (struct addr:85966d40)
[ 444] services.exe (struct addr:8614c030)
[ 460] lsass.exe (struct addr:86171030)
[ 468] lsm.exe (struct addr:8617b4f8)
[ 564] svchost.exe (struct addr:861d9bc8)
[ 628] svchost.exe (struct addr:863fb8a8)
[ 816] sppsvc.exe (struct addr:86426838)
[ 856] svchost.exe (struct addr:854abd40)
[ 880] svchost.exe (struct addr:854c5030)
[ 916] svchost.exe (struct addr:854d7a70)
[ 1240] svchost.exe (struct addr:8614cb80)
[ 1280] svchost.exe (struct addr:854f7d40)
[ 1608] spoolsv.exe (struct addr:85578660)
[ 1636] svchost.exe (struct addr:85554af0)
[ 792] SearchIndexer. (struct addr:8562ac08)
[ 1128] taskhost.exe (struct addr:858d9d40)
[ 1524] dwm.exe (struct addr:857f3a60)
[ 1728] explorer.exe (struct addr:858d9180)
[ 1720] regsvr32.exe (struct addr:8605f398)
[ 248] svchost.exe (struct addr:863ed030)
[ 1024] svchost.exe (struct addr:86420390)
[ 256] WmiPrvSE.exe (struct addr:854014a0)
For Linux you need to install the target kernel's debug package (to get the DWARF symbols for the kernel):
ssh root@linux
echo "Kernel version: "$(uname -r)
apt-get install linux-image-$(uname -r)-dbg
exit
We will use the dwarf2json tool to convert the debug information into the required JSON configuration file. Make note of the Kernel version of the target and make sure to update the System.map and vmlinux paths to reflect the correct kernel version:
cd ~/drakvuf/dwarf2json
go build
sudo su
kpartx -a /dev/vg/linux
mount -o ro /dev/mapper/vg-linux1 /mnt
./dwarf2json linux --system-map /mnt/boot/System.map-5.3.0-0.bpo.2-amd64 --elf /mnt/usr/lib/debug/vmlinux-5.3.0-0.bpo.2-amd64 > /root/linux.json
umount /mnt
kpartx -d /dev/vg/linux
printf "linux {\n\tvolatility_ist = \"/root/linux.json\";\n}" >> /etc/libvmi.conf
Now running vmi-process-list should show a similar output:
sudo vmi-process-list linux
Process listing for VM linux (id=29)
[ 0] swapper/0 (struct addr:ffffffff8181a460)
[ 1] systemd (struct addr:ffff88007b3a92b0)
[ 2] kthreadd (struct addr:ffff88007b3a8960)
[ 3] ksoftirqd/0 (struct addr:ffff88007b3a8010)
[ 5] kworker/0:0H (struct addr:ffff88007a8109a0)
[ 6] kworker/u2:0 (struct addr:ffff88007a810050)
[ 7] rcu_sched (struct addr:ffff88007a847330)
[ 8] rcu_bh (struct addr:ffff88007a8469e0)
[ 9] migration/0 (struct addr:ffff88007a846090)
[ 10] watchdog/0 (struct addr:ffff88007a85f370)
[ 11] khelper (struct addr:ffff88007a85ea20)
[ 12] kdevtmpfs (struct addr:ffff88007a85e0d0)
[ 13] netns (struct addr:ffff88007a8d13b0)
[ 14] xenwatch (struct addr:ffff88007a8d0a60)
[ 15] xenbus (struct addr:ffff88007a8d0110)
[ 17] khungtaskd (struct addr:ffff88007a902aa0)
[ 18] writeback (struct addr:ffff88007a902150)
[ 19] ksmd (struct addr:ffff88007a935430)
[ 20] khugepaged (struct addr:ffff88007a934ae0)
[ 21] crypto (struct addr:ffff88007a934190)
[ 22] kintegrityd (struct addr:ffff88007a93f470)
[ 23] bioset (struct addr:ffff88007a93eb20)
[ 24] kblockd (struct addr:ffff88007a93e1d0)
[ 25] kswapd0 (struct addr:ffff8800776d34b0)
[ 26] vmstat (struct addr:ffff8800776d2b60)
[ 27] fsnotify_mark (struct addr:ffff8800776d2210)
[ 33] kthrotld (struct addr:ffff88007770c290)
Now we are ready to build and install DRAKVUF®:
cd ~/drakvuf
meson setup build --native-file llvm.ini
ninja -C build
To simply trace the execution of the system:
sudo ./build/drakvuf -r <path to json config file> -d <domid>
For example:
sudo ./build/drakvuf -r /root/windows7-sp1.json -d 7
To see all available options:
./build/drakvuf --help
Optional: Generate usermode profiles
DRAKVUF® has some enhanced functionality which can be enabled by providing necessary JSON configuration file for particular.dll
or .sys
files. For instance, network monitoring plugin (socketmon) requires the creation of a JSON config file for the tcpip.sys
kernel module, which is normally located at C:\Windows\System32\drivers\tcpip.sys
. You will need to copy this file to where you will be generating the JSON configuration file at. You can generate the JSON configuration file for it similar to how you generated the one for the Windows kernel:
python3 ~/drakvuf/tools/pdbguid.py tcpip.sys
python3 ~/drakvuf/volatility3/volatility/framework/symbols/windows/pdbconv.py --guid abb23d00ee7e4165b6aff66f2df02eb22 -p tcpip.pdb -o tcpip.json
You should provide the path to the JSON configuration file by using DRAKVUF®'s -T
or --json-tcpip
command line option. Type drakvuf --help
in order to display the list of auxilary JSON configuration files that are accepted by DRAKVUF® and the corresponding command line options.
Citation
If you use DRAKVUF® in an academic project, please cite using the following bibtex key:@inproceedings{lengyel2014drakvuf,
author = {Lengyel, Tamas K. and Maresca, Steve and Payne, Bryan D. and Webster, George D. and Vogl, Sebastian and Kiayias, Aggelos},
title = {Scalability, Fidelity and Stealth in the DRAKVUF Dynamic Malware Analysis System},
booktitle = {Proceedings of the 30th Annual Computer Security Applications Conference},
year = {2014}
}
Acknowledgements
The DRAKVUF® project is supported by The Honeynet Project