__ ___        __            
  / // ( )___   / /  ___  ___ _
 / _  /|/(_-<  / /__/ _ \/ _ `/
/_//_/  /___/ /____/\___/\_, / 

Using Volatility Toolkit for malware sample extraction from a memory dump

Sometimes it might happen that you see some signs or simply have a feeling that malware is running on a Windows host (surprising, huh?). Maybe one of the IDSes detected traffic to a known C&C server or maybe HDD is working like crazy but the AV running on the machine doesn't raise any alarm.

You can, of course, RDP to that host or access it directly and begin the investigation but before you'll find out what's going on, malware can remove itself and all the traces of it's activity. In such situation you should consider taking a memory dump from infected host and perform the analysis with no need to rush.

Creating memory dump

First you need to dump the memory to a disk or get the hibernate file which contains a copy of memory. Even if malware will actually remove itself at one point you'll still be able to, in most cases, get the binary and perform analysis. There is a variety of tools which can be used to grab a memory dump. The one I like the most is called Comae Memory Toolkit (previously Moonsols DumpIt), consisiting of two tools, DumpIt and Hibr2Bin. It's fast and easy to use and works even in Windows 10. Unfortunately when it comes to remote execution it becomes problematic. What works however, if you're running Windows, is a combination of mdd and PsExec which is a part of Sysinternals PsTools. If you're a Linux user you can use psexec module in Metasploit Framework instead, or smb-psexec.nse script for Nmap. If you have direct access to investigated machine, run DumpIt from pen drive or a network share.

DumpIt requires administrator's rights. Windows Vista and up will most likely ask you to escalate privileges, on XP you'll have Shift + Right Click and select 'Run As...'. If you're running Windows and want to run mdd remotely, place the PsExec.exe and mdd_1.3.exe (or any other version) in the same directory which is easily accessible from the command line. Remember that username and password will be sent over network in plain text, so it's very easy to capture it by an unauthorized person. To create a memory dump, run the following command:

  C:\Forensic>PsExec.exe \\HOSTNAME_OR_IP -u DOMAIN\privileged_account -p passwd -c mdd_1.3.exe - -o C:\MEMORY.DMP

In Linux you can use Metasploit's psexec module. First start Metasploit:

  $ msfconsole

Next you have to launch the psexec module and set the details:

  msf > use exploit/windows/smb/psexec
  msf exploit(psexec) > set RHOST HOSTNAME_OR_IP
  msf exploit(psexec) > set LHOST YOUR_HOSTNAME_OR_IP
  msf exploit(psexec) > set SMBDomain DOMAIN
  SMBDomain => DOMAIN
  msf exploit(psexec) > set SMBUser privileged_user
  SMBUser => privileged_user
  msf exploit(psexec) > set SMBPass password
  SMBPass => password
  msf_exploit(psexec) > set VERBOSE yes
  VERBOSE => yes

Here it gets a bit tricky. Usually I have a SMB fileshare accessible from investigated machine, on which the mdd executable is stored. In different environment you might have to create such fileshare holding mdd executable, so it can be accessed from the investigated host.

It's time to connect:

  msf exploit(psexec) > exploit

Now we'll get the shell and run mdd:

  meterpreter > shell
  Process 4324 created.
  Channel 1 created.
  Microsoft Windows [Version 5.1.2600]
  (C) Copyright 1985-2001 Microsoft Corp.

  C:\WINDOWS\system32> \\SERVER\share\mdd_1.3.exe -o C:\MEMORY.DMP

When the dump is ready you can fetch the file from \\HOSTNAME_OR_IP\C$\MEMORY.DMP using Windows Explorer (remember that proper access rights are needed) or using smbclient in Linux. Any other method which is possible for and preferred by you will also do.

Analyzing memory dump

Time for the fun part. Volatility is an awesome tool for performing memory forensics. It's free and written in Python which allows it to run well in Windows, MacOS and Linux. In Windows you can either install Python to run Volatility or use a standalone build which already contains required Python binaries with Volatility itself packed into one executable. In Linux you have to install Python (most likely you already have it). Volatility is present in Kali Linux (BackTrack successor) by default. For Gentoo, which I'm running, there's an official ebuild available although it have to be unmasked if you're using a stable branch (for that refer to a proper documentation). When unmasking is done, simply install the toolkit:

  $ emerge -av app-forensics/volatility

Volatility is well documented (Wiki, command reference), there's also a quite nice cheat sheet for it. All options and modules can be also listed with a '--help' switch:

  $ volatility --help

Let's take a sample memory dump from the infected machine. At first it would be nice to identify Windows version and system architecture:

  $ volatility -f /path/to/MEMORY.DMP imageinfo

The above command will return a number of strings. One of them should be similar to the following:

  Suggested Profile(s) : WinXPSP2x86, WinXPSP3x86 (Instantiated with WinXPSP2x86)

Now we know that investigated machine is running Windows XP SP3 (originally SP2, later updated to SP3). The architecture is a good old x86. With that information in hand we can set the profile and location of image file:

  $ export VOLATILITY_LOCATION=file:///path/to/MEMORY.DMP

Thanks to second command we will not have to add the '-f /path/to/MEMORY.DMP' every time we run Volatility. It's time to list all the processes. We are looking for those which are hidden or their name is suspicious.

  $ volatility psxview

No hidden processes here (then we'd see 'False' in pslist or psscan column), couple of entries however look quite interesting:

  Offset(P)  Name                    PID pslist psscan thrdproc pspcdid csrss
  ---------- -------------------- ------ ------ ------ -------- ------- -----
  0x06b3c8c8 kyzu.exe               3284 True   True   False    True    False
  0x06e42968 elazi.exe              5544 True   True   False    True    False

Smells like ZBot. This time we're lucky, we know what we're probably dealing with. Still we don't have a binary and AV doesn't detect the threat. Let's find a parent process(es) for these two:

  $ volatility pstree

The most interesting part of listing:

  Name                                  Pid   PPid   Thds   Hnds Time 
  ---------------------------------- ------ ------ ------ ------ --------------------
   0x86297020:explorer.exe             1384   3444     39    909 2013-05-13 12:51:55
  . 0x86b3c8c8:kyzu.exe                3284   1384      0 ------ 2013-05-13 12:52:04
   0x86e42968:elazi.exe                5544   4696      0 ------ 2013-05-13 12:54:55

As you can see kyzu.exe was executed by explorer.exe, but parent process for elazi.exe was already terminated and no traces are left in memory. Bad news are not over, all those '------' indicate that processes were already paged and we will not be able to simply dump them. Let's check if psscan will find our missing parent for elazi.exe:

  $ volatility psscan

No luck. Nothing here... no parent or other interesting process. Maybe we'll have more luck with network connections?

  $ volatility connscan

Unfortunately not. All the connections are either to local services or Microsoft servers.

There is an awesome plugin available for Volatility. It's called malfind and it looks for code which was injected into a process. Let's run it:

  $ volatility malfind -D /path/to/dump/dir

Command above will dump parts of memory holding processes with injected code into a given directory. When it's done, we can list all the files and sort them by size:

  $ cd /path/to/dump/dir
  $ ls -lS

What's very interesting in here is that one sample with size 245760 Bytes was injected into multiple processes, some of them are listed below:

  -rw-r--r-- 1 h users 245760 05-28 23:59 process.0x86297020.0x11f000.dmp
  -rw-r--r-- 1 h users 245760 05-28 23:59 process.0x86b83b78.0xf30000.dmp
  -rw-r--r-- 1 h users 245760 05-28 23:59 process.0x86b86af8.0xcf0000.dmp
  -rw-r--r-- 1 h users 245760 05-28 23:59 process.0x86ba58a0.0xdf0000.dmp

Let's upload one of these to VirusTotal and... poof. ZBot. Detection ratio: 21/47. Results can be found here.

We confirmed that machine indeed is infected with ZBot. Let's look at the process tree once again and search for memory offsets listed above (as a part of malfind dump names):

   0x86297020:explorer.exe              1384   3444     39    909 2013-05-13 12:51:55
  . 0x86d79898:AcroRd32.exe             1348   1384      0 ------ 2013-05-13 21:25:29
  .. 0x86b83b78:iexplore.exe            3668   1348      2     79 2013-05-13 12:52:04
  . 0x86b86af8:ctfmon.exe               2260   1384      7    129 2013-05-13 12:52:04
  . 0x86ba58a0:rundll32.exe             2708   1384      1     87 2013-05-13 12:52:04

After analysing the tree of all processes in which the injected code was found, it's easy to see which process is the root:

  0x86297020:explorer.exe              1384   3444     39    909 2013-05-13 12:51:55

Unfortunately parent process of explorer.exe (with pid 3444) wasn't found. It indicates that person which wrote the malware did the homework and finding the main process is not going to be easy.

Checking content of registry keys is also possible with Volatility. At first let's find the memory offsets of interested hives:

  $ volatility hivelist

Usually it's good to focus on these:

  0xe6562b60 0x55de5b60 \Device\HarddiskVolume1\Documents and Settings\User\ntuser.dat
  0xe53e2b60 0x3f210b60 \Device\HarddiskVolume1\WINDOWS\system32\config\default
  0xe18e46f0 0x0fd1f6f0 \Device\HarddiskVolume1\WINDOWS\system32\config\software
  0xe18e36f0 0x0fcb66f0 \Device\HarddiskVolume1\WINDOWS\system32\config\SAM
  0xe53e6320 0x23486320 \Device\HarddiskVolume1\WINDOWS\system32\config\SECURITY
  0xe1036758 0x0b20a758 \Device\HarddiskVolume1\WINDOWS\system32\config\system

Depending on hive, you can f.e. look for apps added to one of many autorun keys (there are dozens of pages in the web listing such keys, quite good one can be found here). Let's check one of the most popular locations:

  $ volatility printkey -o 0xe6562b60 -K 'Software\Microsoft\Windows\CurrentVersion\Run'

We're really lucky, double hit!

  REG_SZ Symantec : (S) rundll32 "C:\Documents and Settings\User\Local Settings\Application Data\Mozilla\Symantec\dzhxvn.dll",startThreadW
  REG_SZ Ukywxua : (S) "C:\Documents and Settings\User\Application Data\Ocmu\kyzu.exe"

Second entry is for the already known file kyzu.exe. Now we can fetch the file from infected machine and submit it for analysis to VirusTotal. Most likely it will be the same malware as the one previously extracted using malfind.

The first finding however is something new. After quick digging we find that dzhxvn.dll is a Trojan known as AVKill.

Let's see if we can get that dll from our dump:

  $ volatility dlllist | grep dzhxvn.dll

The force is still with us, Volatility found our dll:

  0x02da0000 0x5e000 C:\Documents and Settings\User\Local Settings\Application Data\Mozilla\Symantec\dzhxvn.dll
  0x02b00000 0x5e000 C:\Documents and Settings\User\Local Settings\Application Data\Mozilla\Symantec\dzhxvn.dll
  0x02170000 0x5e000 C:\Documents and Settings\User\Local Settings\Application Data\Mozilla\Symantec\dzhxvn.dll
  0x10000000 0x5e000 C:\Documents and Settings\User\Local Settings\Application Data\Mozilla\Symantec\dzhxvn.dll

Let's dump it:

  $ volatility dlldump -r dzhxvn.dll -D /path/to/dump/dir

The dll was dumped multiple times because it was allocated in memory more than once. For that dll VirusTotal shows detection score of 3/47 (results are here), from major AVs only Microsoft detects this file as Trojan:Win32/Tracur.AV.

There's one more tool not being a part of Volatility Toolkit which I'd like to mention here. It's called strings and if you're running Linux you have it in your system already. For Windows you can get it as a part of Sysinternals PsTools. It examines any file for ASCII strings. Let's run it on our ZBot sample:

  $ strings process.0x86297020.0x11f0000.dmp > /path/to/output.file

Now open the output file in your favorite text editor. In my ZBot sample I found a very interesting string:

  Coded by BRIAN KREBS for personal use only. I love my job & wife.

Cheers, Brian!


I've covered only one possible way to perform a memory dump analysis which might not always work. Still, it should provide you with a good starting point. Rest I leave to your creativity.