Skip to content
KitploitKITPLOIT
HerramientasBlog
Enviar
HerramientasBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

··Feeds·Contacto·Privacidad·© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
Herramientas/GitHubGitHub/gabriellandau/edrsandblast-godfault
Herramientas DefensivasEscalada de PrivilegiosForensia de MemoriaExplotaciónPost-ExplotaciónRed TeamingDesarrollo de PayloadsArchived
GitHubgabriellandau/edrsandblast-godfault

EDRSandblast-GodFault

EDRSandblast-GodFault

Ver Repositorio
273509hace 3 añosAún no revisado

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
Compartir

EDRSandblast-GodFault

Por Gabriel Landau en Elastic Security. Modificación de EDRSandblast - vea el README original a continuación.

Integra GodFault en EDR Sandblast, logrando el mismo resultado sin el uso de ningún controlador vulnerable.

Salida de Ejemplo```

C:\Users\user\Desktop\Offsets>EDRSandblast.exe --kernelmode cmd


| | __ | __ \ / | | | | | | | | | | | | | | |) | ( __ _ _ __ | | | | | __ _ | | | | | | | | _ / _ \ / | '_ \ / _ | ' | |/ ` / __| __| | || || | | \ \ ) | (| | | | | (| | |) | | (| _ | | ||_____/|| _|/ _,|| ||_,|_./||_,|__/__|

D3FC0N 30 Edition | Thomas DIOT (@_Qazeer) & Maxime MEIGNAN (@th3m4ks)

[!] If kernel mode bypass is enabled, it is recommended to enable usermode bypass as well (e.g. to unhook the NtLoadDriver API call)

[===== KERNEL MODE =====]

[+] Setting up prerequisites for the kernel read/write primitives... [+] Loading kernel related offsets from the CSV file [*] System's ntoskrnl.exe file version is: ntoskrnl_22621-1702.exe [+] Offsets are available for this version of ntoskrnl.exe (ntoskrnl_22621-1702.exe)! [+] Checking if any EDR kernel notify rountines are set for image loading, process and thread creations... [+] [NotifyRountines] Enumerating process creation callbacks [+] Running command: GodFault.exe -t 2684 [?] Server does not appear to be running. Attempting to install it... [+] CSRSS PID is 748 [+] Testing initial ability to acquire PROCESS_ALL_ACCESS to System: Failure [+] Ready. Spawning WinTcb. [+] SpawnPPL: Waiting for child process to finish. [+] Thread 2684 (KTHREAD FFFF910961E4C080) has been blessed by GodFault [+] [NotifyRountines] fffff8034df25500 [cng.sys + 0x5500] [+] [NotifyRountines] fffff8034e9efdc0 [WdFilter.sys + 0x4fdc0] [+] [NotifyRountines] Found callback belonging to EDR driver WdFilter.sys [+] [NotifyRountines] fffff803487bc460 [ksecdd.sys + 0x1c460] [+] [NotifyRountines] fffff8034eff3fd0 [tcpip.sys + 0x13fd0] [+] [NotifyRountines] fffff8034f5ed980 [iorate.sys + 0xd980] [+] [NotifyRountines] fffff8034dea8890 [CI.dll + 0x88890] [+] [NotifyRountines] fffff803525079f0 [dxgkrnl.sys + 0x179f0] [+] [NotifyRountines] fffff80352be0a70 [vm3dmp.sys + 0x10a70] [+] [NotifyRountines] fffff8036ebccd00 [peauth.sys + 0x3cd00] [+] [NotifyRountines] fffff8036eda1550 [wtd.sys + 0x1550] [+] [NotifyRountines] Found a total of 1 EDR / security products driver(s) [+] [NotifyRountines] Enumerating thread creation callbacks [+] [NotifyRountines] fffff8034e9f15c0 [WdFilter.sys + 0x515c0] [+] [NotifyRountines] Found callback belonging to EDR driver WdFilter.sys [+] [NotifyRountines] fffff8034e9f1350 [WdFilter.sys + 0x51350] [+] [NotifyRountines] Found callback belonging to EDR driver WdFilter.sys [+] [NotifyRountines] fffff8036eb71010 [mmcss.sys + 0x1010] [+] [NotifyRountines] Found a total of 2 EDR / security products driver(s) [+] [NotifyRountines] Enumerating image loading callbacks [+] [NotifyRountines] fffff8034e9f0820 [WdFilter.sys + 0x50820] [+] [NotifyRountines] Found callback belonging to EDR driver WdFilter.sys [+] [NotifyRountines] fffff80352ab5710 [ahcache.sys + 0x25710] [+] [NotifyRountines] Found a total of 1 EDR / security products driver(s)

Descargar herramienta

[+] Checking if EDR callbacks are registered on processes and threads handle creation/duplication... [+] [ObjectCallblacks] Enumerating Process object callbacks : [+] [ObjectCallblacks] Callback at FFFF800C5E2F2940 for handle creations & duplications: [+] [ObjectCallblacks] Status: Enabled [+] [ObjectCallblacks] Preoperation at 0xfffff8034e9eda30 [WdFilter.sys + 0x4da30] [+] [ObjectCallblacks] Callback belongs to an EDR and is enabled! [+] [ObjectCallblacks] Enumerating Thread object callbacks : [+] [ObjectCallblacks] Object callbacks are present !

[+] [ETWTI] Checking the ETW Threat Intelligence Provider state... [+] [ETWTI] ETW Threat Intelligence Provider is ENABLED!

[+] Process is NOT "safe" to launch our payload, removing monitoring and starting another process...

[+] [ETWTI] Disabling the ETW Threat Intel provider by patching ProviderEnableInfo at 0xffff91095ce8c430 with 0x00. [+] [ETWTI] The ETW Threat Intel provider was successfully disabled!

[+] Removing kernel callbacks registered by EDR for process creation, thread creation and image loading... [+] [NotifyRountines] Removing process creation callbacks [+] [NotifyRountines] Removing callback of EDR driver "WdFilter.sys" [callback addr: 0xfffff8034970c2a8 | callback struct: 0xffff91095dbf3a5f | callback function: 0xfffff8034e9efdc0] [+] [NotifyRountines] Removing thread creation callbacks [+] [NotifyRountines] Removing callback of EDR driver "WdFilter.sys" [callback addr: 0xfffff8034970c4a0 | callback struct: 0xffff91095dbf3b1f | callback function: 0xfffff8034e9f15c0] [+] [NotifyRountines] Removing callback of EDR driver "WdFilter.sys" [callback addr: 0xfffff8034970c4a8 | callback struct: 0xffff91095dbf3b4f | callback function: 0xfffff8034e9f1350] [+] [NotifyRountines] Removing image loading callbacks [+] [NotifyRountines] Removing callback of EDR driver "WdFilter.sys" [callback addr: 0xfffff8034970c6a0 | callback struct: 0xffff91095dbf3e4f | callback function: 0xfffff8034e9f0820]

[+] Disabling kernel callbacks registered by EDR for process and thread opening or handle duplication... [+] [ObjectCallblacks] Disabling WdFilter.sys callback...

[+] All EDR drivers were successfully removed from Kernel callbacks!

================================================== Starting a new unmonitored process...

[!] If kernel mode bypass is enabled, it is recommended to enable usermode bypass as well (e.g. to unhook the NtLoadDriver API call)

[===== KERNEL MODE =====]

[+] Setting up prerequisites for the kernel read/write primitives... [+] Loading kernel related offsets from the CSV file [*] System's ntoskrnl.exe file version is: ntoskrnl_22621-1702.exe [+] Offsets are available for this version of ntoskrnl.exe (ntoskrnl_22621-1702.exe)! [+] Checking if any EDR kernel notify rountines are set for image loading, process and thread creations... [+] [NotifyRountines] Enumerating process creation callbacks [+] Running command: GodFault.exe -t 8344 [+] Thread 8344 (KTHREAD FFFF91096169F080) has been blessed by GodFault [+] Initial blessing successful [+] [NotifyRountines] fffff8034df25500 [cng.sys + 0x5500] [+] [NotifyRountines] fffff803487bc460 [ksecdd.sys + 0x1c460] [+] [NotifyRountines] fffff8034eff3fd0 [tcpip.sys + 0x13fd0] [+] [NotifyRountines] fffff8034f5ed980 [iorate.sys + 0xd980] [+] [NotifyRountines] fffff8034dea8890 [CI.dll + 0x88890] [+] [NotifyRountines] fffff803525079f0 [dxgkrnl.sys + 0x179f0] [+] [NotifyRountines] fffff80352be0a70 [vm3dmp.sys + 0x10a70] [+] [NotifyRountines] fffff8036ebccd00 [peauth.sys + 0x3cd00] [+] [NotifyRountines] fffff8036eda1550 [wtd.sys + 0x1550] [+] [NotifyRountines] No EDR driver(s) found! [+] [NotifyRountines] Enumerating thread creation callbacks [+] [NotifyRountines] fffff8036eb71010 [mmcss.sys + 0x1010] [+] [NotifyRountines] No EDR driver(s) found! [+] [NotifyRountines] Enumerating image loading callbacks [+] [NotifyRountines] fffff80352ab5710 [ahcache.sys + 0x25710] [+] [NotifyRountines] No EDR driver(s) found!

[+] Checking if EDR callbacks are registered on processes and threads handle creation/duplication... [+] [ObjectCallblacks] Enumerating Process object callbacks : [+] [ObjectCallblacks] Callback at FFFF800C5E2F2940 for handle creations & duplications: [+] [ObjectCallblacks] Status: Disabled [+] [ObjectCallblacks] Preoperation at 0xfffff8034e9eda30 [WdFilter.sys + 0x4da30] [+] [ObjectCallblacks] Callback belongs to an EDR but is disabled. [+] [ObjectCallblacks] Enumerating Thread object callbacks : [+] [ObjectCallblacks] Object callbacks are not found !

[+] [ETWTI] Checking the ETW Threat Intelligence Provider state... [+] [ETWTI] ETW Threat Intelligence Provider is DISABLED!

[+] Process is "safe" to launch our payload

[+] Kernel callbacks have normally been removed, starting cmd.exe WARNING: EDR kernel callbacks will be restored after exiting the cmd prompt (by typing exit) WARNING: While unlikely, the longer the callbacks are removed, the higher the chance of being detected / causing a BSoD upon restore is!

Microsoft Windows [Version 10.0.22621.1702] (c) Microsoft Corporation. All rights reserved.

C:\Users\user\Desktop\Offsets>

root@kitploit:~
# EDRSandBlast

`EDRSandBlast` es una herramienta escrita en `C` que utiliza un controlador firmado vulnerable para evadir las detecciones de EDR (callbacks de rutinas de notificación, callbacks de objetos y el proveedor `ETW TI`) y las protecciones de `LSASS`. También se implementan múltiples técnicas de unhooking en modo usuario para evadir la monitorización en modo usuario.

En el momento del lanzamiento, se utilizó una combinación de técnicas de modo usuario (`--usermode`) y modo kernel (`--kernelmode`) para volcar la memoria de `LSASS` bajo el escrutinio de un EDR, sin ser bloqueado ni generar eventos relacionados con "Volcado de credenciales del SO" en la consola (en la nube) del producto. Las pruebas se realizaron en 3 productos EDR distintos y fueron exitosas en cada caso.

## Descripción

### Omisión de EDR mediante la eliminación de rutinas de notificación del kernel

Los productos EDR utilizan callbacks de "Notify Routines" del kernel en Windows para ser notificados por el kernel de la actividad del sistema, como la creación de procesos e hilos y la carga de imágenes (`exe` / `DLL`).

Estos callbacks del kernel se definen desde el espacio del kernel, generalmente desde el controlador que implementa los callbacks, utilizando una serie de APIs documentadas (`nt!PsSetCreateProcessNotifyRoutine`, `nt!PsSetCreateThreadNotifyRoutine`, etc.). Estas APIs añaden rutinas de callback proporcionadas por el controlador a arrays no documentados de rutinas en el espacio del kernel:
  - `PspCreateProcessNotifyRoutine` para la creación de procesos
  - `PspCreateThreadNotifyRoutine` para la creación de hilos
  - `PspLoadImageNotifyRoutine` para la carga de imágenes

`EDRSandBlast` enumera las rutinas definidas en esos arrays y elimina cualquier rutina de callback vinculada a una lista predefinida de controladores EDR (más de 1000 controladores de productos de seguridad compatibles; consulte la [sección de detección de controladores EDR](#detección-de-controladores-y-procesos-edr)). La enumeración y eliminación son posibles gracias a la explotación de una primitiva arbitraria de lectura/escritura de memoria del kernel proporcionada por la explotación de un controlador vulnerable (consulte la [sección de controladores vulnerables](#detección-de-controladores-vulnerables)).

Los offsets de los arrays mencionados se recuperan mediante múltiples técnicas; consulte la [sección de offsets](#offsets-de-ntoskrnl-y-wdigest).

### Omisión de EDR mediante la eliminación de callbacks de objetos

Los productos EDR (e incluso EPP) a menudo registran "callbacks de objetos" mediante el uso de la API del kernel `nt!ObRegisterCallbacks`. Estos callbacks permiten que el producto de seguridad sea notificado en cada generación de handles sobre tipos de objetos específicos (Windows ahora admite callbacks de objetos relacionados con procesos, hilos y escritorios). Una generación de handle puede ocurrir al abrir un objeto (llamada a `OpenProcess`, `OpenThread`, etc.) así como al duplicar un handle (llamada a `DuplicateHandle`, etc.).

Al ser notificado por el kernel en cada una de estas operaciones, un producto de seguridad puede analizar la legitimidad de la creación del handle (por ejemplo, un proceso desconocido intenta abrir LSASS) e incluso bloquearlo si se detecta una amenaza.

En cada registro de callback mediante `ObRegisterCallbacks`, se añade un nuevo elemento a la lista doblemente enlazada `CallbackList` presente en el objeto `_OBJECT_TYPE` que describe el tipo de objeto afectado por el callback (ya sea un proceso, un hilo o un escritorio). Desafortunadamente, estos elementos se describen mediante una estructura que no está documentada ni publicada en los archivos de símbolos por Microsoft. Sin embargo, estudiarla a partir de varias versiones de `ntoskrnl.exe` parece indicar que la estructura no cambió entre (al menos) las compilaciones 10240 y 22000 de Windows 10 (de 2015 a 2022).

La estructura mencionada, que representa un registro de callback de objeto, es la siguiente:```C
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;

La estructura OB_CALLBACK mencionada anteriormente también está sin documentar, y está definida por lo siguiente:```C 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;

root@kitploit:~
Para deshabilitar las devoluciones de llamada de objetos registradas por EDR, se implementan tres técnicas en
`EDRSandblast`; sin embargo, solo una está habilitada por el momento.

#### Usando el campo `Enabled` de `OB_CALLBACK_ENTRY`
Esta es la técnica predeterminada habilitada en `EDRSandblast`. Para detectar y deshabilitar
las devoluciones de llamada de objetos relacionadas con EDR, se recorre la lista `CallbackList` ubicada en los objetos `_OBJECT_TYPE`
vinculados a los tipos *Process* y *Thread*. Ambos `_OBJECT_TYPE` son
señalados por símbolos globales públicos en el kernel, `PsProcessType` y `PsThreadType`.

Se asume que cada elemento de la lista se ajusta a la estructura `OB_CALLBACK_ENTRY` descrita anteriormente
(suposición que parece cumplirse al menos en todas las versiones de Windows 10 al momento de escribir esto).
Las funciones definidas en los campos `PreOperation` y `PostOperation` se localizan para verificar
si pertenecen a un controlador EDR, y si es así, las devoluciones de llamada simplemente se deshabilitan alternando el indicador `Enabled`.

Si bien es una técnica bastante segura, tiene el inconveniente de depender de una estructura
no documentada; para reducir el riesgo de manipulación insegura de esta estructura, se realizan
verificaciones básicas para validar que algunos campos tengan los valores esperados:
* `Enabled` es `TRUE` o `FALSE` (*no te rías, un `BOOL` es un `int`, por lo que podría ser cualquier cosa que no sea `1` o `0`*);
* `Operations` es `OB_OPERATION_HANDLE_CREATE`,  `OB_OPERATION_HANDLE_DUPLICATE` o ambos;
* `ObjectType` apunta a `PsProcessType` o `PsThreadType`.

#### Desvinculando la `CallbackList` de hilos y procesos
Otra estrategia que no depende de una estructura no documentada (y por lo tanto es teóricamente
más robusta frente a cambios del kernel NT) es la desvinculación de toda la `CallbackList`
tanto para procesos como para hilos. El objeto `_OBJECT_TYPE` es el siguiente:```C
struct _OBJECT_TYPE {
	LIST_ENTRY TypeList;
	UNICODE_STRING Name;
	[...]
	_OBJECT_TYPE_INITIALIZER TypeInfo;
	[...]
	LIST_ENTRY CallbackList;
}

Haciendo que los punteros Flink y Blink de la LIST_ENTRY del CallbackList apunten a la LIST_ENTRY misma, se vacía efectivamente la lista. Dado que la estructura _OBJECT_TYPE está publicada en los símbolos del núcleo, la técnica no depende de desplazamientos/estructuras hardcodeadas. Sin embargo, tiene algunos inconvenientes.

El primero es no poder deshabilitar únicamente las devoluciones de llamada del EDR; de hecho, la técnica afecta a todas las devoluciones de llamada de objetos que podrían haber sido registradas por software "legítimo". No obstante, cabe señalar que las devoluciones de llamada de objetos no son utilizadas por ningún componente preinstalado en Windows 10 (en el momento de escribir esto), por lo que deshabilitarlas no debería afectar la estabilidad de la máquina (incluso menos si la desactivación es solo temporal).

El segundo inconveniente es que las operaciones de identificadores de procesos o subprocesos son realmente frecuentes (casi continuas) en el funcionamiento normal del sistema operativo. Por lo tanto, si la primitiva de escritura en el núcleo utilizada no puede realizar una escritura QWORD "atómicamente", existe una alta probabilidad de que el núcleo acceda al puntero _OBJECT_TYPE.CallbackList.Flink en medio de su sobrescritura. Por ejemplo, el controlador vulnerable MSI RTCore64.sys solo puede realizar una escritura DWORD a la vez, por lo que se necesitarán 2 IOCTL distintos para sobrescribir el puntero, entre los cuales el núcleo tiene una alta probabilidad de usarlo (lo que resulta en un fallo). Por otro lado, el controlador vulnerable DELL DBUtil_2_3.sys puede realizar escrituras de tamaños arbitrarios en un solo IOCTL, por lo que usar este método con él no corre el riesgo de causar un fallo.

Deshabilitar las devoluciones de llamada de objetos por completo

Una última técnica que encontramos fue deshabilitar completamente el soporte de devoluciones de llamada de objetos para subprocesos y procesos. Dentro de la estructura _OBJECT_TYPE correspondiente a los tipos de proceso y subproceso reside un campo TypeInfo, que sigue la estructura documentada _OBJECT_TYPE_INITIALIZER. Esta última contiene un campo de bits ObjectTypeFlags, cuya bandera SupportsObjectCallbacks determina si el tipo de objeto descrito (Proceso, Subproceso, Escritorio, Token, Archivo, etc.) admite o no el registro de devoluciones de llamada de objetos. Como se indicó anteriormente, solo los tipos de objeto Proceso, Subproceso y Escritorio admiten estas devoluciones de llamada en una instalación de Windows en el momento de escribir esto.

Dado que el bit SupportsObjectCallbacks es verificado por ObpCreateHandle o ObDuplicateObject incluso antes de leer el CallbackList (y antes de ejecutar las devoluciones de llamada, por supuesto), invertir el bit en tiempo de ejecución del núcleo deshabilita efectivamente la ejecución de todas las devoluciones de llamada de objetos.

El principal inconveniente del método es simplemente que KPP ("PatchGuard") monitorea la integridad de algunas (¿todas?) estructuras _OBJECT_TYPE y desencadena una 0x109 Bug Check con el parámetro 4 igual a 0x8, lo que significa que una estructura de tipo de objeto ha sido alterada.

Sin embargo, realizar la desactivación / reactivación (y la acción "maliciosa" intermedia) lo suficientemente rápido debería ser suficiente para "adelantarse" a PatchGuard (a menos que tenga mala suerte y se realice una verificación periódica justo en el momento equivocado).

Bypass de EDR mediante la desactivación del proveedor ETW Microsoft-Windows-Threat-Intelligence

El proveedor ETW Microsoft-Windows-Threat-Intelligence registra datos sobre los usos de algunas API de Windows comúnmente utilizadas de forma maliciosa. Esto incluye la API nt!MiReadWriteVirtualMemory, llamada por nt!NtReadVirtualMemory (que se utiliza para volcar la memoria de LSASS) y monitoreada por la función nt!EtwTiLogReadWriteVm.

Los productos EDR pueden consumir los registros producidos por el proveedor ETW TI a través de servicios o procesos que se ejecutan como, respectivamente, SERVICE_LAUNCH_PROTECTED_ANTIMALWARE_LIGHT o PS_PROTECTED_ANTIMALWARE_LIGHT, y asociados con un controlador Early Launch Anti Malware (ELAM).

Como publicó slaeryan en una publicación del blog de CNO Development Labs, el proveedor ETW TI se puede deshabilitar por completo parcheando, en la memoria del núcleo, su atributo ProviderEnableInfo a 0x0. Consulte la excelente publicación del blog mencionada anteriormente para obtener más información sobre la técnica.

De manera similar a la eliminación de devoluciones de llamada del núcleo, los desplazamientos necesarios de ntoskrnl.exe (nt!EtwThreatIntProvRegHandleOffset, GuidEntry de _ETW_REG_ENTRY y ProviderEnableInfo de _ETW_GUID_ENTRY) se calculan en el archivo NtoskrnlOffsets.csv para varias versiones del núcleo de Windows.

Bypass de EDR mediante bypass de hooking en espacio de usuario

Cómo funciona el hooking en espacio de usuario

Para monitorear fácilmente las acciones realizadas por los procesos, los productos EDR a menudo implementan un mecanismo llamado hooking en espacio de usuario. Primero, los productos EDR registran una devolución de llamada del núcleo (generalmente devoluciones de llamada de carga de imagen o creación de proceso, ver arriba) que les permite ser notificados al inicio de cada proceso.

Cuando un proceso es cargado por Windows, y antes de que realmente se inicie, el EDR puede inyectar una DLL personalizada en el espacio de direcciones del proceso, que contiene su lógica de monitoreo. Durante la carga, esta DLL inyecta "hooks" al inicio de cada función que debe ser monitoreada por el EDR. En tiempo de ejecución, cuando las funciones monitoreadas son llamadas por el proceso bajo vigilancia, estos hooks redirigen el flujo de control a algún código de supervisión presente en la DLL del EDR, lo que le permite inspeccionar argumentos y valores de retorno de estas llamadas.

La mayoría de las veces, las funciones monitoreadas son llamadas al sistema (como NtReadVirtualMemory, NtOpenProcess, etc.), cuyas implementaciones residen en ntdll.dll. Interceptar llamadas a funciones Nt* permite a los productos estar lo más cerca posible del límite entre el espacio de usuario y el espacio del núcleo (permaneciendo en el espacio de usuario), pero también se pueden monitorear funciones de algunas DLL de nivel superior.

A continuación se muestran ejemplos de la misma función, antes y después de ser enganchada por el producto EDR:```assembly NtProtectVirtualMemory proc near mov r10, rcx mov eax, 50h test byte ptr ds:7FFE0308h, 1 jnz short loc_18009D1E5 syscall retn loc_18009D1E5: int 2Eh retn NtProtectVirtualMemory endp

root@kitploit:~
#### `--validate`

Especificar `--validate` le indica a Linkly que realice validación de enlaces usando solicitudes HTTP HEAD. Esta funcionalidad verifica que los enlaces en tus archivos estén accesibles.

Esta bandera también se puede proporcionar mediante la variable de entorno:

- **Variable de entorno**: `LINKLY_VALIDATE`
  - `true` - Realizar validación de enlaces para todos los archivos
  - `false` - No validar enlaces```assembly
NtProtectVirtualMemory proc near
	jmp     sub_7FFC74490298     ; --> "hook", jump to EDR analysis function
	int 3                        ; overwritten instructions
	int 3                        ; overwritten instructions
	int 3                        ; overwritten instructions
	test byte_7FFE0308, 1        ; <-- execution resumes here after analysis
	jnz short loc_7FFCB44AD1E5
	syscall
	retn
loc_7FFCB44AD1E5:
	int 2Eh
	retn
NtProtectVirtualMemory   endp			

Detección de hooks

Los hooks en el espacio de usuario tienen la "debilidad" de estar ubicados en la memoria de usuario, lo que significa que son directamente observables y modificables por el proceso bajo análisis. Para detectar automáticamente hooks en el espacio de direcciones del proceso, la idea principal es comparar las diferencias entre la DLL original en disco y la biblioteca residente en memoria, que ha sido potencialmente alterada por un EDR. Para realizar esta comparación, EDRSandblast sigue los siguientes pasos:

  • La lista de todas las DLL cargadas se enumera gracias a InLoadOrderModuleList ubicada en el PEB (para evitar llamar a cualquier API que pudiera estar monitorizada y ser sospechosa)
  • Para cada DLL cargada, se lee su contenido en disco y se analizan sus cabeceras. La biblioteca correspondiente, residente en memoria, también se analiza para identificar secciones, exportaciones, etc.
  • Se analizan y aplican las reubicaciones de la DLL, teniendo en cuenta la dirección base de la biblioteca cargada correspondiente. Esto permite que el contenido de la biblioteca en memoria y la DLL del disco tengan exactamente el mismo contenido (en las secciones donde se aplican las reubicaciones), haciendo así que la comparación sea fiable.
  • Se enumeran las funciones exportadas y se comparan los primeros bytes de las versiones "en memoria" y "en disco". Cualquier diferencia indica una alteración que se ha realizado después de que la DLL se cargara, y por lo tanto es muy probablemente un hook de EDR.

Nota: El proceso se puede generalizar para encontrar diferencias en cualquier lugar de las secciones no escribibles y no solo al inicio de las funciones exportadas, por ejemplo, si los productos EDR comienzan a aplicar hooks en medio de las funciones :) Por lo tanto, no se usa en la herramienta, pero se ha implementado en findDiffsInNonWritableSections.

Para eludir la monitorización realizada por estos hooks, son posibles múltiples técnicas, y cada una tiene ventajas e inconvenientes.

Bypass de hooks usando... desenganche

El método más intuitivo para evitar la monitorización basada en hooks es eliminar los hooks. Dado que los hooks están presentes en la memoria a la que el propio proceso puede acceder, para eliminar un hook, el proceso puede simplemente:

  • Cambiar los permisos de la página donde se encuentra el hook (RX -> RWX o RW)
  • Escribir los bytes originales que se conocen gracias al contenido de la DLL en disco
  • Volver a cambiar los permisos a RX

Este enfoque es bastante simple y se puede utilizar para eliminar todos los hooks detectados de una sola vez. Realizado por una herramienta ofensiva al principio, permite que el resto del código sea completamente ajeno al mecanismo de enganche y funcione normalmente sin ser monitorizado.

Sin embargo, tiene dos inconvenientes principales. Es probable que el EDR esté monitorizando el uso de NtProtectVirtualMemory, por lo que usarlo para cambiar los permisos de la página donde se han instalado los hooks es (al menos conceptualmente) una mala idea. Además, si el EDR ejecuta un hilo y periódicamente verifica la integridad de los hooks, esto también podría provocar alguna detección.

Para detalles de implementación, consulte la ruta de código de la función unhook() cuando unhook_method es UNHOOK_WITH_NTPROTECTVIRTUALMEMORY.

Nota importante: por simplicidad, esta técnica está implementada en EDRSandblast como la técnica base utilizada para mostrar las otras técnicas de bypass; cada una de ellas demuestra cómo obtener una versión no monitorizada de NtProtectVirtualMemory, pero realiza la misma operación después (desenganchar un hook específico).

Bypass de hooks usando un trampolín personalizado

Para evitar un hook específico, es posible simplemente "saltar por encima" y ejecutar el resto de la función tal cual. Primero, se deben recuperar los bytes originales de la función monitorizada, que han sido sobrescritos por el EDR para instalar el hook, a partir del archivo DLL. En nuestro ejemplo de código anterior, estos serían los bytes correspondientes a las siguientes instrucciones:```assembly mov r10, rcx mov eax, 50h

root@kitploit:~
Identificar estos bytes es una tarea sencilla, ya que podemos realizar un *diff* limpio de
ambas versiones de la biblioteca (en memoria y en disco), como se describió anteriormente. Luego,
ensamblamos una instrucción de salto que está diseñada para redirigir el flujo de control al código
que sigue inmediatamente después del hook, en la dirección `NtProtectVirtualMemory +
sizeof(overwritten_instructions)````assembly
jmp NtProtectVirtualMemory+8

Finalmente, concatenamos estos opcodes, los almacenamos en memoria ejecutable (recién creada) y mantenemos un puntero a ellos. Este objeto se denomina "trampolín" y puede usarse como puntero a función, estrictamente equivalente a la función original NtProtectVirtualMemory.

El principal beneficio de esta técnica, como para todas las técnicas siguientes, es que el hook nunca se borra, por lo que cualquier verificación de integridad realizada por el EDR sobre los hooks debería pasar. Sin embargo, requiere asignar memoria primero escribible y luego ejecutable, lo cual es típico de una asignación de shellcode, atrayendo así el escrutinio del EDR.

Para detalles de implementación, consulte la ruta de código de la función unhook() cuando unhook_method es UNHOOK_WITH_INHOUSE_NTPROTECTVIRTUALMEMORY_TRAMPOLINE. Recuerde que la técnica solo se muestra en nuestra implementación y, al final, se utiliza para eliminar hooks de la memoria, como todas las técnicas siguientes.

Bypass de hooks usando el propio trampolín del EDR

El producto EDR, para que su hook funcione, debe guardar en algún lugar de la memoria los opcodes que ha eliminado. Peor aún (o "mejor", desde el punto de vista del atacante), para usar efectivamente las instrucciones originales, el EDR probablemente se ha asignado un trampolín en algún lugar para ejecutar la función original después de interceptar la llamada.

Este trampolín se puede buscar y usar como reemplazo de la función hookeada, sin necesidad de asignar memoria ejecutable, ni llamar a ninguna API excepto VirtualQuery, que probablemente no está monitorizada por ser una función inocua.

Para encontrar el trampolín en memoria, recorremos todo el espacio de direcciones usando VirtualQuery buscando memoria confirmada y ejecutable. Para cada región de memoria de este tipo, la escaneamos buscando una instrucción de salto que tenga como destino la dirección que sigue a las instrucciones sobrescritas (NtProtectVirtualMemory+8 en nuestro ejemplo anterior). El trampolín se puede usar entonces para llamar a la función hookeada sin disparar el hook.

Esta técnica funciona sorprendentemente bien, ya que recupera casi todos los trampolines en los EDR probados. Para detalles de implementación, consulte la ruta de código de la función unhook() cuando unhook_method es UNHOOK_WITH_EDR_NTPROTECTVIRTUALMEMORY_TRAMPOLINE.

Bypass de hooks usando un DLL duplicado

Otro método simple para obtener acceso a una versión no monitorizada de la función NtProtectVirtualMemory es cargar una versión duplicada de la biblioteca ntdll.dll en el espacio de direcciones del proceso. Dado que dos DLL idénticos pueden cargarse en el mismo proceso, siempre que tengan nombres diferentes, podemos simplemente copiar el archivo legítimo ntdll.dll en otra ubicación, cargarlo usando LoadLibrary (o reimplementar el proceso de carga), y acceder a la función usando GetProcAddress por ejemplo.

Esta técnica es muy simple de entender e implementar, y tiene una probabilidad decente de éxito, ya que la mayoría de los productos EDR no reinstalan hooks en DLL recién cargados una vez que el proceso está en ejecución. Sin embargo, el gran inconveniente es que copiar binarios firmados por Microsoft bajo un nombre diferente a menudo se considera sospechoso por parte de los propios productos EDR.

No obstante, esta técnica está implementada en EDRSandblast. Para detalles de implementación, consulte la ruta de código de la función unhook() cuando unhook_method es UNHOOK_WITH_DUPLICATE_NTPROTECTVIRTUALMEMORY.

Bypass de hooks usando syscalls directas

Para utilizar funciones relacionadas con llamadas al sistema, un programa puede reimplementar syscalls (en ensamblador) para llamar a las características correspondientes del SO sin tocar realmente el código en ntdll.dll, que podría estar monitorizado por el EDR. Esto evita completamente cualquier hookeo en modo usuario realizado sobre funciones syscall en ntdll.dll.

Esto tiene, no obstante, algunos inconvenientes. Primero, implica poder conocer la lista de números de syscall de las funciones que el programa necesita, la cual cambia para cada versión de Windows. Esto se mitiga implementando múltiples heurísticas que se sabe que funcionan en todas las versiones anteriores de Windows NT (ordenar las exportaciones Zw* de ntdll, buscar la instrucción mov rax, #syscall_number en la función ntdll asociada, etc.), y comprobar que todas devuelven el mismo resultado (véase Syscalls.c para más detalles).

Además, las funciones que no son técnicamente syscalls (por ejemplo, LoadLibraryX/LdrLoadDLL) también podrían estar monitorizadas y no pueden simplemente reimplementarse usando una syscall.

La técnica de syscalls directas está implementada en EDRSandblast. Como se mencionó anteriormente, solo se utiliza para ejecutar NtProtectVirtualMemory de forma segura y eliminar todos los hooks detectados.

Para detalles de implementación, consulte la ruta de código de la función unhook() cuando unhook_method es UNHOOK_WITH_DIRECT_SYSCALL.

Explotación de controladores vulnerables

Como se mencionó anteriormente, cada acción que necesita una lectura o escritura de memoria del kernel depende de un controlador vulnerable para proporcionar esta primitiva. En EDRSanblast, agregar soporte para un nuevo controlador que proporcione la primitiva de lectura/escritura se puede hacer "fácilmente", solo es necesario implementar tres funciones:

  • Una función ReadMemoryPrimitive_DRIVERNAME(SIZE_T Size, DWORD64 Address, PVOID Buffer) que copia Size bytes desde la dirección de kernel Address al buffer de espacio de usuario Buffer;
  • Una función WriteMemoryPrimitive_DRIVERNAME(SIZE_T Size, DWORD64 Address, PVOID Buffer) que copia Size bytes desde el buffer de espacio de usuario Buffer a la dirección de kernel Address;
  • Una función CloseDriverHandle_DRIVERNAME() que garantiza que todos los manejadores del controlador estén cerrados (necesario antes de la operación de desinstalación, que es independiente del controlador, por el momento).

Como ejemplo, actualmente dos controladores son compatibles con EDRSandblast: RTCore64.sys (SHA256: 01AA278B07B58DC46C84BD0B1B5C8E9EE4E62EA0BF7A695862444AF32E87F1FD) y DBUtils_2_3.sys (SHA256: 0296e2ce999e67c76352613a718e11516fe1b0efc3ffdb8918fc999dd76a73a5). El siguiente código en KernelMemoryPrimitives.h debe actualizarse si el controlador vulnerable utilizado necesita cambiarse, o si se implementa uno nuevo.```C #define RTCore 0 #define DBUtil 1 // Select the driver to use with the following #define #define VULN_DRIVER RTCore

#if VULN_DRIVER == RTCore #define DEFAULT_DRIVER_FILE TEXT("RTCore64.sys") #define CloseDriverHandle CloseDriverHandle_RTCore #define ReadMemoryPrimitive ReadMemoryPrimitive_RTCore #define WriteMemoryPrimitive WriteMemoryPrimitive_RTCore #elif VULN_DRIVER == DBUtil #define DEFAULT_DRIVER_FILE TEXT("DBUtil_2_3.sys") #define CloseDriverHandle CloseDriverHandle_DBUtil #define ReadMemoryPrimitive ReadMemoryPrimitive_DBUtil #define WriteMemoryPrimitive WriteMemoryPrimitive_DBUtil #endif

root@kitploit:~
### Detección de controladores y procesos EDR
Actualmente se utilizan múltiples técnicas para determinar si un controlador o proceso específico
pertenece o no a un producto EDR.

En primer lugar, el nombre del controlador puede usarse simplemente para ese propósito. De hecho, Microsoft
asigna números específicos llamados "Altitudes" para todos los controladores que necesitan insertar callbacks
en el kernel. Esto permite un orden determinista en la ejecución de los callbacks, independiente del
orden de registro, pero basado únicamente en el uso del controlador. Una lista de (fabricantes de) controladores
que han reservado *altitude* específico se puede encontrar
[en MSDN](https://docs.microsoft.com/en-us/windows-hardware/drivers/ifs/allocated-altitudes).
Como consecuencia, Microsoft ofrece una lista casi exhaustiva de nombres de controladores de seguridad vinculados a
productos de seguridad, principalmente en las listas "FSFilter Anti-Virus" y "FSFilter Activity
Monitor". Estas listas de nombres de controladores están incrustadas en EDRSandblast, así como
contribuciones adicionales.

Además, los ejecutables y DLL de EDR suelen estar firmados digitalmente con el
certificado de firma del fabricante. Por lo tanto, verificar el firmante de un ejecutable o DLL
asociado a un proceso puede permitir identificar rápidamente productos EDR.

Además, los controladores deben estar firmados directamente por Microsoft para poder cargarse en
el espacio del kernel. Si bien el fabricante del controlador no es directamente el firmante del controlador en sí,
parece que el nombre del fabricante aún se incluye dentro de un atributo de la firma;
esta técnica de detección aún está por investigar e implementar.

Finalmente, al enfrentarse a un EDR desconocido para EDRSandblast, el mejor enfoque es ejecutar
la herramienta en modo "audit" y verificar la lista de controladores que han registrado callbacks del kernel;
luego se puede agregar el nombre del controlador a la lista, recompilar la herramienta y volver a ejecutarla.

### Bypass de RunAsPPL

El mecanismo de `Protección de la Autoridad de Seguridad Local (LSA)`, introducido por primera vez
en Windows 8.1 y Windows Server 2012 R2, aprovecha la tecnología `Protected Process
Light (PPL)` para restringir el acceso al proceso `LSASS`. La protección `PPL`
regula y restringe operaciones, como la inyección de memoria o el volcado de memoria de procesos protegidos,
incluso desde un proceso que posee el privilegio `SeDebugPrivilege`. Bajo el modelo de protección de procesos,
solo los procesos que se ejecutan con niveles de protección más altos pueden realizar operaciones en
procesos protegidos.

La estructura `_EPROCESS`, utilizada por el kernel de Windows para representar un proceso
en la memoria del kernel, incluye un campo `_PS_PROTECTION` que define el nivel de protección
de un proceso a través de sus atributos `Type` (`_PS_PROTECTED_TYPE`) y `Signer` (`_PS_PROTECTED_SIGNER`).

Al escribir en la memoria del kernel, el proceso de EDRSandblast puede actualizar su propio
nivel de protección a `PsProtectedSignerWinTcb-Light`. Este nivel es suficiente para
volcar la memoria del proceso `LSASS`, ya que "domina" a `PsProtectedSignerLsa-Light`,
el nivel de protección del proceso `LSASS` que se ejecuta con el mecanismo `RunAsPPL`.

`EDRSandBlast` implementa la autoprotección de la siguiente manera:
  - abre un identificador al proceso actual
  - filtra todos los identificadores del sistema usando `NtQuerySystemInformation` para encontrar el identificador
    abierto en el proceso actual, y la dirección de la estructura `EPROCESS` del proceso actual
    en la memoria del kernel.
  - usa la vulnerabilidad de lectura/escritura arbitraria del controlador `Micro-Star MSI
    Afterburner` para sobrescribir el campo `_PS_PROTECTION` del proceso actual
    en la memoria del kernel. Los desplazamientos del campo `_PS_PROTECTION`
    en relación con la estructura `EPROCESS` (definidos por la versión de `ntoskrnl` en
    uso) se calculan en el archivo `NtoskrnlOffsets.csv`.

### Bypass de Credential Guard

Microsoft `Credential Guard` es una tecnología de aislamiento basada en virtualización,
introducida en `Windows 10 (edición Enterprise)` de Microsoft, que impide
el acceso directo a las credenciales almacenadas en el proceso `LSASS`.

Cuando `Credentials Guard` está activado, se crea un proceso `LSAIso` (*LSA Isolated*) en
`Modo Virtual Seguro`, una característica que aprovecha las extensiones de virtualización
de la CPU para proporcionar una seguridad adicional de los datos en la memoria. El acceso al
proceso `LSAIso` está restringido incluso para un acceso con el contexto de seguridad
`NT AUTHORITY\SYSTEM`. Al procesar un hash, el proceso `LSA`
realiza una llamada `RPC` al proceso `LSAIso` y espera el resultado de
`LSAIso` para continuar. Por lo tanto, el proceso `LSASS` no contendrá ningún
secreto y, en su lugar, almacenará `Datos aislados de LSA`.

Como se indica en la investigación original realizada por `N4kedTurtle`: "`Wdigest` se puede
habilitar en un sistema con Credential Guard parcheando los valores de
`g_fParameter_useLogonCredential` y `g_IsCredGuardEnabled` en la memoria".
La activación de `Wdigest` hará que se almacenen credenciales en texto claro en la memoria
de `LSASS` para cualquier nuevo inicio de sesión interactivo (sin requerir un reinicio del
sistema). Consulte la
[publicación del blog de investigación original](https://teamhydra.blog/2020/08/25/bypassing-credential-guard/)
para obtener más detalles sobre esta técnica.

`EDRSandBlast` simplemente hace que el PoC original sea un poco más amigable para OpSec y
proporciona soporte para varias versiones de `wdigest.dll` (a través de desplazamientos
calculados para `g_fParameter_useLogonCredential` y `g_IsCredGuardEnabled`).

### Recuperación de desplazamientos
Para realizar de manera confiable las operaciones de omisión de monitoreo del kernel, EDRSandblast necesita
saber exactamente dónde leer y escribir en la memoria del kernel. Esto se hace usando desplazamientos de
variables globales dentro de la imagen de destino (ntoskrnl.exe, wdigest.dll), así como el desplazamiento
de campos específicos en estructuras cuyas definiciones son publicadas por Microsoft en archivos
de símbolos. Estos desplazamientos son específicos de cada compilación de las imágenes de destino y deben recopilarse
al menos una vez para una versión de plataforma específica.

La elección de usar desplazamientos "codificados" en lugar de búsquedas de patrones para localizar las estructuras
y variables utilizadas por EDRSandblast se justifica por el hecho de que las API no documentadas
responsables de la adición/eliminación de callbacks del kernel están sujetas a cambios y que cualquier intento
de leer o escribir en la memoria del kernel en la dirección incorrecta puede (y a menudo resultará) en un
`Bug Check` (`Pantalla azul de la muerte`). Un bloqueo de la máquina no es aceptable en escenarios tanto de
red-teaming como de pruebas de penetración normales, ya que una máquina que se bloquea
es altamente visible para los defensores y perderá cualquier credencial que aún estuviera en memoria en el
momento del ataque.

Para recuperar los desplazamientos para cada versión específica de Windows, se implementan dos enfoques.

#### Recuperación manual de desplazamientos
Los desplazamientos requeridos de `ntoskrnl.exe` y `wdigest.dll` se pueden extraer usando el
script de Python proporcionado `ExtractOffsets.py`, que se basa en `radare2` y `r2pipe`
para descargar y analizar símbolos de archivos PDB, y extraer los desplazamientos necesarios de
ellos. Los desplazamientos se almacenan luego en archivos CSV para su uso posterior por EDRSandblast.

Para admitir de forma inmediata una amplia gama de compilaciones de Windows, muchas versiones de
los binarios `ntoskrnl.exe` y `wdigest.dll` son referenciadas por
[Winbindex](https://winbindex.m417z.com/) y se pueden descargar automáticamente
(y extraer sus desplazamientos) mediante `ExtractOffsets.py`. Esto permite extraer desplazamientos
de casi todos los archivos que alguna vez se publicaron en paquetes de actualización de Windows (hasta la fecha, más de 450
versiones de `ntoskrnl.exe` y más de 30 de `wdigest.dll` están disponibles y precalculadas).

#### Recuperación y actualización automática de desplazamientos
Se ha implementado una opción adicional en `EDRSandBlast` para permitir que el programa
descargue los archivos `.pdb` necesarios del Servidor de Símbolos de Microsoft, extraiga los
desplazamientos requeridos e incluso actualice los archivos `.csv` correspondientes si están presentes.

El uso de la opción `--internet` hace que la ejecución de la herramienta sea mucho más simple, pero introduce
un riesgo adicional de OpSec, ya que se descarga un archivo `.pdb` y se coloca en el disco durante
el proceso. Esto es requerido por las funciones de `dbghelp.dll` utilizadas para analizar la base de datos
de símbolos; sin embargo, se podría implementar en el futuro un análisis completo de PDB en memoria para
eliminar este requisito y reducir la huella de la herramienta.

## Uso

El controlador vulnerable `RTCore64.sys` se puede obtener en:```
http://download-eu2.guru3d.com/afterburner/%5BGuru3D.com%5D-MSIAfterburnerSetup462Beta2.zip

Uso rápido```

Usage: EDRSandblast.exe [-h | --help] [-v | --verbose] <audit | dump | cmd | credguard> [--usermode [--unhook-method ]] [--kernelmode] [--dont-unload-driver] [--dont-restore-callbacks] [--driver <RTCore64.sys>] [--service <SERVICE_NAME>] [--nt-offsets <NtoskrnlOffsets.csv>] [--wdigest-offsets <WdigestOffsets.csv>] [--add-dll ]* [-o | --dump-output <DUMP_FILE>]

root@kitploit:~
### Opciones```
-h | --help             Show this help message and exit.
-v | --verbose          Enable a more verbose output.

Actions mode:

        audit           Display the user-land hooks and / or Kernel callbacks without taking actions.
        dump            Dump the LSASS process, by default as 'lsass' in the current directory or at the
                        specified file using -o | --output <DUMP_FILE>.
        cmd             Open a cmd.exe prompt.
        credguard       Patch the LSASS process' memory to enable Wdigest cleartext passwords caching even if
                        Credential Guard is enabled on the host. No kernel-land actions required.

--usermode              Perform user-land operations (DLL unhooking).
--kernelmode            Perform kernel-land operations (Kernel callbacks removal and ETW TI disabling).

--unhook-method <N>
   Choose the userland un-hooking technique, from the following:

        1 (Default)     Uses the (probably monitored) NtProtectVirtualMemory function in ntdll to remove all
                        present userland hooks.
        2               Constructs a 'unhooked' (i.e. unmonitored) version of NtProtectVirtualMemory, by
                        allocating an executable trampoline jumping over the hook, and remove all present
                        userland hooks.
        3               Searches for an existing trampoline allocated by the EDR itself, to get an 'unhooked'
                        (i.e. unmonitored) version of NtProtectVirtualMemory, and remove all present userland
                        hooks.
        4               Loads an additional version of ntdll library into memory, and use the (hopefully
                        unmonitored) version of NtProtectVirtualMemory present in this library to remove all
                        present userland hooks.
        5               Allocates a shellcode that uses a direct syscall to call NtProtectVirtualMemory,
                        and uses it to remove all detected hooks

Other options:

--dont-unload-driver                    Keep the vulnerable driver installed on the host
                                        Default to automatically unsinstall the driver.
--dont-restore-callbacks                Do not restore the EDR drivers' Kernel Callbacks that were removed.
                                        Default to restore the callbacks.

--driver <RTCore64.sys>                 Path to the vulnerable driver file.
                                        Default to 'RTCore64.sys' in the current directory.
--service <SERVICE_NAME>                Name of the vulnerable service to intall / start.

--nt-offsets <NtoskrnlOffsets.csv>      Path to the CSV file containing the required ntoskrnl.exe's offsets.
                                        Default to 'NtoskrnlOffsets.csv' in the current directory.
--wdigest-offsets <WdigestOffsets.csv>  Path to the CSV file containing the required wdigest.dll's offsets
                                        (only for the 'credguard' mode).
                                        Default to 'WdigestOffsets.csv' in the current directory.

--add-dll <dll name or path>            Loads arbitrary libraries into the process' address space, before starting
                                        anything. This can be useful to audit userland hooking for DLL that are not
                                        loaded by default by this program. Use this option multiple times to load
                                        multiple DLLs all at once.
                                        Example of interesting DLLs to look at: user32.dll, ole32.dll, crypt32.dll,
                                        samcli.dll, winhttp.dll, urlmon.dll, secur32.dll, shell32.dll...

-o | --output <DUMP_FILE>               Output path to the dump file that will be generated by the 'dump' mode.
                                        Default to 'lsass' in the current directory.

-i | --internet                         Enables automatic symbols download from Microsoft Symbol Server
                                        If a corresponding *Offsets.csv file exists, appends the downloaded offsets to the file for later use
                                        OpSec warning: downloads and drops on disk a PDB file for ntoskrnl.exe and/or wdigest.dll

Compilación

EDRSandBlast (solo x64) se compiló en Visual Studio 2019 (Windows SDK Versión: 10.0.19041.0 y Conjunto de herramientas de plataforma: Visual Studio 2019 (v142)).

Uso de ExtractOffsets.py

Tenga en cuenta que ExtractOffsets.py solo se ha probado en Windows.```

Installation of Python dependencies

pip.exe install -m .\requirements.txt

Script usage

ExtractOffsets.py [-h] -i INPUT [-o OUTPUT] [-d] mode

positional arguments: mode ntoskrnl or wdigest. Mode to download and extract offsets for either ntoskrnl or wdigest

optional arguments: -h, --help show this help message and exit -i INPUT, --input INPUT Single file or directory containing ntoskrnl.exe / wdigest.dll to extract offsets from. If in download mode, the PE downloaded from MS symbols servers will be placed in this folder. -o OUTPUT, --output OUTPUT CSV file to write offsets to. If the specified file already exists, only new ntoskrnl versions will be downloaded / analyzed. Defaults to NtoskrnlOffsets.csv / WdigestOffsets.csv in the current folder. -d, --download Flag to download the PE from Microsoft servers using list of versions from winbindex.m417z.com.

root@kitploit:~
## Detección
Desde el punto de vista del defensor (proveedor de EDR, Microsoft, analistas de SOC que miran la telemetría de EDR, ...), se pueden utilizar múltiples indicadores para detectar o prevenir este tipo de técnicas.

### Lista blanca de controladores
Dado que cada acción realizada por la herramienta en la memoria en modo kernel depende de un controlador vulnerable para leer/escribir contenido arbitrario, los eventos de carga de controladores deben ser examinados minuciosamente por el producto EDR (o analistas de SOC), y generar una alerta ante cualquier carga de controlador inusual, o incluso bloquear controladores vulnerables conocidos. Este último enfoque es incluso [recomendado por Microsoft](https://docs.microsoft.com/en-us/windows/security/threat-protection/windows-defender-application-control/microsoft-recommended-driver-block-rules): cualquier dispositivo Windows con HVCI (*Hypervisor-protected code integrity*) habilitado incorpora una lista de bloqueo de controladores, y esto se convertirá progresivamente en un comportamiento predeterminado en Windows (ya lo es en Windows 11).

### Comprobaciones de integridad de la memoria del kernel
Dado que un atacante aún podría usar un controlador vulnerable desconocido para realizar las mismas acciones en la memoria, el controlador EDR podría verificar periódicamente que sus devoluciones de llamada del kernel aún estén registradas, ya sea inspeccionando directamente la memoria del kernel (como hace esta herramienta), o simplemente activando eventos (creación de procesos, creación de hilos, carga de imágenes, etc.) y comprobando que las funciones de devolución de llamada son efectivamente invocadas por el kernel ejecutivo.

Como nota al margen, este tipo de estructura de datos podría protegerse mediante el reciente mecanismo [Kernel Data Protection (KDP)](https://www.microsoft.com/security/blog/2020/07/08/introducing-kernel-data-protection-a-new-platform-security-technology-for-preventing-data-corruption/), que se basa en Virtual Based Security, para hacer que el array de devoluciones de llamada del kernel no sea escribible sin llamar a las API correctas.

La misma lógica podría aplicarse a variables ETW sensibles como `ProviderEnableInfo`, abusada por esta herramienta para deshabilitar la generación de eventos de ETW Threat Intelligence.

### Detección en modo usuario
El primer indicador de que un proceso está activamente tratando de evadir el hooking en modo usuario son los accesos a archivos para cada DLL correspondiente a los módulos cargados; en una ejecución normal, un proceso en modo usuario rara vez necesita leer archivos DLL fuera de una llamada `LoadLibrary`, especialmente `ntdll.dll`.

Para proteger el hooking de API de ser eludido, los productos EDR podrían comprobar periódicamente que los hooks no se hayan alterado en la memoria, dentro de cada proceso monitorizado.

Finalmente, para detectar la evasión de hooks (abuso de un trampolín, uso de syscalls directas, etc.) que no implique la eliminación de los hooks, los productos EDR podrían potencialmente confiar en las devoluciones de llamada del kernel asociadas a los syscalls abusados (ej. `PsCreateProcessNotifyRoutine` para el syscall `NtCreateProcess`, `ObRegisterCallbacks` para el syscall `NtOpenProcess`, etc.), y realizar un análisis de la pila de llamadas en modo usuario para determinar si el syscall fue activado desde una ruta normal (`kernel32.dll` -> `ntdll.dll` -> syscall) o anormal (ej. `program.exe` -> syscall directo).


## Agradecimientos

- Enumeración y eliminación de devoluciones de llamada del kernel:
  https://github.com/br-sn/CheekyBlinder

- Primitivas de lectura/escritura de memoria del kernel a través del controlador vulnerable
  `Micro-Star MSI Afterburner`:
  https://github.com/Barakat/CVE-2019-16098/

- Deshabilitación del proveedor ETW Threat Intelligence:
  https://public.cnotools.studio/bring-your-own-vulnerable-kernel-driver-byovkd/exploits/data-only-attack-neutralizing-etwti-provider

- Instalación/desinstalación de controladores: https://github.com/gentilkiwi/mimikatz

- Lista inicial de nombres de controladores EDR:
  https://github.com/SadProcessor/SomeStuff/blob/master/Invoke-EDRCheck.ps1

- Bypass de Credential Guard reactivando `Wdigest` a través de parcheo de memoria
  de `LSASS`: https://teamhydra.blog/2020/08/25/bypassing-credential-guard/


## Autores

[Thomas DIOT (Qazeer)](https://github.com/Qazeer/)
[Maxime MEIGNAN (themaks)](https://github.com/themaks)

## Licencia

Licencia CC BY 4.0 - https://creativecommons.org/licenses/by/4.0/