Engineering Process Injection Detections — Part 3: Analytic Logic

David Polojac
Posts By SpecterOps Team Members
12 min readAug 27, 2020

--

This is the third post in a series covering some of the thought processes and methodologies used when developing detections for offensive techniques. In the previous posts Jonathan Johnson discussed research and data modeling.

Part 1: Research

Part 2: Data Modeling

In the first post, Jonny talks about the initial stage of research and his approach when starting the detection development process. In the second post he looks at data modeling and the process of isolating events created as a result of executing a Proof of Concept (PoC) exploit (credit to Dwight Hohnstein for the PoC used), establishing relationships within data, and normalizing data to allow for more effective and efficient analysis.

This post covers the final step— developing analytics that can be used to detect offensive techniques. Like the last two posts, Process Hollowing is used as the example technique that is being detected.

From Data Models to Analytics

In the context of detection engineering, an analytic is a logic statement or query that is used to identify an offensive tactic, technique, or procedure based on correlated data and behaviors. The research and data modeling steps from the first two posts provided the information needed to start creating analytics. Some of the data and indicators seen in the attack include:

  • The name of the PoC binary (processhollowing.exe)
  • The parent process of processhollowing.exe
  • The directory from which processhollowing.exe was ran
  • The user that executed processhollowing.exe
  • Processes accessed with specific access rights
  • A “Hello World” text box pop-up

Some of these may be more obvious than others, and there are many more that can be identified. Any event that was generated due to the execution of a technique presents a potential way to detect it, but only some of these are suitable for practical use. A couple questions that can help decide what may work are:

  • What data is available?
  • How unique is the behavior or indicator to this technique?

I’ll look at two potential analytics as an example:

  • Analytic 1 — The name of the PoC binary-processhollowing.exe
  • Analytic 2 — Processes being accessed with specific access rights

Analytic 1 — The name of the binary used to perform the technique is processhollowing.exe. It may seem too simple or specific but honing in on indicators such as file names, hashes, or strings embedded in binaries can be an easy way to detect known implementations of a technique. These indicators can’t always be predicated and are normally easy to alter without affecting the functionality of the technique. Because of this, analytics that focus on behavioral qualities should be included since they are more likely to catch various implementations of a technique.

Analytic 2 — During research Jonny identified that Sysmon Event ID (EID) 10 contains the process_granted_access field. This event was logged upon PoC execution when processhollowing.exe opened a handle to another process. Research showed that specific process access rights (PROCESS_VM_WRITE, PROCESS_VM_OPERATION, PROCESS_SUSPEND_RESUME, PROCESS_CREATE_PROCESS) are required to perform process hollowing. This may be another approach to detect the technique.

Considerations for Analytics

What data is available?

Answering this question first can save a lot of time since it filters out any analytics that require a data source I can’t access. The data modeling step documented which sensors and data sources are available — Sysmon and Windows Event Logs. Sysmon EID 1 and EID 10 provide the data needed for both Analytic 1 and 2, as seen in the photo below via the process_parent_name, process_name, process_target_name, and process_granted_access fields.

The events discovered during data modeling

How unique is the behavior or indicator to this technique?

Several behaviors and characteristics can be identified in the data generated by technique execution, but many of these are very common in benign activity as well, resulting in False Positive (FP) events. The Detection Spectrum explains the difference between broad and precise analytics and is helpful when figuring out how these indicators relate to the technique. An analytic that detects the executable name processhollowing.exe will have a low FP rate in most environments since that shouldn’t be too common in benign network activity. This analytic is more precise.

On the other hand, an analytic looking at process access rights will likely have more FPs due to the large number of standard, benign instances where process access rights are utilized. This analytic is more towards the broad side of the spectrum.

The volume of FPs should be considered to determine if an analytic has potential to be used as part of a detection. In general — the less, the better. There’s normally a limit to the number of FPs an analytic should return within a certain time-frame before the time required to triage all the events makes it unfit. However, various ways of implementing analytics, such as a weighted scoring system for alerts, can make FPs less of an issue. Analytics with too many FPs can sometimes be tuned to filter them out while minimizing the possibility of a True Positive event being filtered.

Defining the Strategy

For Analytic 1 I need to find logs that reference the names of binaries being executed. Which events should I be focusing on? Both analytics focus on process creation and execution related events. Based on the outputs of Data Modeling, I know that Sysmon EID 1 (Process Creation) and Sysmon EID 10 (Process Access) logs are generated when executing the PoC. I’ll focus on these two events going forward since they appear to provide the data I’m looking for. Since I know which data sources I’m using I can define how the analytic will function.

