0%
毅种循环

模块 81 - 规避 AV(反病毒软件)

恶意软件开发课程 - 规避 AV(反病毒软件)


模块 81 - 规避 AV(反病毒软件)#

规避 AV(反病毒软件)#

简介#

到目前为止,我们已经演示了许多创建和执行 Payload(有效载荷)加载器的方法和技术,这些加载器可以规避各种安全软件程序。本模块将从头开始构建一个功能丰富的 Payload 加载器,以巩固前面模块所学的内容。

💡 初学者提示:为什么要构建一个“全能型”加载器?

类比理解: 想象你正在准备一场秘密潜入任务

  • 在之前的模块里,我们单独学习了如何翻墙(直接系统调用)、如何伪装(API Hashing)、如何加密文件(RC4)。
  • 本模块:我们将把这些“单项技能”整合在一起,打造一套功能齐全的间谍装备包。这是一个综合练习,旨在让你理解如何将这些互补的技术有机地结合起来,构建一个能在现实复杂防御环境下生存的工具。

建议你创建一个空的 Visual Studio 项目,跟随本模块一起动手操作。

Payload 加载器功能清单#

我们实现的这个 Payload 加载器将具备以下功能:

  • 远程代码注入支持:能够将代码注入到其他进程中。
  • Mapping 注入:利用 Hell’s Gate 实现的 Direct Syscalls(直接系统调用) 进行映射注入。
  • API Hashing:隐藏静态导入表特征。
  • 反分析功能 (Anti-Analysis):检测沙箱与调试器。
  • RC4 Payload 加密:保护 Shellcode(外壳代码)不被静态扫描。
  • 密钥暴力破解 (Brute-forcing):动态找回解密密钥,对抗自动化分析。
  • 移除 CRT 库:减小体积并改变二进制足迹。

Hell’s Gate 环境搭建#

此加载器利用通过 Hell’s Gate 获取的 Direct Syscalls(直接系统调用)进行 Payload 注入。首先,必须创建 Structs.hHellsGate.cHellAsm.asm 文件。这些文件包含了执行直接系统调用所需的必要函数。Structs.h 文件用于保存 Windows 未公开结构,并包含在后续的 C 文件中。它包含 PEBTEB 等结构定义,这些是实现 Hell’s Gate 所必不可少的。

HellAsm.asm 文件将与 代码仓库 中的文件相同。至于 HellsGate.c,它将包含以下函数。

📚 知识扩展:Hell’s Gate 的核心原理

Hell’s Gate(地狱之门)技术通过动态解析 ntdll.dll 的导出表,在内存中搜索特殊的汇编指令(如 mov eax, <SSN>),从而在不依赖固定版本号的情况下提取系统调用号(SSN)。这使得恶意软件可以绕过 EDR 在用户态 API 上设置的钩子。

HellsGate.c

上面的代码还没有定义 VX_TABLE_ENTRY 结构或 djb2 函数。为了解决这个问题,我们将创建两个新文件:WinApi.cCommon.h

  • WinApi.c:此文件用于存储 CRT 库替代函数以及 Hell’s Gate 和 API Hashing 实现中使用的字符串哈希函数。
  • Common.h:此文件提供公共函数原型(以便跨文件调用)、自定义结构定义、Syscall(系统调用)的哈希值以及 WinAPIs。

原有的 djb2 字符串哈希函数将被 HashStringJenkinsOneAtATime32BitA/W 函数替换,从而改变了 Hell’s Gate 中原始使用的哈希算法。

WinApi.c

Common.h

Common.h 文件中定义 VX_TABLE_ENTRY,然后更新 HellsGate.c 文件以包含它并使用 HASHA 代替 djb2

VX_TABLE_ENTRY 结构定义

typedef struct _VX_TABLE_ENTRY {
	PVOID   pAddress;     // 函数在内存中的地址
	UINT32	uHash;        // 函数名的哈希值
	WORD    wSystemCall;  // 提取出的系统调用号 (SSN)
} VX_TABLE_ENTRY, * PVX_TABLE_ENTRY;
c

计算 Syscall(系统调用)哈希值#

必须创建一个新项目用于计算所使用的 Syscall(系统调用)的哈希值,并将其打印到控制台。Hasher(哈希计算器)项目将包含一个如下所示的 C 文件。

Hasher.c

Hasher 运行结果#

