恶意软件中常用的 API
Reading time: 11 minutes
tip
学习和实践 AWS 黑客技术:
HackTricks Training AWS Red Team Expert (ARTE)
学习和实践 GCP 黑客技术:
HackTricks Training GCP Red Team Expert (GRTE)
学习和实践 Azure 黑客技术:
HackTricks Training Azure Red Team Expert (AzRTE)
支持 HackTricks
- 查看 订阅计划!
- 加入 💬 Discord 群组 或 Telegram 群组 或 在 Twitter 🐦 上关注我们 @hacktricks_live.
- 通过向 HackTricks 和 HackTricks Cloud GitHub 仓库提交 PR 来分享黑客技巧。
通用
网络
| 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
许多 loaders 将它们的 TCP 流包装在 SslStream 中,并将服务器的 leaf certificate 与嵌入的副本进行固定(certificate pinning)。Bot info/tasks 常被压缩(例如 GZip)。当响应超过某个阈值(约 ~1 MB)时,数据会被分割成小块(例如 16 KB 分段),以规避基于大小的启发式检测并减少反序列化期间的内存峰值。
持久化
| Registry | File | Service |
|---|---|---|
| RegCreateKeyEx() | GetTempPath() | OpenSCManager |
| RegOpenKeyEx() | CopyFile() | CreateService() |
| RegSetValueEx() | CreateFile() | StartServiceCtrlDispatcher() |
| RegDeleteKeyEx() | WriteFile() | |
| RegGetValue() | ReadFile() |
加密
| Name |
|---|
| WinCrypt |
| CryptAcquireContext() |
| CryptGenKey() |
| CryptDeriveKey() |
| CryptDecrypt() |
| CryptReleaseContext() |
反分析/虚拟机检测
| Function Name | Assembly Instructions |
|---|---|
| IsDebuggerPresent() | CPUID() |
| GetSystemInfo() | IN() |
| GlobalMemoryStatusEx() | |
| GetVersion() | |
| CreateToolhelp32Snapshot [Check if a process is running] | |
| CreateFileW/A [Check if a file exist] |
基于区域/键盘布局的执行保护
许多 stealer/loader 会在特定语言区域下立即中止,以规避研究人员并遵从威胁行为者的限制。常见检查包括:
GetKeyboardLayout用于枚举已安装的布局(按线程/用户)GetLocaleInfoA/W用于解析国家/地区代码GetSystemDefaultLangID/GetUserDefaultLangID
如果任何匹配到被阻止的列表(通常为 CIS 国家),loader 会在进行网络 IOCs 或注入之前立即退出。
防御/威胁狩猎
- 标记那些在执行早期查询多个区域/键盘 API 然后退出且无可观察活动的进程。
- 将其与来自开源项目(例如 VMDetector)复用的反 VM 检查(BIOS 字符串、PnP 设备、磁盘型号、服务)进行关联,以捕获受控执行。
模拟器 API 指纹识别与睡眠规避
恶意软件经常通过搜索 Defender 的虚拟化导出(见 Malware Protection Emulator)来指纹识别沙箱模拟器。如果在进程中存在这些符号(不区分大小写扫描),执行会被延迟 10–30 分钟并重新检查,以浪费分析时间。
作为 canary 使用的 API 名称示例:
MpVmp32Entry,MpVmp32FastEnter,MpCallPreEntryPointCode,MpCallPostEntryPointCode,MpFinalize,MpReportEvent*,MpSwitchToNextThread*VFS_*系列:VFS_Open,VFS_Read,VFS_MapViewOfFile,VFS_UnmapViewOfFile,VFS_FindFirstFile/FindNextFile,VFS_CopyFile,VFS_DeleteFile,VFS_MoveFileThrdMgr_*:ThrdMgr_GetCurrentThreadHandle,ThrdMgr_SaveTEB,ThrdMgr_SwitchThreads
典型的延迟原语(用户态):
cmd /c timeout /t %RANDOM_IN_[600,1800]% > nul
Argument gatekeeping
- 操作者有时会要求在运行 payload 前存在一个看起来无害的 CLI switch(例如
/i:--type=renderer用以模拟 Chromium 子进程)。如果该 switch 缺失,loader 会立即退出,阻止简单的 sandbox 执行。
Stealth
| Name | |
|---|---|
| VirtualAlloc | 分配内存 (packers) |
| VirtualProtect | 更改内存权限 (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
- 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 Executable Injection: 可执行文件会被写入受害进程的内存,并从那里执行。
Process Hollowing (a.k.a RunPE)
Process Hollowing 是 Windows 恶意软件常用的 defence-evasion / execution 技巧之一。其思路是以 suspended 状态启动一个合法进程,移除(hollow)其原始映像并在其位置复制任意 PE。当主线程恢复时,恶意的入口点就在受信任二进制(通常由 Microsoft 签名)的掩护下执行。
典型流程:
- 以 suspended 状态生成一个良性宿主(例如
RegAsm.exe,rundll32.exe,msbuild.exe),以确保尚未执行任何指令。
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);
- 将恶意 payload 读入内存并解析其 PE 头以获取
SizeOfImage、sections 和新的EntryPoint。 - NtUnmapViewOfSection / ZwUnmapViewOfSection – 取消映射被挂起进程的原始映像基址。
- VirtualAllocEx – 在远程进程内为
SizeOfImage保留 RWX 内存。 - WriteProcessMemory – 先复制
Headers,然后遍历各 section 复制其 raw data。 - SetThreadContext – 在上下文结构中修补
EAX/RAX(x64 上为RCX)或Rip的值,使EIP指向 payload 的EntryPoint。 - ResumeThread – 线程继续执行,运行攻击者提供的代码。
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);
}
在 DarkCloud Stealer 活动中观察到的实用笔记:
- The loader 选择了
RegAsm.exe(.NET Framework 的一部分)作为宿主 —— 一个已签名的二进制文件,不太可能引起注意。 - 解密后的 VB6 stealer (
holographies.exe) 并不会被写入磁盘;它只存在于 hollowed process 内,令静态检测更困难。 - 敏感字符串(regexes、paths、Telegram credentials)按字符串使用 RC4-encrypted 加密,仅在运行时解密,进一步增加了内存扫描的难度。
检测思路:
- 对从未创建 GUI/控制台窗口且在内存区域被分配为 RWX 之前就以
CREATE_SUSPENDED启动的进程发出告警(对良性代码而言很罕见)。 - 跨进程查找调用序列
NtUnmapViewOfSection ➜ VirtualAllocEx ➜ WriteProcessMemory。 - 注意将受信任的 developer utilities 用作 hollowing 宿主 的异常使用,尤其是
MSBuild.exe、RegAsm.exe、rundll32.exe,且其父进程为短寿命的 loader。 - 搜索从用户可写路径启动的
msbuild.exe或没有对应.sln/.proj上下文却发起出站连接的msbuild.exe(ATT&CK T1127.001 + T1055.012)。
Common host processes and path resolution
MSBuild.exe常被选为 hollowing 宿主以混入 developer tooling。加载器通常在与体系结构匹配的位置搜索:C:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild.exeC:\Windows\Microsoft.NET\Framework64\v4.0.30319\MSBuild.exeC:\Windows\System32\MSBuild.exeC:\Windows\SysWOW64\MSBuild.exe- 在调用
CreateProcess(..., CREATE_SUSPENDED, ...)之前,选择与当前 payload/OS 架构匹配的宿主。
Hooking
- The SSDT (System Service Descriptor Table) 指向 kernel functions (ntoskrnl.exe) 或 GUI driver (win32k.sys),使用户进程能够调用这些函数。
- rootkit 可能会修改这些指针至其控制的地址。
- IRP (I/O Request Packets) 在组件之间传输数据片段。内核中几乎所有组件都使用 IRP,每个 device object 都有其可被 hook 的函数表:DKOM (Direct Kernel Object Manipulation)。
- IAT (Import Address Table) 对解析依赖关系很有用。可以 hook 此表以劫持将被调用的代码。
- EAT (Export Address Table) Hooks。此类 hook 可以在 userland 完成,目标是 hook DLL 的导出函数。
- Inline Hooks:这类方式较难实现,涉及修改函数本身的代码,例如在函数开头放置跳转指令。
References
- Unit42 – New Infection Chain and ConfuserEx-Based Obfuscation for DarkCloud Stealer
- Check Point Research – Under the Pure Curtain: From RAT to Builder to Coder
- Unit 42 – PhantomVAI Loader Delivers a Range of Infostealers
- MITRE ATT&CK – Trusted Developer Utilities Proxy Execution: MSBuild (T1127.001)
- VMDetector – virtualization checks (open-source)
tip
学习和实践 AWS 黑客技术:
HackTricks Training AWS Red Team Expert (ARTE)
学习和实践 GCP 黑客技术:
HackTricks Training GCP Red Team Expert (GRTE)
学习和实践 Azure 黑客技术:
HackTricks Training Azure Red Team Expert (AzRTE)
支持 HackTricks
- 查看 订阅计划!
- 加入 💬 Discord 群组 或 Telegram 群组 或 在 Twitter 🐦 上关注我们 @hacktricks_live.
- 通过向 HackTricks 和 HackTricks Cloud GitHub 仓库提交 PR 来分享黑客技巧。
HackTricks