Analytic 1 — Search for process events that contain the string processhollowing.exe

Analytic 2 — Search for process access events with the rights used for Process Hollowing

Creating Queries

Like in programming, a useful first step for creating an analytic is writing out a plain-language pseudo-analytic. This pseudo-analytic describes the behaviors, data, and relationships involved in the analytic without worrying about specific query-language syntax. The core functionality of the analytic will normally remain the same across different security solutions, while the specific query syntax may change.

The pseudo-analytic is then used to create a query in the proper format for the environment, in this case Kibana Query Language (KQL).

Analytic 1

Name of the PoC binary (processhollowing.exe)

Strategy/Pseudo-Code

Search for process events that contain the string “processhollowing.exe”

Kibana Query

(event_id:1 OR event_id:10) AND “processhollowing.exe”

This query returns Sysmon EID 1 (Process Creation) and Sysmon EID 10 (Process Access) events that contain the string processhollowing.exe.

Results of the query looking for the string “processhollowing.exe”
Results of the Kibana query for the first analytic

Analytic 2

Processes being accessed with defined rights

Strategy/Pseudo-Code

Search for process access events with the rights used for the Process Hollowing PoC

Kibana Query

event_id:10 AND process_granted_access:2097151

This query returns Sysmon EID 10 events that utilize the same permissions of the PoC used during testing (2097151) represented by a decimal value. The next section goes into more details on this.

Results showing processhollowing.exe with many false positives
Results of the Kibana Query for the second analytic

Tuning and Refinement

Both of the above queries returned the events from the Process Hollowing PoC and successfully identified the technique being used, also returning some FPs. If FPs are returned the query can still be refined to filter them out while trying to keep as much of the core functionality as possible. In this case, I triage each event to determine if it is related to the technique I am detecting and adjust my query to exclude any event which is not.

For the Analytic 1 Query the only FP events returned were related to msmpeng.exe (Windows Defender Antivirus Service). This appears to be Windows Defender interacting with the malicious executable. While seeing this during an investigation would stand out, its not directly related to the core Process Hollowing execution behavior, and so I’ll choose to filter it out. The final query, which returns no FPs, is:

(event_id:1 OR event_id:10) AND NOT process_name:msmpeng.exe AND “processhollowing.exe”

The Analytic 2 query resulted in a lot of events that don’t appear to be connected to Process Hollowing. It looks like the process_granted_access rights utilized by processhollowing.exe are commonly used, especially by Windows system binaries. In fact, the access rights utilized by the PoC, represented by the value 2097151, are the full rights — PROCESS_ALL_ACCESS.

This presents a problem. For Analytic 1 I simply filtered out the few false positives that were not directly related to the core execution of the PoC. Using this same approach for Analytic 2 has a higher chance of filtering out True Positives if an exclusion is made for all of these Windows binaries.

Based on the research done in Part 1 I know that Process Hollowing doesn’t necessarily need full access rights in order to be performed. The minimum rights needed are:

PROCESS_VM_WRITE
PROCESS_VM_OPERATION
PROCESS_SUSPEND_RESUME
PROCESS_CREATE_PROCESS

Converting the rights to to the associated values found in the Microsoft Documentation and summing up the results gives the decimal value 2312. Since the PoC doesn’t utilize these I could try to modify it in order to validate the functionality. Using this value may result in less FPs and identify process hollowing exploits that utilize the bare minimum rights, but it wouldn’t catch the PoC used during testing. At this point it looks like it may be difficult to implement an operational process rights-based analytic with only KQL queries. If I can manipulate and access the data in additional ways it could open up new vectors to create an analytic focused on the behavior of the technique from multiple stages of execution.

Analytics solutions like Jupyter Notebooks can be used to for this, enabling operations like inner JOINs. Jonny created a Jupyter notebook that can more accurately identify process hollowing based on bare minimum process access rights and the expected behavior of the technique during execution.

The Jupyter notebook from Johnny’s github
Process Hollowing Jupyter Notebook Analytic

Overall, this notebook returns logs where an unsigned binary executed to create a process, accessed another process with the minimum rights, and was eventually terminated. Incorporating additional checks like binary signatures helps reduce FPs. Here is where this analytic ties into the chain of events for process hollowing (see Part 2 for more details):

  • The initial exploit, unsigned exploit binary processhollowing.exe is executed and a process is created (EID 4688 & 7)
  • This process creates a new process in a suspended state (EID 1, 10, & 4688)
  • A section of memory in the new process is unmapped
  • A binary is inserted into memory
  • ResumeThread is called, executing HelloWorld.exe
  • The original ProcessHollowing.exe process terminates (EID 5)

