12 KiB
API comunes usadas en Malware
{{#include ../banners/hacktricks-training.md}}
Genérico
Redes
Sockets sin procesar | Sockets WinAPI |
---|---|
socket() | WSAStratup() |
bind() | bind() |
listen() | listen() |
accept() | accept() |
connect() | connect() |
read()/recv() | recv() |
write() | send() |
shutdown() | WSACleanup() |
TLS pinning y transporte fragmentado
Muchos loaders envuelven su flujo TCP en SslStream
y fijan el certificado leaf del servidor contra una copia embebida (certificate pinning). La información/tareas del bot se comprime (p. ej., GZip). Cuando las respuestas superan un umbral (~1 MB), los datos se fragmentan en pequeños fragmentos (p. ej., segmentos de 16 KB) para evitar heurísticas basadas en el tamaño y reducir picos de memoria durante la deserialización.
Persistencia
Registro | Archivo | Servicio |
---|---|---|
RegCreateKeyEx() | GetTempPath() | OpenSCManager |
RegOpenKeyEx() | CopyFile() | CreateService() |
RegSetValueEx() | CreateFile() | StartServiceCtrlDispatcher() |
RegDeleteKeyEx() | WriteFile() | |
RegGetValue() | ReadFile() |
Cifrado
Nombre |
---|
WinCrypt |
CryptAcquireContext() |
CryptGenKey() |
CryptDeriveKey() |
CryptDecrypt() |
CryptReleaseContext() |
Anti-análisis/VM
Nombre de función | Instrucciones de ensamblador |
---|---|
IsDebuggerPresent() | CPUID() |
GetSystemInfo() | IN() |
GlobalMemoryStatusEx() | |
GetVersion() | |
CreateToolhelp32Snapshot [Check if a process is running] | |
CreateFileW/A [Check if a file exist] |
Emulator API fingerprinting & evasión de sleep
Malware suele hacer fingerprinting de emuladores de sandbox buscando las exports virtualizadas de Defender (vistas en el Malware Protection Emulator). Si cualquiera de estos símbolos está presente (escaneo case-insensitive del proceso), la ejecución se retrasa 10–30 minutos y se vuelve a comprobar para consumir tiempo del análisis.
Ejemplos de nombres de API usados como canarios:
MpVmp32Entry
,MpVmp32FastEnter
,MpCallPreEntryPointCode
,MpCallPostEntryPointCode
,MpFinalize
,MpReportEvent*
,MpSwitchToNextThread*
- familia
VFS_*
:VFS_Open
,VFS_Read
,VFS_MapViewOfFile
,VFS_UnmapViewOfFile
,VFS_FindFirstFile/FindNextFile
,VFS_CopyFile
,VFS_DeleteFile
,VFS_MoveFile
ThrdMgr_*
:ThrdMgr_GetCurrentThreadHandle
,ThrdMgr_SaveTEB
,ThrdMgr_SwitchThreads
Primitiva típica de retardo (user-land):
cmd /c timeout /t %RANDOM_IN_[600,1800]% > nul
Control de argumentos
- Los operadores a veces requieren que esté presente un switch de CLI con apariencia benigno antes de ejecutar el payload (p. ej.,
/i:--type=renderer
para imitar procesos hijos de Chromium). Si el switch está ausente, el loader sale inmediatamente, dificultando la ejecución naive en sandboxes.
Stealth
Nombre | Descripción |
---|---|
VirtualAlloc | Alloc memory (packers) |
VirtualProtect | Change memory permission (packer giving execution permission to a section) |
ReadProcessMemory | Injection into external processes |
WriteProcessMemoryA/W | Injection into external processes |
NtWriteVirtualMemory | |
CreateRemoteThread | DLL/Process injection... |
NtUnmapViewOfSection | |
QueueUserAPC | |
CreateProcessInternalA/W |
Execution
Nombre de función |
---|
CreateProcessA/W |
ShellExecute |
WinExec |
ResumeThread |
NtResumeThread |
Misceláneo
- GetAsyncKeyState() -- registro de teclas
- SetWindowsHookEx -- registro de teclas
- GetForeGroundWindow -- Obtener el nombre de la ventana activa (o la web abierta en un navegador)
- LoadLibrary() -- Importar librería
- GetProcAddress() -- Obtener la dirección de la función
- CreateToolhelp32Snapshot() -- Listar procesos en ejecución
- GetDC() -- Captura de pantalla
- BitBlt() -- Captura de pantalla
- InternetOpen(), InternetOpenUrl(), InternetReadFile(), InternetWriteFile() -- Acceder a Internet
- FindResource(), LoadResource(), LockResource() -- Acceder a recursos del ejecutable
Malware Techniques
DLL Injection
Execute an arbitrary DLL inside another process
- Locate the process to inject the malicious DLL: CreateToolhelp32Snapshot, Process32First, Process32Next
- Open the process: GetModuleHandle, GetProcAddress, OpenProcess
- Write the path to the DLL inside the process: VirtualAllocEx, WriteProcessMemory
- Create a thread in the process that will load the malicious DLL: CreateRemoteThread, LoadLibrary
Other functions to use: NTCreateThreadEx, RtlCreateUserThread
Reflective DLL Injection
Load a malicious DLL without calling normal Windows API calls.
The DLL is mapped inside a process, it will resolve the import addresses, fix the relocations and call the DllMain function.
Thread Hijacking
Find a thread from a process and make it load a malicious DLL
- Find a target thread: CreateToolhelp32Snapshot, Thread32First, Thread32Next
- Open the thread: OpenThread
- Suspend the thread: SuspendThread
- Write the path to the malicious DLL inside the victim process: VirtualAllocEx, WriteProcessMemory
- Resume the thread loading the library: ResumeThread
PE Injection
Portable Execution Injection: The executable will be written in the memory of the victim process and it will be executed from there.
Process Hollowing (a.k.a RunPE)
Process Hollowing
is one of the favourite defence-evasion / execution tricks used by Windows malware. The idea is to launch a legitimate process in the suspended state, remove (hollow) its original image from memory and copy an arbitrary PE in its place. When the primary thread is finally resumed the malicious entry-point executes under the guise of a trusted binary (often signed by Microsoft).
Typical workflow:
- Spawn a benign host (e.g.
RegAsm.exe
,rundll32.exe
,msbuild.exe
) suspended so that no instructions run yet.
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);
- Read the malicious payload into memory and parse its PE headers to obtain
SizeOfImage
, sections and the newEntryPoint
. - NtUnmapViewOfSection / ZwUnmapViewOfSection – unmap the original image base of the suspended process.
- VirtualAllocEx – reserve RWX memory of
SizeOfImage
inside the remote process. - WriteProcessMemory – copy the
Headers
first, then iterate over sections copying their raw data. - SetThreadContext – patch the value of
EAX/RAX
(RCX
on x64) orRip
in the context structure so thatEIP
points to the payload’sEntryPoint
. - ResumeThread – the thread continues, executing the attacker-supplied code.
Minimal proof-of-concept (x86) skeleton:
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ácticas observadas en la campaña DarkCloud Stealer:
- El loader seleccionó
RegAsm.exe
(parte del .NET Framework) como host – un binario firmado que probablemente no llame la atención. - El VB6 stealer descifrado (
holographies.exe
) no se escribe en disco; solo existe dentro del hollowed process, lo que dificulta la detección estática. - Las cadenas sensibles (regexes, paths, credenciales de Telegram) están RC4-encrypted por cadena y solo se descifran en runtime, complicando aún más el memory scanning.
Ideas de detección:
- Alertar sobre procesos
CREATE_SUSPENDED
que nunca crean ventanas GUI/console antes de que se asigne una región de memoria como RWX (raro en código benigno). - Buscar una secuencia de llamadas
NtUnmapViewOfSection ➜ VirtualAllocEx ➜ WriteProcessMemory
entre procesos diferentes.
Hooking
- La SSDT (System Service Descriptor Table) apunta a funciones del kernel (ntoskrnl.exe) o al driver de GUI (win32k.sys), de modo que los procesos de usuario puedan llamar a estas funciones.
- Un rootkit puede modificar estos pointers hacia direcciones que controla.
- IRP (I/O Request Packets) transmiten fragmentos de datos de un componente a otro. Casi todo en el kernel usa IRPs y cada device object tiene su propia function table que puede ser hooked: DKOM (Direct Kernel Object Manipulation)
- La IAT (Import Address Table) es útil para resolver dependencias. Es posible hookear esta tabla para secuestrar el código que será llamado.
- EAT (Export Address Table) Hooks. Estos hooks pueden hacerse desde userland. El objetivo es hookear funciones exportadas por DLLs.
- Inline Hooks: Este tipo es difícil de lograr. Implica modificar el código de las funciones en sí. Quizá poniendo un jump al inicio de las mismas.
Referencias
- Unit42 – New Infection Chain and ConfuserEx-Based Obfuscation for DarkCloud Stealer
- Check Point Research – Under the Pure Curtain: From RAT to Builder to Coder
{{#include ../banners/hacktricks-training.md}}