Windows 静态恶意代码免杀与逃逸技术(一)

Windows 静态恶意代码免杀与逃逸技术(一)

免责声明

本文仅用于学习和技术研究,读者利用本文所提供的信息造成的任何直接或间接的影响和损失均由该读者负责,文章作者以及公众号不为此承担任何责任,请遵守国家网络安全法,维护良好的网络环境。

为什么要研究免杀技术?

当前主流企业环境中普遍部署了多种安全防御体系,包括:

杀毒软件(如 Windows Defender、Kaspersky 等)

EDR(终端检测与响应系统)

沙盒分析系统、IPS/IDS、主机防火墙等

面对日益复杂和智能化的安全检测机制,如何有效绕过这些静态和动态的检测,成为漏洞验证、安全测试和红队攻防中的关键能力之一。

本文将重点讲解shellcode免杀的基本原理与逃逸技巧适用于初学免杀的师傅。

什么是静态免杀?

静态免杀(Static AV Evasion) 是指在目标程序尚未执行的情况下,依靠对其文件结构、元数据、字符串特征等静态属性的分析,来避免被安全软件检测的一种免杀方式。

其核心目标是:“在不运行代码的前提下,使程序看起来像一个正常文件。”

常见的静态检测特征

类型
详细描述
敏感字符串
powershell, cmd.exe, CreateRemoteThread, 网络IP 等
导入表 (IAT) 出现可疑 API
VirtualAlloc, WriteProcessMemory, LoadLibraryA 等
YARA 规则匹配
根据总结的恶意模式给出符合值
文件声明信息
系统类型、编译器等声明字段
Section 特征
.text, .rdata 等软件段的名称和属性
资源/绑定信息
不合理的应用软件进程对应关联
IOC 标识
通常被用于后段防御的特征信息

所以我们要做的,就是改变“外观”、打乱特征,隐藏意图,使文件看起来“平常无奇”。

Shellcode 编码和加密技术

1.1 XOR 编码

使用单字节密钥对原始 shellcode 逐字节异或编码,简单高效但容易被识别。

1.2 UUID 编码

将 shellcode 按 16 字节分块编码为 UUID 字符串,可规避正则匹配与部分 YARA 检测。

1.3 SGN 编码

基于 https://github.com/EgeBalci/sgn 的编码工具,编码后 shellcode 可直接执行,无需解码。

建议和其他编码加密技术混合使用效果挺不错的。

1.4 AES 加密

使用对称加密方式对 shellcode 进行加密,在执行前进行解密。

推荐使用开源库:https://github.com/kokke/tiny-AES-c,兼容 C 与 C++。

这边也是就列出个我个人比较喜欢使用的,加密方面各位师傅也可以自己研究下什么好用还有很多编码方式如mac地址,ipv4/v6,base64编码等等,这边就不全部列出来了

IAT 检查与逃避技术

Windows PE 文件会在导入表(Import Address Table)中记录程序运行前所需加载的函数(如:LoadLibraryAGetProcAddressWinExecVirtualAllocWriteProcessMemory 等) 安全产品常通过扫描导入表中是否包含这些典型敏感API来判断程序是否具有恶意行为

图片加载失败


2.1 延迟加载技术

运行时使用 LoadLibraryA 和 GetProcAddress 进行动态加载,避免在 IAT 中显示出光标函数。

在程序初始化时不导入可疑API,而是在运行时动态获取其地址,绕过静态IAT检查

2.2 API 哈希调用技术

GetProcAddress 同样容易暴露,因此可以进一步隐藏:自定义实现函数查找逻辑,通过 API 哈希值匹配导出表中的函数名,进而得到函数地址。现在就留个实现,后续会写篇详细解释API Hashing

还有很多办法可以绕过IAT检测如:手动解析 API 地址从PEB 解析 Export Table 获取函数地址、回调函数、syscall、apc注入等这里由于是面向初学的师傅就留着后面单独讲

3. 熵

3.1. 什么是熵

在信息论中,熵是衡量信息不确定性或随机程度的一个指标。

通俗理解就是:

熵越高,内容越随机、越混乱;熵越低,内容越有序、可预测。

杀毒软件/EDR 会检测可执行文件中是否有高熵段(比如 .text 段内大量高熵 shellcode),作为可疑特征,像shellcode加密,函数调用混淆之类的东西,像这种技术本质上是在加密和压缩数据,因此提高了数据的不可预测性/无序性,也就是提高了熵,熵越大,数据就越有可能被混淆或加密,文件也就越有可能是恶意的

3.2. 如何降低熵

3.2.1. 编码

降低熵的一种办法是不使用如aes加密之类会提高熵的加密方式只使用前面提到的sgn+uuid、ipv4/v6、mac编码,因为这些编码具有一定程度的组织和顺序的数据。因此,与具有完全随机字节的二进制数据相比,相似的字节模式将具有较低的熵值

3.2.2. 删除CRT库

CRT(即 C 运行时库)是 C 编程语言的标准接口。 杀毒软件检测特征

导入表中包含 msvcrt.dll / ucrtbase.dll

使用 __mainCRTStartup 等 CRT 初始化入口

包含 C++ 异常处理结构,TLS 回调等

这会暴露你程序是由编译器编译出来的正常 PE 文件,更容易被分析器理解,进而提取出 shellcode 或恶意逻辑。

没有 CRT,就像是「手写汇编」或「Loader」,更接近“原始代码”状态。不过这会导致包含"stdio.h"中的函数无法正常运行不能使用例如printf、strlen、strcat、memcpy这些C的函数,需要我们编写自己的“CRT函数”,直接去github搜或者问gpt即可,这里给给出个示例

https://github.com/vxunderground/VX-API

默认情况下,在 Visual Studio 中编译应用程序时,“运行时库”选项设置为“多线程 DLL (/MD)”。使用此选项,CRT 库 DLL 会动态链接,这意味着它们在运行时加载。 需要将运行时库选项设置为“多线程(/MT)” 从二进制文件中删除 CRT,以及 IAT 导入函数减少,这可能会因函数功能导入太少或为零而引起怀疑。 尤其是与 API 哈希结合使用,我们需要通过添加不改变程序行为的WinAPI 函数来伪装IAT。比如可以使用NULL 参数来初始化 WinAPI 函数,还可以将它们包含在永远不会执行的 if 语句中

不过现在的编译器都会自动优化,识别刀if条件无法满足他会优化这部分代码不会包含再编译后的程序中,需要在编译器设置中关闭代码优化,或者使用逻辑欺骗编译器正在使用这段代码

3.2.3. 插入英文字符串

可以参考这篇文章的内容https://cloud.tencent.com/developer/article/2360969

欢迎建议反馈本文如有不严谨之处或存在技术性错误,欢迎各位师傅批评指正。如有建议或问题,也欢迎在评论区或私信留言交流,共同进步!



0 条评论
某人
表情
可输入 255

没有评论