Report an incident
Report an incident

HID simulation for DRAKVUF
20 August 2021 | Jan Gruber | #malware, #tools, #drakvuf

Guest post by our Google Summer of Code student, Jan Gruber
Project proposal: https://summerofcode.withgoogle.com/projects/#6703931754807296

Overview

My project for GSoC 2021 was to realize an undetectable simulation of human behaviour in the VMI-based sandbox DRAKVUF, which resulted in the contribution of a plugin named hidsim - short for "HID (human interface device) simulator".

This plugin enhances DRAKVUF with the ability to inject randomized human-like mouse movements, replay pre-recorded HID-events and perform autonomous button clicks. It achieves that by reconstructing the GUI of Windows systems and looking for new dialogs using a stealthy and thus undetectable VMI-based approach.

If you are interested in using the final work product, jump right to the "How to use hidsim" section.

Main contributions

The main contributions to DRAKVUF's codebase are following pull requests. They introduced the a/m plugin hidsim and a utility named hiddump to capture and store HID-events for later replay. To view the code on GitHub, refer to the following links to the directories containing the source files submitted to DRAKVUF:

During the project, a total of roughly 3200 lines of code and 700 lines of comments were submitted in 10 pull requests:

  1. Major changes
  2. Minor changes

Besides these contributions to DRAKVUF's codebase, several utility tools and PoCs have been created. Here I would like to mention an Ansible role to quickly create a development environment for the work on DRAKVUF - ansible-drakvuf, and the PoC of VMI-based GUI reconstruction on Windows 7 systems named vmi-gui-reconstruction.

Motivation

In order to be a reliable black-box malware analysis system, DRAKVUF has to mitigate the observer effect, which can be utilized to perform anti-sandbox detecting techniques. One way for malware to determine if it is running in a sandbox environment is to query the I/O communication port in order to identify human interaction from HID devices with the system. This technique was modelled within tools like pafish or InviZzzible and was discussed in several research papers like 1 and 2. Existing open-source sandboxes like Cuckoo employed appropriate countermeasures to fool the malware by running code inside the guest VM 3, which uses the WinAPI exposed by user32.dll 4.

DRAKVUF’s engine, which follows the paradigm of being absolutely stealthy 5, did not provide I/O-emulation, although it is desperately needed to further camouflage its sandbox nature. Therefore an I/O-emulation module should be built to simulate a human user sitting in front of the screen and interacting with the system to trick the malware into showing its malicious behavior. This GSoC project aimed therefore, to overcome this caveat by creating a simulation module for DRAKVUF without any code execution inside the analysis guest, which was formulated in the initial project proposal, that can be found here: https://summerofcode.withgoogle.com/projects/#6703931754807296

Chronology of the project

Initial research

The first step was to determine the best method for "injecting" HID-events into the guest. Initial research was performed to determine, whether a VMI-based or a QEMU-based approach best fits the project's needs.

In the course of this, the data structures in Windows' MOUCLASS.sys-driver, which maintains the functionality for all mice/touchpads attached to the system, were investigated. A ring buffer pointed to by MOUCLASS.sys's device extension was identified, which stores device-agnostic mouse movement data 6. The MOUSE_INPUT_DATA stored there, could be manipulated inside the Windows kernel debugger WinDbg to move the mouse. However, to trigger read-operations from this queue-like ring buffer, an interrupt has to be generated. Given the OS dependency, fragility, and complexity of this approach, it did not seem to be an ideal choice.

Other considered options, like creating a kernel module in Xen's dom0, which simulates a supposedly physical device that could be passed through to the guest, or the usage of usbredir and the SPICE protocol were discarded in favor of QEMU's built-in capabilities.

QEMU provides the QEMU machine protocol (QMP) as well as the human monitor protocol (HMP), which is basically a subset of the former, to allow applications to control a QEMU instance by sending commands. While the HMP-approach, which uses command lines, seemed to be rather convenient, it lacks the ability to send absolute mouse positions, which was a hard requirement because relative events are not taken 1-by-1 due to mouse acceleration, so a roundtrip to the guest would have been needed to check the cursor's actual position. However, the QEMU Machine Protocol (QMP) enables a more fine grained control of a QEMU instance by sending JSON-commands (according to RFC 4627) directly to its Unix domain (or TCP) socket. Those commands are specified by the so-called QAPI 7. Several commands allow the sending of HID-events over a QMP-socket to a QEMU instance 8, so that QEMU's handlers update the virtualized HID-devices accordingly. When used in combination with a tablet device, absolute cursor positions can be specified like this as well:

