Friday, May 2, 2014

Volatility and Linux

I have recently had a task at work which required me to preform memory forensics on a Linux virtual machine (VM). I have done a little memory forensics before but mostly on Windows machines. This was a perfect opportunity to take a deeper dive into memory forensics on Linux. You can't talk about memory forensics without Volatility! Volatility is once again written in python and one of my favorite tools. It can be used to analyze memory from Windows,Mac, Linux and Android. Volatility can be found here.

Setup

For this blog, I am using version 2.3.1 of Volatility on Mac running Lion. After downloading Volatility and unpacking it, you can run it simply by running the "python vol.py" or "./vol.py" in the volatility directory. Upon your first run depending on your setup, you may be missing a few python modules. I was missing the crypto which was easily fixed by using "easy_install".

 Volatility uses something called profiles for each type of operating system (os). These profiles tells Volatility how to understand the memory image it is inspecting. For Windows most of these profiles are pre-built into Volatility making Windows analysis setup pretty easy. However we are looking to analysis a Linux system so we need to build a profile. For this example, we are going to analysis a 64 bit Fedora 16 VM running 3.6.11-4.fc16.x86_64 kernel.

 To create a profile you must obtain two files from the machine you are looking to analyze: the System.map file, and a “module.dwarf” file. Obtaining the System.map file is as easy as navigating to the “/boot” directory and copying it. The “module.dwarf” file requires a few extra steps. First you must install the dwarf library. On Fedora this is done by using “yum install libdwarf-tools”. Once libdwarf is install you need to put a copy of volatility onto the Fedora machine. Unpack volatility and navigate to the “volatility-2.3.1/tools/linux” directory and execute “make.” This will build a module.dwarf file for this version of Fedora. Copy this file off the Fedora VM and combine it with the System.map file in a zip bundle. The name of the zip bundle does not make a difference to volatility, however you will want to name it something descriptive, like fedora16profile.zip. This zip file needs to be placed in “volatility/plugins/overlays/linux/fedora16profile.zip”

 With a profile created, it is now possible to analyze memory from this Fedora machine. There are several ways to pull a memory images from a VM, however it is easiest, in my opinion, to analysis the “.mem” file created when a VM is in a suspended state. So first lets suspend the VM so volatility can be run on the “.vmem” file.

The first step is to ensure the profile created is loading into volatility, and volatility associates this profile with the image. Technically volatility should auto detect which type of profile to use, however in order to avoid confusion and other issues, the specific profile can be specified. If the help function can be loaded while specifying the profile without error, this is a very good indicator that everything is functioning properly.

 First we need to determine what the name of the profile is that was just created according to volatility. This can be done using the "--info" option. As seen in the output below Volatility will print out all the profiles it is aware of. If the profile you just created does not exist in the list, you probably have your zip profile in the wrong directory or the wrong files in the zip package.

python vol.py -f Fedora-64.vmem --info                                                                                          
Volatility Foundation Volatility Framework 2.3.1

...

Profiles
--------
Linuxfedora16profilex64 - A Profile for Linux fedora16profile x64
VistaSP0x64             - A Profile for Windows Vista SP0 x64
VistaSP0x86             - A Profile for Windows Vista SP0 x86
VistaSP1x64             - A Profile for Windows Vista SP1 x64
VistaSP1x86             - A Profile for Windows Vista SP1 x86
VistaSP2x64             - A Profile for Windows Vista SP2 x64
VistaSP2x86             - A Profile for Windows Vista SP2 x86
Win2003SP0x86           - A Profile for Windows 2003 SP0 x86
Win2003SP1x64           - A Profile for Windows 2003 SP1 x64
Win2003SP1x86           - A Profile for Windows 2003 SP1 x86
Win2003SP2x64           - A Profile for Windows 2003 SP2 x64
Win2003SP2x86           - A Profile for Windows 2003 SP2 x86
Win2008R2SP0x64         - A Profile for Windows 2008 R2 SP0 x64
Win2008R2SP1x64         - A Profile for Windows 2008 R2 SP1 x64
Win2008SP1x64           - A Profile for Windows 2008 SP1 x64
Win2008SP1x86           - A Profile for Windows 2008 SP1 x86
Win2008SP2x64           - A Profile for Windows 2008 SP2 x64
Win2008SP2x86           - A Profile for Windows 2008 SP2 x86
Win7SP0x64              - A Profile for Windows 7 SP0 x64
Win7SP0x86              - A Profile for Windows 7 SP0 x86
Win7SP1x64              - A Profile for Windows 7 SP1 x64
Win7SP1x86              - A Profile for Windows 7 SP1 x86
WinXPSP1x64             - A Profile for Windows XP SP1 x64
WinXPSP2x64             - A Profile for Windows XP SP2 x64
WinXPSP2x86             - A Profile for Windows XP SP2 x86
WinXPSP3x86             - A Profile for Windows XP SP3 x86
...
In the output below you will notice we are passing the “.vmem” file from the virtual machine using the “ –f ” option along with specifying the profile using the “--profile” option and “–h” for the man page.

