03 - Hunting por Defesa Evasiva (Process Injection, Masquerading)
video: https://youtu.be/... no frontmatter da nota.Hunting por Defesa Evasiva (Process Injection, Masquerading)
Nota 03 do Capítulo 08, "Técnicas de Hunting por TTPs", cobrindo a tática de Defesa Evasiva
(TA0005) com foco em injeção de processo e masquerading. Exige telemetria de Sysmon e de EDR
e dialoga com a nota 01, com o TH.11 de hunting de endpoint, com o TH.13 de hunting de memória
e com o capítulo 25 de análise técnica de artefatos.
1. Contexto e Posicionamento na Biblioteca
A Defesa Evasiva é a tática em que o adversário trabalha para não ser visto, e por isso produz menos eventos de infraestrutura que persistência ou movimento lateral. A consequência para o caçador é direta: não há evento único que revele evasão, e a detecção depende de sinais de baixo nível, como acesso anômalo à memória de outro processo, relações pai e filho que a rotina administrativa não produz e pequenas fraudes de identidade em nomes e caminhos de binários. É a tática em que a qualidade da telemetria pesa mais que a quantidade, e onde Sysmon com configuração madura, cobrindo eventos 8, 10, 1 e 5, faz diferença decisiva.
A nota divide a caça em duas frentes complementares. A primeira cobre process injection, incluindo CreateRemoteThread, process hollowing e APC injection, técnicas que manipulam a memória de processos legítimos para executar código. A segunda cobre masquerading, incluindo renomeação de binários do sistema, caminhos imitadores, o caractere RTLO e o uso de assembly inline por interpretadores. As duas frentes convergem no mesmo princípio do TH.11: comparar o observado com o que o sistema operacional produz quando ninguém o manipula.
2. Process Injection: Técnicas e Sinais
As técnicas de injeção compartilham uma sequência de primitivas: obter handle de outro processo, alocar ou mapear memória nele, escrever código nessa memória e disparar a execução por thread remota, por APC enfileirada ou por troca do contexto de um processo suspenso. O ATT&CK cataloga as variantes sob T1055, com CreateRemoteThread em T1055.001 e hollowing em T1055.012, e a tabela resume o que cada variante deixa visível na telemetria.
| Variante | ID ATT&CK | Sinal na telemetria | Evento decisivo |
|---|---|---|---|
| CreateRemoteThread | T1055.001 | Thread remota criada por processo fonte incomum | Sysmon 8 |
| Process hollowing | T1055.012 | Binário legítimo com nome duplicado na árvore, seção RWX, unbacked memory | Sysmon 1 e telemetria de memória do EDR |
| APC injection | T1055.004 | Escrita em memória remota sem thread nova, com execução ao retomar thread | Sysmon 10 com CallTrace sem módulo |
| Acesso amplo à memória | T1055 general | GrantedAccess permissivo de origem não depuradora | Sysmon 10 |
Dois sinais merecem destaque por robustez. O primeiro é o CallTrace do Sysmon 10: quando a pilha de chamadas não resolve para módulo legítimo no disco, exibindo UNKNOWN ou apontando para DLLs de interpretadores como VBE7.DLL, há execução fora das seções mapeadas, padrão quase sempre malicioso. O segundo é a memória unbacked executável, visível na telemetria nativa de EDRs modernos, que denuncia código rodando em região alocada em runtime, exatamente onde payloads injetados vivem. Esses sinais sobrevivem à variação de técnica melhor que qualquer assinatura de ferramenta.
3. Masquerading: Renomeação, Caminhos Imitadores e RTLO
Masquerading é a fraude de identidade do binário, catalogada no T1036, e se apoia na premissa de que analistas e ferramentas julgam processos pelo nome. As formas mais comuns são quatro. A renomeação simples copia rundll32, regsvr32 ou cmd para outro nome ou, inversamente, renomeia o payload para nomes como svchost.exe em caminhos errados. Os caminhos imitadores mantêm o nome correto mas trocam o caminho, usando Sysmte32 com letras trocadas, System32 com espaço final, System32x ou caminhos em ProgramData que imitam a hierarquia oficial. O RTLO insere o caractere de reversão de texto U+202E no nome do arquivo, fazendo um executável chamado exe.jsoc exibir codex.exe na interface. A quarta forma abusa de metadados: versão, descrição e empresa falsos que imitam fornecedores conhecidos.
A defesa do caçador é a comparação sistemática: o nome executado contra o OriginalFileName embutido no binário, registrado pelo Sysmon 1; o caminho executado contra o caminho canônico do binário de mesmo nome; e o nome visível contra a presença do U+202E. Todas as três comparações são determinísticas, produzem pouquíssimos falsos positivos e se prestam tanto à caça pontual quanto à detecção permanente do capítulo 18. O abuso de assembly inline por PowerShell fecha o quadro: scripts que declaram P/Invoke com VirtualAlloc, CreateThread e Marshal.Copy executam shellcode sem dropar binário, e o script block logging do evento 4104 preserva a evidência.
4. Consultas Práticas em KQL
4.1 Thread remota e acesso à memória
Os índices posicionais do Sysmon 8 e do Sysmon 10 abaixo refletem o schema padrão e devem ser validados com um evento real, como alertado na nota 01, porque coletores podem reordenar campos.
Event
| where Source == "Microsoft-Windows-Sysmon" and EventID == 8
| extend X = parse_xml(EventData).DataItem.EventData.Data
| extend SourceImage = tostring(X[4]["@text"]), TargetImage = tostring(X[7]["@text"]),
StartModule = tostring(X[10]["@text"]), StartFunction = tostring(X[11]["@text"])
| where not(SourceImage has "\\Windows\\System32\\")
| project TimeGenerated, Computer, SourceImage, TargetImage, StartModule, StartFunction
Event
| where Source == "Microsoft-Windows-Sysmon" and EventID == 10
| extend X = parse_xml(EventData).DataItem.EventData.Data
| extend SourceImage = tostring(X[5]["@text"]), TargetImage = tostring(X[8]["@text"]),
GrantedAccess = tostring(X[9]["@text"]), CallTrace = tostring(X[10]["@text"])
| where GrantedAccess in ("0x1FFFFF", "0x1F1FFB", "0x1F0FFF", "0x1F03FF")
and SourceImage has_any ("winword.exe", "excel.exe", "wscript.exe", "powershell.exe", "msbuild.exe")
| where CallTrace has "UNKNOWN" or CallTrace has "VBE7.DLL"
| project TimeGenerated, Computer, SourceImage, TargetImage, GrantedAccess, CallTrace
4.2 Pai e filho impossível e indícios de hollowing
A consulta abaixo empilha relações pai e filho improváveis, que em frotas administradas são raras o suficiente para o corte de raridade do TH.8 funcionar bem.
DeviceProcessEvents
| where Timestamp > ago(30d)
| where InitiatingProcessFileName in~ ("notepad.exe", "calc.exe", "wordpad.exe", "outlook.exe", "w3wp.exe")
and FileName in~ ("powershell.exe", "cmd.exe", "wscript.exe", "rundll32.exe")
| summarize Ocorrencias = count(), Hosts = dcount(DeviceName)
by InitiatingProcessFileName, FileName, FolderPath
| where Ocorrencias <= 3
| order by Ocorrencias asc
Indício clássico de hollowing na telemetria de EDR é o binário de nome legítimo com linha de comando de interpretador, ou o processo cujo pai tem o mesmo nome dele, padrão de self-hollowing onde o launcher e o impostor compartilham o nome.
DeviceProcessEvents
| where Timestamp > ago(7d)
| where FileName =~ InitiatingProcessFileName
and ProcessCommandLine has_any ("-enc", "FromBase64", "VirtualAlloc", "-nop -w hidden", "-sta")
| project Timestamp, DeviceName, FileName, ProcessCommandLine, InitiatingProcessId, InitiatingProcessCommandLine
4.3 Renomeação e caminhos imitadores
A comparação entre nome executado e OriginalFileName detecta a renomeação com baixíssimo ruído, e o filtro por binários do sistema concentra a busca onde a fraude vale a pena para o adversário.
Event
| where Source == "Microsoft-Windows-Sysmon" and EventID == 1
| extend X = parse_xml(EventData).DataItem.EventData.Data
| extend Image = tostring(X[4]["@text"]), OriginalFileName = tostring(X[9]["@text"]),
ParentImage = tostring(X[20]["@text"]), CommandLine = tostring(X[10]["@text"])
| extend NomeExecutado = tostring(split(Image, "\\")[-1])
| where isnotempty(OriginalFileName) and NomeExecutado !~ OriginalFileName
| where OriginalFileName in~ ("rundll32.exe", "regsvr32.exe", "mshta.exe", "powershell.exe",
"wscript.exe", "cmd.exe", "svchost.exe", "dllhost.exe")
| project TimeGenerated, Computer, NomeExecutado, OriginalFileName, ParentImage, CommandLine
DeviceProcessEvents
| where Timestamp > ago(7d)
| where FileName in~ ("rundll32.exe", "svchost.exe", "cmd.exe", "powershell.exe", "mshta.exe", "regsvr32.exe")
| where FolderPath !has "\\Windows\\System32" and FolderPath !has "\\Windows\\SysWOW64"
| summarize Ocorrencias = count(), Hosts = dcount(DeviceName) by FileName, FolderPath
| order by Ocorrencias asc
O caractere RTLO é capturado pela busca do codepoint U+202E via sintaxe \x{202E} do motor de expressões regulares, invisível na tela mas inequívoca no dado.
DeviceProcessEvents
| where Timestamp > ago(30d)
| where FileName matches regex @"\x{202E}" or FolderPath matches regex @"\x{202E}"
or ProcessCommandLine matches regex @"\x{202E}"
| project Timestamp, DeviceName, FileName, FolderPath, ProcessCommandLine
4.4 Assembly inline e P/Invoke por PowerShell
O script block logging preserva a declaração de APIs do Win32 usadas para alocar e executar memória, e as assinaturas abaixo cobrem o vocabulário típico de shellcode carregado inline.
Event
| where EventID == 4104 and Source contains "PowerShell"
| where Message has_any ("VirtualAlloc", "VirtualProtect", "CreateThread", "Marshal::Copy",
"GetDelegateForFunctionPointer", "Add-Type", "LoadLibrary", "GetProcAddress")
| summarize Ocorrencias = count(), Hosts = dcount(Computer) by bin(TimeGenerated, 1h)
| where Hosts >= 1
5. Exemplo de Caça Completa
Cenário: relatório do capítulo 05 descreve loader de um grupo de ransomware que injeta payload em dllhost e disfarça o dropper como rundll32. A hipótese do TH.6 é que a cadeia deixa Sysmon 8 com fonte de usuário e destino de sistema. A primeira consulta de thread remota retorna um evento cujo SourceImage é um rundll32 em caminho de usuário do perfil, e o Sysmon 1 correspondente mostra OriginalFileName igual ao próprio rundll32, ou seja, binário legítimo renomeado por cópia, executando de caminho não canônico.
A investigação avança pela cadeia completa: o Sysmon 11 recupera a origem do arquivo dropado, o 4104 revela o script PowerShell que executou a cópia com API de alocação de memória, e a telemetria de memória do EDR confirma seção unbacked executável no dllhost alvo. A linha do tempo fecha o caso em um loader com duas camadas de evasão. A erradicação remove o binário e bloqueia o caminho de usuário para execução de rundll32 via AppLocker, o IOC de hash entra no TH.10 e a regra de renomeação de binários do sistema vira detecção permanente no capítulo 18, validada primeiro em modo silencioso por duas semanas.
6. Erros Comuns e Pontos de Atenção
- Aplicar a consulta de thread remota sem filtrar ruído de ferramentas legítimas de depuração e de agentes de monitoramento, que em frotas grandes produzem falsos positivos contínuos; construir primeiro a baseline de origens recorrentes do TH.2.
- Tratar GrantedAccess elevado como malícia automática: ferramentas de suporte usam máscaras amplas, e o julgamento deve combinar origem, alvo e CallTrace, nunca a máscara isolada.
- Confiar no nome visível para julgar binário: interface do explorador e colunas de relatórios exibem o que o RTLO quer que seja visto, e apenas o OriginalFileName e o hash resolvem a identidade real.
- Esquecer SysWOW64 nas consultas de caminho canônico, gerando falsos positivos em processos de 32 bits em sistemas de 64 bits.
- Desligar o script block logging por volume: sem o 4104, assembly inline por PowerShell é invisível, e a alternativa de telemetria do EDR, embora útil, não preserva o conteúdo do script para a análise do capítulo 25.
7. Integração com o Restante da Biblioteca
A caça de evasiva é o terreno do TH.11 e do TH.13: a primeira técnica fornece o framework de caça de endpoint e a segunda aprofunda a análise de memória que confirma injeção quando a telemetria de processo não basta. As baselines do INS.5 e do TH.2 determinam quais relações pai e filho e quais caminhos são raros na frota, e a conversão dos padrões validados em regras do capítulo 18 e do DET.x fecha o ciclo. A análise técnica dos artefatos capturados, dropper, shellcode e metadados falsos, alimenta o capítulo 25 e enriquece o clustering de campanhas do capítulo 05.
Uma orientação operacional encerra a nota: as consultas de masquerading são determinísticas e baratas, ideais para conversão em detecção permanente, enquanto as consultas de injeção dependem de baseline e rendem mais como caça dirigida, disparada por indicador de campanha ou por alerta fraco do EDR que precisa de contexto. Separar as duas famílias nessa lógica evita que o ruído da injeção contamine a rotina e que o valor estável do masquerading fique preso em caças ocasionais.