KVM-based Virtual Machine Instrospection.
This project add virtual machine introspection to the KVM hypervisor to monitor a running virtual machine without a guest agent.
Once the traps are set, the VM will be in a "paused" state and go back to the
hypervisor on every system call.
In details, the traps are working directly at the instruction level, on syscall
and sysret
, which means that you can also stop the VM when the system call
returns from the kernel.
When the VM is "paused", some introspection can be done by reading or writing
into the memory. Therefore it is possible to reconstruct VM state and understand
the system call context
(process name, system call name).
Futhermore, we are able to decode the system call
parameters and display what file is being created (in the case of NtCreateFile
,
for Windows
only).
A hooking API allows you to define callbacks
on top of the system calls you intercept:
def enter_NtCreateFile(syscall):
DesiredAccess = syscall.args[1]
object_attributes = syscall.args[2]
obj = ObjectAttributes(object_attributes, syscall.process)
buffer = obj.ObjectName.Buffer
access = FileAccessMask(DesiredAccess)
syscall.hook = {
'object_name': buffer,
'access': access.rights
}
Resulting in this output:
[
{
"event": {
"cr3": "0x76f9e000",
"vcpu": 0,
"rax": "0x52",
"direction": "enter",
"type": "syscall"
},
"name": "NtCreateFile",
"process": {
"pid": 2344,
"name": "powershell.exe"
},
"hook": {
"object_name": "\\??\\C:\\Program Files\\Windows Sidebar\\Gadgets\\PicturePuzzle.Gadget\\en-US\\gadget.xml",
"access": [
"SYNCHRONIZE",
"GENERIC_READ",
"FILE_READ_ATTRIBUTES"
]
}
},
]
This project is divided into 4 components:
kvm
: linux kernel with vmi patches for KVMqemu
: patched for a fast memory accessnitro
: userland library which receives events, introspects the virtual machine state, and fills the semantic gaplibvmi
: virtual machine instrospection library with unified memory access accrossXen
andKVM
Go to the vagrant/
sub-directory to install a development environement for kvm-vmi
Unfortunately, it is not possible to compile the KVM modules as an out-of-tree
build. You will have to compile and install a new kernel along with the new modules.
- Start by compiling a new kernel in
kvm
- Reboot
- Make sure you loaded the modified kernel module (
make reload
) - Go to
nitro
to setup the userland component and intercept syscalls - Compile the modified version of
qemu
if you intend to analyze syscall events
Based on the work of Jonas Pfoh
: