Incident response investigation usually involves the collection and analysis of a vast amount of evidence, including analysis of processes being executed. Looking at their timing and their ancestors provides researchers an initial understanding of what happened on the machine being investigated.
As a security researcher, when analyzing a live running system, one of the first operations I usually perform is to run Process Explorer. Knowing the running processes on a system provides a basic understanding of what is currently happening on the machine. Process Explorer provides more than just a snapshot of running process; the tree view also gives you the execution context (process ancestors) showing the order of and relationship between the various running processes.
However, context is everything. It’s difficult to determine from a single process creation record whether an activity is malicious. But by linking events together and understanding the chain of executions, you can establish valuable context that will simplify the investigation and can lead to better results.
There are many sources of process execution evidence – Prefetch, ShimCache, UserAssist, Windows Security Event Log and more. We reviewed several tools for viewing historic process execution evidence, but could not find one that provides the right context, so we set out to create our own. In this blog we show how we overcame several obstacles to create “HistoricProcessTree”, a tool that visualizes historic process execution evidence (based on Event ID 4688 - Process Creation Event) in a tree view.
A deeper look at the need for context
Let’s dive a little deeper by looking at the following process tree:
Figure 1: Process tree view in Process Explorer
An isolated process create event, for example the creation of jp2launcher.exe
(PID 16288) (Java process) from iexplore.exe (PID 11804), does not necessarily raise suspicion. The same is true for the spawning of cmd.exe (PID 13928) from jp2launcher.exe (PID 16288). However, looking at the complete chain provides context for the entire operation. In this case, the fact that iexplore.exe created jp2launcher.exe, which then created cmd.exe, is definitely something interesting that warrants investigation.
(PID 16288) (Java process) from iexplore.exe (PID 11804), does not necessarily raise suspicion. The same is true for the spawning of cmd.exe (PID 13928) from jp2launcher.exe (PID 16288). However, looking at the complete chain provides context for the entire operation. In this case, the fact that iexplore.exe created jp2launcher.exe, which then created cmd.exe, is definitely something interesting that warrants investigation.
Like every tool that enumerates processes, the most natural way to represent the context is in a tree-like structure. Using the tree view allows you to easily understand a chain of process execution and see the ancestors of any given process. Therefore, in developing HistoricProcessTree, we applied this construct to post-mortem forensics investigations, where the only source of process execution information is the Windows Event Log.
Utilizing the Process Creation Event
On a Windows system, Process Creation Event (Event ID 4688) is generated for every process that is executed and stored in the Windows Security Event Log. However, it is not audited by default; process tracking auditing needs to be enabled. You can read more articles about how to enable auditing of Event ID 4688, such as this one on the TechNet site.
Microsoft included several improvements to the Process Creation Event with the release of Windows 10, the most significant of which is the addition of the Creator Process Name field.
It is considered a good practice to enable auditing of the process’ command-line arguments. This can be configured through GPO, as described here.
Figure 2: An example of Event ID 4688
Our survey of existing tools
Sharing knowledge and tools in the Digital Forensics & Incident Response (DFIR) community is quite common. Knowing this, we first looked for existing tools to meet our needs.
The first tool we looked at was Event Log Explorer by FSPro Labs. Event Log Explorer works with both local and remote event logs as well as with event log files. Though it is efficient and easy to use, there is no tree-like scheme, making the understanding of execution context and ancestry not a trivial task.
Figure 3: Output of Event Log Explorer tool
The second tool we tried was williballenthin’s process-forest. It is an awesome tool, but as Willi himself mentioned in his GitHub page, it has some limitations. For example, time execution may not be optimal for large event logs files. It does have the ability to display information in a tree-like structure, but it’s limited to a simple console text output.
Figure 4: Output of process-forest tool
Introducing our tool - HistoricProcessTree
So as mentioned, having no luck finding the solution we were looking for, we decided to dive into the task ourselves. We designed a tool that accepts an .evtx. Our first step was to parse an event log and turn it into a tree object. With the help of the python anytree module, this was fairly easy. The result looked like regular command-line tool output:
Our second step was to add some features to our tree, such as the ability to perform an advanced search and view additional information about a node. To do this, we used an existing JQuery library bootstrap-treeview by Jonathan Miles.
Obstacles
1. Parsing .evtx file
Windows stores the event log in a .evtx file type. Our tool needed to be able to parse the information stored in those files. There are several common methods to parse the .evtx log file, including python modules such as python-evtx and Powershell’s
“Get-WinEvent”. By testing both of them, we determined that Powershell command “Get-WinEvent” was significantly faster.
“Get-WinEvent”. By testing both of them, we determined that Powershell command “Get-WinEvent” was significantly faster.
The following graph demonstrates the time differences, in seconds, between the two methods. For example, parsing ~10K events, the average time with Powershell
“Get-WinEvent” is 20 seconds, while with python-evtx it is two minutes.
“Get-WinEvent” is 20 seconds, while with python-evtx it is two minutes.
2. Parent Process ID collision
In Windows, a process ID is a number in range of DWORD that is associated with a process object. Once a process terminates, its process ID is available for reuse. There may be a situation in which a new process receives a PID value that was previously assigned to another process. The larger the time sampling range, the higher the chances that a PID value will be reused by multiple processes.
Let’s use an example to clarify:
- At 1:00pm iexplore.exe was created and received PID 2222.
- At 1:05pm iexplore.exe was terminated, at which time PID 2222 was released and available for reuse.
- At 9:00pm, malware.exe was created and received PID 2222.
- At 9:02pm, malware.exe created cmd.exe, which was assigned PID 1337.
Looking at event log, we know that cmd.exe (PID 1337) was created by PID 2222. There were two different processes that received the PID 2222: iexplore.exe and malware.exe. If we only inspect the Event ID 4688, it is impossible to know for certain whether iexplore.exe or malware.exe is the parent process of cmd.exe (1337).
As a solution, we marked processes with uncertain ancestors (such as cmd.exe, in this case), with a “?” at the forefront of the created process name, informing the user that the parent process information is not trustworthy, as shown below:
Figure 5: Process ID collision example
Final result
The tool, written in python, accepts an .evtx file and an optional time-range input. Once the file is loaded, the tool iterates over the event log file and uses PowerShell’s
“Get-WinEvent” to filter only the process creation events in a specific time range. For each event, it creates anytree nodes that hold the relevant data, e.g. the process name and creation time. Event objects are linked to each other, and the relationship between objects is based on child/parent relationship. Finally, when we have a tree structure of the information, the tool will generate an HTML file with the tree-view data.
“Get-WinEvent” to filter only the process creation events in a specific time range. For each event, it creates anytree nodes that hold the relevant data, e.g. the process name and creation time. Event objects are linked to each other, and the relationship between objects is based on child/parent relationship. Finally, when we have a tree structure of the information, the tool will generate an HTML file with the tree-view data.
Summary
A tree view of processes can be helpful for incident response investigations. There are several existing tools that are designed for working with Security Event Log, but we failed to find one that enables an easy-to-use tree-view visualization of process ancestry.
“HistoricProcessTree” was designed to address that need. We encourage the community to use it for DFIR investigations.
Tags:
How To