Shellcode生成、加载与加密技术全解析:从原理到实践
字数 2723 2025-09-23 19:27:38

Shellcode生成、加载与加密技术全解析:从原理到实践

一、Shellcode概述

Shellcode是一种恶意代码,它通过劫持计算机内存中正在运行的程序的正常流程,重定向流程以执行恶意代码而非正常程序,从而为攻击者提供shell或系统访问权限。Shellcode通常是结合漏洞利用的低级编程代码或机器代码。

Shellcode特征

  1. 包含执行所需shell的所有指令,同时保持相对较小的体积
  2. 在内存中"位置独立" - 无法预知将加载到目标进程内存的具体位置
  3. 不包含可能导致错误或崩溃的内容(如空字符0x00)
  4. 能够使用注入技术(代码或反射注入)搭载现有内存分配

二、Shellcode生成

Shellcode执行过程分为四步:

  1. 打开目标进程
  2. 在进程中分配内存
  3. 将shellcode写入分配的内存
  4. 从远程进程创建新线程执行Shellcode

攻击者需要根据目标系统选择适当的可执行文件类型:

  • Windows系统:.EXE或.DLL
  • Linux系统:.ELF
  • Android系统:.APK

三、Shellcode存放位置

1. .data节

PE文件的.data节包含已初始化全局变量和静态变量,可读写,适合需要运行时解密/加密的shellcode。

示例代码:

#include <Windows.h>
#include <stdio.h>

unsigned char Data_RawData[] = {
    // shellcode字节数组
};

int main() {
    printf("[i] Data_RawData 变量 : 0x%p \n", Data_RawData);
    getchar();
    return 0;
}

2. .rdata节

使用const限定符指定的变量为"只读"数据,任何修改尝试会导致访问冲突。

示例代码:

const unsigned char Rdata_RawData[] = {
    // shellcode字节数组
};

3. .text节

.text节存储具有可执行内存权限的变量,可直接执行而无需编辑内存权限。

示例代码:

#pragma section(".text")
__declspec(allocate(".text")) const unsigned char Text_RawData[] = {
    // shellcode字节数组
};

4. .rsrc节

.rsrc节适合存储较大的shellcode,避免.data或.rdata节的大小限制。

存储步骤:

  1. 在Visual Studio中添加资源文件
  2. 导入重命名为.ico扩展名的原始shellcode
  3. 指定资源类型为"RCDATA"

访问.rsrc节中shellcode的API:

  • FindResourceW - 获取资源位置
  • LoadResource - 检索资源数据句柄
  • LockResource - 获取资源数据指针
  • SizeofResource - 获取资源大小

更新.rsrc节shellcode的方法:

  1. 使用HeapAlloc分配内存
  2. 用memcpy将shellcode复制到临时缓冲区
  3. 在新缓冲区中进行解密等操作

四、Shellcode加载技术

语言开发Loader比较

语言 可移植性 编译大小 执行速度 检测难度 特点
Rust ★★☆☆☆ ★★★★☆ ★★★★★ 静态: ★★★☆☆
动态: ★★★★☆
体积略大于C/C++,无GC,免杀潜力大
Go ★★★★★ ★☆☆☆☆ ★★★★☆ 静态: ★★★☆☆
动态: ★★★☆☆
编译后体积大(数MB),运行时特征明显
C/C++ ★★☆☆☆ ★★★★★ ★★★★★ 静态: ★★☆☆☆
动态: ★★★★☆
体积最小(几十KB),直接系统调用能力强
C# ★★★☆☆ ★★★☆☆ ★★★☆☆ 静态: ★☆☆☆☆
动态: ★★★☆☆
结合D/Invoke后检测率降低
汇编 ☆☆☆☆☆ ★★★★★ ★★★★★ 静态: ★★★★★
动态: ★★★★★
体积最小,完全自定义,编写难度最高

加载方法

1. 基于内存加载

使用WinAPI系统调用动态分配RWX内存,移动shellcode并启动执行线程。

优点:

  • 使用标准WinAPI调用,可靠性高
  • 内存区域可执行、可写、可读,便于修改shellcode

缺点:

  • 容易被成熟的AV/EDR系统检测

2. 直接函数调用加载

将shellcode数组地址强制转换为函数指针并调用。

3. 使用回调函数加载

通过Windows回调函数执行Shellcode,系统将shellcode当作回调函数运行。

4. 创建线程执行加载

创建新线程并将入口点设置为shellcode地址。

5. 基于汇编加载

