Best EDR Of The Market: herramienta para aprender a evadir AV/EDR

Best EDR Of The Market (en adelante BEOTM) de @Xacone (Yazid) es un EDR de c贸digo abierto dise帽ado para servir como campo de pruebas para comprender y evitar algunos de los mecanismos de detecci贸n empleados por muchos EDR conocidos.

A continuaci贸n veremos descripci贸n general muy r谩pida de las t茅cnicas que implementa BEOTM sin entrar en detalle sobre los m茅todos de evasi贸n.  

DLL hooking

 
BEOTM realiza la inyecci贸n de DLL en m煤ltiples niveles interceptando funciones sensibles como las utilizadas para la asignaci贸n de memoria, creaci贸n/manipulaci贸n de procesos o subprocesos, cambiando los derechos de acceso a los grupos de memoria, etc. El hooking se logra inyectando la DLL en el proceso de destino.
Una vez inyectada, la DLL redirigir谩 las llamadas de funciones hookeadas a sus propias rutinas internas para inspeccionar su contenido y luego decidir si contin煤a o no con la llamada invocando la rutina original.

Eso s铆, BEOTM se limita (por ahora) a mostrar un mensaje a trav茅s de la salida est谩ndar (para hooks de NTDLL) o a mostrar un cuadro de mensaje (para hooks Kernelbase/Kernel32) alertando que la rutina ha sido interceptada.

NT-Level hooking VS Reflective DLL Loader: 


Kernel32-Level hooking VS proceso leg铆timo:

Rutinas/funciones hookeadas

Las funciones que el EDR hookea a trav茅s de las DLL inyectadas se describen en el archivo "TrigerringFunctions.json". La versi贸n inicial de BEOTM incluye archivos DLL precompilados, pero se pueden compilar otros archivos DLL con las funciones que queramos interceptar.

Las DLL inyectables de BEOTM se basan en Microsoft Detours como interfaz para la interceptaci贸n de llamadas API.

A continuaci贸n vemos una descripci贸n detallada de lo que sucede cuando la DLL intercepta NtAllocateVirtualMemory:

Threads Call Stack Monitoring

Este m茅todo implica la monitorizaci贸n continua del registro de instrucciones RIP de cada hilo. Cuando el registro RIP apunta a la direcci贸n de una rutina/funci贸n exportada desde cualquier DLL o a la direcci贸n de un 谩rea contenida en la implementaci贸n de esta exportaci贸n, y el usuario ha especificado en el archivo TrigerringFunctions.json que desea monitorizar esa rutina/funci贸n, el hilo se pausa y su pila de llamadas se desenrola. Se analizan todos los par谩metros de todas las rutinas que apila. Si una secuencia de bytes en un par谩metro coincide con un patr贸n predefinido en el archivo YaroRules.json, el proceso se detiene y se genera una alerta.

A diferencia del hooking DLL y el hooking IAT, de hecho hay una respuesta con este m茅todo: podemos especificar en el archivo TrigerringFunctions.json qu茅 funciones queremos monitorizar en el nivel de la pila de llamadas del subproceso y podemos definir los patrones que deseamos identificar en YaroRules.json.

Threads Call Stack Monitoring VS NT-Level XOR-Encrypted Shellcode Loader:

Threads Call Stack Monitoring VS Reflective DLL Loader: 

Echemos un vistazo a bajo nivel que sucede, aqu铆 hay un programa simple que asigna un pool de memoria virtual de 4096 bytes a trav茅s de VirtualAlloc:


