Desvendando Evasão de EDR: Técnicas Modernas de Unhooking em APIs de Sistema
Um estudo aprofundado sobre como soluções modernas de EDR monitoram chamadas nativas em userland e como agentes de ameaça utilizam unhooking e direct syscalls.
No cenário atual de segurança ofensiva e defensiva, as soluções de Endpoint Detection and Response (EDR) tornaram-se o pilar central na contenção de intrusões corporativas. No entanto, a grande maioria dos agentes de proteção em nível de endpoint baseia sua telemetria primária em Userland API Hooking.
Neste artigo técnico, exploramos a mecânica de monitoramento por injeção em bibliotecas dinâmicas (ntdll.dll), as limitações inerentes desse modelo e como operadores de Red Team simulam técnicas avançadas de evasão com Perun’s Fart, Direct Syscalls e Full NTDLL Unhooking.
Como os EDRs Operam em Userland
Quando um processo é inicializado no Windows, o sistema carrega os binários base e suas dependências. A solução de EDR injeta uma biblioteca DLL auxiliar (por exemplo, edr_hook.dll) no espaço de endereçamento virtual de todo processo recém-criado.
Essa DLL sobrescreve os primeiros bytes de funções críticas na ntdll.dll com uma instrução de desvio (JMP ou CALL de 5 a 14 bytes), redirecionando a execução para a engine de análise do antivírus:
[Fluxo Normal]
Processo -> ntdll!NtAllocateVirtualMemory -> SYSCALL -> Kernel
[Fluxo com EDR Hooking]
Processo -> ntdll!NtAllocateVirtualMemory
-> JMP 0x7FFA... [edr_engine.dll] (Inspeção de Buffers / Argumentos)
-> Retorno / Bloqueio
Caso os parâmetros da chamada (como alocação de memória com permissão PAGE_EXECUTE_READWRITE via NtAllocateVirtualMemory ou criação de thread remota via NtCreateThreadEx) indiquem atividade maliciosa, o alerta é disparado antes mesmo da transição para o kernel (Ring 0).
O Calcanhar de Aquiles: Userland é Terra de Ninguém
O princípio fundamental de arquitetura de sistemas operacionais é claro: código executando em Ring 3 possui o mesmo nível de privilégio que qualquer outro código em Ring 3 pertencente ao mesmo processo.
Portanto, um executável possui autoridade irrestrita para ler, remapear e modificar as páginas de memória de suas próprias DLLs carregadas. É aqui que as técnicas de desativação de hooks entram em cena.
Técnica 1: Leitura Limpa do Disco (Disk Unhooking)
A abordagem clássica consiste em ler a seção .text da ntdll.dll diretamente do arquivo em disco (C:\Windows\System32\ntdll.dll) e sobrescrever a seção corrompida em memória:
// Pseudo-código demonstrativo de restauração de seção .text
HANDLE hFile = CreateFileA("C:\\Windows\\System32\\ntdll.dll", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
HANDLE hMapping = CreateFileMappingA(hFile, NULL, PAGE_READONLY | SEC_IMAGE, 0, 0, NULL);
LPVOID pCleanNtdll = MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0);
// Identificar cabeçalhos PE e obter ponteiro da seção .text
PIMAGE_NT_HEADERS ntHeaders = (PIMAGE_NT_HEADERS)((PBYTE)pCleanNtdll + ((PIMAGE_DOS_HEADER)pCleanNtdll)->e_lfanew);
PIMAGE_SECTION_HEADER textSec = IMAGE_FIRST_SECTION(ntHeaders);
// Alterar permissão da memória em execução para RWX
DWORD oldProtect;
VirtualProtect((LPVOID)targetTextAddress, textSec->SizeOfRawData, PAGE_EXECUTE_READWRITE, &oldProtect);
// Copiar bytes originais limpos sobre os hooks instalados pelo EDR
memcpy((LPVOID)targetTextAddress, (LPVOID)cleanTextAddress, textSec->SizeOfRawData);
// Restaurar proteção original RX
VirtualProtect((LPVOID)targetTextAddress, textSec->SizeOfRawData, oldProtect, &oldProtect);
Aviso de Detecção: Muitos EDRs modernos monitoram chamadas a
CreateFileapontando paraSystem32\ntdll.dllou utilizam callbacks de driver do kernel (PsSetCreateProcessNotifyRoutine) para alertar sobre remapeamento de memória de código.
Técnica 2: Syscalls Diretas e Dinâmicas (SysWhispers / TartarusGate)
Em vez de alterar a memória do processo, operadores ofensivos utilizam Direct Syscalls. Ao invés de invocar a API fornecida pela ntdll.dll, o binário monta diretamente a instrução de syscall em assembly:
; Exemplo de Syscall stub para NtAllocateVirtualMemory (x64)
mov r10, rcx
mov eax, 0x18 ; Syscall Service Number (SSN) específico da build do Windows
syscall
ret
Como o número de serviço do sistema operacional (SSN) muda a cada build ou atualização de segurança do Windows (KB), técnicas como TartarusGate e HalosGate vasculham dinamicamente a ntdll.dll em memória, identificam padrões de bytes vizinhos e calculam o SSN correto em tempo de execução sem disparar sensores estáticos.
Como as Equipes de Defesa Devem Mitigar
- Priorizar Telemetria do Kernel (ETW-Ti): Soluções modernas devem utilizar o Threat Intelligence Event Tracing for Windows (
ETW-Ti), que fornece dados de alocações e execuções a partir do próprio kernel, onde o atacante em userland não tem alcance. - Habilitar Arbitrary Code Guard (ACG): Políticas de mitigação do Windows como ACG impedem que páginas de memória pré-existentes tenham suas proteções alteradas para executáveis.
- Auditoria com Pentests Ofensivos Reais: Não assuma que a simples presença do agente de EDR garante proteção contra agentes qualificados. Testes de Red Team manuais são o único método empírico de validar a eficácia dos seus controles.
Artigo publicado pela equipe de Pesquisa Ofensiva da Nexo Security. Para testes de validação de controles de endpoint em sua infraestrutura, consulte nossos serviços de Red Team.