如何从恶意PE/.exe可执行文件生成更短的shellcode?
从恶意PE/.exe生成短体积shellcode的可行方案
通用PE转shellcode工具(如pe2shc、Donut默认配置)生成的载荷体积偏大,核心原因是工具默认将完整PE节区、通用PE加载逻辑、重定位/导入表解析、多场景适配代码全打包进了shellcode段。要压缩shellcode长度、提升后续混淆处理效率,可采用以下经过实战验证的方案:
- 前置裁剪原始PE文件,从源头压缩待转码内容
不要直接用编译生成的原始PE做转码,先删除PE内所有非必要内容:调试节、冗余重定位表(固定基址加载场景可直接移除)、未使用的导入函数、版本/图标资源、数字签名、节区对齐填充字节,可通过CFF Explorer或pefile库完成裁剪。如果PE是自行编译的,调整编译选项为/Os(体积优先优化)、关闭CRT默认启动逻辑、关闭异常处理与安全检查、仅静态链接实际用到的函数,很多默认编译的小型程序光CRT冗余逻辑就占数KB空间,裁剪后PE本体可缩小60%以上。 - 替换通用重型加载stub,使用极简加载逻辑
通用转码工具为了全场景适配,内置了32/64位自适应、.NET程序集支持、参数传递、EDR钩子绕过、错误提示等大量非必要逻辑,不需要的功能可全部关闭,甚至可以自行编写极简加载stub:仅保留「申请可执行内存、拷贝PE节区到对应内存位置、修复核心导入函数地址、跳转到OEP」四个核心逻辑,整个stub长度可控制在100B以内。如果你的PE仅用到少量核心系统函数,不需要写通用导入表遍历逻辑,直接通过PEB遍历定位模块基址、用硬编码哈希匹配导出函数地址即可,比通用加载器体积小一个数量级。 - 采用分阶段加载架构,避免全功能打包进初始shellcode
如果PE本身功能复杂、无法通过裁剪大幅缩小体积,不要强行将整个PE转换为单段shellcode。将初始shellcode的逻辑压缩到最精简:仅保留解密、内存加载核心逻辑,体积控制在数百字节以内,运行后再从内存/本地解密拉取完整PE载荷直接在内存加载即可。这种架构下后续做混淆(花指令插入、指令替换、块拆分、跳转混淆)时,仅需要处理数百字节的初始stub,处理耗时从数小时降到秒级,从根本上解决大体积shellcode混淆效率低的问题。 - 转码后做shellcode层冗余裁剪
生成初始shellcode后先做反汇编梳理,删除永远不会触发的分支(比如确定目标为64位环境就删掉所有32位适配分支)、调试用的int3断点、错误提示字符串、空指令填充,通用工具生成的shellcode中这类无效内容通常占总长度的50%以上,裁剪后体积可直接砍半。
注意:上述技术仅可用于授权范围内的红队防御研究,禁止用于未授权的网络攻击活动,所有操作需遵守当地网络安全相关法律法规。
内容的提问来源于stack exchange,提问作者Ben kubi
相关产品推荐
相关产品推荐

