Dez técnicas de injeção de processo: um levantamento técnico das técnicas comuns e em alta
Nota do editor: a Elastic uniu forças com a Endgame em outubro de 2019 e migrou parte do conteúdo do blog da Endgame para elastic.co/pt/. Veja Elastic Security para saber mais sobre nossas soluções integradas de segurança.
A injeção de processos é uma técnica de evasão de defesa amplamente utilizada, frequentemente em técnicas de malware e adversários sem arquivo, e envolve executar código personalizado dentro do espaço de endereçamento de outro processo. A injeção de processos melhora a furtividade, e algumas técnicas também alcançam persistência. Embora existam inúmeras técnicas de injeção de processos, neste blog apresento dez técnicas vistas no mercado que executam código de malware em nome de outro processo. Além disso, forneço capturas de tela de muitas dessas técnicas para facilitar a engenharia reversa e a análise de malware, auxiliando na detecção e defesa contra essas técnicas comuns.
1. INJEÇÃO CLÁSSICA DE DLL VIA CREATEREMOTETHREAD E LOADLIBRARY
Essa técnica é uma das mais comuns usadas para injetar malware em outro processo. O malware escreve o caminho para sua biblioteca de enlace dinâmico malicioso (DLL) no espaço de endereçamento virtual de outro processo, e garante que o processo remoto o carregue criando uma thread remota no processo alvo.

O malware precisa primeiro mirar em um processo para injeção (por exemplo, svchost.exe). Isso geralmente é feito pesquisando entre processos chamando um trio de Interfaces de Programa de Aplicação (API): CreateToolhelp32Snapshot, Process32First e Process32Next. CreateToolhelp32Snapshot é uma API usada para enumerar estados de heap ou módulo de um processo especificado ou de todos os processos, e retorna um snapshot. O Process32First recupera informações sobre o primeiro processo no snapshot, e então o Process32Next é usado em um loop para iterar por eles. Após encontrar o processo alvo, o malware obtém o controle do processo alvo chamando o OpenProcess.
Como mostrado na Figura 1, o malware chama o VirtualAllocEx para ter um espaço para escrever o caminho em sua DLL. O malware então chama o WriteProcessMemory para gravar o caminho na memória alocada. Por fim, para que o código seja executar em outro processo, o malware chama API como CreateRemoteThread, NtCreateThreadEx ou RtlCreateUserThread. Os dois últimos são indocumentados. No entanto, a ideia geral é passar o endereço do LoadLibrary para uma dessas API, de modo que um processo remoto precise executar a DLL em nome do malware.
O CreateRemoteThread é rastreado e sinalizado por muitos produtos de segurança. Além disso, requer uma DLL maliciosa no disco que pode ser detectada. Considerando que invasores geralmente injetam código para evitar defesas, invasores sofisticados provavelmente não usarão essa abordagem. A captura de tela abaixo mostra um malware chamado Rebhip realizando essa técnica.

Sha256: 07b8f25e7b536f5b6f686c12d04edc37e11347c8acd5c53f98a174723078c365
2. INJEÇÃO EXECUTÁVEL PORTÁTIL (INJEÇÃO PE)
Em vez de passar o endereço da LoadLibrary, malware pode copiar seu código malicioso para um processo aberto existente e fazê-lo ser executar (seja via um pequeno shellcode, ou chamando o CreateRemoteThread). Uma vantagem da injeção de PE em relação à técnica LoadLibrary é que o malware não precisa lançar uma DLL maliciosa no disco. Semelhante à primeira técnica, o malware aloca memória em um processo host (por exemplo, VirtualAllocEx) e, em vez de escrever um "caminho DLL", ele escreve seu código malicioso chamando WriteProcessMemory. No entanto, o obstáculo nessa abordagem é a mudança do endereço base da imagem copiada. Quando um malware injeta seu PE em outro processo, ele terá um novo endereço base que é imprevisível, exigindo que ele recalcule dinamicamente os endereços fixos de seu PE. Para superar isso, o malware precisa encontrar seu endereço da tabela de realocação no processo host e resolver os endereços absolutos da imagem copiada passando por seus descritores de realocação.

