Malware analysis with VM instrumentation, WMI, winexe, Volatility and Metabrik

In this article, we will show how to take advantage of Metabrik to automate some malware analysis tasks. The goal will be to execute a malware in a virtual machine (VM), just after you saved a snapshot of Windows operating system. In our example, this snapshot only includes running processes, but you will see you can do more than just that. Here, we introduce remote::wmi, remote::winexe and system::virtualbox Briks.

We will also introduce the forensic::volatility Brik which can help you perform dynamic malware analysis and extract IOCs, for instance.

Tip: you can use <tab> keystroke to complete Brik names and Commands while using The Metabrik Shell.

Setting up the environment

wmic and winexe are programs that have to be compiled by yourself. Fortunately, Metabrik makes this process as easy as running the install Command. Since wmic and winexe programs ship with the same software suite, you just have to run install Command for one of remote::wmi or remote::winexe Briks. We don’t run the install Command with system::virtualbox Brik, because we suppose you already have some VitualBox VMs installed.

use brik::tool
use remote::wmi
use remote::winexe
use forensic::volatility
help remote::wmi
help remote::winexe
help forensic::volatility
run brik::tool install_needed_packages remote::wmi
run brik::tool install_needed_packages remote::volatility


Your VM also has to be configured to allow WMI accesses for a given user, and have the WINEXESVC service started. Some help on how to do that can be found in remote::wmi and remote::winexe Briks source code.

Starting a VM and taking a snapshot

Our environment is up and running. Let’s start a VM and take a snapshot before we execute a malware within it remotely. For the purpose of this exercise, the malware will simply be calc.exe program.

use system::virtualbox
help system::virtualbox
run system::virtualbox list


Let’s start our Windows machine in headless mode: we don’t want to speak with this kind of GUI.

set system::virtualbox type headless
run system::virtualbox start 602782ec-40c0-42ba-ad63-4e56a8bd5657
run system::virtualbox snapshot_live 602782ec-40c0-42ba-ad63-4e56a8bd5657 "before calc.exe"



I know the IP address of the machine, but you could have found it by using ARP scanning on vboxnet0 interface thanks to the network::arp Brik.

