hacktricks/src/reversing/common-api-used-in-malware.md

9.7 KiB
Raw Blame History

API Comum Usado em Malware

{{#include ../banners/hacktricks-training.md}}

Genérico

Rede

Sockets Brutos Sockets WinAPI
socket() WSAStratup()
bind() bind()
listen() listen()
accept() accept()
connect() connect()
read()/recv() recv()
write() send()
shutdown() WSACleanup()

Persistência

Registro Arquivo Serviço
RegCreateKeyEx() GetTempPath() OpenSCManager
RegOpenKeyEx() CopyFile() CreateService()
RegSetValueEx() CreateFile() StartServiceCtrlDispatcher()
RegDeleteKeyEx() WriteFile()
RegGetValue() ReadFile()

Criptografia

Nome
WinCrypt
CryptAcquireContext()
CryptGenKey()
CryptDeriveKey()
CryptDecrypt()
CryptReleaseContext()

Anti-Análise/VM

Nome da Função Instruções de Assembly
IsDebuggerPresent() CPUID()
GetSystemInfo() IN()
GlobalMemoryStatusEx()
GetVersion()
CreateToolhelp32Snapshot [Verificar se um processo está em execução]
CreateFileW/A [Verificar se um arquivo existe]

Stealth

Nome
VirtualAlloc Alocar memória (packers)
VirtualProtect Alterar permissão de memória (packer dando permissão de execução a uma seção)
ReadProcessMemory Injeção em processos externos
WriteProcessMemoryA/W Injeção em processos externos
NtWriteVirtualMemory
CreateRemoteThread Injeção de DLL/Processo...
NtUnmapViewOfSection
QueueUserAPC
CreateProcessInternalA/W

Execução

Nome da Função
CreateProcessA/W
ShellExecute
WinExec
ResumeThread
NtResumeThread

Diversos

  • GetAsyncKeyState() -- Registro de teclas
  • SetWindowsHookEx -- Registro de teclas
  • GetForeGroundWindow -- Obter nome da janela em execução (ou o site de um navegador)
  • LoadLibrary() -- Importar biblioteca
  • GetProcAddress() -- Importar biblioteca
  • CreateToolhelp32Snapshot() -- Listar processos em execução
  • GetDC() -- Captura de tela
  • BitBlt() -- Captura de tela
  • InternetOpen(), InternetOpenUrl(), InternetReadFile(), InternetWriteFile() -- Acessar a Internet
  • FindResource(), LoadResource(), LockResource() -- Acessar recursos do executável

Técnicas de Malware

Injeção de DLL

Executar uma DLL arbitrária dentro de outro processo

  1. Localizar o processo para injetar a DLL maliciosa: CreateToolhelp32Snapshot, Process32First, Process32Next
  2. Abrir o processo: GetModuleHandle, GetProcAddress, OpenProcess
  3. Escrever o caminho para a DLL dentro do processo: VirtualAllocEx, WriteProcessMemory
  4. Criar uma thread no processo que carregará a DLL maliciosa: CreateRemoteThread, LoadLibrary

Outras funções a serem usadas: NTCreateThreadEx, RtlCreateUserThread

Injeção de DLL Reflexiva

Carregar uma DLL maliciosa sem chamar as chamadas normais da API do Windows.
A DLL é mapeada dentro de um processo, resolverá os endereços de importação, corrigirá as realocações e chamará a função DllMain.

Sequestro de Thread

Encontrar uma thread de um processo e fazê-la carregar uma DLL maliciosa

  1. Encontrar uma thread alvo: CreateToolhelp32Snapshot, Thread32First, Thread32Next
  2. Abrir a thread: OpenThread
  3. Suspender a thread: SuspendThread
  4. Escrever o caminho para a DLL maliciosa dentro do processo da vítima: VirtualAllocEx, WriteProcessMemory
  5. Retomar a thread carregando a biblioteca: ResumeThread

Injeção PE

Injeção de Execução Portátil: O executável será escrito na memória do processo da vítima e será executado a partir daí.

Hollowing de Processo (a.k.a RunPE)

Process Hollowing é um dos truques favoritos de evasão de defesa / execução usados por malware do Windows. A ideia é lançar um processo legítimo no estado suspenso, remover (hollow) sua imagem original da memória e copiar um PE arbitrário em seu lugar. Quando a thread primária é finalmente retomada, o ponto de entrada malicioso é executado sob a aparência de um binário confiável (frequentemente assinado pela Microsoft).

Fluxo de trabalho típico:

  1. Criar um host benigno (por exemplo, RegAsm.exe, rundll32.exe, msbuild.exe) suspenso para que nenhuma instrução seja executada ainda.
STARTUPINFOA  si = { sizeof(si) };
PROCESS_INFORMATION pi;
CreateProcessA("C:\\Windows\\Microsoft.NET\\Framework32\\v4.0.30319\\RegAsm.exe",
NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &si, &pi);
  1. Ler a carga maliciosa na memória e analisar seus cabeçalhos PE para obter SizeOfImage, seções e o novo EntryPoint.
  2. NtUnmapViewOfSection / ZwUnmapViewOfSection desmapear a base da imagem original do processo suspenso.
  3. VirtualAllocEx reservar memória RWX de SizeOfImage dentro do processo remoto.
  4. WriteProcessMemory copiar os Headers primeiro, depois iterar sobre as seções copiando seus dados brutos.
  5. SetThreadContext corrigir o valor de EAX/RAX (RCX em x64) ou Rip na estrutura de contexto para que EIP aponte para o EntryPoint da carga.
  6. ResumeThread a thread continua, executando o código fornecido pelo atacante.

Esqueleto mínimo de prova de conceito (x86):

void RunPE(LPCSTR host, LPVOID payload, DWORD payloadSize){
// 1. create suspended process
STARTUPINFOA si = {sizeof(si)}; PROCESS_INFORMATION pi;
CreateProcessA(host, NULL,NULL,NULL,FALSE,CREATE_SUSPENDED,NULL,NULL,&si,&pi);

// 2. read remote PEB to get ImageBaseAddress
CONTEXT ctx; ctx.ContextFlags = CONTEXT_FULL;
GetThreadContext(pi.hThread,&ctx);
PVOID baseAddr;
ReadProcessMemory(pi.hProcess,(PVOID)(ctx.Ebx+8),&baseAddr,4,NULL);

// 3. unmap original image & allocate new region at same base
NtUnmapViewOfSection(pi.hProcess,baseAddr);
PVOID newBase = VirtualAllocEx(pi.hProcess,baseAddr,pHdr->OptionalHeader.SizeOfImage,
MEM_COMMIT|MEM_RESERVE,PAGE_EXECUTE_READWRITE);
// 4-5. copy headers & sections …
// 6. write new image base into PEB and set Eip
WriteProcessMemory(pi.hProcess,(PVOID)(ctx.Ebx+8),&baseAddr,4,NULL);
ctx.Eax = (DWORD)(newBase) + pHdr->OptionalHeader.AddressOfEntryPoint;
SetThreadContext(pi.hThread,&ctx);
// 7. run!
ResumeThread(pi.hThread);
}

Notas práticas observadas na campanha DarkCloud Stealer:

  • O loader escolheu RegAsm.exe (parte do .NET Framework) como host um binário assinado que provavelmente não chamará atenção.
  • O stealer VB6 decifrado (holographies.exe) não é gravado no disco; ele existe apenas dentro do processo oco, dificultando a detecção estática.
  • Strings sensíveis (regexes, caminhos, credenciais do Telegram) são RC4-encriptadas por string e só são decriptadas em tempo de execução, complicando ainda mais a varredura de memória.

Ideias de detecção:

  • Alertar sobre processos CREATE_SUSPENDED que nunca criam janelas GUI/console antes que uma região de memória seja alocada como RWX (raro para código benigno).
  • Procurar por uma sequência de chamadas NtUnmapViewOfSection ➜ VirtualAllocEx ➜ WriteProcessMemory em diferentes processos.

Hooking

  • A SSDT (System Service Descriptor Table) aponta para funções do kernel (ntoskrnl.exe) ou driver GUI (win32k.sys) para que processos de usuário possam chamar essas funções.
  • Um rootkit pode modificar esses ponteiros para endereços que ele controla.
  • IRP (I/O Request Packets) transmitem pedaços de dados de um componente para outro. Quase tudo no kernel usa IRPs e cada objeto de dispositivo tem sua própria tabela de funções que pode ser hookada: DKOM (Manipulação Direta de Objetos do Kernel).
  • A IAT (Import Address Table) é útil para resolver dependências. É possível hookar essa tabela para sequestrar o código que será chamado.
  • EAT (Export Address Table) Hooks. Esses hooks podem ser feitos a partir do userland. O objetivo é hookar funções exportadas por DLLs.
  • Inline Hooks: Esse tipo é difícil de alcançar. Isso envolve modificar o código das próprias funções. Talvez colocando um salto no início delas.

Referências

{{#include ../banners/hacktricks-training.md}}