# 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 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 1. Locate the process to inject the malicious DLL: CreateToolhelp32Snapshot, Process32First, Process32Next 2. Open the process: GetModuleHandle, GetProcAddress, OpenProcess 3. Write the path to the DLL inside the process: VirtualAllocEx, WriteProcessMemory 4. 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 1. Find a target thread: CreateToolhelp32Snapshot, Thread32First, Thread32Next 2. Open the thread: OpenThread 3. Suspend the thread: SuspendThread 4. Write the path to the malicious DLL inside the victim process: VirtualAllocEx, WriteProcessMemory 5. 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: 1. Spawn a benign host (e.g. `RegAsm.exe`, `rundll32.exe`, `msbuild.exe`) **suspended** so that no instructions run yet. ```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. Read the malicious payload into memory and parse its PE headers to obtain `SizeOfImage`, sections and the new `EntryPoint`. 3. **NtUnmapViewOfSection** / **ZwUnmapViewOfSection** – unmap the original image base of the suspended process. 4. **VirtualAllocEx** – reserve RWX memory of `SizeOfImage` inside the remote process. 5. **WriteProcessMemory** – copy the `Headers` first, then iterate over sections copying their raw data. 6. **SetThreadContext** – patch the value of `EAX/RAX` (`RCX` on x64) or `Rip` in the context structure so that `EIP` points to the payload’s `EntryPoint`. 7. **ResumeThread** – the thread continues, executing the attacker-supplied code. Minimal proof-of-concept (x86) skeleton: ```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 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](https://unit42.paloaltonetworks.com/new-darkcloud-stealer-infection-chain/) - [Check Point Research – Under the Pure Curtain: From RAT to Builder to Coder](https://research.checkpoint.com/2025/under-the-pure-curtain-from-rat-to-builder-to-coder/) {{#include ../banners/hacktricks-training.md}}