mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
191 lines
9.7 KiB
Markdown
191 lines
9.7 KiB
Markdown
# 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}}
|