O que você precisa saber sobre “Process Ghosting”, um novo ataque de adulteração de imagem executável

s equipes de segurança que defendem os ambientes Windows geralmente contam com produtos antimalware como a primeira linha de defesa contra executáveis ​​maliciosos. A Microsoft fornece aos fornecedores de segurança a capacidade de registrar retornos de chamada que serão invocados na criação de processos no sistema. Os desenvolvedores de driver podem chamar APIs como PsSetCreateProcessNotifyRoutineEx para receber esses eventos.

Apesar do nome, os retornos de chamada PsSetCreateProcessNotifyRoutineEx não são realmente invocados na criação de processos, mas sim na criação dos primeiros threads dentro desses processos. Isso cria uma lacuna entre o momento em que um processo é criado e o momento em que os produtos de segurança são notificados de sua criação. Também dá aos autores de malware uma janela para adulterar o executável de apoio antes que os produtos de segurança possam verificá-lo. Exemplos recentes de tais ataques de adulteração incluem Process Doppelgänging e Process Herpaderping , que abusam desse comportamento para escapar de produtos de segurança.

Este blog descreve um novo ataque de adulteração de imagem executável semelhante, mas diferente de, Doppelgänging e Herpaderping. Com essa técnica, um invasor pode gravar um malware no disco de forma que seja difícil verificá-lo ou excluí-lo – e onde ele executa o malware excluído como se fosse um arquivo normal no disco. Essa técnica não envolve injeção de código, esvaziamento de processo ou NTFS transacional (TxF).

O nascimento de um processo

O Gerenciador de Tarefas do Windows mostra uma lista de processos em execução no sistema. Cada um desses processos está associado a um arquivo executável no disco, como svchost.exe. Isso ocorre porque o Windows inicia processos de arquivos executáveis, geralmente terminando com uma extensão de arquivo EXE.

É importante observar que os processos não são executáveis ​​e os executáveis ​​não são processos. No exemplo do Gerenciador de Tarefas acima, há vários processos iniciados de RuntimeBroker.exe e svchost.exe.

Para iniciar um novo processo, uma série de etapas deve ocorrer. Em versões modernas do Windows, eles são normalmente executados no kernel por NtCreateUserProcess – no entanto, as APIs de componentes individuais (NtCreateProcessEx etc) ainda estão expostas e funcionais para fins de compatibilidade com versões anteriores. Essas etapas são:

  1. Abra um identificador para o executável a ser iniciado. Exemplo: hFile = CreateFile (“C: \ Windows \ System32 \ svchost.exe”) 2
  2. Crie uma seção de “imagem” para o arquivo. Uma seção mapeia um arquivo, ou uma parte de um arquivo, para a memória. Uma seção de imagem é um tipo especial de seção que corresponde a arquivos Portable Executable (PE) e só pode ser criada a partir de arquivos PE (EXE, DLL, etc.). Exemplo: hSection = NtCreateSection (hFile, SEC_IMAGE)
  3. Crie um processo usando a seção de imagem. Exemplo: hProcess = NtCreateProcessEx (hSection)
  4. Atribuir argumentos de processo e variáveis ​​de ambiente. Exemplo: CreateEnvironmentBlock / NtWriteVirtualMemory
  5. Crie um thread para executar no processo. Exemplo: NtCreateThreadEx

Esta é a aparência do Process Monitor:

explorer.exe iniciando notepad.exe, conforme visto no Process Monitor

Os processos são iniciados a partir de executáveis, mas alguns dos dados no arquivo executável são modificados à medida que são mapeados em um processo. Para contabilizar essas modificações, o gerenciador de memória do Windows armazena em cache as seções de imagem no momento de sua criação. Isso significa que as seções da imagem podem se desviar de seus arquivos executáveis.

Processos de verificação de malware

A Microsoft fornece aos fornecedores de segurança a capacidade de registrar retornos de chamada que serão invocados na criação de processos e threads no sistema. Os desenvolvedores de driver podem chamar APIs como PsSetCreateProcessNotifyRoutineEx e PsSetCreateThreadNotifyRoutineEx para receber esses eventos.

Apesar do nome, os retornos de chamada PsSetCreateProcessNotifyRoutineEx não são realmente invocados na criação de processos, mas sim na criação dos primeiros threads dentro desses processos. Isso cria uma lacuna entre o momento em que um processo é criado e o momento em que os produtos de segurança são notificados de sua criação. Ele também oferece aos autores de malware uma janela para adulterar o arquivo de backup e a seção antes que os produtos de segurança possam verificá-los.

