Some of the most critical solutions in detecting malicious activities within IT environments are Endpoint Detection and Response (EDR) solutions. One of the most commonly used EDRs is Microsoft Defender for Endpoint (MDE), designed to detect and respond to malicious activities. However, as with any security measure, understanding its detection mechanisms is crucial for both defenders and attackers.
In this blog, we delve into the intricacies of MDE’s detection capabilities, particularly focusing on how it handles detecting malicious activities within .NET applications. Through a series of observations and experiments, we uncover a vulnerability that allows sophisticated attackers to bypass detection: the reliance on module names for detecting malicious .NET applications. Our findings reveal that MDE’s approach can be circumvented, posing a risk to security operations. Join us as we explore this vulnerability, demonstrate how it can be exploited, and discuss the implications for enhancing security measures.
Observation
We noticed that when executing common malicious .NET applications, a high alert is created in MDE with the message: “Process loaded suspicious .NET assembly” (Figure 1). Raising a high alert in an environment often leads to an investigation, leading to further activities being detected by the Security Operations Center (SOC).
Figure 1. High alert raised in MDE by executing a .NET application
To bypass the detection in MDE, we first need to understand how this detection works. Take a look at the timeline of MDE to gain more information about the events that occurred during the execution of the .NET application. In the timeline (Figure 2), we can see a series of events related to the loading process in the .NET application. Notably, the alert was generated immediately after the first module was loaded – prior to the completion of the application's execution. Based on this observation, we suspect that the implemented detection is based on the module names that are being loaded, without any further behavioral analysis.
Figure 2. The timeline of the .NET application execution
Experiment
To evaluate our hypothesis, we compiled two empty .NET applications that do not contain any malicious code. The two empty .NET applications are:
- Application A – a program with the module name ‘Snaffler’ (Figure 3).
- Application B – a program with an adjusted module name but with the same contents as Application A (Figure 4).
Figure 3. Source code of Application A, the fake Snaffler program
Figure 4. Source code of Application B, the dummy program.
When we execute Application A from our malware implant, we notice that even a non-malicious application will trigger a high alert in MDE (Figure 5). Meaning that at least one of the detections is likely to have been built around the module names. As a double check, we also execute Application B. As expected, this did not lead to an alert, while similar events are being shown in the timeline (Figure 6).
Figure 5. The execution of application A, using Snaffler as a module name.
Figure 6. The execution of Application B, using FooBarApplication as a module name.
To summarize our findings at this stage, the detection of MDE seems to be around matching the module names to a list of well-known malicious .NET applications. As shown in this blog, the detection around module names can be easily bypassed by changing the names of modules within applications. To fully showcase this, we made a fork of the Snaffler source code, which is readily available on GitHub and detected by MDE by default. We changed every module name with the mention of ‘Snaffler’ to ‘Znaffler’. An example of our adjustments can be seen in Figure 7.
Figure 7. An example of the code changes we made
After changing and recompiling the .NET project, we simply executed it again. As expected, the Snaffler version called Znaffler does not lead to an alert in MDE (Figure 8), meaning that we bypassed the detection. Changing module names can be automated by using readily available .NET obfuscators.
Figure 8. The timeline events of the Znaffler execution
Conclusion
Our exploration into Microsoft Defender for Endpoint (MDE) brings insights into the detection mechanisms of malicious .NET applications executed via Common Runtime Language. The observations in this investigation reveal that MDE's current detection strategy for .NET applications may be overly reliant on matching known malicious module names. This presents an opportunity for security professionals or malicious attackers to evade detection simply by altering module names – a method proven effective in our tests, as demonstrated with the 'Snaffler' to 'Znaffler' transition.
It is crucial to recognize that while these findings could aid in developing more robust security strategies, they also shed light on potential areas for improvement in detection tools like MDE. By continually evaluating and adapting to the detection capabilities of security software, cybersecurity practitioners can ensure the resilience of their environments against actual adversaries.
Contact
Sven Thiessen
Senior Tech Specialist
KPMG in the Netherlands