Throughout the early phases of my career, I managed various EDR products all while wearing the “hat of the day” to address other tasks. The tasks involving EDR would have included deploying agents to endpoints, detection engineering, and addressing problems such as “poor performance” complaints from users. One of the difficulties that I faced was when I had to migrate from one product to another, while making the switch transparent to the user so as to not inconvenience them. Prior to these deployments, it is ideal to implement the best practices as recommended by the vendor and most importantly implement the exclusions for other EDR agents that are installed on the devices and vice versa to ensure a smooth transition. Depending on the switch between vendors, you were bound to run into some kind of problem and, at times, did not have a smooth transition. In rare instances, the conflict between the products caused problems that left users unable to work. Back then, I didn’t know why these problems occurred, but proceeded to quickly resolve the issue and continue pushing the migration.
A recent discussion that I had was around the topic of Minifilters and the role they play in EDR agents on endpoints. This was the first time I had heard about Minifilters, and I was surprised to learn how integral they are to detecting malware within Windows. I thought it would be interesting to take some time to detail my learning about Minifilter concepts, detections, and common evasion strategies utilized by malware authors.
Minifilter Foundations
FltMgr.sys
The Microsoft Filesystem Filter Manager (FltMgr.sys) is a system-supplied kernel-mode driver that was introduced as an enhancement of Windows NT file Input/Output (I/O) management post-Windows 2000. It seeks to address some of the major problems identified through the use of legacy filter drivers, one of which is handling recursion within the filesystem. The primary issue surrounding these legacy drivers is how they interact with file I/O operations. When these operations take place, each request will be passed through the device stack which could lead to potential deadlocks, or even resource spikes if they are not written correctly. While I cannot specifically point to these conflicts being the issue between EDRs, I can suspect that this is why two AV products can’t get along, especially when you’re transitioning between the two as they fight for the requests.
Microsoft provided FltMgr to assist developers when they are writing minifilters to promote a smoother integration with the file system, leading to higher quality driver development. Each request sent to the filesystem is handled by FltMgr, and it subsequently presents these requests to minifilters that are on the system. FltMgr is only active when a minifilter driver is loaded, and is attached to the file system. The minifilters are not directly attached to the filesystem stack, but rather through the I/O operations that they wish to filter.
Minifilter and Load Order Group Altitudes
According to the Microsoft documentation, minifilters are attached in a specific order when they are loaded through FltMgr.sys. This ensures that there are no conflicts between other minifilters on the system such as Activity Monitors, EDR/AV, Backup/Replication, and even encryption while the request is being intercepted by the filter manager. During this time, the filter manager calls registered minifilters according to their assigned altitude.
There is a set of load order groups that are loaded at startup, and are broken down according to their type. (AV, Storage, Encryption, etc.) Each of those groups are given an altitude range. Within these ranges, each filter driver must have a unique altitude identifier/number, which are provisioned by Microsoft. The groups are loaded as they appear on the stack in relation to their distance from the file system itself.
Load order group | Altitude range | Group description |
---|---|---|
Filter | 420000-429999 | Same as the Filter load order group that was available on Windows 2000 and earlier. This group loads last and thus attaches furthest from the file system. |
FSFilter Top | 400000-409999 | For filter drivers that must attach above all other FSFilter types. |
FSFilter Activity Monitor | 360000-389999 | Includes filter drivers that observe and report on file I/O. |
FSFilter Undelete | 340000-349999 | Includes filters that recover deleted files. |
FSFilter Anti-Virus | 320000-329999 | Includes filter drivers that detect and disinfect viruses during file I/O. |
FSFilter Replication | 300000-309999 | Includes filter drivers that replicate file data to remote servers. |
FSFilter Continuous Backup | 280000-289999 | Includes filter drivers that replicate file data to backup media. |
FSFilter Content Screener | 260000-269999 | Includes filter drivers that prevent the creation of specific files or file content. |
FSFilter Quota Management | 240000-249999 | Includes filter drivers that provide enhanced file system quotas. |
FSFilter System Recovery | 220000-229999 | Includes filter drivers that perform operations to maintain operating system integrity, such as the System Restore (SR) filter. |
FSFilter Cluster File System | 200000-209999 | Includes filter drivers that are used in products that provide file server metadata across a network. |
FSFilter HSM | 180000-189999 | Includes filter drivers that perform hierarchical storage management. |
FSFilter Imaging | 170000-175000 | Includes ZIP-like filter drivers that provide a virtual namespace. |
FSFilter Compression | 160000-169999 | Includes filter drivers that perform file data compression. |
FSFilter Encryption | 140000-149999 | Includes filter drivers that encrypt and decrypt data during file I/O. |
FSFilter Virtualization | 130000- 139999 | Includes filter drivers that virtualize the file path, such as the Least Authorized User (LUA) filter driver added in Windows Vista. |
FSFilter Physical Quota Management | 120000-129999 | Includes filter drivers that manage quotas by using physical block counts. |
FSFilter Open File | 100000-109999 | Includes filter drivers that provide snapshots of already open files. |
FSFilter Security Enhancer | 80000-89999 | Includes filter drivers that apply lockdown and enhanced access control lists (ACLs). |
FSFilter Copy Protection | 60000-69999 | Includes filter drivers that check for out-of-band data on media. |
FSFilter Bottom | 40000-49999 | Provided for filter drivers that must attach below all other FSFilter types. |
FSFilter System | 20000-29999 | Reserved for internal use. |
FSFilter Infrastructure | <20000 | Reserved for internal use. This group loads first and thus attaches closest to the file system. |
Considering that we are primarily interested in EDR altitudes, here are some examples (Altitudes subject to change by Microsoft):
Altitude | EDR | Vendor |
---|---|---|
329355.5 | sentinelmonitor.sys | SentinelOne |
328800 | mbam.sys | Malwarebytes |
328010 | wdfilter.sys | Microsoft |
324050 | sophosed.sys | Sophos |
321410 | csagent.sys | CrowdStrike |
Minifilter Detections
When minifilters are registered on a system, an .inf file is provided that includes requirements for running the driver, the configuration needed, startup type, and load order group. These instructions are used by SetupAPI, which then takes the information and places it into the registry. Within the minifilter, there will be major functions that will be monitored/observed as they align with its purpose. All I/O requests that are sent to drivers are delivered in the form of I/O Request Packets (IRPs). The details surrounding how to write a minifilter are not going to be a part of this post, but here are some major functions that an Anti-Virus/EDR filter might use:
Function Name | Description |
IRP_MJ_CREATE | A new file is being created or a handle to an existing file is being opened. |
IRP_MJ_READ | Data is being read from a file. |
IRP_MJ_WRITE | Data is being written to a file. |
IRP_MJ_CLOSE | A handle to a file object is being closed. |
IRP_MJ_QUERY_SECURITY | The security information about a file is being requested. |
As you can imagine, many of these major functions would be important for monitoring/detection purposes. When these major functions are included in a minifilter, it means that they can view into the IRP itself and determine the purpose of the request. This enables the minifilter to do things like detect data being written to a file or observing process memory activities that are critical to understanding how malware operates. A great example of a program that would use all major functions would be Sysmon.
Minifilter Evasion
One of the ways that malware can evade minifilters is to review the code and determine if there are logic flaws that can be abused. I would venture to say that the comprehensiveness of the minifilter contributes to the accuracy of detection for different AV/EDR products. The weaker the minifilter, the less that endpoint protection agent is going to detect and/or prevent.
While it may not be common, another valid method for evasion is to simply unload the minifilter if you are able to obtain administrative privileges. Earlier in the article, the altitudes of the various products were listed. Some of the less-sophisticated minifilters can be removed by issuing an unload command, passing the altitude of that minifilter. These altitudes are often not going to change, and generally speaking, it is unadvised for them to change.
Lastly, a more creative approach to evasion is to include your own minifilter driver and register it in the system. Once the minifilter is registered, you could change the altitiude of the minifilter to catch the IRPs before other minifilters, and even to prevent I/O operations to reach the EDR minifilters.
Thanks for reading!
Archives
Calendar
M | T | W | T | F | S | S |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 | 29 |
30 | 31 |
Leave a Reply