APIs comunes usadas en Malware

Reading time: 9 minutes

tip

Aprende y practica Hacking en AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica Hacking en GCP: HackTricks Training GCP Red Team Expert (GRTE) Aprende y practica Hacking en Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Apoya a HackTricks

Genérico

Redes

Raw SocketsWinAPI Sockets
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 comprimen (p. ej., GZip). Cuando las respuestas superan un umbral (~1 MB), los datos se fragmentan en pequeños chunks (p. ej., segmentos de 16 KB) para evitar heurísticas basadas en tamaño y reducir picos de memoria durante la deserialisation.

Persistencia

RegistryFileService
RegCreateKeyEx()GetTempPath()OpenSCManager
RegOpenKeyEx()CopyFile()CreateService()
RegSetValueEx()CreateFile()StartServiceCtrlDispatcher()
RegDeleteKeyEx()WriteFile()
RegGetValue()ReadFile()

Cifrado

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

Anti-Analysis/VM

Function NameAssembly Instructions
IsDebuggerPresent()CPUID()
GetSystemInfo()IN()
GlobalMemoryStatusEx()
GetVersion()
CreateToolhelp32Snapshot [Check if a process is running]
CreateFileW/A [Check if a file exist]

Control de ejecución basado en locale/teclado

Muchos stealers/loaders abortan en ciertas locales para evadir a los investigadores y cumplir con las restricciones del threat-actor. Comprobaciones típicas:

  • GetKeyboardLayout para enumerar los layouts instalados (por hilo/usuario)
  • GetLocaleInfoA/W para resolver códigos de país/región
  • GetSystemDefaultLangID / GetUserDefaultLangID

Si cualquiera coincide con una lista bloqueada (comúnmente países de la CIS), el loader sale inmediatamente antes de generar IOCs de red o realizar inyección.

Defence/hunting

  • Señalar procesos que consulten múltiples APIs de locale/teclado al inicio de la ejecución y que luego salgan sin actividad observable.
  • Correlacionar con chequeos anti-VM (cadenas BIOS, dispositivos PnP, modelo de disco, servicios) reutilizados de proyectos open-source (p. ej., VMDetector) para detectar ejecución condicionada.

Fingerprinting de API de emuladores & evasión por sleep

El malware suele fingerprintear emuladores de sandbox buscando las exports virtualizadas de Defender (visto 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 desperdiciar tiempo de análisis.

Ejemplos de nombres de API usados como canarios:

  • MpVmp32Entry, MpVmp32FastEnter, MpCallPreEntryPointCode, MpCallPostEntryPointCode, MpFinalize, MpReportEvent*, MpSwitchToNextThread*
  • VFS_* family: VFS_Open, VFS_Read, VFS_MapViewOfFile, VFS_UnmapViewOfFile, VFS_FindFirstFile/FindNextFile, VFS_CopyFile, VFS_DeleteFile, VFS_MoveFile
  • ThrdMgr_*: ThrdMgr_GetCurrentThreadHandle, ThrdMgr_SaveTEB, ThrdMgr_SwitchThreads

Typical delay primitive (user-land):

cmd
cmd /c timeout /t %RANDOM_IN_[600,1800]% > nul

Filtrado de argumentos

  • Los operadores a veces requieren que esté presente un switch de CLI con aspecto benigno antes de ejecutar el payload (por ejemplo, /i:--type=renderer para imitar procesos hijo de Chromium). Si falta el switch, el loader sale inmediatamente, impidiendo la ejecución ingenua en un sandbox.

Sigilo

Nombre
VirtualAllocReservar memoria (packers)
VirtualProtectCambiar permisos de memoria (packer que da permiso de ejecución a una sección)
ReadProcessMemoryInyección en procesos externos
WriteProcessMemoryA/WInyección en procesos externos
NtWriteVirtualMemory
CreateRemoteThreadDLL/Process injection...
NtUnmapViewOfSection
QueueUserAPC
CreateProcessInternalA/W

Ejecución

Nombre de la función
CreateProcessA/W
ShellExecute
WinExec
ResumeThread
NtResumeThread

Miscelánea

  • GetAsyncKeyState() -- Registro de teclas
  • SetWindowsHookEx -- Registro de teclas
  • GetForeGroundWindow -- Obtener el nombre de la ventana en ejecución (o el sitio web desde un navegador)
  • LoadLibrary() -- Importar librería
  • GetProcAddress() -- Importar librería
  • 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 los recursos del ejecutable

Malware Techniques

DLL Injection

Execute an arbitrary DLL inside another process

  1. Localizar el proceso en el que inyectar el DLL malicioso: CreateToolhelp32Snapshot, Process32First, Process32Next
  2. Abrir el proceso: GetModuleHandle, GetProcAddress, OpenProcess
  3. Escribir la ruta del DLL dentro del proceso: VirtualAllocEx, WriteProcessMemory
  4. Crear un thread en el proceso que cargue el DLL malicioso: CreateRemoteThread, LoadLibrary

Otras funciones a usar: 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

  1. Encontrar un thread objetivo: CreateToolhelp32Snapshot, Thread32First, Thread32Next
  2. Abrir el thread: OpenThread
  3. Suspender el thread: SuspendThread
  4. Escribir la ruta del DLL malicioso dentro del proceso víctima: VirtualAllocEx, WriteProcessMemory
  5. Reanudar el thread para que cargue la librería: ResumeThread

PE Injection

Portable Execution Injection: El ejecutable será escrito en la memoria del proceso víctima y se ejecutará desde allí.

Process Hollowing (a.k.a RunPE)

Process Hollowing es uno de los trucos favoritos de defence-evasion / execution usados por el malware en Windows. La idea es lanzar un proceso legítimo en estado suspendido, eliminar (hollow) su imagen original de la memoria y copiar un PE arbitrario en su lugar. Cuando el hilo primario se reanude finalmente, el entry-point malicioso se ejecuta bajo la apariencia de un binario confiable (a menudo firmado por Microsoft).

Flujo típico:

  1. Crear un host benigno (p. ej. RegAsm.exe, rundll32.exe, msbuild.exe) suspendido de modo que aún no se ejecuten instrucciones.
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);
  1. Leer el payload malicioso en memoria y parsear sus cabeceras PE para obtener SizeOfImage, secciones y el nuevo EntryPoint.
  2. NtUnmapViewOfSection / ZwUnmapViewOfSection – desempaquetar (unmap) la base de imagen original del proceso suspendido.
  3. VirtualAllocEx – reservar memoria RWX de SizeOfImage dentro del proceso remoto.
  4. WriteProcessMemory – copiar primero los Headers, luego iterar sobre las secciones copiando sus datos crudos.
  5. SetThreadContext – parchear el valor de EAX/RAX (RCX en x64) o Rip en la estructura de contexto para que EIP apunte al EntryPoint del payload.
  6. ResumeThread – el hilo continúa, ejecutando el código suministrado por el atacante.