{ "execute": "input-send-event" ,
    "arguments": { "events": [
        { "type": "abs", "data" : { "axis": "x", "value" : 0x4000 } },
        { "type": "abs", "data" : { "axis": "y", "value" : 0x4000 } } ] } }

Since Xen, the hypervisor utilized by DRAKVUF, uses the qemu device model this is an excellent choice to achieve the illusion of a person sitting in front of the sandbox's alleged screen.

Implementation of HID-event injection

After the decision to build upon QMP was made, the implementation was designed as a plugin, which could be compiled conditionally and enabled selectively, if needed. One deviation from other DRAKVUF plugins is that hidsim does not rely on callbacks to do its work but runs concurrently in relation to DRAKVUF's "main loop" and uses a timer-based approach to determine when to send HID-events from the worker-thread to the QMP-socket. The following figure provides a high-level overview of the components of the plugin:

High-level overview of the plugin

The plugin provides three options:

  1. Replay pre-recorded HID-events
  2. Perform random mouse movements
  3. Click on buttons autonomously

Replay of pre-recorded events

One requirement was to be able to replay pre-recorded HID events. To accomplish this, an additional tool named hiddump was created, which serves this purpose. It is a utility program that captures HID events on a Linux system and stores relative and normalized versions of those events in a binary file. It utilizes the input subsystem of the Linux kernel to record HID events. When executed, hiddump reads input_event-structs from one or multiple event files under /dev/input/, which are continuously polled during the recording period. The timing information, which is provided in the form of timeval-structs, is converted to a relative timestamp starting at the beginning of the recording. If the event houses coordinates, then those are mapped to a value range, which QEMU uses in its monitor protocol. After the retrieval and normalization of the events, they are dumped to stdout or sequentially written to a specified file in a simple binary representation. By using the input event format of the Linux input subsystem, the tool builds upon a proven format and a stable interface. For more information about the inner working of hiddump, its usage and the format of HID template files, refer to the readme on Github.

After recording the user-interaction as desired, the resulting file can then serve as a template for sending those recorded HID events to an analysis guest by utilizing the plugin hidsim and specifying the CLI argument --hid-template /path/to/events.bin. How this could look like in practice is shown by the following figure.

Replay of pre-recorded HID-events

Randomized mouse movement

To run hidsim without any parameters but defeat anti-sandbox techniques also, randomized mouse movement was also added. To accomplish this, a random coordinate, which lies within a bounding box of maximum displacement values is drawn from an approximately uniform distribution, and a random time interval is drawn from a gaussian distribution. Afterwards, the cursor is moved smoothly to the target coordinates within the determined timeframe, which results in human-like mouse movements.

GUI-reconstruction and autonomous button clicking

The capability to reconstruct the GUI on the fly was initially not in the scope of the project. After implementing the functionality presented above, this was the next logical step, however. At first, a proof-of-concept had to be created, which resulted in vmi-reconstruct-gui. This is basically a reimplementation of Brendan Dolan-Gavitt's screenshot-plugin for Volatility 9 using libvmi to reconstruct the graphical user interface of a Windows 7-guest running on a Xen hypervisor. So with the help of virtual machine introspection, it is possible to recreate a visual representation of the desktop presented to the user - respectively the basic building blocks of it - as a wireframe model:

Resulting wireframe illustration

For a detailed description of this approach and the considered data structures, refer to the project's readme. Those exploration activities built the base for bringing the GUI reconstruction functionality into DRAKVUF. The hidsim-plugin was extended to set up a trap on the system call NtUSerShowWindow, which is exposed by win32k.sys - the kernel-mode portion of the Windows GUI subsystem 10. By placing this trap, the hidsim-plugin gets notified about updates of the GUI without employing some kind of busy-waiting so that a second thread can start to reconstruct the GUI based on the in-memory data structures and scan for clickable buttons if needed. To sum it up, this is done by retrieving the active desktop and iterating all window stations, then building up a list of windows - tagWND-structs to be more specific - and looking at the top $n$ elements to check if there is a button of interest. If this is the case, the other thread, responsible for generating HID-events, will be notified about the coordinates to click next, which is illustrated in the following figure.

Autonomous button clicking