Bypassing the Analytic (Looking for Blind Spots)

Not all analytics will detect a technique 100% of the time. If the technique indicator or behavior that the analytic focuses on can be modified by an attacker then there’s a chance that the analytic can be bypassed, creating a gap in detection (a blind spot).

To evade Analytic 1, an attacker simply needs to use an executable that isn’t named processhollowing.exe. This is trivial to do and would result in an easy bypass of the analytic, as the query would not return the events associated with the attack.

Examples of how Analytic 2 can be bypassed include:

  • Using a combination of access rights not equal to 2312 that still have the required permissions
  • Using several handles to perform the technique — one handle to start and suspend the process, a separate handle to modify the memory, and another to resume the process
  • Altering the Sysmon configuration or service
  • Using API calls that are not monitored by Sysmon

It’s normal for analytics to have blind spots. This doesn’t mean that it won’t be useful, just that there are certain situations in which it won’t work as intended. Researching, identifying, and documenting these blind spots helps determine the weaknesses of the analytic and the circumstances in which an attacker may evade it.

Blind spot documentation also helps decide how to best focus efforts for improving the overall security program — including tool acquisitions, configurations, and policies. Blind spots can mitigated and sometimes eliminated with changes in these areas.

The Finished Analytic

At this point I have two analytics that can be used to detect process hollowing, the first one being more specific to this implementation. I’ve filtered out false positives so that I’m not overwhelmed with events and alerts, and identified some conditions in which an attacker can bypass these analytics.

Analytic 1 by itself is not the most robust solution due to how precise it is. The blind spot identified shows that this will only alert with a specific and easily modifiable filename. There is value in using it though, and I would likely identify additional precise analytics to increase the chance of detecting common implementations of the technique.

Analytic 2 has more chance of detecting process hollowing in general since it focuses on broad behaviors. Between the two analytics, this one is more likely to trigger when process hollowing is performed in a variety of ways and by various threat actors. It focuses more on the core indicators that must be present for the technique to work. An attacker can possibly change these, but must do so in a way that still allows for successful execution of the technique.

Now that I have some finished analytics I’ll look at my environment to decide how to best implement them. There are several ways these can be used, such as for hunt operations or monitoring and alerting. Instead of using just one analytic, I can increase the chance of detection by using both. Joshua Prager’s Detection in Depth post goes into more detail about using multiple analytics to detect a technique.

Overall, layering analytics that focus on different aspects of the technique is a useful way to reduce blind spots and detect multiple variations of the same technique. Going forward, I can tie this into the concept of Capability Abstraction and potentially develop analytics that can detect the technique’s behavior at each abstraction layer, providing a more robust detection strategy.

Conclusion

This series looked at the process of detection engineering, beginning with research, moving into understanding the available data and isolating events related to execution of a PoC, and then finally looking at an approach to developing analytics for offensive techniques.

Research lays the foundation for detections. The information about process hollowing obtained in this step reveals the core functionality of how it works and what is required. This research then helps decide what to focus on during data modeling. Using a PoC allows for testing and identification of events that are related to the technique. Analytics can then be built around the events that were identified as related to process hollowing.

One of my first steps for analytic development is to create a list of indicators seen when executing the PoC and isolating events. A couple questions helped guide and understand which of these indicators may have potential to be developed further:

  • What data is available?
  • How unique is the behavior or indicator to this technique?

After looking through the list of indicators and answering these questions, I chose two that seemed to have potential. The strategy of how this analytic functions was defined and a pseudo-query was created to help guide the creation of a language-specific query.

Running these queries to look for the PoC data resulted in FP events for both analytics. Tuning and refinement involved filtering out these unwanted results. I was able to filter out FPs from Analytic 1, but Analytic 2 required additional data operations and logic to get it to a usable state. Jupyter Notebooks allowed for a more flexible approach that focused on the behavior of the technique at multiple stages of execution. Blind spots were identified and documented to understand the weaknesses of the analytics, which were then ready to be implemented.

The detection engineering process can be approached in many ways. This series showed one approach that Jonny and I use and have had success with in the past. The analytics created from this process are not necessarily the best way to detect process hollowing, and there are many more that can be made. Different data sources, PoCs, and access to data can all enable the creation of analytics that aren’t possible with the setup used in this lab. These factors vary between environments, and so the analytics that are possible will as well.

Regardless of the approach used, researching the technique, understanding the available data, and identifying technique behaviors/indicators are important parts of developing detections for offensive techniques, and ultimately, catching malicious activity on the network.

--

--