Volatility Memory Forensics Framework for Ubuntu

After having obtained a memory image using FireWire (or other methods), I eventually wanted to actually examine what was going on as the image was taken.

Installing Volatility

Volatility is a framework that helps ripping interesting information out of a Windows XP memory dump. Although “strings” and “dd” are good tools, analysing 1GB of binary crap is not really a fun thing to do. Volatility knows how to parse the memory and allows to do fancy stuff on the memory.

Installation of Volatility is a bit weird because it is obviously written for Windows and they hardcode the path of a Windows Python interpreter. Also, their module system is a bit weird, but in fairness works at least alrightish. The application itself is funnily packaged. They don’t really make use of namespaces and depend on modules being locally available.

That made it painful produce a Debian/Ubuntu package, but I made it and you can find it in my PPA. To install volatility through that PPA, you might want to do a:

sudo add-apt-repository ppa:ubuntu-bugs-auftrags-killer/muelli && sudo apt-get update && sudo apt-get install volatility

I think I packaged every available module so that you don’t need to go through 13 stupid^W very helpful but funny pages. You can see the available commands via plugins here:

muelli@xbox:/tmp$ volatility
/usr/lib/pymodules/python2.6/forensics/win32/crashdump.py:31: DeprecationWarning: the sha module is deprecated; use the hashlib module instead
  import sha
*** Unable to load module kernel_hooks: No module named pefile
*** Unable to load module usermode_hooks2: No module named pefile
*** Unable to load module malfind2: No module named pydasm
*** Unable to load module kernel_hooks: No module named pefile
*** Unable to load module usermode_hooks2: No module named pefile
*** Unable to load module malfind2: No module named pydasm

	Volatile Systems Volatility Framework v1.3
	Copyright (C) 2007,2008 Volatile Systems
	Copyright (C) 2007 Komoku, Inc.
	This is free software; see the source for copying conditions.

	usage: volatility cmd [cmd_opts]

	Run command cmd with options cmd_opts
	For help on a specific command, run 'volatility cmd --help'

	Supported Internal Commands:
		connections    	Print list of open connections
		connscan       	Scan for connection objects
		connscan2      	Scan for connection objects (New)
		datetime       	Get date/time information for image
		dlllist        	Print list of loaded dlls for each process
		dmp2raw        	Convert a crash dump to a raw dump
		dmpchk         	Dump crash dump information
		files          	Print list of open files for each process
		hibinfo        	Convert hibernation file to linear raw image
		ident          	Identify image properties
		memdmp         	Dump the addressable memory for a process
		memmap         	Print the memory map
		modscan        	Scan for modules
		modscan2       	Scan for module objects (New)
		modules        	Print list of loaded modules
		procdump       	Dump a process to an executable sample
		pslist         	Print list of running processes
		psscan         	Scan for EPROCESS objects
		psscan2        	Scan for process objects (New)
		raw2dmp        	Convert a raw dump to a crash dump
		regobjkeys     	Print list of open regkeys for each process
		sockets        	Print list of open sockets
		sockscan       	Scan for socket objects
		sockscan2      	Scan for socket objects (New)
		strings        	Match physical offsets to virtual addresses (may take a while, VERY verbose)
		thrdscan       	Scan for ETHREAD objects
		thrdscan2      	Scan for thread objects (New)
		vaddump        	Dump the Vad sections to files
		vadinfo        	Dump the VAD info
		vadwalk        	Walk the vad tree

	Supported Plugin Commands:
		cachedump      	Dump (decrypted) domain hashes from the registry
		cryptoscan     	Find TrueCrypt passphrases
		driverirp      	Print driver IRP function addresses
		driverscan     	Scan for driver objects
		fileobjscan    	Scan for file objects
		getsids        	Print the SIDs owning each process
		hashdump       	Dump (decrypted) LM and NT hashes from the registry
		hivedump       	Dump registry hives to CSV
		hivelist       	Print list of registry hives
		hivescan       	Scan for _CMHIVE objects (registry hives)
		idt            	Print Interrupt Descriptor Table (IDT) entries
		intobjscan     	Scan for interrupt handler registrations
		keyboardbuffer 	Print BIOS keyboard buffer
		lsadump        	Dump (decrypted) LSA secrets from the registry
		memmap_ex_2    	Print the memory map
		moddump        	Dump loaded kernel modules to disk.
		mutantscan     	Scan for mutant (mutex) objects
		objtypescan    	Scan for object type objects
		orphan_threads 	Find kernel threads that don't map back to loaded modules
		printkey       	Print a registry key, and its subkeys and values
		pslist_ex_1    	Print list running processes
		pslist_ex_3    	Print list running processes
		ssdt           	Display SSDT entries
		suspicious     	Find suspicious command lines and display them
		symlinkobjscan 	Scan for symbolic link objects
		thread_queues  	Print message queues for each thread
		usrdmp_ex_2    	Dump the address space for a process

	Example: volatility pslist -f /path/to/my/file