直接控制硬件,效率最高,但完全针对特定CPU架构和操作系统。

五、Shellcode加密技术

加密可隐藏恶意代码,使安全解决方案更难检测,并延长恶意软件在系统中的隐藏时间。

加密的利弊

  • 优点:规避基于签名的检测
  • 缺点:高熵值文件可能被AV/EDR标记为可疑

加密类型

1. XOR异或加密

异或运算特性:

  • 反转性质:a XOR b XOR b = a
  • 交换律:a XOR b = b XOR a
  • 结合律:(a XOR b) XOR c = a XOR (b XOR c)

2. RC4加密

流密码,速度快且高效,使用同一函数进行加密和解密。

实现函数:

  • rc4Init - 初始化rc4context结构
  • rc4Cipher - 执行RC4加密

示例代码:

// RC4加密示例
rc4Init(&rc4Ctx, key, sizeof(key));
rc4Cipher(&rc4Ctx, shellcode, shellcodeSize);

// RC4解密示例
rc4Init(&rc4Ctx, key, sizeof(key));
rc4Cipher(&rc4Ctx, encryptedShellcode, shellcodeSize);

3. AES加密

对称密钥算法,类型包括:

  • AES128 - 128位密钥
  • AES192 - 192位密钥
  • AES256 - 256位密钥

操作模式:

  • CBC - 需要初始化向量(IV)
  • GCM

AES结构:

typedef struct _AES {
    BCRYPT_ALG_HANDLE hAlgorithm;
    BCRYPT_KEY_HANDLE hKey;
    PBYTE pbKeyObject;
    PBYTE pbIV;
    DWORD cbKeyObject;
    DWORD cbIV;
    DWORD cbBlockLen;
    PBYTE pbPlainText;
    DWORD cbPlainText;
    PBYTE pbCipherText;
    DWORD cbCipherText;
} AES, *PAES;

CNG (Cryptographic Next Generation)函数:

  • BCryptOpenAlgorithmProvider - 加载CNG提供程序
  • BCryptGetProperty - 检索属性值
  • BCryptSetProperty - 初始化属性
  • BCryptGenerateSymmetricKey - 创建密钥对象
  • BCryptEncrypt/BCryptDecrypt - 加密/解密数据
  • BCryptDestroyKey - 销毁密钥对象
  • BCryptCloseAlgorithmProvider - 关闭算法提供者

六、Shellcode传递技术

1. Web远程文件读取

通过Loader从远程web加载shellcode,避免直接上传工具被拦截。

优点:

  • 减少对多种工具的免杀需求
  • 仅上传Loader降低被检测风险

2. 图片(BMP)隐写术

将Shellcode隐藏在BMP图片的RGB像素中,利用文件结构特性嵌入数据。

3. Shellcode加载器

将加载程序与实际Shellcode分离到不同进程空间,避免行为检测。

关键点:

  • 运行时分析通常不关心程序会做什么
  • 避免直接使用函数指针执行解密后的Shellcode
  • 使用Loader间接加载和执行Shellcode
