How to implement behavioral analysis in Linux at the hypervisor level

How to implement behavioral analysis in Linux at the hypervisor level

Hello, Habre! My name is Oleksiy Kolesnikov, I work in the malware detection department of the Positive Technologies Expert Security Center (PT Expert Security Center, PT ESC). I recently spoke at the AVAR 2023 international conference in Dubai. He talked about the new plugins developed by PT Expert Security Center for the open source dynamic malware analysis system DRAKVUF, and showed how to use them in the PT Sandbox to detect current threats for Linux.

Below is a mini-review of popular tools for monitoring malicious data in Linux, about the operation of our plugins in DRAKVUF and analysis of VPOs using them.

Linux monitoring tools

Most often, events from the operating system must be collected either to build endpoint detection and response or to analyze VPOs in a sandbox. We will dwell on the second option in more detail, talk about the shortcomings of popular Linux malware monitoring tools.


Auditd — one of the most popular solutions in the community due to a simple installation process, clear syntax, the ability to analyze system calls and file system events. Unfortunately, auditd is not perfect, it has some drawbacks:

  • Lack of a single message format. A program running auditd can send messages in any format. It’s not as convenient as, for example, using JSON exclusively.

  • Events are displayed by ID sequence number. For example, first 645, then 646, and then again 645. This complicates and slows down the work.

  • Low flexibility of rules. Auditd does not allow access to the entire kernel, but only allows you to work with the API. This is inconvenient when there is a need to write something more complex than a system call interceptor.

  • Risk of system compromise. A malicious program, after obtaining root rights, can disable the logging system. In this case, the entire system of analysis will be useless.

inotify and fanotify

There are other Linux IDP monitoring tools. Example, inotify and fanotifybut they are also imperfect. Yes, the inotify_event structure does not allow you to find out complete information about the process: the specialist will receive a message about the event that occurred, but which program initiated it will remain a mystery. As a solution to this problem, the Linux kernel developers suggest using fanotify: the event has a file and process descriptor. However, even this information will not be enough: the name of the program that initiated the security event will remain unknown.


Another tool for building an isolated environment eBPF (Extended Berkley Packer Filter). Today, it is not just a set of packet filters, but a full-fledged virtual machine that allows you to write programs of any complexity in the C programming language – from monitoring network traffic to analyzing system performance and security. Such programs interact using BPF_MAP, which is a common hashmap for programs in user space and kernel space.

eBPF combines the functionality of auditd, inotify and fanotify. With the help of the Linux kprobe mechanism, you can intercept any kernel function, and with the help of uprobe, you can intercept any function from User Space. But even this does not save users from the obvious shortcomings of the tool:

  • hard binding to special BPF functions called helpers;

  • availability of a guarantee for the execution time of the program, which does not allow the use of any cycles except constant ones;

  • the limit of the number of instructions is 4096 for Linux kernel versions up to 5.2 and up to 1 million for newer versions.

What plugins we have made

DRAKVUF is a system of dynamic analysis of malicious files. It works in conjunction with the Xen hypervisor, allowing simultaneous analysis of several machines in an isolated environment. The LibVMI (Virtual Machine Introspection) component is responsible for analyzing the system state. It allows not only to read virtual memory, but also to modify it. This approach makes it possible to safely run malicious code in it.

The DRAKVUF modular system can be improved with the help of various plugins, which allows you to achieve great flexibility when analyzing potentially dangerous code. If the existing plugins are not enough to analyze VPO, you can write them yourself, as we at Positive Technologies have done.


Procmon is a new plugin for DRAKVUF developed by PT Expert Security Center to track the appearance of new processes on a Linux system. To explain the logic of its work, I will remind you how a process is created in the Linux kernel and what information is stored in it.

To run any program in Linux, you need to call one of the functions of the exec family. At the same time, it should be remembered that the execve and execveat system calls do not create a new process, but replace the current instance of the program by replacing the stack, heap, and data segment. The fork and clone calls are responsible for creating independent processes. This is how the creation of a new process looks schematically in Linux:

The running process wants to call the whoami command, for which it calls a system function from the libc library that calls fork. The execve system call occurs only after receiving a new process ID.

To store information about all processes, the Linux kernel uses the task_struct structure – a linked list that allows access to each process in the system. A structure is an abstraction of a process, thanks to which it is possible to obtain the PID (Process ID, process identifier), Parent PID (parent process identifier), information about child processes, short name, and other information about the running process.

Another structure involved in starting the process is called linux_binrpm (Linux Binary Program). It allows you to get a pointer to the file descriptor, the name of the interpreter, and even the fact that the privileges have been elevated. The key difference between this structure and task_struct is its purpose. Linux_binrpm stores information about the process to be started, while task_struct describes a process already running on the system.