So yeah, some warnings are due to missing dependencies. But it’s all packaged with the exception of pydasm. So if you have enough time at your hands, please do that 😉

If you have another module that you want to have added or if anything doesn’t work, please give me a shout.

Using Volatility

An interesting question might be whether someone has viewed a given picture. We know that the physical address space contains many 4kB sized pages. This is a problem for analysing the memory because we usually expect data to be larger than 4kB and this data is most likely fragmented in physical memory. So extracting a picture from the raw memory dump, while possible would be problematic. Our approach was to create a contiguous dump of a processes virtual memory address space and to search our target image in that memory dump. Fortunately, volatility is already able to dump a process’ virtual memory address space, which leaves us with the admittedly not too hard task of finding and extracting binary data of that picture.

We started by generating a list of running processes from the RAM image to identify the process ID of our target process (firefox in our case):

$ volatility pslist -f memorydump
Name                 Pid    PPid   Thds   Hnds   Time
firefox.exe          2212   2720   22     320    Sat Mar 20 14:33:29 2010

Afterwards, we dump the processes virtual memory, using the PID of that process, into a file. Using this we can start searching for our target picture in the process memory dump:

$ volatility memdmp -p 2212 -f memorydump

If we knew that the picture file that is being searched for was a JPEG and we found that these files have a start and end byte sequence 0xffd8 and 0xffd9 respectively. While this was helpful information we still need to narrow down our search. Using xxd we can take small byte sequences from the body of original picture and search for this sequence in the process’ ID image file. Using this method we are able to find the start of the JPEG picture, in the firefox process memory dump. Here, we can see that the start of the JPEG image marker (0xffd8) occurs at address 0x4e20008 in the image dump:

4e20000: 120e 0200 120e 0200 ffd8 ffe0 0010 4a46  ..............JF
4e20010: 4946 0001 0200 0064 0064 0000 ffec 0011  IF.....d.d......
4e20020: 4475 636b 7900 0100 0400 0000 3c00 00ff  Ducky.......<...

Then from this point forwards in the file, a search for the JPEG end of file byte sequence (0xffd9) gives us the address of the end of the JPEG picture in the memory image file. Here we can see that the JPEG picture ends at address 0x4e40e19:

