ShellCode 免杀方法
1. 改变 ShellCode 特征
这是最基本也是最重要的一步。原始的 ShellCode 往往包含固定的、已知的字节序列,这些序列很容易被杀毒软件识别
- 编码 (Encoding): 使用各种编码技术,如 XOR、Base64、RC4 等,对 ShellCode 进行加密或混淆。在运行时,ShellCode 会被解码器(Decoder)解密后再执行。这样,静态文件中的 ShellCode 就不再是原始字节,从而绕过了静态查杀
- 多态/自修改 (Polymorphism): 每次生成 ShellCode 时,都使用不同的加密密钥和解码器代码。这样,即使 ShellCode 本身相同,其外部封装也总是变化的,使签名查杀变得困难
- 分块加载 (Chunking): 将 ShellCode 分割成多个小块,分散存储在不同的位置。在运行时,再将这些小块按顺序加载到内存中,重新组装成完整的 ShellCode。这可以避免单个大块的恶意代码被检测
2. 改变 ShellCode 加载方式
仅仅改变 ShellCode 的静态特征是不够的,还需要改变其在内存中的加载和执行方式,绕过行为检测
- 反射式 DLL 注入: 不将 ShellCode 直接写入内存,而是将它作为 DLL 文件反射性地加载到目标进程中。这种技术可以绕过一些基于内存特征的检测
- 内存申请方式: 避免使用像
VirtualAlloc
这样常用的 API 函数来分配可执行内存。可以尝试使用其他函数,如HeapAlloc
,或者通过一些更隐蔽的手段来获取可执行内存 - API 函数混淆: 恶意软件通常会调用一些特定的敏感 API 函数,如
CreateProcess
、WriteProcessMemory
等。可以通过动态解析、哈希查找等方式,避免在代码中直接写出这些函数名,而是运行时再解析得到地址。这可以绕过一些基于 API 调用的行为检测 - 白加黑 (LOLBAS): 利用 Windows 系统中已有的合法程序(如
rundll32.exe
,certutil.exe
等)来加载和执行恶意代码。这种方式利用了“白名单程序”的信任,使恶意行为看起来像是合法操作