Observe como a API de criação de processo não documentado NtCreateProcess pega uma seção, não um arquivo, um identificador:

NTSYSCALLAPI
NTSTATUS
NTAPI
NTCreateProcess ( _Out_ PHANDLE ProcessHandle , _In_ ACCESS_MASK DesiredAccess , _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes , _In_ PUNHO ParentProcess , _In_ BOOLEAN InheritObjectTable , _In_opt_ PUNHO SectionHandle , _In_opt_ PUNHO DebugPort , _In_opt_ PUNHO ExceptionPort );
    
    
    
    
    
    
    
    
    

Quando um processo é iniciado, os produtos de segurança recebem as seguintes informações sobre o processo que está sendo iniciado:

typedef struct _PS_CREATE_NOTIFY_INFO { 
  SIZE_T               Size ; união { bandeiras 
    ULONG ; struct { 
      ULONG FileOpenNameAvailable : 1 ; 
      ULONG IsSubsystemProcess : 1 ; 
      ULONG Reservado : 30 ; }; }; 
  HANDLE               ParentProcessId ; 
  CLIENT_ID            CreatingThreadId ; struct _FILE_OBJECT * FileObject ; 
   
           
    
  
  
  PCUNICODE_STRING     ImageFileName ; 
  PCUNICODE_STRING     CommandLine ; 
  NTSTATUS             CreationStatus ; } PS_CREATE_NOTIFY_INFO , * PPS_CREATE_NOTIFY_INFO ;
 

De interesse é o FILE_OBJECT, que é o objeto kernel correspondente ao HANDLE passado para NtCreateSection na seção anterior. Este FILE_OBJECT normalmente corresponde a um arquivo no disco, que pode ser verificado em busca de malware.

Os produtos de segurança também podem usar callbacks de minifiltro do sistema de arquivos, que recebem notificações quando os arquivos são criados, interagidos ou fechados. O impacto no sistema da varredura de cada operação de leitura e gravação pode ser significativo, portanto, os arquivos normalmente são varridos ao serem abertos e fechados por motivos de desempenho.

Existem outros pontos de interceptação de produtos de segurança em potencial que não discutiremos aqui. Veja esta palestra para mais informações.

Trabalho prévio

Doppelganging de processo

O Windows Transactional NTFS (TxF) é um mecanismo que permite que um aplicativo execute uma série de operações do sistema de arquivos como uma única transação atômica, que é então confirmada ou revertida. Os arquivos podem existir dentro de uma transação que, se revertida, nunca é visível para o sistema de arquivos subjacente. Usando o TxF, é possível criar uma seção de imagem a partir de um arquivo dentro de uma transação e, em seguida, reverter essa transação. É possível criar um processo a partir dessas seções de imagem.

Process Herpaderping

Depois de criar a seção de imagem, Process Herpaderping usa o identificador de arquivo existente para sobrescrever o executável com um PE chamariz. Embora isso deixe o engodo no disco, é diferente daquele em execução na memória. O engodo permanece no disco durante toda a vida do processo de carga útil.

Reconstrução de imagem do processo

A nova imagem do processo explora um problema de sincronização de cache no kernel do Windows, causando uma incompatibilidade entre o caminho de um arquivo executável e o caminho relatado para as seções de imagem criadas a partir desse executável. Ao carregar uma DLL em um caminho falso, descarregá-la e, em seguida, carregá-la a partir de um novo caminho, várias APIs do Windows retornarão o caminho antigo. Isso pode enganar os produtos de segurança, fazendo-os procurar imagens carregadas no caminho errado.

Fantasiar um processo

Podemos construir sobre Doppelgänging e Herpaderping para executar executáveis ​​que já foram excluídos. Existem várias maneiras de excluir um arquivo no Windows, incluindo: 3

O Windows tenta impedir que os executáveis ​​mapeados sejam modificados. Depois que um arquivo é mapeado para uma seção de imagem, as tentativas de abri-lo com FILE_WRITE_DATA (para modificá-lo) falharão com ERROR_SHARING_VIOLATION. As tentativas de exclusão por meio de FILE_DELETE_ON_CLOSE / FILE_FLAG_DELETE_ON_CLOSE falham com ERROR_SHARING_VIOLATION. NtSetInformationFile (FileDispositionInformation) requer o direito de acesso DELETE. Mesmo que o direito de acesso DELETE seja concedido a arquivos mapeados para seções de imagem, NtSetInformationFile (FileDispositionInformation) falha com STATUS_CANNOT_DELETE. As tentativas de exclusão por meio de FILE_SUPERCEDE / CREATE_ALWAYS falham com ACCESS_DENIED. 

