杏吧传媒

Search
searchclose icon
huntress logo

Silencing the EDR Silencers

Glitch effectGlitch effectGlitch effect

As many security practitioners know, tampering with Endpoint Detection and Response (EDR) products is a deep desire for threat actors and red teamers alike. I spoke about this briefly at BlackHat this year in my 鈥淓DR Blinded, Now What?鈥 杏吧传媒 booth talk.

__wf_reserved_inherit
Speaking at BlackHat. Photo cred to my twin John Hammond.

In one of the slides, I talked about how one of the most common ways to 鈥渂lind鈥 EDRs is to apply firewall rules against the desired EDR applications. This technique is unique in the way that an attacker doesn鈥檛 need to directly access an EDR鈥檚 application themselves (open a handle to the process or file). Instead, they alter the application鈥檚 ability to communicate outbound to their server, as well as alter the server鈥檚 ability to communicate inbound to the application. So, although the EDR can collect telemetry of an action, those actions aren't being sent up for detections or investigations. In this blog, I'll touch on this technique and discuss how products can protect themselves from this attack.聽

Blocking Mechanisms聽

While we discuss the various ways one might block application's network communications, two ways really come to mind that are the most prevalent today:聽

  1. Creating Windows Defender Firewall with Advanced Security rules
  2. Creating Windows Filtering Platform (WFP) rules聽

Now, that might sound repetitive because it slightly is. That鈥檚 because the built-in Windows Defender Firewall leverages the Windows Filtering Platform to enforce its rules. However, I call it out because, as we鈥檒l see later, we have to adjust the solution because depending on how you interact with each feature, the settings are set in different locations.聽

Note: Before we proceed, it鈥檚 important to state that we鈥檒l only be looking at default Windows firewall capabilities, not third-party ones. This blog also only focuses on when firewall rules are set via the Windows Firewall or WFP.

Windows FirewallI

The has the ability to create custom rules that either allow or disallow an application to speak out through the network. Both inbound and outbound. There are no restrictions on which processes are targeted by these firewall rules, so as long as an attacker has local administrator rights they can successfully add an EDR agent into the firewall rule and block network connections. Most people have probably seen the following page as it relates to the Windows Firewall:

Figure 1: Windows Defender Firewall with Advanced Security Window

There is also an easy built-in tool to create firewall rules called netsh:

Figure 2: netsh advfirewall example

For something more custom, someone could leverage the and COM interfaces. Users can implement this themselves quite easily. A well-known tool that does this is , which eventually leverages the method in the INetFwRules COM interface to create a new firewall rule against a known EDR binary.

Figure 3: EDRSandblast firewall creation example

Now, it鈥檚 good to note that with Windows AV turned on, Defender does block firewall rules being made against MsMpEng.exe. However, the key point is that this can be done against any EDR, and if they鈥檙e not monitoring, the network communications will be cut off. When these firewall rules are created, they鈥檙e actually stored in the registry under:

HKLM\System\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\FirewallRules\{GUID}

{GUID} represents the firewall rule. This is stored as a REG_SZ value where the data holds the information about the rule:

v2.32|Action=Block|Active=TRUE|Dir=In|App={application-path}|Name={firewall-rule-name}|Desc={firewall-rule-name}|

Let鈥檚 touch on the most important bits of this rule:聽

  • Action - the firewall action to take (allow or block)
  • Active - whether or not the firewall rule is currently active or not
  • Dir - direction to permit or deny communication between either In(bound) or Out(bound)
  • App - the application to block or allow
  • Name - firewall rule name
  • Desc (optional) - description of the firewall

There are other optional flags that can be put into the string as well. The three biggest tags here are Action, Dir, and App.

So before we move forward into the WFP, let鈥檚 remember the registry key HKLM\System\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\FirewallRules\{GUID}. This will come in handy later when we discuss solutions.

Windows Filtering Platform (WFP)

The Windows Firewall leverages the to enforce its rules. Here, we won鈥檛 go in-depth about the internals of the WFP simply because we believe that a lot of other great researchers have. In fact, the following are great resources:聽

  • by
  • by

Interacting with the WFP is a lot easier because there are direct APIs that we can take advantage of. A list of WFP APIs can be found . For purposes of creating a WFP filter, the desired API is . Many reading this blog have likely heard of . This function is leveraged to for both IPv4 and IPv6 addresses. When these rules are applied, there are two things that have to exist:

  • A provider - policy provider that is used for the management of the filter
  • A filter (inbound and outbound) - rule that if the conditions are met, takes the actions specified聽

There are four types of run-time filters that users can interact with. , , , and . The most valuable are persistent filters to an attacker, as they live until the filter is removed. When filters are set, they鈥檙e stored in the registry just like firewall rules, just in a different location:

Figure 4: Procmon output of WFP filters and provider being set

Each provider and filter is stored as a {GUID} value, and the filter data is stored as a byte array (REG_BINARY).