Essa técnica é semelhante a outras técnicas, como a injeção reflexiva de DLL e o módulo de memória, já que eles não depositam nenhum arquivo no disco. No entanto, as abordagens de módulo de memória e injeção reflexiva de DLL são ainda mais furtivas. Eles não dependem de API adicionais do Windows (por exemplo, CreateRemoteThread ou LoadLibrary), pois carregam e executam sozinhos na memória. A injeção reflexiva de DLL funciona criando uma DLL que se mapeamento para a memória quando executada, em vez de depender do carregador da Windows. Módulo de Memória é semelhante à injeção reflexiva de DLL, exceto que o injetor ou loader é responsável por mapeamento a DLL de destino na memória em vez do mapeamento da DLL em si. Em um post anterior no blog, essas duas abordagens de memória foram amplamente discutidas.
Ao analisar a injeção de PE, é muito comum ver loops (geralmente dois loops "para", um aninhado no outro), antes de uma chamada para o CreateRemoteThread. Essa técnica é bastante popular entre criptografadores (softwares que criptografam e ofuscam malware). Na Figura 2, o teste unitário de amostra está aproveitando essa técnica. O código possui dois loops aninhados para ajustar sua tabela de realocação, que podem ser vistos antes das chamadas para WriteProcessMemory e CreateRemoteThread. A instrução "e 0x0fff" também é outro bom indicador, mostrando que os primeiros 12 bits são usados para obter o deslocamento para o endereço virtual do bloco de realocação que o contém. Agora que o malware recalculou todos os endereços necessários, tudo o que ele precisa fazer é passar seu endereço inicial para o CreateRemoteThread e executar.

Sha256: ce8d7590182db2e51372a4a04d6a0927a65b2640739f9ec01cfd6c143b1110da
3. ESCAVAMENTO DE PROCESSOS (TAMBÉM CONHECIDO COMO SUBSTITUIÇÃO E CORRIMENTO DE PROCESSOS)
Em vez de injetar código em um programa host (por exemplo, injeção de DLL), o malware pode executar uma técnica conhecida como esvaziamento de processos. O esvaziamento de processos ocorre quando um malware desmapeia (esvazia) o código legítimo da memória do processo alvo e sobrescreve o espaço de memória do processo alvo (por exemplo, svchost.exe) com um executável malicioso.

O malware primeiro cria um novo processo para hospedar o código malicioso em modo suspenso. Como mostrado na Figura 3, isso é feito chamando o CreateProcess e definindo a Flag de Criação de Processos para CREATE_SUSPENDED (0x00000004). A thread principal do novo processo é criada em estado suspenso e só é executar quando a função ResumeThread é chamada. Em seguida, o malware precisa trocar o conteúdo do arquivo legítimo pelo seu payload malicioso. Isso é feito desmapeando a memória do processo alvo chamando ZwUnmapViewOfSection ou NtUnmapViewOfSection. Essas duas API basicamente liberam toda a memória apontada por uma seção. Agora que a memória está desmapeada, o loader executa o VirtualAllocEx para alocar nova memória para o malware e usa o WriteProcessMemory para gravar cada seção do malware no espaço de processamento alvo. O malware chama o SetThreadContext para apontar o ponto de entrada para uma nova seção de código que ele escreveu. No final, o malware retoma a thread suspensa chamando o ResumeThread para tirar o processo do estado suspenso.

Sha256: eae72d803bf67df22526f50fc7ab84d838efb2865c27aef1a61592b1c520d144
4. SEQUESTRO DE EXECUÇÃO DE THREADS (TAMBÉM CONHECIDO COMO SUSPENDER, INJETAR E RETOMAR (SIR))
Essa técnica tem algumas semelhanças com a técnica de esvaziamento do processo discutida anteriormente. No sequestro de execução de threads, o malware atinge uma thread já existente de um processo e evita qualquer operação ruidosa de criação de processos ou threads. Portanto, durante a análise, você provavelmente verá chamadas para CreateToolhelp32Snapshot e Thread32First seguidas pelo OpenThread.