Uma observação importante, no entanto, é que essa restrição de exclusão só entra em vigor depois que o executável é mapeado em uma seção de imagem. Isso significa que é possível criar um arquivo, marcá-lo para exclusão, mapeá-lo para uma seção de imagem, fechar o identificador de arquivo para concluir a exclusão e, em seguida, criar um processo a partir da seção agora sem arquivo. Este é o Process Ghosting.

O fluxo de ataque é:

  1. Crie um arquivo
  2. Coloque o arquivo em um estado de exclusão pendente usando NtSetInformationFile (FileDispositionInformation) . Nota: Tentar usar FILE_DELETE_ON_CLOSE em vez disso não excluirá o arquivo.
  3. Grave o executável de carga útil no arquivo. O conteúdo não é mantido porque o arquivo já está com exclusão pendente. O estado de exclusão pendente também bloqueia tentativas externas de abertura de arquivo.
  4. Crie uma seção de imagem para o arquivo.
  5. Feche o identificador de exclusão pendente, excluindo o arquivo.
  6. Crie um processo usando a seção de imagem.
  7. Atribuir argumentos de processo e variáveis ​​de ambiente.
  8. Crie um thread para executar no processo.

Os retornos de chamada do antivírus são invocados na criação do thread, que ocorre depois que o arquivo é excluído. As tentativas de abrir o arquivo ou executar E / S no arquivo excluído falharão com STATUS_FILE_DELETED. As tentativas de abrir o arquivo antes da conclusão da exclusão falharão com STATUS_DELETE_PENDING.

Esse tipo de violação também pode ser aplicado a DLLs, porque as DLLs são seções de imagem mapeadas.

Demo

O vídeo abaixo mostra o Windows Defender detectando e bloqueando a execução de um programa potencialmente indesejado (PUP), o Windows Credential Editor, que pode ser usado por invasores para movimento lateral. Em seguida, mostra como o Ghosting interfere na capacidade do Defender de escanear e bloquear o filhote.https://play.vidyard.com/jsnyBCf6QRQY3pPt8DDhPc?disable_popouts=1&v=4.2.30&type=inline

Examinando a atividade do sistema durante a demonstração, podemos ver o Defender tentando inicialmente abrir o executável de carga útil para digitalizá-lo, mas falhando porque o arquivo está em um estado de exclusão pendente. As tentativas posteriores de abri-lo falham porque o arquivo já foi excluído. A carga útil (ghost.exe) é executada sem problemas.

Detecção

O Elastic Security detecta uma variedade de técnicas de adulteração de imagem de processo, incluindo Doppelgänging, Herpaderping e Ghosting. Ele faz isso verificando o FILE_OBJECT quanto a anormalidades durante o retorno de chamada de criação do processo. Eles são relatados em eventos de criação de processo em process.Ext.defense_evasions .

Comparando técnicas

Com base em uma tabela útil da documentação do Process Herpaderping, podemos comparar o fluxo básico da API entre as várias técnicas:

ModeloTécnica
Esvaziamentomapa -> modificar seção -> executar
Doppelgangingtransact -> write -> map -> rollback -> execute
Herpaderpingescrever -> mapear -> modificar -> executar -> fechar
Ghostingexcluir pendente -> escrever -> mapa -> fechar (excluir) -> executar

Conclusão

Neste blog, pesquisamos o estado da arte em ataques de adulteração de imagens executáveis ​​do Windows e, em seguida, divulgamos um novo tipo de ataque. Em seguida, demonstramos esse ataque contornando o software de segurança comum e mostramos como detectá-lo usando um software disponível gratuitamente.

Divulgação responsável : enviamos um relatório de bug ao MSRC em 2021-05-06, incluindo um rascunho desta postagem do blog, um vídeo de demonstração e o código-fonte de um PoC. Eles responderam em 2021-05-10, indicando que isso não atende seus padrões de manutenção, porhttps://aka.ms/windowscriteria.

Referências

1. Com algumas exceções, como os processos do sistema e do registro.
2. Esses exemplos são pseudocódigo.
3.   https://go.microsoft.com/fwlink/?LinkId=140636 Página 32, “Semântica de exclusão de arquivo”

Fonte: https://www.elastic.co/