Figure 5: WFP filter byte array example

This can make parsing this data a little more difficult than the firewall rules above just because it isn鈥檛 just a simple string value. However, an easy way to interact with filters is with the Get-FwFilter PowerShell cmdlet. For example, you can get the information about a filter via the Get-FwFilter cmdlet if you have the FilterId or FilterKey:

FilterID
Loading Gist...
FilterKey
Loading Gist...

This is a great option if you鈥檙e curious what a specific filter is doing on your machine. Now, let鈥檚 see how to stop this from happening against an EDR application!

厂辞濒耻迟颈辞苍听

We鈥檝e identified that firewall rules and WFP filters are both eventually set in the registry. This is great for anyone trying to pick up on this activity because there are multiple ways to monitor the registry. We鈥檇 like to propose two avenues that a product could take if they want to stop this tampering technique in its tracks: Prevention and Immediate Removal.

Prevention

Products can either prevent it by leveraging a pre-callback routine for RegSetValue (). If a product has access to the kernel via a driver, then they could leverage to receive notifications when any registry value set operation is performed in the registry. Upon doing so, they could parse out the registry path and the data being set, and if it matched, they could return STATUS_ACCESS_DENIED to prevent that key from being set. A successful implementation would look something like the following:聽

Figure 6: EDRSandblast failing to create firewall rules

You can see that the firewall rules aren't successfully created because they're blocked through the registry pre-callback RegNtPreSetValueKey notification. This works great from a prevention standpoint, but to be honest, I don鈥檛 always think it鈥檚 a good idea to parse or process data in the kernel unless it鈥檚 really lightweight. And although this works well for the firewall rules, that data is stored as a string value, where the WFP filters are stored as a byte array. Like the firewall rules above, this shouldn鈥檛 be processed/parsed in the kernel.

Immediate Removal

The methodology of 鈥渋mmediate removal鈥 is similar to the method above, except that you鈥檙e technically allowing the undesired action to take place before doing anything about it. This can be done by monitoring for these registry value set operations via a post-callback (). This callback is notified once the action has already taken place in the registry. Now, someone could still process/parse this data in the kernel and deal with it, but I recommend storing the post-callback data and shipping it down to a user-mode agent so that it can take care of the parsing and processing. Figure 7 shows a very high-level architecture of how this can be done. There are many ways to do this, and this isn鈥檛 the only right way, but this is just how I did it when I created the proof-of-concept within .

Figure 7: Basic EDR architecture for registry post-callback

Once the data is successfully shipped down to the user-mode agent and parsed, then the agent can safely get rid of the rules. You can鈥檛 just delete the registry keys because the rules/filters aren't immediately reset. Instead, you must remove them in a way so that the filtering engine refreshes after the removal. You could delete the registry key, but then you鈥檇 have to reboot the machine. Obviously, this approach isn鈥檛 an appropriate option, as products want to do modifications during runtime. There are some effective options to achieve this, however. For firewall rules, I leveraged COM to do this:

Figure 8: Code example for INetFwRules::Remove

I validated that the registry value held the undesired firewall policy and used the to remove the firewall policy. Figure 9 shows how it looks after implementation:

Figure 9: Example of malicious firewall rules being removed in real-time

You can see the rules were successfully created but immediately removed, rendering the tampering technique useless.聽

For the filters and providers within the WFP, I leveraged the function to delete the filter and the function to delete the provider.

Figure 10: Code example of removing malicious WFP filters and providers

After this is implemented, we can see the filters and providers that are created, with EDRSilencer successfully deleted:

Figure 11: Example of malicious WFP filters being removed in real-time

While this method might not be "preventing" the rules from being written, it's just as effective. The product doesn鈥檛 need to parse and process this data in the kernel, and the removal is almost immediate. Lastly, you don鈥檛 have to use the registry callbacks, as the WFP has the security event that states when a new rule is created. Someone could monitor for that and perform the same actions as above to remove that rule.

Conclusion

Tampering with EDRs is a very hot topic, and I see many people talking about leveraging firewall policies and WFP filters to blind EDRs. It鈥檚 clear this is very effective. It鈥檚 also unique, as the attacker doesn鈥檛 have to interface with the EDR鈥檚 processes directly. I鈥檝e yet to see anyone go in-depth on how to stop or mitigate this tamper technique, so I wanted to provide some potential solutions. I hope this helps you understand this tampering technique better and how to mitigate it.

Want to dive into even more attacker techniques? Join us at Tradecraft Tuesday! No products, no pitches鈥攋ust tradecraft.

Categories
Share

Sign Up for 杏吧传媒 Updates

Get insider access to 杏吧传媒 tradecraft, killer events, and the freshest blog updates.

By submitting this form, you accept our Terms of Service & Privacy Policy
Oops! Something went wrong while submitting the form.
杏吧传媒 at work