Após obter um controle para o thread de destino, o malware coloca o thread em modo suspenso ao chamar o SuspendThread para realizar sua injeção. O malware chama VirtualAllocEx e WriteProcessMemory para alocar memória e realizar a injeção de código. O código pode conter shellcode, o caminho para a DLL maliciosa e o endereço da LoadLibrary.
A Figura 4 ilustra um troiano genérico usando essa técnica. Para sequestrar a execução da thread, o malware modifica o registrador EIP (um registrador que contém o endereço da próxima instrução) da thread alvo chamando SetThreadContext. Depois, o malware retoma a thread para executar o shellcode que ele escreveu no processo host. Do ponto de vista do invasores, a abordagem SIR pode ser problemática porque suspender e executar uma thread no meio de uma chamada ao sistema pode causar o travamento do sistema. Para evitar isso, um malware mais sofisticado retomaria e tentaria novamente depois se o registrador EIP estiver dentro do intervalo de NTDLL.dll.

Sha256: 787cbc8a6d1bc58ea169e51e1ad029a637f22560660cc129ab8a099a745bd50e
5. INJEÇÃO DE GANCHO VIA SETWINDOWSHOOKEX
Hooking é uma técnica usada para interceptar chamadas de função. Malware pode aproveitar a funcionalidade de hooking para carregar sua DLL maliciosa quando um evento é acionado em um thread específico. Isso geralmente é feito chamando o SetWindowsHookEx para instalar uma rotina de hook na cadeia de hooks. A função SetWindowsHookEx recebe quatro argumentos. O primeiro argumento é o tipo de evento. Os eventos refletem a variedade de tipos de ganchos e variam desde pressionar teclas no teclado (WH_KEYBOARD) até comandos do mouse (WH_MOUSE), TCC, etc. O segundo argumento é um apontamento para a função que o malware quer invocar na execução do evento. O terceiro argumento é um módulo que contém a função. Assim, é muito comum ver chamadas para LoadLibrary e GetProcAddress antes de chamar SetWindowsHookEx. O último argumento para essa função é o fio com o qual o procedimento do gancho deve ser associado. Se esse valor for definido como zero, todas as threads realizam a ação quando o evento é acionado. No entanto, malware geralmente atinge um único thread para menos ruído, então também é possível ver chamadas CreateToolhelp32Snapshot e Thread32Next antes do SetWindowsHookEx para buscar e direcionar um único thread. Uma vez que a DLL é injetada, o malware executa seu código malicioso em nome do processo que seu threadId foi passado para a função SetWindowsHookEx. Na Figura 5, o Locky Ransomware implementa essa técnica.

Sha256: 5d6ddb8458ee5ab99f3e7d9a21490ff4e5bc9808e18b9e20b6dc2c5b27927ba1
6. INJEÇÃO E PERSISTÊNCIA VIA MODIFICAÇÃO DO REGISTRO (EX.: APPINIT_DLLS, APPCERTDLLS, IFEO)
Appinit_DLL, AppCertDlls e IFEO (Image File Execution Options) são todas chaves de registro que malware utiliza tanto para injeção quanto para persistência. As inscrições estão localizadas nos seguintes locais:
HKLM\Software\Microsoft\Windows NT\CurrentVersion\Windows\Appinit_Dlls HKLM\Software\Wow6432Node\Microsoft\Windows NT\CurrentVersion\Windows\Appinit_Dlls HKLM\System\CurrentControlSet\Control\Control\Session Manager\AppCertDlls HKLM\Software\Microsoft\Windows NT\currentversion\image opções de execução de arquivo
AppInit_DLLs
Malware pode inserir a localização da biblioteca maliciosa sob a chave Appinit_Dlls registro para que outro processo carregue a biblioteca. Cada biblioteca sob essa chave de registro é carregada em todo processo que carrega User32.dll. User32.dll é uma biblioteca muito comum usada para armazenar elementos gráficos, como caixas de diálogo. Assim, quando um malware modifica essa subchave, a maioria dos processos carrega a biblioteca maliciosa. A Figura 6 demonstra o troiano Ginwui confiando nessa abordagem para injeção e persistência. Ele simplesmente abre a chave do registro Appinit_Dlls chamando RegCreateKeyEx e modifica seus valores chamando RegSetValueEx.

