Quirks of an EDR: Usermode (in progress)

Introduction

EDR vendors solve the same problems, they just do it differently. This causes logical pitfalls to occur. This is a work in progress article about an EDR. A formal representation of my notes. A static ( not dynamic) analysis of different parts of an EDR. I'll highlight some remarks on the usermode components. Kernel mode part might come later. I'll try to be concise and on point. Of course, everything I mention here needs dynamic analysis to verify.

Hook Installation

The EDR installs hooks on a set of API functions in ntdll.dll to log telemetry into ETW by injecting a dll into all processes. Each function meant to be hooked is represented by a 4-part structure whose elements are in order: 
  1. The name of the DLL where it resides.
  2. The name of the API function
  3. A pointer to the original function
  4. The "hook"


The "hook" is a function that calls the original one and logs telemetry. 
The next figure is an example:


After calling the original API function by the pointer in that qword_xxxxxxxx, there is a condition that involves the variable v14

To avoid logging unnecessary telemetry through recursive hooks, this EDR makes use of repurposing a field in the Thread Environment Block because it's thread safe. It increments it, reads it into v14 then decrements it. Later in the checks it verifies if it was incremented more than once.


The used field is at offset 0x1758 from the TEB.


This one is ReservedForOle field which it repurposed here as a counter.


The next diagram illustrates when telemetry is logged (inc/decrementing that ReservedForOld is excluded from the diagram)


The thing is, every thread has access to its own Thread Environment Block Structure. So, it can write a big value in the ReservedForOle field and trick the EDR into thinking it's always inside a hook and thus suppress Telemetry.

Decoy DLLs

While looking at another DLL of the EDR. I came accross this table.


At first, I thought it was a table of suspicious DLL's to be flagged. But it also included a dll belonging to the EDR. Searching online, I found out it does this thing of loading some decoy DLL's. 

It also employs LdrEnumerateLoadedModule API function with a callback that compares loaded DLL names to names in this table and skips monitoring them.


The problem lies in the string comparison function. It implements a sliding window comparison. Which allows XXXXkern3l32.dll to be also whitelisted.


References

https://www.geoffchappell.com/studies/windows/km/ntoskrnl/inc/api/pebteb/teb/index.htm

Comments