Skip to content
KitploitKITPLOIT
ToolsBlog
Log in
Submit
ToolsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

FeedsContactPrivacy© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
EDRSandblast — Weaponizes vulnerable signed drivers to bypass EDR kernel callbacks, object callbacks, ETW TI provider, and userland hooks for LSASS memory dumping and credential extraction. | Kitploit
Tools/GitHubGitHub/wavestone-cdt/edrsandblast
Defensive ToolsPrivilege EscalationExploitationPenetration TestingRed Teaming
GitHubwavestone-cdt/edrsandblast

EDRSandblast

Weaponizes vulnerable signed drivers to bypass EDR kernel callbacks, object callbacks, ETW TI provider, and userland hooks for LSASS memory dumping and credential extraction.

View Repository
1.8k320182 years agoReviewed by Kitploit

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

EDRSandBlast

EDRSandBlast is a tool written in C that weaponize a vulnerable signed driver to bypass EDR detections (Notify Routine callbacks, Object Callbacks and ETW TI provider) and LSASS protections. Multiple userland unhooking techniques are also implemented to evade userland monitoring.

As of release, combination of userland (--usermode) and Kernel-land (--kernelmode) techniques were used to dump LSASS memory under EDR scrutiny, without being blocked nor generating "OS Credential Dumping"-related events in the product (cloud) console. The tests were performed on 3 distinct EDR products and were successful in each case.

Description

EDR bypass through Kernel Notify Routines removal

EDR products use Kernel "Notify Routines" callbacks on Windows to be notified by the kernel of system activity, such as process and thread creation and loading of images (exe / DLL).

These Kernel callbacks are defined from kernel-land, usually from the driver implementing the callbacks, using a number of documented APIs (nt!PsSetCreateProcessNotifyRoutine, nt!PsSetCreateThreadNotifyRoutine, etc.). These APIs add driver-supplied callback routines to undocumented arrays of routines in Kernel-space:

  • PspCreateProcessNotifyRoutine for process creation
  • PspCreateThreadNotifyRoutine for thread creation
  • PspLoadImageNotifyRoutine for image loading

EDRSandBlast enumerates the routines defined in those arrays and remove any callback routine linked to a predefined list of EDR drivers (more than 1000 drivers of security products supported, see the EDR driver detection section. The enumeration and removal are made possible through the exploitation of an arbitrary Kernel memory read / write primitive provided by the exploitation of a vulnerable driver (see Vulnerable drivers section).

The offsets of the aforementioned arrays are recovered using multiple techniques, please refer to Offsets section.

EDR bypass through Object Callbacks removal

EDR (and even EPP) products often register "Object callbacks" through the use of the nt!ObRegisterCallbacks kernel API. These callbacks allow the security product to be notified at each handle generation on specific object types (Processes, Threads and Desktops related object callbacks are now supported by Windows). A handle generation may occur on object opening (call to OpenProcess, OpenThread, etc.) as well as handle duplication (call to DuplicateHandle, etc.).

By being notified by the kernel on each of these operations, a security product may analyze the legitimacy of the handle creation (e.g. an unknown process is trying to open LSASS), and even block it if a threat is detected.

At each callback registration using ObRegisterCallbacks, a new item is added to the CallbackList double-linked list present in the _OBJECT_TYPE object describing the type of object affected by the callback (either a Process, a Thread or a Desktop). Unfortunately, these items are described by a structure that is not documented nor published in symbol files by Microsoft. However, studying it from various ntoskrnl.exe versions seems to indicate that the structure did not change between (at least) Windows 10 builds 10240 and 22000 (from 2015 to 2022).

The mentionned structure, representing an object callback registration, is the following:

typedef struct OB_CALLBACK_ENTRY_t {
    LIST_ENTRY CallbackList; // linked element tied to _OBJECT_TYPE.CallbackList
    OB_OPERATION Operations; // bitfield : 1 for Creations, 2 for Duplications
    BOOL Enabled;            // self-explanatory
    OB_CALLBACK* Entry;      // points to the structure in which it is included
    POBJECT_TYPE ObjectType; // points to the object type affected by the callback
    POB_PRE_OPERATION_CALLBACK PreOperation;      // callback function called before each handle operation
    POB_POST_OPERATION_CALLBACK PostOperation;     // callback function called after each handle operation
    KSPIN_LOCK Lock;         // lock object used for synchronization
} OB_CALLBACK_ENTRY;

The OB_CALLBACK structure mentionned above is also undocumented, and is defined by the following:

typedef struct OB_CALLBACK_t {
    USHORT Version;                           // usually 0x100
    USHORT OperationRegistrationCount;        // number of registered callbacks
    PVOID RegistrationContext;                // arbitrary data passed at registration time
    UNICODE_STRING AltitudeString;            // used to determine callbacks order
    struct OB_CALLBACK_ENTRY_t EntryItems[1]; // array of OperationRegistrationCount items
    WCHAR AltitudeBuffer[1];                  // is AltitudeString.MaximumLength bytes long, and pointed by AltitudeString.Buffer
} OB_CALLBACK;

In order to disable EDR-registered object callbacks, three techniques are implemented in EDRSandblast; however only one is enabled for the moment.

Using the Enabled field of OB_CALLBACK_ENTRY

This is the default technique enabled in EDRSandblast. In order to detect and disable EDR-related object callbacks, the CallbackList list located in the _OBJECT_TYPE objects tied to the Process and Thread types is browsed. Both _OBJECT_TYPEs are pointed by public global symbols in the kernel, PsProcessType and PsThreadType.

Each item of the list is assumed to fit the OB_CALLBACK_ENTRY structure described above (assumption that seems to hold at least in all Windows 10 builds at the time of writing). Functions defined in PreOperation and PostOperation fields are located to checks if they belong to an EDR driver, and if so, callbacks are simply disabled toggling the Enabled flag.

While being a pretty safe technique, it has the inconvenient of relying on an undocumented structure; to reduce the risk of unsafe manipulation of this structure, basic checks are performed to validate that some fields have the expected values :

  • Enabled is either TRUE or FALSE (don't laugh, a BOOL is an int, so it could be anything other than 1 or 0);
  • Operations is OB_OPERATION_HANDLE_CREATE, OB_OPERATION_HANDLE_DUPLICATE or both;
  • ObjectType points on PsProcessType or PsThreadType.

Unlinking the CallbackList of threads and process

Another strategy that do not rely on an undocumented structure (and is thus theoretically more robust against NT kernel changes) is the unlinking of the whole CallbackList for both processes and threads. The _OBJECT_TYPE object is the following:

struct _OBJECT_TYPE {
	LIST_ENTRY TypeList;
	UNICODE_STRING Name;
	[...]
	_OBJECT_TYPE_INITIALIZER TypeInfo;
	[...]
	LIST_ENTRY CallbackList;
}

Making the Flink and Blink pointers of the CallbackList LIST_ENTRY point to the LIST_ENTRY itself effectively make the list empty. Since the _OBJECT_TYPE structure is published in the kernel' symbols, the technique does not rely on hardcoded offsets/structures. However, it has some drawbacks.

The first being not able to only disable callbacks from EDR; indeed, the technique affects all object callbacks that could have been registered by "legitimate" software. It should nevertheless be noted that object callbacks are not used by any pre-installed component on Windows 10 (at the time of writing) so disabling them should not affect the machine stability (even more so if the disabling is only temporary).

Download Tool