Sha256: 9f10ec2786a10971eddc919a5e87a927c652e1655ddbbae72d376856d30fa27c
AppCertDlls
Essa abordagem é muito semelhante à AppInit_DLLs, exceto que as DLLs sob essa chave de registro são carregadas em todo processo que chama as funções da API Win32 CreateProcess, CreateProcessAsUser, CreateProcessWithLogonW, CreateProcessWithTokenW e WinExec.
Opções de Execução de Arquivo de Imagem (IFEO)
O IFEO é tipicamente usado para fins de depuração. Os desenvolvedores podem definir o "Valor Depurador" sob essa chave de registro para anexar um programa a outro executável para depuração. Portanto, sempre que o executável é executar, o programa anexado a ele será executar. Para usar esse recurso, você pode simplesmente fornecer o caminho para o depurador e anexá-lo ao executável que deseja analisar. Malwares podem modificar essa chave de registro para se injetar no executável de destino. Na Figura 7, o trojan Diztakun implementa essa técnica modificando o valor do depurador do Gerenciador de Tarefas.

Sha256: f0089056fc6a314713077273c5910f878813fa750f801dfca4ae7e9d7578a148
7. INJEÇÃO E BOMBARDEAMENTO ATÔMICO DE APC
Malwares podem aproveitar as Chamadas de Procedimento Assíncronas (API) para forçar outra thread a executar seu código personalizado, anexando-o à fila API da thread de destino. Cada thread possui uma fila de API que aguardam a execução quando a thread de destino entra no estado alterável. Uma thread entra em estado de alerta se chamar as funções SleepEx, SignalObjectAndWait, MsgWaitForMultipleObjectsEx, WaitForMultipleObjectsEx ou WaitForSingleObjectEx. O malware geralmente procura qualquer thread que esteja em um estado alterável e então chama OpenThread e QueueUserAPC para colocar um API em fila em um thread. QueueUserAPC recebe três argumentos: 1) um handle para a thread de destino; 2) um ponteiro para a função que o malware deseja executar; 3) e o parâmetro que é passado ao ponteiro da função. Na Figura 8, o malware Amanahe primeiro chama o OpenThread para adquirir um handle de outra thread, e então chama QueueUserAPC com LoadLibraryA como ponteiro de função para injetar sua DLL maliciosa em outra thread.
AtomBombing é uma técnica que foi introduzida pela pesquisa do enSilo e depois usada no Dridex V4. Como discutimos em detalhes em um post anterior no blog, a técnica também depende da injeção de API. No entanto, ele utiliza tabelas de átomos para escrever na memória de outro processo.

Sha256: f74399cc0be275376dad23151e3d0c2e2a1c966e6db6a695a05ec1a30551c0ad
8. INJEÇÃO EXTRA DE MEMÓRIA DE JANELAS (EWMI) VIA SETWINDOWLONG
O EWMI depende da injeção na memória extra da janela da bandeja do Explorer, e já foi usado algumas vezes entre famílias de malwares como Gapz e PowerLoader. Ao registrar uma classe janela, uma aplicação pode especificar um número adicional de bytes de memória, chamado de memória extra de janela (EWM). No entanto, não há muito espaço em EWM. Para contornar essa limitação, o malware grava código em uma seção compartilhada de explorer.exe e usa SetWindowLong e SendNotifyMessage para ter um ponteiro de função que aponta para o shellcode e então executar.
O malware tem duas opções quando se trata de escrever em uma seção compartilhada. Ele pode criar uma seção compartilhada e mapeá-la tanto para si mesma quanto para outro processo (por exemplo, explorer.exe), ou simplesmente abrir uma seção compartilhada que já existe. A primeira tem a sobrecarga de alocar espaço de heap e chamar NTMapViewOfSection, além de algumas outras chamadas de API, então a segunda abordagem é usada com mais frequência. Após o malware escrever seu shellcode em uma seção compartilhada, ele usa GetWindowLong e SetWindowLong para acessar e modificar a memória extra de janela de "Shell_TrayWnd". GetWindowLong é uma API usada para recuperar o valor de 32 bits no offset especificado para a memória extra de janela de um objeto de classe janela, e SetWindowLong é usado para alterar valores no offset especificado. Ao fazer isso, o malware pode simplesmente alterar o deslocamento de um ponteiro de função na classe janela e apontá-lo para o código de shell escrito na seção compartilhada.
Como a maioria das outras técnicas mencionadas acima, o malware precisa acionar o código que escreveu. Em técnicas discutidas anteriormente, malware conseguia isso chamando API como CreateRemoteThread, QueueUserAPC ou SetThreadContext. Com essa abordagem, o malware aciona o código injetado chamando SendNotifyMessage. Após a execução do SendNotifyMessage, Shell_TrayWnd recebe e transfere o controle para o endereço apontado pelo valor previamente definido pelo SetWindowLong. Na Figura 9, um malware chamado PowerLoader usa essa técnica.