编译并运行后,程序将生成如下结果,应将其复制到 Common.h 文件中。

哈希计算结果
哈希计算结果

此外,必须更新 VX_TABLE 结构定义,以包含将要使用的 Syscall(系统调用)。

typedef struct _VX_TABLE {
	VX_TABLE_ENTRY NtCreateSection;
	VX_TABLE_ENTRY NtMapViewOfSection;
	VX_TABLE_ENTRY NtUnmapViewOfSection;
	VX_TABLE_ENTRY NtClose;
	VX_TABLE_ENTRY NtCreateThreadEx;
	VX_TABLE_ENTRY NtWaitForSingleObject;
} VX_TABLE, * PVX_TABLE;
c

利用 Hell’s Gate 进行 Payload 注入#

Hell’s Gate 设置成功后,即可实现 Payload 注入。我们将创建一个新文件 Inject.c,如下所示。

Inject.c 文件的要点说明:

  • InitializeSyscalls:此函数初始化全局变量 g_Sys(类型为 VX_TABLE),供后续使用。
  • RemoteMappingInjectionViaSyscalls:此函数通过 bLocal 参数同时支持本地和远程映射注入。
    • bLocalTRUE,则 dwLocalFlag 设置为 PAGE_EXECUTE_READWRITE 以适应本地执行,并跳过第二次 NtMapViewOfSection
    • bLocalFALSE,则 dwLocalFlag 保持 PAGE_READWRITE,并调用第二次 NtMapViewOfSection 在远程进程中分配空间。
    • pExecAddress 用于保存注入 Payload 的基地址,最终传递给 NtCreateThreadEx 执行。

Inject.c

进程枚举#

为了创建一个完整的进程注入模块,需要使用 NtQuerySystemInformation 系统来获取目标进程句柄(正如在 Process Enumeration - NtQuerySystemInformation 模块中所述)。

💡 初学者提示:为什么要用底层系统调用进行进程枚举?

通常我们可以用 CreateToolhelp32Snapshot 来查找进程。但在高级规避场景中,杀软会密切监控这类“高阶”进程管理函数。通过直接调用 NtQuerySystemInformation,我们绕过了这些监控点,隐蔽地获取系统中所有活跃进程的列表。

入口函数 (main.c)#

最后,通过 main 函数整合所有功能。


反分析功能 (Anti-Analysis)#

为了增强加载器的隐蔽性,我们创建了一个名为 AntiAnalysis.c 的新文件。该文件包含了以下功能:

  • 自删除功能:源自 Anti-Debugging - Self-Deletion 模块。
  • 鼠标点击监控:源自 Anti-Virtual Environments - Multiple Techniques 模块,用于检测自动化沙箱环境。
  • 延迟执行:使用 NtDelayExecution 实现,源自 Anti-Virtual Environments - Multiple Delay Execution Techniques 模块。

💡 初学者提示:为什么键盘/鼠标监控能预防虚拟机?

类比理解: 许多自动分析沙箱就像是一个无人驾驶的汽车测试场。虽然汽车在跑,但里面没有真实的司机。

  • 我们的策略:程序在运行前先“观察”有没有人动过鼠标(点击)。如果是真实的物理机器,用户迟早会点击。如果是沙箱,往往只有机械的点击甚至完全没有模拟点击。通过“数点击次数”,我们可以分辨出对面是真实的用户,还是冷冰冰的代码。

AntiAnalysis.c

加载器运行结果#

远程代码注入演示#

远程注入成功
远程注入成功
注入效果
注入效果

本地代码注入演示#

本地注入成功
本地注入成功
本地效果
本地效果

📚 知识扩展:为什么要区分本地和远程注入?

  • 本地注入:代码在加载器自身的进程内运行。即使加载器崩溃,也不会影响系统其他部分,且权限与加载器一致,隐蔽性较高(因为没有跨进程行为)。
  • 远程注入:将代码注入到系统常见进程(如 notepad.exeexplorer.exe)。这样做的好处是即便加载器进程结束,恶意逻辑仍在后台运行,且可以借助受信任进程的身份建立网络连接,绕过简单的防火墙规则。

总结#

本模块通过整合 Direct Syscalls、API Hashing、反分析及精准的内存管理,展示了如何构建一个现代化的、具备高度规避能力的 Payload 加载器。这些技术的叠加应用,显著提高了穿透防线并成功执行代码的成功率。