4e40e00: d5c2 5047 3401 82c7 b75c 5638 2624 461d  ..PG4....\V8&$F.
4e40e10: 4c54 f6b1 3d3c 4b3f ffd9 6500 2800 2700  LT..=<K?..e.(.'.
4e40e20: 7000 7800 2700 2c00 2700 2700 2900 3b00  p.x.'.,.'.'.).;.

Then using dd with a block size of one byte, and knowing the start and end addresses of our picture image obtained above, we can get python to work out the decimal number of bytes to skip into the file and also the decimal number of bytes to count or read from that position.

$ dd if=2212.dmp bs=1 skip=$(python -c 'print 0x4e20008')
         count=$(python -c 'print 0x4e40e20 - 0x4e20008') > recovered.jpg
134674+0 records in
134674+0 records out
134674 bytes (135 kB) copied, 0.812532 s, 166 kB/s

To verify that the picture extracted from RAM is the same as original picture we can get as hash of both files:

$ sha256sum Goofy\ Finger.jpg recovered.jpg
e87db764d0f2baccdd5b68dd0324c31ee2281a787d27de38c48e6e9c300b2349  Goofy Finger.jpg
e87db764d0f2baccdd5b68dd0324c31ee2281a787d27de38c48e6e9c300b2349  recovered.jpg
$ display recovered.jpg

Collecting Password Hashes

For password recovery purposes one might be interested in obtaining the hashed passwords of a running (Windows) system. As a nice side effect, we will gain all existing users on that system. Fortunately, a plugin for volatilty exists which allows dumping the password hashes. The process, however, is a bit cumbersome and could be more automated in the future. We start off finding Registry data in the memory using the hivescan command which will give us the offset of the data in memory. We scan two of these memory locations to make sure that we identify the Security and the System hive whichs addresses we have to remember (in our case 0xe1035b60 and 0xe16bdb60). With these addresses, we run the volatility hashdump tool which happily prints all the password hashes.

$ python volatility hivescan -f memorydump
/tmp/volatility-1.3b/forensics/win32/crashdump.py:31: DeprecationWarning: the sha module is deprecated; use the hashlib module instead
  import sha
Offset          (hex)
58175496        0x377b008
58202976        0x3781b60
63080280        0x3c28758
118954848       0x7171b60
268880736       0x1006cb60
292773896       0x11736008
294130688       0x11881400
414687240       0x18b7a008
421538656       0x19202b60
424552368       0x194e27b0
425945952       0x19636b60
436572168       0x1a059008
705187848       0x2a085008
$ python volatility hivelist -f memorydump  -o 0x377b008
/tmp/volatility-1.3b/forensics/win32/crashdump.py:31: DeprecationWarning: the sha module is deprecated; use the hashlib module instead
  import sha
Address      Name
0xe1e8cb60   \DaS\joe\LS\AD\Microsoft\Windows\UsrClass.dat
0xe261f008   \DaS\joe\NTUSER.DAT
0xe1e65b60   \DaS\LocalService\LS\AD\Microsoft\Windows\UsrClass.dat
0xe1f14008   \DaS\LocalService\NTUSER.DAT
0xe1e797b0   \DaS\NetworkService\LS\AD\Microsoft\Windows\UsrClass.dat
0xe1e03008   \DaS\NetworkService\NTUSER.DAT
0xe1776008   \WINDOWS\system32\config\software
0xe1756400   \WINDOWS\system32\config\default
0xe16e3b60   \WINDOWS\system32\config\SECURITY
0xe16bdb60   \WINDOWS\system32\config\SAM
0xe14b8758   [no name]
0xe1035b60   \WINDOWS\system32\config\system
0xe102e008   [no name]
$ python volatility hivelist -f memorydump  -o 0x1a059008
/tmp/volatility-1.3b/forensics/win32/crashdump.py:31: DeprecationWarning: the sha module is deprecated; use the hashlib module instead
  import sha
Address      Name
0xe1e03008   \Documents and Settings\NetworkService\NTUSER.DAT
0xe1776008   \WINDOWS\system32\config\software
0xe1756400   \WINDOWS\system32\config\default
0xe16e3b60   \WINDOWS\system32\config\SECURITY  <-- Security Hive
0xe16bdb60   \WINDOWS\system32\config\SAM
0xe14b8758   [no name]
0xe1035b60   \WINDOWS\system32\config\system    <-- System Hive
0xe102e008   [no name]
0xe1e8cb60   \DaS\joe\LS\AD\Microsoft\Windows\UsrClass.dat
0xe261f008   \DaS\joe\NTUSER.DAT
0xe1e65b60   \DaS\LocalService\LS\AD\Microsoft\Windows\UsrClass.dat
0xe1f14008   \DaS\LocalService\NTUSER.DAT
0xe1e797b0   \DaS\NetworkService\LS\AD\Microsoft\Windows\UsrClass.dat
$ python volatility hashdump -f memorydump  -y 0xe1035b60 -s 0xe16bdb60
/tmp/volatility-1.3b/forensics/win32/crashdump.py:31: DeprecationWarning: the sha module is deprecated; use the hashlib module instead
  import sha

Having obtained these hashes, one could use, i.e. Ophcrack to recover the password. A web based interface is available and successfully recovered each and every password (i.e.: empty, BLOGGS, MARY123, SMITH, KO*5VUMOWUKGAD). Advanced attacks such as Pass-The-Hash might also be possible.

It would be interesting to know, how to obtain password hashes from a running Linux or Mac system. The technique should be straight forward: Obtain RAM, get your own hash and search for this well known hash in memory. The harder work will then be to identify the data structures in which the hashes are embedded to reliably identify the hash storage for generality.

Creative Commons Attribution-ShareAlike 3.0 Unported
This work by Muelli is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported.