I recently gave a presentation at A2Y.asm called "Rekalling a Volatile Past; A brief introduction to memory forensics". This blog post is a written version of the presentation. It does not contain the demo presented, which will be in a later blog post, and it does not discuss how to collect the memory dumps.
The presentation can be found here
What is memory forensics
Memory forensics is a subset of digital forensics, so the question starts as what is digital forensics? Digital forensics is essentially the act of investigating a computer. Traditionally we see more regarding Disk Forensics. Disk forensics typically involves taking a copy of a hard drive of a computer, looking for indicators of compromise (IOCs). This involves looking for file artifacts as well as operating system artifacts. Disk forensics can also give you an idea of what has happened over a long period of time with the machine. However, to make a copy of the hard drive, the analyst must first turn off the machine. This destroys any evidence that was contained in the volatile memory.
This is where memory forensics comes in - Before the machine is shut down to make a copy of the hard drive, the analyst should also create a memory dump. This allows an analyst to search for any IOCs that persist only in memory, such as the current running processes and the network connections. It also shows the analyst exactly what was happening on that machine at that particular moment. Another benefit to memory forensics is much of what is in memory is in plain text, as a code needs to be in a readable format to be processed. You can also find encryption keys, as they had to be loaded in memory to encrypt or decrypt. Overall memory forensics can play a critical role in an investigation.
Hopefully I've convinced you at this point memory forensics is worthwhile. The next question becomes, what tools can you use to analyze memory?
Volatility is a very well known
framework written in python. It was released in 2007, and has been maintained
ever since. There are two main components of Volatility; the profiles and the
plugins. The profiles are based on what operating system the memory came from,
such as Windows XP, or Windows 7. It allows Volatility to interpret the bits and
bytes. Plugins are modules of code that an analyst will run to look for
something specific in memory. An example plugin could be
pslist which will
list out all the processes.
Rekall started as a fork of Volatilty, that soon grew into a whole platform that supports memory forensics. Rekall focuses on efficiency, robustness, and live memory analysis. It contains many of the same plugins as Volatility does, however it profiles memory in a different manner. While Volatility will give a generic profile to memory (such as WindowsXPSP1), Rekall using the GUID on Windows to get a much more granular grasp on the memory data structures.
While everyone has their own style of starting an investigation, I'll give a brief overview of how a beginner can start learning. This is not meant to be an end all be all, and I highly encourage everyone to experiment with different plugins and tactics.
I personally like to start by seeing what processes were running on the machine
at the time of collection. Sometimes there is an easy win in this, such as
malware.exe. However, it is not always quite that simple. We must
first understand how we can search for processes. The first is through a doubly
linked list. Essentially, all processes have a parent process, and may have
children processes. Each process then is linked to the other processes, and we
can map out all the processes in memory by walking up or down this doubly
linked list. Another way to find processes are by scanning memory for
EPROCESS structures. If a process wants to be treated as a process by the
computer, it must conform to this
EPROCESS structure. Sometimes malicious
processes unlink themselves from the doubly linked list to hide. However, they
will still conform to the
EPROCESS structure, meaning we can still find them
So now that we know a bit more about processes, how do we find bad ones? To do
so, we have to look for anomalous behavior. To identify anomalous behavior, we
need to know our baseline for the operating system we are analyzing. If there
is something outside of the norm, then it may be worth investigating further.
We can also compare the output of listing processes through the doubly linked
list, and scanning for processes by the
EPROCESS structure. If there is a
process that appears in latter but not the former, it may be worth
Plugins you can use to analyze processes:
pslist- looks through the doubly linked list
psscan- searches for
pstree- shows the parent child relationship of processes
psxview- shows if a process was found in a particular manner
Another easy way to look for malicious behavior is to look at the network
connections the computer was making at the time of memory collection. If a
process that shouldn't be making network connections is now making them, that
would be interesting anomalous behavior to look into, for example, if
calculator.exe was reaching out to Russia, it would be suspicious. If you see
connections being made to a particular port that is abnormal for this
computer, it may be worth investigating.
Plugins you can use to search for network connections:
connscan- works for Windows XP
connections- works for Windows XP
netscan- works for Windows 7
netstat- works for Windows 7 and above
Malware typically likes to hide its activity, and one of the ways to do this is by making legitimate processes to its dirty work. We can see three great examples of this through:
- Remote DLL Injections
- Remote Code Injections
- Hollow Process Injections
Remote DLL injections are where a malicious process modified the registry key for a legitimate process, to have the legitimate process load up a malicious Dynamic Link Library (DLL). This malicious DLL is run alongside the legitimate DLLs, hiding in plain sight.
Remote code injection is where a malicious process latches on to a legitimate process, and allocates memory space on behalf of the legitimate process, and inserts its code in that memory allocation. This allows the malicious code to run alongside the legitimate code.
Hollow process injection is where the malicious process starts a new instance of a legitimate process, however before the legitimate process fully initializes, the malicious process clears out everything the legitimate process was going to load, and instead replaces it with malicious code. This hollows out the legitimate process, making it just a shell for the malicious code.
Plugins you can use to detect code injection:
dlllist- lists out all the dynamic link libraries.
ldrmodules- shows all executable images, including DLLs, if they were loaded at init time, if they are still loaded, and where they are mapped to.
malfind- looks for Portable Executable (PE) files, or valid CPU instructions that were loaded after initialization of the process.