The procmon plugin does not intercept the execve system call, but the begin_new_exec function. This is due to the small amount of information about the program running in execve. The body of the begin_new_exec function, in turn, performs the process substitution expected from the execve call. Thus, when intercepting the function at the beginning of the call, we have information about the parent process along with the linux_binprm structure, from which we can get information about the child process, and at the time of exiting the function – information about the new running program.

As an example of how the procmon plugin works, I launched two processes in Ubuntu 20.04 with the Linux 5.15 kernel: uname and whoami. In the ProcessName field – the name launches process, and in ImagePathName – the name is launched process The plugin additionally extracts the command line and other fields from the linux_binprm structure. This information is enough to, for example, build a schedule of processes.


Another plugin for the DRAKVUF system is filetracer. It allows you to capture file system events in Linux. During its development and testing, we encountered the task of automatically determining the version of the Linux kernel. The fact is that the order of parameters in functions has changed after the release of kernel version 5.12. As a solution, we added a special method drakvuf_get_kernel_version to the code, which allows you to find out the current version of the kernel.

As an example of the plug-in, I suggest you consider the handler code for the intercepted do_truncate method. Our method of determining the kernel version, in addition to performing the main task, allows us to control the process of receiving arguments from a function.

As for the logic of the filetrader, it is much simpler than procmon. The result cannot but please: the events have the necessary information about the actions of the program, which allows you to make a verdict about its possible harmful behavior. So, with the help of the plugin, we get the name of the process reading the file, the name of the file and its method, permissions, and its location in the system.

And what else?

I’ve only talked about two plugins that my team and I have developed for DRAKVUF, but there are actually many more. All of them are obviously aimed at obtaining complete information about the operation of malicious software. For example, syscalls – for monitoring system calls, rebootmon – for monitoring reboot events.

In addition, two more plugins are currently in development:

  1. fileextractor – to extract from the virtual machine the files that the sample creates or downloads during operation.

  2. socketmon — to track program activity. This plugin will be a good addition to traffic, because it will allow a specialist to track which process created a particular request.

How our plugins for DRAKVUF analyze malware entering the PT Sandbox

As an example of how plugins work, let’s look at how they detect three families of malware in Linux – XorDDoS, BPFDoor and Mirai. Analyzing malware is not a quick task, so for the sake of demonstration I focused on key features in malware behavior.


One of the main properties of XorDDoS is the fixing of VPO in the temporary directory tmp.

On the left in the picture is the event that captures the tracer file. Here you can see that the analyzed process makes a write system call, but since we are intercepting kernel functions, the vfs_write method writes a file with a random name to tmp. On the right is pseudocode from the decompiler, which demonstrates the fact that the file write function is called. Pinning in tmp is fixed, which means that the VPO has been detected.


A special feature of BPFDoor is the ability to filter network connections by installing a BPF filter on a Linux network socket.

The image on the left shows which event syscalls captures. The plugin allows you to see the name of the process, the method, as well as the string identifiers for the enum values ​​of the SOL_SOCKET and SO_ATTACH_FILTER sockets. On the right – pseudocode, which shows the work of the plug-in according to the VPO detector.


Mirai is a backdoor for spreading botnets. One example of its operation is the implicit execution of the prctl system call with the PR_SET_NAME parameter. Calling prctl allows you to change the name of a process to hide it from the network administrator when he, for example, checks the list of running processes.

To detect such activity, you will need the events of two DRAKVUF plugins – filetracer and syscalls. Therefore, I additionally allocated a function with the help of which the sample VPO writes to the stdout stream.

The event received from the syscalls plugin allows you to see the name of the prctl system call, as well as the PR_SET_NAME parameter. p align=”justify”> The filetracer plugin, in turn, allows you to find out the value of the FileName field – 1, and another value in ThreadName – /var/Sofia. Since all these events are initiated by a single process in the system, they can be correlated with each other by identifiers and conclude that the process was initiated by Mirai.


Therefore, implementing agentless behavioral analysis of IDPs in Linux-based systems is not an easy, but still possible task. The complexity is largely caused by the lack of ready-made solutions that would be completely suitable. Thanks to this approach, we gained a lot of flexibility when analyzing malicious data.

All plugins developed by me and my colleagues from the PT ESC team are available to every DRAKVUF user. The open source tool itself is currently under active development, so anyone can contribute to the community and make Linux VPO analysis more accessible and complete.

Oleksiy Kolesnikov

Specialist of PT ESC malware detection department

More useful articles about our plugins for DRAKVUF and more:

Related posts