Endpoint Detection & Response (EDR) Tools are now hiding themselves under different aliases, running at different layers of the system (kernel, user etc.) and on top of that, more and more products with different nuances are hitting the market all the time.
But why does this matter? Situational awareness is critical to the success of a red team engagement, understanding what defensive products and subsequent insight, detections and capabilities the defenders may have access to is critical in your decision-making process / OODA loop. This loop also needs to be robust and repeatable as you move host to host, network to network, environment to environment.
Historically red team operators have relied on their experience and knowledge to pick out signs of defensive products from process listings and some excellent tools were produced to help with this regex style approach such as Seatbelt or @r3dQu1nn‘s aggressor scripts. The problem with all these tools is that they are just that, a regex or check of one area, e.g. process list, directory, registry etc.
All the above leads to unreliable and inconsistent situational awareness results and none account for the capability many EDR’s such as Carbon Black and SysMon have where they can be renamed on the surface to hide themselves from prying eyes. For those unaware of this feature, when you build a Carbon Black package to roll out to your fleet, you get the option to name the binary anything you want e.g.
audiodrv.exe. The name in the process listing will then be
audiodrv.exe and typically defensive products are privileged processes so as a regular user all you get is the process name. SysMon has the same ability and the renaming extends to its minifilter drivers (.sys) etc, as well.
The solution? Introducing SharpEDRChecker to solve all your situational awareness problems!
SharpEDRChecker is the new and improved C# implementation of my originally developed PowerShell version. It is C2 agnostic and can be reflectively loaded into memory and executed without the need to drop it on disk. It also comes pre-packaged in PoshC2, run “SharpEDRChecker” from the implant handler and it will automatically be loaded and executed.
SharpEDRChecker solves our problems by doing multiple checks across multiple parts of the system, its files and their metadata, crucially including data which cannot be changed because the code signing of the binaries and drivers would become invalidated. This means that despite EDR vendors best efforts, they can no longer hide!
The class-by-class breakdown of the checks are as follows, note that everything is called from the main Program class and most classes leverage the EDRData class. EDRData contains all the company / vendor and product names to check all attributes for. There is also a PrivilegeChecker class used when the program first runs and notifies you of your current user context, if you are not admin then some data may not be available to you, as always do your own due diligence.
Really the crux / backbone of SharpEDRChecker, this is the data / metadata that cannot be changed without invalidating code signing and breaking things. Just about every other *Checker class uses FileChecker as part of their own checks to go grab the following information on exes, DLLs, drivers, etc. which you will see in the following screenshots under “File Metadata”.
- Product Name
- File Name
- Original Filename
- Internal Name
- Company Name
- File Description
- Product Version
- Legal Copyright
- Legal Trademarks
ProcessChecker – Processes
There are two key parts to this class, the first is to inspect all processes running on the system by looking at the following elements for every process:
- Process Name
- CmdLine args
- Process ID
- Parent Process ID
- File Metadata via FileChecker class on the binary from BinaryPath
ProcessChecker – Modloads
The second part of this class checks all the modloads (DLLs loaded) in your current running process, this is important as many defensive products such as Cylance and AMSI will load DLLs into processes.
ProcessChecker will get all modules / DLLs loaded into your implants current running process then run FileChecker against every DLL found to identify any defensive products loaded into your process.
Inspects all installed services regardless of their state and performs similar checks to ProcessChecker. It also reports if the service is running or not which can be useful to know.
- Service Name
- Display Name
- File Metadata via FileChecker on the binary from PathName
The most interesting class from a challenge and development perspective, C# has no way to really get the driver data needed for reliable checks. Enter Platform Invoke, for those not familiar, P/Invoke it is an absolutely excellent project that allows “calling Win32 and other unmanaged APIs from managed code”. To get the data needed, the PSAPI.dll is P/Invoke’d in this class which allows access to “EnumDeviceDrivers”, “GetDeviceDriverBaseName” and “GetDeviceDriverFileName”, more info on PSAPI use for driver info here: https://docs.microsoft.com/en-us/windows/win32/psapi/device-driver-information
Once we have all the driver info it is back to our checks again using the following:
- Driver FileName
- Driver BaseName
- File Metadata via FileChecker on the driver/.sys from DriverPath
The least exciting but just as important for the purposes of being thorough is the DirectoryChecker class which pretty much does what it says on the tin. It will get all subdirectories inside the common install directories; “Program Files”, “Program Files (x86)” and “ProgramData”, then check all those subdirectories against EDRData.
Once the tool has finished running you will get a nice little TLDR summary that surmises the results from each check and gives you the keywords for why (if any) things were flagged. Allowing you as the operator to then review the more in-depth output as required.
In terms of a roadmap, adding new vendors and products to EDRData is a never-ending task, I would love to add remote host checking capability in the future so you can check a host before laterally moving to it. There is a RegistryChecker placeholder class there for when I find a reason to parse through the registry, as of yet, I have found no reason to do so other than for redundancy because it hasn’t given me anything that isn’t already being found elsewhere. Lastly, a Process OpSec check would be nice to tell you OpSec safe processes to migrate into for certain actions / implant types. Maybe in the future I will write a Python version for NIX/OSX as well.
It was a lot of fun writing this tool to help with a crucial part in the red team kill chain and solve the “EDR tooling being able to hide itself” problem in a creative manner. If you have ideas, feature requests or would like to contribute, feel free to reach out to me on Twitter @PwnDexter or open a PR on Github!
Thanks for taking the time to read my ramblings and I hope SharpEDRChecker serves you well in your future engagements!