python vol.py -f Fedora-64.vmem --profile=Linuxfedora16profilex64 -h   
                                                          
Volatility Foundation Volatility Framework 2.3.1
Usage: Volatility - A memory forensics analysis platform.

Options:
  -h, --help            list all available options and their default values.
                        Default values may be set in the configuration file
                        (/etc/volatilityrc)
  --conf-file=/Users/mckeed/.volatilityrc
                        User based configuration file
  -d, --debug           Debug volatility
  --plugins=PLUGINS     Additional plugin directories to use (colon separated)
  --info                Print information about all registered objects
  --cache-directory=/Users/mckeed/.cache/volatility
                        Directory where cache files are stored
  --cache               Use caching
  --tz=TZ               Sets the timezone for displaying timestamps
  -f FILENAME, --filename=FILENAME
                        Filename to use when opening an image
  --profile=Linuxfedora16profilex64
                        Name of the profile to load

This demonstrates that the profile is working correctly. Notice help only listed the functions dealing with Linux. This is because volatility recognizes the image as a Linux image and doesn't show you incompatible plugins. Now that we have everything setup, it is time to analyze some memory!

 Using Volatility

  Volatility has a lot of features and plugins, I am only going to demonstrate a few of the most common and ones that I recently used. First is pslist. This a rather important plugin since as I recently discovered many other plugins rely on it. "pslist" shows a list of the running processes in memory with there pid and memory offset. Many other plugins need the PID to preform there task even when supplied by the user, the output of pslist is still referenced. Depending on the size of the memory image, this can take some time to run. Below is an example of the output from pslist. I am only showing a small sample of the output.
python vol.py -f Fedora-64.vmem --profile=Linuxfedora16profilex64 linux_pslist ─┘

Volatility Foundation Volatility Framework 2.3.1
Offset             Name                 Pid             Uid             Gid    DTB                Start Time
------------------ -------------------- --------------- --------------- ------ ------------------ ----------
...
0xffff88003a3c9720 auditd               804             0               0      0x0000000036742000 
0xffff88003af94560 abrtd                818             0               0      0x0000000039ee2000 
0xffff88003af92e40 abrt-dump-oops       819             0               0      0x000000003cdb4000 
0xffff88003aa91720 audispd              823             0               0      0x000000003aaaa000 
0xffff88003aa92e40 atd                  824             0               0      0x000000003cf88000 
0xffff88003aa94560 NetworkManager       825             0               0      0x000000003cf89000 
0xffff88003ab54560 avahi-daemon         830             70              70     0x000000003ae1e000 
0xffff88003c390000 sedispatch           831             0               0      0x000000003ae76000 
0xffff88003c392e40 system-setup-ke      833             0               0      0x000000003ae75000 
0xffff88003ad68000 systemd-logind       836             0               0      0x000000003ae72000 
0xffff88003ad6c560 mcelog               839             0               0      0x000000003ae7d000 
0xffff880039dec560 crond                848             0               0      0x000000003cf39000 
0xffff88003ab52e40 rsyslogd             861             0               0      0x000000003cb81000 
0xffff8800364b5c80 dbus-daemon          864             81              81     0x000000003afd1000 
0xffff88003676c560 acpid                867             0               0      0x000000003cb80000 
0xffff880036fe2e40 rpc.idmapd           887             0               0      0x000000003bc71000 
0xffff88003ad69720 avahi-daemon         907             70              70     0x000000003ae48000 
0xffff880039dedc80 polkitd              946             0               0      0x0000000039e1e000 
0xffff88003b612e40 modem-manager        950             0               0      0x000000003af7e000 
0xffff88003aa2c560 sshd                 955             0               0      0x000000003abf1000 
0xffff88003a235c80 rpcbind              961             0               0      0x000000003ab9f000 
0xffff88003a234560 rpc.statd            980             29              29     0x000000003ab99000 
0xffff88003af90000 sendmail             1204            51              51     0x000000003b8b7000 
0xffff880039de9720 vmware-vmblock-      1209            0               0      0x000000003abbc000 
0xffff880036769720 vmtoolsd             1229            0               0      0x000000003995b000 
0xffff88003a231720 gdm-binary           1261            0               0      0x000000003a627000 
0xffff88003aa29720 gdm-simple-slav      1303            0               0      0x000000003991f000 
0xffff88003af91720 Xorg                 1328            0               0      0x000000003be73000 
...

