DRAKVUF™

Black-box Binary Analysis System

View on GitHub Wiki Documentation Download as .tar.gz

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.

Coverity Scan Build Status

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:

Can I run DRAKVUF in a nested hypervisor?

Yes! It is possible to install Xen and DRAKVUF in a Virtual Machine where hardware-assisted nested virtualization is enabled. On Xen you can enable nested virtualization with 'nestedhvm=1' in your domain configuration.

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:

Plugins are also available for Windows to monitor several system aspects:

There are many opportunities to improve and extend DRAKVUF. Take a look at our Issues page and also, just to name a few more:

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 7/10/2017 DRAKVUF now requires Xen 4.9. Please pay attention to the updated VM configuration specifying the altp2m option for a domain.

The following packages are normally required to build Xen and DRAKVUF on Debian based Linux distros. The system has been mainly tested on Debian Jessie and Ubuntu 14.04 LTS.

sudo apt-get install wget git bcc bin86 gawk bridge-utils iproute libcurl3 libcurl4-openssl-dev bzip2 pciutils-dev build-essential make gcc clang libc6-dev libc6-dev-i386 linux-libc-dev zlib1g-dev python-dev python-pip 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 check libjson-c-dev libfuse-dev checkpolicy liblzma-dev autoconf-archive
We will be installing a slightly modified version of Xen 4.8 that includes a built-in XSM policy required for DRAKVUF.
cd ~
git clone https://github.com/tklengyel/drakvuf
cd drakvuf
git submodule init
git submodule update
cd xen
./configure --enable-githttp
make -j4 dist-xen
make -j4 dist-tools
To install Xen with dom0 getting 4GB RAM assigned and two dedicated CPU cores (tune it as preferred):
sudo su
make -j4 install-xen
make -j4 install-tools
echo "GRUB_CMDLINE_XEN_DEFAULT=\"dom0_mem=4096M,max:4096M dom0_max_vcpus=4 dom0_vcpus_pin=true hap_1gb=false hap_2mb=false altp2m=1 flask_enforcing=1\"" >> /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
update-rc.d xencommons defaults 19 18
update-rc.d xendomains defaults 21 20
update-rc.d xen-watchdog defaults 22 23
Once you are done with these steps, you can finalize your setup:
update-grub
reboot

Also make sure you are running a relatively recent kernel (anything above 3.8 should just work).

uname -r
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 v4.7
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
maxcpus = 2
builder = "hvm"
boot = "cd"
hap = 1
acpi = 1
on_poweroff = "destroy"
on_reboot = "destroy"
on_crash = "destroy"
vnc=1
vnclisten="0.0.0.0"
usb = 1
usbdevice = "tablet"
altp2m = 2
shadow_memory = 16
audio=1
soundhw='hda'
vif = [ 'type=ioemu,model=e1000,bridge=xenbr0,mac=00:06:5B:BA:7C:01' ]
disk = [ 'phy:/dev/vg/windows7-sp1,hda,w', 'file:/path/to/your/windows7.iso,hdc:cdrom,r' ]
Enter the LibVMI folder in the drakvuf folder and build it:
cd ~/drakvuf/libvmi
./autogen.sh
./configure --disable-kvm
Make sure the output is like the following:
Feature         | Option
----------------|---------------------------
Xen Support     | --enable-xen=yes
KVM Support     | --enable-kvm=no
File Support    | --enable-file=yes
Shm-snapshot    | --enable-shm-snapshot=no
Rekall profiles | --enable-rekall-profiles=yes
----------------|---------------------------

OS              | Option
----------------|---------------------------
Windows         | --enable-windows=yes
Linux           | --enable-linux=yes


Tools           | Option                    | Reason
----------------|---------------------------|----------------------------
Examples        | --enable-examples=yes
VMIFS           | --enable-vmifs=yes        | yes
Build and install LibVMI:
make
sudo make install
sudo echo "export LD_LIBRARY_PATH=\$LD_LIBRARY_PATH:/usr/local/lib" >> ~/.bashrc
Build and install Rekall. Note that Rekall doesn't necessarily have to be installed on the same machine where DRAKVUF is as it is not used during runtime. Setup steps:
cd ~/drakvuf/rekall/rekall-core
sudo pip install setuptools
python setup.py build
sudo python setup.py install
Now we will create the Rekall profile 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
Now generate the Rekall profile:
cd /tmp
rekall fetch_pdb ntkrpamp 684da42a30cc450f81c535b4d18944b12
rekall parse_pdb ntkrpamp > windows7-sp1.rekall.json
sudo mv windows7-sp1.rekall.json /root
With this profile ready we can create the LibVMI config:
sudo su
printf "windows7-sp1 { \n\
    ostype = \"Windows\"; \n\
    rekall_profile = \"/root/windows7-sp1.rekall.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-x86 (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 build the initial kernel profile in the guest itself.
ssh [email protected]
apt-get install git zip linux-headers-$(uname -r) build-essential
git clone --depth=1 https://github.com/google/rekall
cd rekall/tools/linux
make
This will generate a ZIP file with your kernel-version as filename. For example, 3.16.0-4-amd64.zip. Copy this file to your DRAKVUF host (for example using scp). There we will convert it to the proper JSON Rekall profile.
rekal convert_profile 3.16.0-4-amd64.zip /root/linux.json
sudo printf "linux { \n\
    ostype = \"Linux\"; \n\
    rekall_profile = \"/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
autoreconf -vi
./configure
make
To simply trace the execution of the system:
sudo ./src/drakvuf -r <rekall profile> -d <domid>
For example:
sudo ./src/drakvuf -r /root/windows7-sp1.rekall.json -d 7
To see all available options:
./src/drakvuf

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}
}