In this series of articles, we’ll learn about how processes reside in memory and the different ways to find and list them in case of Memory and volatility. I will be using Volatility plugins to find processes in memory. Once we know how to find processes in memory, in Part 2 we’ll see how to enumerate them.
Note: The scope of this article is limited to just showing how a process can be found and enumerated in memory. In this article, I will not cover any investigation/hunting of malicious processes. Bonus points to you if you can spot suspicious processes from screenshots.
Process in memory
Processes are represented in memory using _EPROCESS structure names and each process has its own virtual private memory space that contains all the components needed to run the process, such as the process executable, DLLs, stack, heap, etc. This is how it looks in Windows 7 32bit .
Now, as we can see, there are many properties that make up a process. Below are some of the important ones that will come in handy in your investigation.
The _EPROCESS structure will always be located in non-paged memory.
CreateTime and ExitTime show the UTC timestamp of the process that starts first and Exit respectively.
ImageFileName: stores the first 16 ASCII characters of the name of the executable process.
ActiveProcessLink: This is a doubly linked list that actually links all running processes in memory. There is a forward and backward pointer that connects all the processes. Later in this article we will see how some popular plugins like pslist rely on this list enumeration and can be defeated by attackers.
ActiveThreads: Displays the number of threads running in this processing context.
PCB & PEB: Process Control Block (PCB) is the basis of _EPROCESS and Process of Environment Block (PEB) points to DLLs, environment variables, stacks, command line arguments, etc.
VadRoot in Case of Memory and volatility:
VadRoot: It is the root node of the VAD tree and shows the allocated memory segments for this process.
Ways to find processes in memory using volatility
As we can see below, we give the profile type selection when launching the Volatility plugins because it tells the code running in the background to look at specific offsets and then start watching the pointers to get all the objects like Process. To enumerate a process, Volatility first finds the Kernel Debugger data block to detect PsActiveProcessHead, which itself points to the _EPROCESS list.
Following are the different ways to enumerate the in-memory processes that Volatility provides us in the form of plugins:
This plugin will iterate through the linked list pointed to by PsActiveProcessHead and run by ActiveProcessLink. The _EPROCESS structure contains this _LIST_ENTRY structure named ActiveProcessLink. This doubly linked list is as below
Below is an example of the pslist in action:
See the number of processes that were running in memory when the image was taken. This plugin is useful for knowing which processes were in the linked list and sorting at the initial level can be done here to find a new unknown process or even a known process with a slightly different name like scvhost.exe and if it is possible, try to map the parent of the child process, although we have a better plugin for this pstree, which we will discuss shortly.
As mentioned above, pslist can be defeated if the process can be disconnected from the doubly linked list. This can be achieved using techniques such as Direct Kernel Object Manipulation (DKOM). This can be done by loading a malicious driver that provides full access to kernel objects, or by using an API function called ZWSystemDebugControl. Below is the output of the psscan plugin. As you can already see, the number of processes listed is more than pslist because psscan went through the entire memory to extract what is related to the Process object. Let’s take a look at it.
This plugin is used to provide an overall picture of the process so that cross-references can be made for different aspects to detect malicious processes. Below is the psxview output
Now let’s look at the output:
I think Offset, Name, pslist, psscan are easy enough to guess.
It is good to map with threads for a process. Threads can be enumerated individually for the _ETHREAD structure and mapped to processes from there.
PspCid: This is a special in-memory table that stores references for all active and thread objects. This table can be manipulated and any process, thread reference can be removed.
Csrss: The client-server runtime subsystem plays a key role in creating processes and threads. Note that this only applies to the self-created process. (system, smss.exe, csrss.exe)
Session and Surface: A session attaches an entire process to a specific user session, and a surface finds every thread attached to a surface that can be mapped to a custom process.
Using –apply-rules with psxview can automatically take care of the exceptions listed above. It shows “Okay” when it reports false, but it’s a false positive and it’s okay to ignore it.
End times are shown when a process is terminated, but this can easily be modified, so cross-check if the process has an exit time, what another column says about it, such as thread (if it actually exited, it should be 0 threads).
This plugin takes the pslist output and actually presents it in a child-parent relationship. A very useful plugin when the in-memory process dump is huge to see any suspicious child-parent relationship. For example, in the output below from pstree, we can see a relationship with extending .’s defines the structure of the relationship.
Note that this only provides a mapping of pslist output, so you may still be missing output knowledge from psscan. What do you think about the cmd.exe process here?
So in this article we have seen how processes can be found in memory and their output can be transformed using Volatility plugins.