Shellcode生成、加载与加密技术全解析:从原理到实践 一、Shellcode概述 Shellcode是一种恶意代码,它通过劫持计算机内存中正在运行的程序的正常流程,重定向流程以执行恶意代码而非正常程序,从而为攻击者提供shell或系统访问权限。Shellcode通常是结合漏洞利用的低级编程代码或机器代码。 Shellcode特征 包含执行所需shell的所有指令,同时保持相对较小的体积 在内存中"位置独立" - 无法预知将加载到目标进程内存的具体位置 不包含可能导致错误或崩溃的内容(如空字符0x00) 能够使用注入技术(代码或反射注入)搭载现有内存分配 二、Shellcode生成 Shellcode执行过程分为四步: 打开目标进程 在进程中分配内存 将shellcode写入分配的内存 从远程进程创建新线程执行Shellcode 攻击者需要根据目标系统选择适当的可执行文件类型: Windows系统:.EXE或.DLL Linux系统:.ELF Android系统:.APK 三、Shellcode存放位置 1. .data节 PE文件的.data节包含已初始化全局变量和静态变量,可读写,适合需要运行时解密/加密的shellcode。 示例代码: 2. .rdata节 使用const限定符指定的变量为"只读"数据,任何修改尝试会导致访问冲突。 示例代码: 3. .text节 .text节存储具有可执行内存权限的变量,可直接执行而无需编辑内存权限。 示例代码: 4. .rsrc节 .rsrc节适合存储较大的shellcode,避免.data或.rdata节的大小限制。 存储步骤: 在Visual Studio中添加资源文件 导入重命名为.ico扩展名的原始shellcode 指定资源类型为"RCDATA" 访问.rsrc节中shellcode的API: FindResourceW - 获取资源位置 LoadResource - 检索资源数据句柄 LockResource - 获取资源数据指针 SizeofResource - 获取资源大小 更新.rsrc节shellcode的方法: 使用HeapAlloc分配内存 用memcpy将shellcode复制到临时缓冲区 在新缓冲区中进行解密等操作 四、Shellcode加载技术 语言开发Loader比较 | 语言 | 可移植性 | 编译大小 | 执行速度 | 检测难度 | 特点 | |------|---------|---------|---------|---------|------| | Rust | ★★☆☆☆ | ★★★★☆ | ★★★★★ | 静态: ★★★☆☆ 动态: ★★★★☆ | 体积略大于C/C++,无GC,免杀潜力大 | | Go | ★★★★★ | ★☆☆☆☆ | ★★★★☆ | 静态: ★★★☆☆ 动态: ★★★☆☆ | 编译后体积大(数MB),运行时特征明显 | | C/C++ | ★★☆☆☆ | ★★★★★ | ★★★★★ | 静态: ★★☆☆☆ 动态: ★★★★☆ | 体积最小(几十KB),直接系统调用能力强 | | C# | ★★★☆☆ | ★★★☆☆ | ★★★☆☆ | 静态: ★☆☆☆☆ 动态: ★★★☆☆ | 结合D/Invoke后检测率降低 | | 汇编 | ☆☆☆☆☆ | ★★★★★ | ★★★★★ | 静态: ★★★★★ 动态: ★★★★★ | 体积最小,完全自定义,编写难度最高 | 加载方法 1. 基于内存加载 使用WinAPI系统调用动态分配RWX内存,移动shellcode并启动执行线程。 优点: 使用标准WinAPI调用,可靠性高 内存区域可执行、可写、可读,便于修改shellcode 缺点: 容易被成熟的AV/EDR系统检测 2. 直接函数调用加载 将shellcode数组地址强制转换为函数指针并调用。 3. 使用回调函数加载 通过Windows回调函数执行Shellcode,系统将shellcode当作回调函数运行。 4. 创建线程执行加载 创建新线程并将入口点设置为shellcode地址。 5. 基于汇编加载 直接控制硬件,效率最高,但完全针对特定CPU架构和操作系统。 五、Shellcode加密技术 加密可隐藏恶意代码,使安全解决方案更难检测,并延长恶意软件在系统中的隐藏时间。 加密的利弊 优点:规避基于签名的检测 缺点:高熵值文件可能被AV/EDR标记为可疑 加密类型 1. XOR异或加密 异或运算特性: 反转性质:a XOR b XOR b = a 交换律:a XOR b = b XOR a 结合律:(a XOR b) XOR c = a XOR (b XOR c) 2. RC4加密 流密码,速度快且高效,使用同一函数进行加密和解密。 实现函数: rc4Init - 初始化rc4context结构 rc4Cipher - 执行RC4加密 示例代码: 3. AES加密 对称密钥算法,类型包括: AES128 - 128位密钥 AES192 - 192位密钥 AES256 - 256位密钥 操作模式: CBC - 需要初始化向量(IV) GCM AES结构: CNG (Cryptographic Next Generation)函数: BCryptOpenAlgorithmProvider - 加载CNG提供程序 BCryptGetProperty - 检索属性值 BCryptSetProperty - 初始化属性 BCryptGenerateSymmetricKey - 创建密钥对象 BCryptEncrypt/BCryptDecrypt - 加密/解密数据 BCryptDestroyKey - 销毁密钥对象 BCryptCloseAlgorithmProvider - 关闭算法提供者 六、Shellcode传递技术 1. Web远程文件读取 通过Loader从远程web加载shellcode,避免直接上传工具被拦截。 优点: 减少对多种工具的免杀需求 仅上传Loader降低被检测风险 2. 图片(BMP)隐写术 将Shellcode隐藏在BMP图片的RGB像素中,利用文件结构特性嵌入数据。 3. Shellcode加载器 将加载程序与实际Shellcode分离到不同进程空间,避免行为检测。 关键点: 运行时分析通常不关心程序会做什么 避免直接使用函数指针执行解密后的Shellcode 使用Loader间接加载和执行Shellcode