Esqueleto mínimo de proof-of-concept (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á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 stealer VB6 descifrado (holographies.exe) no se escribe en disco; solo existe dentro del proceso hollowed, lo que dificulta la static detection.
  • Cadenas sensibles (regexes, paths, Telegram credentials) están RC4-encrypted por cadena y solo se descifran en runtime, complicando aún más la memory scanning.

Ideas de detección:

  • Generar alertas sobre procesos CREATE_SUSPENDED que nunca crean ventanas GUI/console antes de que se asigne una región de memoria con permisos RWX (raro en código benigno).
  • Buscar una secuencia de llamadas NtUnmapViewOfSection ➜ VirtualAllocEx ➜ WriteProcessMemory entre procesos distintos.
  • Uso inusual de utilidades de desarrollador de confianza como hollowing hosts, especialmente MSBuild.exe, RegAsm.exe, rundll32.exe, cuando tienen como padre loaders de corta duración.
  • Buscar msbuild.exe lanzado desde rutas escribibles por el usuario o sin el contexto .sln/.proj correspondiente y que luego realice conexiones salientes (ATT&CK T1127.001 + T1055.012).

Common host processes and path resolution

  • MSBuild.exe se elige frecuentemente como hollowing host para mezclarse con las herramientas de desarrollo. Los loaders suelen buscar en ubicaciones apropiadas para la arquitectura:
  • C:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe
  • C:\Windows\Microsoft.NET\Framework64\v4.0.30319\MSBuild.exe
  • C:\Windows\System32\MSBuild.exe
  • C:\Windows\SysWOW64\MSBuild.exe
  • Seleccionar el host que coincida con la arquitectura actual del payload/OS antes de llamar a CreateProcess(..., CREATE_SUSPENDED, ...).

Hooking

  • La SSDT (System Service Descriptor Table) apunta a funciones del kernel (ntoskrnl.exe) o al driver GUI (win32k.sys) para que los procesos de usuario puedan llamar a esas funciones.
  • Un rootkit puede modificar estos punteros 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 tabla de funciones 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 se pueden hacer desde userland. El objetivo es hookear funciones exportadas por DLLs.
  • Inline Hooks: Este tipo es difícil de conseguir. Involucra modificar el código de las funciones en sí. Tal vez poniendo un jump al inicio de las mismas.

References

tip

Aprende y practica Hacking en AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica Hacking en GCP: HackTricks Training GCP Red Team Expert (GRTE) Aprende y practica Hacking en Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Apoya a HackTricks