my $win = ''
my $user = 'Administrator'
my $password = 'YOUR_SECRET'
set remote::wmi host $win
set remote::wmi user $user
set remote::wmi password $password
set remote::winexe host $win
set remote::winexe user $user
set remote::winexe password $password
run remote::wmi get_win32_process
for (@$RUN) {
print $_->{Name}."\n";

You should see no calc.exe right now.


Now, launch the calc.exe program and search in the process list if you can find it. Note that you will have to run Ctrl+C keystrokes because the program will block here. But calc.exe should still be running on the remote host.

run remote::winexe execute "cmd.exe /c calc.exe"
run remote::wmi get_win32_process
my @processes = map { $_->{Name} } @$RUN
my $found = grep { /calc.exe/ } @processes

In the below screenshot, you will see 2 as a result to the grep command. That’s because we ran two times the execute Command with calc.exe during our testing.


Now, we will restore the VM to its default state, when calc.exe “malware” was not yet run.

run system::virtualbox stop 602782ec-40c0-42ba-ad63-4e56a8bd5657
run system::virtualbox snapshot_restore 602782ec-40c0-42ba-ad63-4e56a8bd5657 "before calc.exe"
run system::virtualbox start 602782ec-40c0-42ba-ad63-4e56a8bd5657
run remote::wmi get_win32_process
my @processes = map { $_->{Name} } @$RUN
my $found = grep { /calc.exe/ } @processes

All clear. No more calc.exe process.

You spoke about Volatility?

Yes. And that’s where it starts to get interesting. You can do the same processes analysis with Volatility (and of course much more). To use Volatility, you need a dump of the system’s memory. To acquire this dump, it’s as simple as using the system::virtualbox dumpguestcore Command. Then, you have to extract the memory dump that is part of the generated core file. You will use the extract_memdump_from_dumpguestcore Command.

Then, you will be able to perform forensic stuff on this memory dump, for instance to search if calc.exe has been popped. If you go back to the original subject -malware analysis-, you will find the Volatility is the tool of choice to check what a malware you just run with remote::winexe Brik did to processes, network handles or registry. That’s a perfect combination of tools to extract IOCs from a malware.

run system::virtualbox dumpguestcore 602782ec-40c0-42ba-ad63-4e56a8bd5657 dump.core
run system::virtualbox extract_memdump_from_dumpguestcore dump.core dump.volatility



EDIT: on some versions of VirtualBox, you will have to use the dumpvmcore Command instead of dumguestcore.

We have a dump usable by Volatility. Let’s dig into it with forensic::volatility Brik:

use forensic::volatility
set forensic::volatility input dump.volatility
run forensic::volatility imageinfo
set forensic::volatility profile $RUN->[0]
run forensic::volatility pslist



And voilà.

A feature of WINEXESVC: get a remote shell on Windows

One last screenshot in regards to remote::winexe Brik: how to get a Windows remote shell:

run remote::winexe execute cmd.exe



We have seen that we can easily perform malware analysis on a Windows machine by using a combination of Briks. By combining features of different tools (VirtualBox, winexe and Volatility) we can, for instance, analyse consequences of running a malware on a machine. Extracting IOCs from a malware is something useful if you want to find which machines were infected on your information systems from a particuliar sample. You could then use remote::wmi Brik to scan your network for these specific patterns.

Extracting IOCs is a huge topic in itself, and we just scratched the surface here by using a dynamic method associated with a “scapegoat” VM. Another way of extracting IOCs is to use static analysis, but that’s a complete different story.

We urge you to play with Volatility (and of course Metabrik), you will see how powerful it could be. Enjoy.

Solving a forensic challenge with Metabrik and Scalpel

I recently discovered the wonderful world of forensic and challenges (read: today). So I decided to add some new Briks just to solve some of them. Let’s dig into the “Find the dog” challenge step-by-step. I will also show how I improved the Scalpel tool by wrapping it with other Briks.

Getting the files

The one from this Metabrik Example is called “Find the dog“, or “Trouvez le chien” in French. Once downloaded and extracted, you got these files:

cd /home/gomor/hgwork/metabrik/challenges/trouvez-le-chien/
my $files = $RUN

First things to do is to check for MIME types of these files. You can also check for the MAGIC types:

use file::type
run file::type get_mime_type $files
run file::type get_magic_type $files

You have a txt file (you should read it for the story behind the dog theft) and a gzip file. Let’s uncompress this one:

use file::compress
run file::compress uncompress $files->[0]
my $file = $RUN
run file::type get_mime_type $file
run file::type get_magic_type $file

Wonderful. It appears to be some kind of filesystem. Let’s analyse that with Scalpel, a filesystem image forensic tool written in Python.

Introducing Scalpel

To use Scalpel, you usually have to create a scalpel.conf file containing metadata on how to extract (or carve) files. For instance, if you want to find and extract ZIP files, you search for the string PK\x03\x04 in a bytestream.

If you want to only check for some files (say odt files), you have to comment out all the lines from that conf file, except the one for odt documents. If you want to search for all file formats, you have to uncomment all the lines. That is the first thing I changed when writing the forensic::scalpel Brik: use a Command to help you generate the configuration file with only what you want to search for.

The other limitation of the tool is its inability to identify extracted files using the libmagic (check for MIME types or MAGIC types). Thus, I added this feature within forensic::scalpel Brik to just do that: separate verified files from unverified ones.

So, let’s dig into this new Brik. It is made upon 4 existing Briks: shell::command, file::find, file::text and of course the file::type one. As you can see, new Briks can be written with already existing Briks.

We will use it to extract files from the challenge (remember, you have to find where is the dog). Because I already know the result (spoiler), I will only search for odt files from the filesystem image challenge:

use forensic::scalpel
run forensic::scalpel generate_conf "[ 'odt' ]"
run forensic::scalpel scan $file
my $verified = $RUN->{verified}

We just wanted to keep verified files. Yes, the ones that went through the file::type Brik and its MIME type identification. Read: the feature lacking from Scalpel.

We now have two odt files, let’s open them with LibreOffice (exercise for the reader).

my $files = join(' ', @$verified)
libreoffice $files

You have a picture of a dog, and a message saying: “Free Britany, or we kill the dog“. We must locate those miscreants. This is a picture, is there some EXIF metadata? Use the image::exif Brik to discover. But first, we have to extract this picture. odt files are simple ZIP files, we use the file::compress Brik again:

run file::compress uncompress $verified->[0]
my $pic = './Pictures/1000000000000CC0000009XXXXXXXXXX.jpg'
run file::type get_mime_type $pic

use image::exif
run image::exif get_metadata $pic


Lots of metadata. But more interestingly, you have the latitude and longitude of the camera which took the picture. Bingo. Sarge, we found the evil doers, let’s go catch them now. Over.


By using a few Briks, we have shown how to solve a simple challenge. As you can see, you can nearly automate it from the beginning to the end. Exercise yourself with Metabrik by downloading the docker image. Enjoy.

EDIT 2015/12/17: some Commands have moved from system::file to file::type, thus some Commands have been renamed in this post, but screen captures remain the same as before.