铸就无特征载荷击败全球杀软(上)"

admin 2026-11-02 15:10:32 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

铸就无特征载荷击败全球杀软(上)

原创

陆安予
陆安予

白帽子安全笔记2.0

2026年11月1日 17:39
江苏

去阅读

摘要:借助强大的Cobalt Strike可塑性可轻松击败全球杀软,这一切是如何做到的?

一、这是什么

本想码一篇无特征载荷吊打全球杀软的文章,但思来想去,如果只贴测试结果,难免会让人难以接受,显得很装。会被问到一万个问题,因为这涉及到非常多的技术,不是几句话就能概括。

比如YARA是什么?,DLL侧载什么时候用?、全球有哪几类杀毒软件?什么时候需要代码混淆?...一口气讲完是不可能的,想要实现这一点绝非易事,因为都是突然进入到这个技术中,如果技术不放在历史中看前后发展过程,那就如同盲人摸象,只会形成只知其一不知二的局面,甚至你研究了半天发现是过去早已淘汰的技术,会形成为什么是这样?这又是什么?就又回到十万个为什么上的问题。

二、技术原理

1. Payloads是什么?

当我们启动强大的Cobalt Strike后,菜单中第三个选项Payloads,这是什么?

Payloads指的是“为了让目标机器上线,而实际发送到目标机器上执行的那段代码”,通常叫载荷。

无论你在这个菜单里选什么,最终生成的载荷核心都是 Beacon。Beacon 是一段运行在目标内存中的轻量级代码,它每隔一段时间(比如 60 秒)就会醒来一次,向你的 CS 团队服务器发送请求:“老板,有任务吗?”,如果有,就执行命令并把结果带回来。这种机制叫“回连”。

什么意思,它的核心就是连哪里,怎么连。

因此,如果想要实现回连,必须想尽一切办法(如钓鱼、侧加载、漏洞利用),把那段Payload送到目标机器的内存里去运行。

2. Payloads为什么有这么多选项?

载荷如果想要实现多功能更隐蔽,比如通信加密、文件管理、进程注入、内存混淆、系统调用等等。功能实现越复杂,文件大小就越大,payload\_x64.bin 默认达到303KB。

因此,意味着在某些情况下,可以牺牲安全性和隐蔽性,只保留一个连接并下载,这叫分阶段,就是Stager Payloads Generator。
为什么要这样设计,这是由Windows设计决定的,比如受Windows命令行最大长度限制,塞不下一个约300KB的完整Beacon,比如缓冲区溢出,攻击者能控制的字节数往往非常有限,载荷它只有909字节。

第一个选项HTA和第二个Ofiice宏选项,宏从2022被微软默认阻止已经无法使用,HTA这个东西,虽然现在也有在APT中看到,但效果不好说。

3. payload\_x64.bin到底是什么

当我们通过菜单Stageless Payload Generator导出一个shellcode文件时,它本质是一个反射DLL。只不过在生成时Cobalt Strike对 DLL 的 DOS 头做了处理,将原本不执行代码的头部区域改写为可执行的shellcode入口,这种技术叫PIC化(Position-Independent Code,位置无关代码),这就让其具备了PIC属性。所以载荷本质上就是一个隐蔽的与位置无关的反射DLL。

4. 为什么要这样设计?

与位置无关代码(PIC),你只要把这个bin丢进目标进程内存并让 CPU 跳转过去,它自己就能跑起来,不需要外部程序做任何其它处理。这种设计让shellcode变得非常通用,你可以自己写任意加载器加载它。而现代普遍都使用这种机制,例如Donut类工具,这使得它绕开了许多杀软对常规DLL加载路径的监控。

但仅仅Donut化显然是不够的,例如Donut格式的shellcode特征检测规则如下。

1

2

3

4

5

6

7

8

function detect() {
    // 1. 核心特征一:检查文件开头是不是 0xE8 (CALL 指令)
    // 2. 核心特征二:检查 CALL 的偏移量与 5 个字节后的数据是否一致
    // 3. 核心特征三:计算 CALL 的目标地址
    // 检查目标地址处是不是 0x59 (POP ECX 指令)
    // 如果以上三个条件全部满足,直接判定为 Donut 生成
    return \"Detected: Donut Shellcode\";
}