Lets study a process further. For this I will choose to look at "vmtoolsd" or process 1229. What libraries has this process loaded into memory? In order to check this we can use a plugin in volatility called "linux_proc_map". This plugin shows all the libraries loaded into memory and where they are located. See a sample of the output below. Notice I am using the pid to grep for all results associated with "vmtoolsd"

python vol.py -f Fedora-64.vmem --profile=Linuxfedora16profilex64 linux_proc_maps | grep 1229 

Pid      Start              End                Flags               Pgoff Major  Minor  Inode      File Path                                                                       
-------- ------------------ ------------------ ------ ------------------ ------ ------ ---------- ---------------------------------------
...

0-    1229 0x0000000000400000 0x0000000000494000 r-x                   0x0    253      1     552735 /usr/lib/vmware-tools/sbin64/vmtoolsd                                           
179-    1229 0x0000000000693000 0x00000000006a8000 r--               0x93000    253      1     552735 /usr/lib/vmware-tools/sbin64/vmtoolsd                                           
358-    1229 0x00000000006a8000 0x00000000006b0000 rw-               0xa8000    253      1     552735 /usr/lib/vmware-tools/sbin64/vmtoolsd                                           
537-    1229 0x00000000006b0000 0x00000000006b3000 rw-                   0x0      0      0          0                                                                                 
716:    1229 0x00000000014d5000 0x000000000153a000 rw-                   0x0      0      0          0 [heap]                                                                          
895-    1229 0x0000003250800000 0x0000003250822000 r-x                   0x0    253      1     935190 /lib64/ld-2.14.90.so                                                            
1074-    1229 0x0000003250a21000 0x0000003250a22000 r--               0x21000    253      1     935190 /lib64/ld-2.14.90.so                                                            
1253-    1229 0x0000003250a22000 0x0000003250a23000 rw-               0x22000    253      1     935190 /lib64/ld-2.14.90.so                                                            
1432-    1229 0x0000003250a23000 0x0000003250a24000 rw-                   0x0      0      0          0                                                                                 
1611-    1229 0x0000003250c00000 0x0000003250dad000 r-x                   0x0    253      1     935191 /lib64/libc-2.14.90.so                                                          
1790-    1229 0x0000003250dad000 0x0000003250fad000 ---              0x1ad000    253      1     935191 /lib64/libc-2.14.90.so                                                          
1969-    1229 0x0000003250fad000 0x0000003250fb1000 r--              0x1ad000    253      1     935191 /lib64/libc-2.14.90.so  
...

Lets take a look at what is on the heap of "vmtoolsd". In order to accomplish this we will need to dump the memory at the address provided by "linux_proc_maps". Volatility has another plugin called "linux_dump_map" which will dump a segment of memory. Memory can be dump either by address or by process. You also must specify a directory to dump too. Since I am only interested in a specific section I am going to dump via address using the "-s" flag.
 
python vol.py -f Fedora-64.vmem --profile=Linuxfedora16profilex64 linux_dump_map -s 0x00000000014d5000 0x000000000153a000  --dump-dir dump 
 
Volatility Foundation Volatility Framework 2.3.1
Task       VM Start           VM End                         Length Path
---------- ------------------ ------------------ ------------------ ----
      1229 0x00000000014d5000 0x000000000153a000            0x65000 dump/task.1229.0x14d5000.vma

Now that we have a memory file to analyze, we can preform any number of forensic techniques. Since there is no specific goal defined here I like to start with a basic strings. When you start to look at the strings output you will notice alot of filenames and paths. What caught my attention while writing this blog was there are alot of file paths that have the same last section. For example "gltext","deco","cubestorm" and my personal favorite "starwars". When I went back and booted the VM, none of these paths actually existed.

strings task.1229.0x14d5000.vma| grep starwars                                                                                   ─┘
/usr/libexec/xscreensaver/starwars
/usr/local/bin/starwars
/usr/bin/starwars
/bin/starwars
/usr/local/sbin/starwars
/usr/sbin/starwars
/sbin/starwars
/home/user/.local/bin/starwars
/home/user/bin/starwars
/usr/libexec/xscreensaver/starwars
/usr/local/bin/starwars
/usr/bin/starwars
/bin/starwars
/usr/local/sbin/starwars
/usr/sbin/starwars
/sbin/starwars
/home/user/.local/bin/starwars
/home/user/bin/starwars
I have no idea why this is here or what this is about, if anyone has more information please comment or send me and email. I will research this and update the post if I come across an explanation. That is the basics of volatility on Linux in a nut shell. Please comment with any questions.