int main() {
    size_t memSize = 4096; // 4 Ko

    LPVOID pMemory = VirtualAlloc(nullptr, memSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
    return 0;
}
los valores de los cuatro par谩metros se transmiten a los registros r8, r9, rcx y rdx que luego se pasar谩n a la pila:

KERNELBASE!VirtualAlloc+0x22:
00007ffb`9bdd1402 4183e0c0        and     r8d,0FFFFFFC0h
00007ffb`9bdd1406 44894c2428      mov     dword ptr [rsp+28h],r9d
00007ffb`9bdd140b 4489442420      mov     dword ptr [rsp+20h],r8d
00007ffb`9bdd1410 4c8d4c2448      lea     r9,[rsp+48h]
00007ffb`9bdd1415 4533c0          xor     r8d,r8d
00007ffb`9bdd1418 488d542440      lea     rdx,[rsp+40h]
00007ffb`9bdd141d 498d48ff        lea     rcx,[r8-1]
00007ffb`9bdd1421 48ff1500ea1f00  call    qword ptr [KERNELBASE!_imp_NtAllocateVirtualMemory (00007ffb`9bfcfe28)]
00007ffb`9bdd1428 0f1f440000      nop     dword ptr [rax+rax]
00007ffb`9bdd142d 85c0            test    eax,eax
00007ffb`9bdd142f 780b            js      KERNELBASE!VirtualAlloc+0x5c (00007ffb`9bdd143c)

Estos mismos par谩metros se pasar谩n al NtAllocateVirtualMemory subyacente:

Si establecemos un punto de interrupci贸n en ntdll!NtAllocateVirtualMemory en el loader del shellcode y desenrolamos la pila de llamadas cuando se alcanza el punto de interrupci贸n, veremos que se pasa una direcci贸n como par谩metro a la rutina, correspondiente a un puntero al shellcode dexoreado.

Aqu铆 hay un diagrama condicional global de c贸mo funciona la monitorizaci贸n de la pila de llamadas de subprocesos en BOTM:

Import Address Table (IAT) Hooking

Este m茅todo opera en el nivel de la tabla de direcciones de importaci贸n (IAT) del proceso de destino al sobrescribir las direcciones de importaciones leg铆timas con las direcciones de exportaciones de una DLL inyectada. Si bien puede parecer similar al hooking de una DLL debido a la inyecci贸n de una DLL, no lo es en absoluto, ya que este m茅todo no implica una instrucci贸n 'jmp' para una funci贸n de trampol铆n.

Se muestra un cuadro de mensaje para cada funci贸n interceptada.

IAT-hooking VS Reflective DLL Loader: 


Algunos podr铆an (quiz谩s) preguntarse c贸mo se preservan los registros con este m茅todo de interceptaci贸n para ser analizados posteriormente, incluso con la adici贸n de un cuadro de mensaje o cualquier instrucci贸n que potencialmente pueda corromper los valores de los registros y distorsionar los valores de los par谩metros. Bueno, todo lo que se necesita es activar IDA para obtener la respuesta: este m茅todo no impide la preservaci贸n y copia de seguridad de los valores de los registros r8, r9, rcx y rdx en otros registros (rbx, rdi, rsi).

SSN Crushing

Bueno, eso es puramente imaginativo y nada realista, simplemente consiste en sobrescribir/anular el valor de Syscall / SSN (N煤mero de servicio del sistema) en el nivel NT con 0x21.

Esto har谩 que el proceso deje de funcionar en la mayor铆a de los casos si tocas rutinas importantes, ya sea porque el programa ha detectado un error de integridad en la suma de comprobaci贸n ntdll que ha cargado en la memoria o porque simplemente se ha da帽ado la llamada al sistema.

Entonces, ¿cu谩l es el punto de eso? Simplemente por intentar, desde el punto de vista de un atacante, revertir el valor de la llamada al sistema y anularlo con su valor real que habr铆as obtenido por cualquier medio

Reglas Yaro

El archivo YaroRules.json no contiene m谩s que los patrones que desea identificar. Puedes divertirte buscando patrones interesantes comunes a muchos shellcodes/payloads 煤tiles, como en este ejemplo que identifica patrones relacionados con el acceso al PEB y el recorrido de entradas LDR para un shellcode TCP inverso generado por metasploit.

Tambi茅n se puede agregar ciertos patrones de artefactos maliciosos conocidos (por ejemplo, Mimikatz).  

YaroRules.json contiene 5 patrones predeterminados correspondientes al patr贸n de acceso a las entradas PEB y PEB_LDR_DATA para un shellcode inverso_tcp generado por Metasploit. Tambi茅n hay otros 3 patrones correspondientes a 谩reas en el encabezado de DOS de un objeto en formato PE.


{
    "Patterns": [
        "d2 65 48 8b 52 60 48 8b 52 18 48 8b 52 20 48 8b 72 50 48",
        "49 be 77 73 32 5f 33 32 00 00",
        "4d 5a",
        "4D 5A 90 00 03 00 00 00 04 00 00 00 FF FF 00 00 B8 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00",
        "00 F0 00 00 00 0E 1F BA 0E 00 B4 09 CD 21 B8 01 4C CD 21 54 68 69 73 20 70 72 6F 67 72 61 6D 20 63 61 6E 6E 6F 74 20 62 65 20 72 75 6E 20 69 6E 20 44 4F 53 20 6D 6F 64 65 2E"
    ]
}

Fuente: https://xacone.github.io/BestEdrOfTheMarket.html

Proyecto: https://github.com/Xacone/BestEdrOfTheMarket


Comentarios