Closing remarks

To sum it up, the project, scheduled to be 175 hours of work, added the capability to simulate human behaviour in a stealthy and therefore, undetectable way. To incorporate this capability, a new plugin was introduced to DRAKVUF’s codebase, which builds upon QEMU’s machine protocol and enables the user to inject either pre-recorded HID-captures or randomized mouse movements. Additionally, autonomous button clicking could be performed for Windows 7-guests. The main code contributions which enable this functionality have already been sketched out, so in summary, a quick peek into the usage of hidsim is presented below.

How to use hidsim

Firstly, record some HID-events propagated by the specified event files for 30 seconds and saves those events in /tmp/events.bin.

$ sudo ./hiddump -e /dev/input/event16 -e /dev/input/8 -d 30 /tmp/events.bin

Afterwards, replay the HID-events stored in this newly generated file:

$ sudo ./src/drakvuf -r <ISF-file.json> -d <domID> -a hidsim -v \
    --hid-template /tmp/events.bin

Alternatively, run the plugin and inject random mouse movements, use -a hidsim with no further options.

$ sudo ./src/drakvuf -r <ISF-file.json> -d <domID> -a hidsim -v

If you are observing a Window 7-system, you can specify --hid-monitor-gui and supply an approriate intermediate symbol table-file for win32k.sys via -W, which will result in automated button clicks.

$ sudo ./src/drakvuf -r <ISF-file.json> -W <Win32K-ISF-file.json> \
    -d <domID> -a hidsim --hid-monitor-gui

Future work

Despite the fact that hidsim is fully functional, there is still work and research to be done in the area of the simulation of human behaviour. Depending on the use case, the specification of human behaviour in the form of playbooks housing predicates instead of pre-recorded event templates and more options to parametrize the HID-generation could be beneficial. Another goal could be to reconstruct the GUI of new Windows systems, do it in a richer way and be able to determine elements drawn by GUI frameworks. Furthermore, a comparison between a VMI-based and a machine vision-based approach could also be interesting.

Acknowledgements

At last, I would like to thank Michał Leszczyński, Adam Kliś and Hubert Jasudowicz for mentoring, providing feedback and reviewing my code. In addition, I'd like to thank DRAKVUFs creator Tamas Lengyel for his mentoring, feedback and his reviews. I am very appreciative that The Honeynet Project and Google Summer of Code made it possible for me to dive into an open-source project in a domain I am very interested in.

Footnotes

1 Cf. Chailytko, A., & Skuratovich, S. (2017). Defeating sandbox evasion: how to increase the successful emulation rate in your virtual environment. In ShmooCon 2017.

2 Cf. Yokoyama, A., Ishii, K., Tanabe, R., Papa, Y., Yoshioka, K., Matsumoto, T., … & Rossow, C. (2016, September). Sandprint: Fingerprinting malware sandboxes to provide intelligence for sandbox evasion. In International Symposium on Research in Attacks, Intrusions, and Defenses (pp. 165-187). Springer, Cham.

3 Cf. https://www.rapid7.com/blog/post/2013/04/16/fooling-malware-like-a-boss-with-cuckoo-sandbox/

4 See https://github.com/cuckoosandbox/cuckoo/blob/master/cuckoo/data/analyzer/windows/modules/auxiliary/human.py

5 Cf. Lengyel, T. K., Maresca, S., Payne, B. D., Webster, G. D., Vogl, S., & Kiayias, A. (2014, December). Scalability, fidelity and stealth in the drakvuf dynamic malware analysis system. In Proceedings of the 30th Annual Computer Security Applications Conference (pp. 386-395).

6 For background information refer to https://docs.microsoft.com/en-us/windows-hardware/drivers/install/overview-of-device-interface-classes and https://github.com/changeofpace/MouClassInputInjection

7 Cf. https://wiki.qemu.org/Documentation/QMP

8 See https://qemu-project.gitlab.io/qemu/interop/qemu-qmp-ref.html#qapidoc-1526

9 See https://volatility-labs.blogspot.com/2012/10/movp-43-taking-screenshots-from-memory.html and http://moyix.blogspot.com/2009/03/using-volatility-for-introspection.html

10 Cf. Yosifovich, P., Solomon, D. A., & Ionescu, A. (2017). Windows Internals, Part 1: System architecture, processes, threads, memory management, and more. Microsoft Press. p. 50

Share: