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

191 lines
9.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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.
```c
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);
```
2. Ler a carga maliciosa na memória e analisar seus cabeçalhos PE para obter `SizeOfImage`, seções e o novo `EntryPoint`.
3. **NtUnmapViewOfSection** / **ZwUnmapViewOfSection** desmapear a base da imagem original do processo suspenso.
4. **VirtualAllocEx** reservar memória RWX de `SizeOfImage` dentro do processo remoto.
5. **WriteProcessMemory** copiar os `Headers` primeiro, depois iterar sobre as seções copiando seus dados brutos.
6. **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.
7. **ResumeThread** a thread continua, executando o código fornecido pelo atacante.
Esqueleto mínimo de prova de conceito (x86):
```c
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
- [Unit42 New Infection Chain and ConfuserEx-Based Obfuscation for DarkCloud Stealer](https://unit42.paloaltonetworks.com/new-darkcloud-stealer-infection-chain/)
{{#include ../banners/hacktricks-training.md}}