而在默认的Cobalt Strike中,默认的头是MZAR,该默认值已被纳入特征。

但之所以Cobalt Strike能成为全球顶级武器,其强大的可塑性设计就是为了规避这一点,既然默认的载荷是反射加载器,我们通过可塑性,使用其自带的强大的用户自定义反射加载器,我们便能直接修改整个默认的反射加载器的心脏,而无需更改任何客户或服务端的代码。

5. 反射DLL又是什么?

该技术于2009年被发布,反射DLL在文件上可以是任意格式,但本质还是DLL,只不过加载方式变了,你只需要加载这个ReflectiveLoader函数就行,它在内存中自我组装运行。

6. 什么是传统DLL注入?

想让代码在别的进程中运行,这叫DLL注入,这种技术在1994年被公开确定,在传统注入中,格式必须是DLL,原因在于DLL是Windows操作系统唯一原生支持的、可被动态加载和执行的代码容器。如果你把一个.exe文件或一段纯文本路径传给 LoadLibrary,系统会直接报错,因为它只解析符合 PE 格式且带有特定 DLL 标识的文件。

但随着发展,这一个巨大的弊端,LoadLibrary,CreateRemoteThread是固有的特征,杀软只需要看静态文件和这个API调用即可确定是DLL注入。

7. 传统DLL注入技术之前是什么?

在传统DLL注入之前,恶意代码的主流形态是独立可执行文件。早期 DOS 时代的文件型病毒感染的就是 .COM 和 .EXE 文件,但这种格式太过显眼且是独立进程容易被检测。

三、总结

1990 年代之前至早期:恶意代码就是独立 EXE(或 COM 文件、引导区病毒)。它直接运行在自己的进程里,没有注入的概念。

1994 年:Richter 公开传统 DLL 注入,恶意代码开始有了“进入别人进程”的标准手段。

2009 年:反射 DLL 注入出现,解决传统注入的落盘和 LoadLibrary 调用问题。

2014 年前后:Cobalt Strike 把反射 DLL 改造成PIC Shellcode形态,进一步简化投递。

与其研究如何免杀到处找加载器,不如先从基础学起,从历史学起,年轻人一定要有一种打破砂锅问到底的精神,先问,这是什么?为什么有这样一个东西?之前之后是什么?一定要这样吗?发展趋势是什么?这样才能真正掌握先进技术,不至于在技术的路上迷路。

    铸就无特征载荷击败全球杀软(上)" 网络安全文章

    铸就无特征载荷击败全球杀软(上)"

    本文介绍利用CobaltStrike可塑性设计生成无特征载荷以规避杀软检测的技术原理。文章从payloads概念讲起,解释stager与stageless区别,深入剖析payload\\_x64.bin本质为PIC化的反射DLL,并回顾传统DLL注入到反射注入的历史演进,强调理解技术发展脉络对掌握免杀技术的重要性。
    【征稿启事】2026IEEE网络韧性与内生安全国际会议(IEEECRESS2026)相约南京,诚邀投稿!" 网络安全文章

    【征稿启事】2026IEEE网络韧性与内生安全国际会议(IEEECRESS2026)相约南京,诚邀投稿!"

    IEEECRESS2026国际会议征稿启事,将于2026年12月4日至6日在南京举行,由紫金山实验室主办。征稿方向涵盖内生安全、网络韧性、AI安全、5G/6G通信安全等前沿领域。论文需英文撰写6至8页,录用论文将收录于IEEE论文集并提交EI检索。投稿截止2026年10月31日,建议相关学者及时投稿。
    聊聊2026信息安全工程师考试的重大变革" 网络安全文章

    聊聊2026信息安全工程师考试的重大变革"

    2026年信息安全工程师考试发生重大变革,案例题不再考传统密码学、防火墙ACL等,转向主机侧、运维实操和模型理解,如Linux权限、Windows访问控制、SSH全链条、移动安全等。命题向实战和热点靠拢,合规政策入题。考试通过率低,证书含金量提升,备考需注重实操。
    评论:0   参与:  0