Sha256: 5e56a3c4d4c304ee6278df0b32afb62bd0d01e2a9894ad007f4cc5f873ab5cf
9. INJEÇÃO USANDO CALÇOS
A Microsoft fornece Shims para desenvolvedores principalmente para compatibilidade retroativa. Os shims permitem que desenvolvedores apliquem correções aos seus programas sem a necessidade de reescrever código. Ao utilizar calços, os desenvolvedores podem dizer ao sistema operacional como lidar com sua aplicação. Os shims são, essencialmente, um meio de interagir com APIs e direcionar executáveis específicos. Malwares podem tirar proveito dos shims para visar um executável tanto para fins de persistência quanto de injeção. O Windows executa o Shim Engine ao carregar um binário, verificando a existência de bancos de dados de shimming para aplicar as devidas correções.
Existem muitas correções que podem ser aplicadas, mas as favoritas dos malwares são aquelas relacionadas, de certa forma, à segurança (por exemplo, DisableNX, DisableSEH, InjectDLL, etc.). Para instalar um banco de dados de shimming, o malware pode utilizar diversas abordagens. Por exemplo, uma abordagem comum é simplesmente executar o sdbinst.exe e apontá-lo para o arquivo sdb malicioso. Na Figura 10, um adware chamado "Search Protect by Conduit" utiliza um shim para persistência e injeção. Ele aplica um shim do tipo "InjectDLL" ao Google Chrome para carregar o arquivo vc32loader.dll. Existem algumas ferramentas para analisar arquivos sdb, mas, para a análise do arquivo sdb listado abaixo, utilizei python-sdb.

Sha256: 6d5048baf2c3bba85adc9ac5ffd96b21c9a27d76003c4aa657157978d7437a20
10. IAT HOOKING E INLINE HOOKING (TAMBÉM CONHECIDOS COMO ROOTKITS DE USERLAND)
IAT hooking e inline hooking são geralmente conhecidos como rootkits de userland. O IAT hooking é uma técnica utilizada por malwares para alterar a tabela de endereços de importação (IAT). Quando uma aplicação legítima chama uma API localizada em uma DLL, a função substituída é executada em vez da original. Por outro lado, no inline hooking, o malware modifica a própria função da API. Na Figura 11, o malware FinFisher realiza IAT hooking ao modificar o destino para o qual a função CreateWindowEx aponta.

Sha256: f827c92fbe832db3f09f47fe0dcaafd89b40c7064ab90833a1f418f2d1e75e8e
CONCLUSÃO
Neste artigo, abordei dez técnicas diferentes que malwares utilizam para ocultar suas atividades dentro de outro processo. De modo geral, o malware injeta diretamente seu shellcode em outro processo ou força outro processo a carregar sua biblioteca maliciosa. Na Tabela 1, classifiquei as diversas técnicas e apresentei exemplos para servir de referência na observação de cada técnica de injeção abordada neste artigo. As figuras incluídas ao longo do texto ajudarão o pesquisador a identificar essas técnicas durante a engenharia reversa de malwares.

Agressores e pesquisadores descobrem regularmente novas técnicas para realizar injeções e garantir o caráter furtivo da operação. Este post detalhou dez técnicas comuns e emergentes, mas existem outras, como o COM hijacking. A missão dos defensores de detectar e prevenir a injeção furtiva de processos nunca chegará ao fim, pois os adversários jamais deixarão de inovar.
Na Endgame, pesquisamos continuamente técnicas avançadas de ocultação e incorporamos proteções ao nosso produto. Combinamos recursos que detectam DLLs maliciosas carregadas por meio de mecanismos de persistência (como AppInit DLLs, COM hijacking, entre outros), impedem diversas formas de injeção de código em tempo real — graças à nossa proteção patenteada contra injeção de shellcode — e detectam payloads maliciosos injetados e em execução na memória (introduzidos por qualquer uma das técnicas citadas) por meio de nossas técnicas de detecção de ataques sem arquivos, que estão com patente em análise. Essa abordagem torna nossa plataforma mais eficaz do que qualquer outro produto do mercado na proteção contra injeção de código, ao mesmo tempo em que maximiza a resiliência contra tentativas de evasão baseadas em técnicas emergentes de injeção de código.