hacktricks/src/reversing/common-api-used-in-malware.md
HackTricks News Bot cf420be47c Add content from: Under the Pure Curtain: From RAT to Builder to Coder
- Remove searchindex.js (auto-generated file)
2025-09-16 18:53:48 +00:00

222 lines
11 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.

# Common API used in Malware
{{#include ../banners/hacktricks-training.md}}
## Generic
### Networking
| Raw Sockets | WinAPI Sockets |
| ------------- | -------------- |
| socket() | WSAStratup() |
| bind() | bind() |
| listen() | listen() |
| accept() | accept() |
| connect() | connect() |
| read()/recv() | recv() |
| write() | send() |
| shutdown() | WSACleanup() |
### TLS pinning and chunked transport
Many loaders wrap their TCP stream in `SslStream` and pin the servers leaf certificate against an embedded copy (certificate pinning). Bot info/tasks are compressed (e.g., GZip). When responses exceed a threshold (~1 MB), data is fragmented into small chunks (e.g., 16 KB segments) to avoid size-based heuristics and reduce memory spikes during deserialisation.
### Persistence
| Registry | File | Service |
| ---------------- | ------------- | ---------------------------- |
| RegCreateKeyEx() | GetTempPath() | OpenSCManager |
| RegOpenKeyEx() | CopyFile() | CreateService() |
| RegSetValueEx() | CreateFile() | StartServiceCtrlDispatcher() |
| RegDeleteKeyEx() | WriteFile() | |
| RegGetValue() | ReadFile() | |
### Encryption
| Name |
| --------------------- |
| WinCrypt |
| CryptAcquireContext() |
| CryptGenKey() |
| CryptDeriveKey() |
| CryptDecrypt() |
| CryptReleaseContext() |
### Anti-Analysis/VM
| Function Name | Assembly Instructions |
| --------------------------------------------------------- | --------------------- |
| IsDebuggerPresent() | CPUID() |
| GetSystemInfo() | IN() |
| GlobalMemoryStatusEx() | |
| GetVersion() | |
| CreateToolhelp32Snapshot \[Check if a process is running] | |
| CreateFileW/A \[Check if a file exist] | |
### Emulator API fingerprinting & sleep evasion
Malware often fingerprints sandbox emulators by searching for Defenders virtualised exports (seen in the Malware Protection Emulator). If any of these symbols are present (case-insensitive scan of the process), execution is delayed for 1030 minutes and re-checked to waste analysis time.
Examples of API names used as canaries:
- `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
```
Argument gatekeeping
- Operators sometimes require a benign-looking CLI switch to be present before running the payload (e.g., `/i:--type=renderer` to mimic Chromium child processes). If the switch is absent, the loader exits immediately, hindering naive sandbox execution.
### Stealth
| Name | |
| ------------------------ | -------------------------------------------------------------------------- |
| 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
| Function Name |
| ---------------- |
| CreateProcessA/W |
| ShellExecute |
| WinExec |
| ResumeThread |
| NtResumeThread |
### Miscellaneous
- GetAsyncKeyState() -- Key logging
- SetWindowsHookEx -- Key logging
- GetForeGroundWindow -- Get running window name (or the website from a browser)
- LoadLibrary() -- Import library
- GetProcAddress() -- Import library
- CreateToolhelp32Snapshot() -- List running processes
- GetDC() -- Screenshot
- BitBlt() -- Screenshot
- InternetOpen(), InternetOpenUrl(), InternetReadFile(), InternetWriteFile() -- Access the Internet
- FindResource(), LoadResource(), LockResource() -- Access resources of the executable
## 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 payloads `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);
}
```
Practical notes observed in the **DarkCloud Stealer** campaign:
* The loader picked `RegAsm.exe` (part of the .NET Framework) as host a signed binary unlikely to draw attention.
* The decrypted VB6 stealer (`holographies.exe`) is *not* dropped on disk; it only ever exists inside the hollowed process making static detection harder.
* Sensitive strings (regexes, paths, Telegram credentials) are **RC4-encrypted** per-string and only decrypted at runtime, further complicating memory scanning.
Detection ideas:
* Alert on `CREATE_SUSPENDED` processes that never create GUI/console windows before a memory region is allocated as **RWX** (rare for benign code).
* Look for a call sequence `NtUnmapViewOfSection ➜ VirtualAllocEx ➜ WriteProcessMemory` across different processes.
## Hooking
- The **SSDT** (**System Service Descriptor Table**) points to kernel functions (ntoskrnl.exe) or GUI driver (win32k.sys) so user processes can call these functions.
- A rootkit may modify these pointer to addresses that he controls
- **IRP** (**I/O Request Packets**) transmit pieces of data from one component to another. Almost everything in the kernel uses IRPs and each device object has its own function table that can be hooked: DKOM (Direct Kernel Object Manipulation)
- The **IAT** (**Import Address Table**) is useful to resolve dependencies. It's possible to hook this table in order to hijack the code that will be called.
- **EAT** (**Export Address Table**) Hooks. This hooks can be done from **userland**. The goal is to hook exported functions by DLLs.
- **Inline Hooks**: This type are difficult to achieve. This involve modifying the code of the functions itself. Maybe by putting a jump at the beginning of this.
## References
- [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}}